Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file chacha20.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159letrotate_leftnb=letopenInt32inlethi=shift_leftnbinletlo=shift_right_logicaln(32-b)inlogorhiloletquarter_round(a,b,c,d)=letopenInt32in(*1. a += b; d ^= a; d <<<= 16;*)leta=addabinletd=logxordainletd=rotate_leftd16in(*2. c += d; b ^= c; b <<<= 12;*)letc=addcdinletb=logxorbcinletb=rotate_leftb12in(*3. a += b; d ^= a; d <<<= 8;*)leta=addabinletd=logxordainletd=rotate_leftd8in(*4. c += d; b ^= c; b <<<= 7;*)letc=addcdinletb=logxorbcinletb=rotate_leftb7in(a,b,c,d)typestate=int32array[@@derivingeq,show]letmake_statel=ifList.lengthl=16thenArray.of_listlelseinvalid_arg"make_state"letgetsi=s.(i)letsetivs=letfj=ifi=jthenvelsegetsjinArray.init16fletquarter_round_states(ia,ib,ic,id)=leta=getsiainletb=getsibinletc=getsicinletd=getsidinletna,nb,nc,nd=quarter_round(a,b,c,d)ins|>setiana|>setibnb|>seticnc|>setidndtypekey=KeyofCstruct.tletmake_keykey=ifCstruct.lenkey=32thenOk(Keykey)elseError"wrong key length"letkey_words(Keykey)=[Cstruct.LE.get_uint32key0;Cstruct.LE.get_uint32key4;Cstruct.LE.get_uint32key8;Cstruct.LE.get_uint32key12;Cstruct.LE.get_uint32key16;Cstruct.LE.get_uint32key20;Cstruct.LE.get_uint32key24;Cstruct.LE.get_uint32key28]typenonce=NonceofCstruct.tletmake_noncenonce=ifCstruct.lennonce=12thenOk(Noncenonce)elseError"wrong nonce length"letnonce_words(Noncenonce)=[Cstruct.LE.get_uint32nonce0;Cstruct.LE.get_uint32nonce4;Cstruct.LE.get_uint32nonce8]let(>>=)xf=matchxwith|Oky->fy|Error_ase->eletmake_state_for_encryption_checked~key~noncecount=letconstant_words=[0x61707865l;0x3320646el;0x79622d32l;0x6b206574l]inletcount_words=[count]inmake_state@@List.concat[constant_words;key_wordskey;count_words;nonce_wordsnonce]letmake_state_for_encryption~key~nonce~count=make_keykey>>=funkey->make_noncenonce>>=funnonce->Ok(make_state_for_encryption_checked~key~noncecount)letreciteratenfx=ifn=0thenxelseiterate(n-1)f(fx)letadd_stateab=Array.init16(funi->Int32.add(getai)(getbi))letprocesss0=letqris=quarter_round_statesiinletinner_blocks=s|>qr(0,4,8,12)|>qr(1,5,9,13)|>qr(2,6,10,14)|>qr(3,7,11,15)|>qr(0,5,10,15)|>qr(1,6,11,12)|>qr(2,7,8,13)|>qr(3,4,9,14)inadd_states0(iterate10inner_blocks0)letserializes=letcs=Cstruct.create64infori=0to15doCstruct.LE.set_uint32cs(4*i)(getsi)done;csletrecsplit_into_blockscs=letlen=Cstruct.lencsinletblock_len=64iniflen=0then[]elseiflen<block_lenthen[cs]elseletblock,rest=Cstruct.splitcsblock_leninblock::split_into_blocksrestletxor_blockab=letn=Cstruct.lenainletr=Cstruct.createninfori=0ton-1doletv_a=Cstruct.get_uint8aiinletv_b=Cstruct.get_uint8biinletv=v_alxorv_binCstruct.set_uint8rivdone;rletencrypt~key~counter~nonceplaintext=make_keykey>>=funkey->make_noncenonce>>=funnonce->letblocks=split_into_blocksplaintextinletrj=ref0inletencrypted_blocks=List.rev_map(funblock->letj=!rjinincrrj;Int32.of_intj|>Int32.addcounter|>make_state_for_encryption_checked~key~nonce|>process|>serialize|>xor_blockblock)blocks|>List.revinOk(Cstruct.concatencrypted_blocks)