123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566externalsalsa_core:int->string->bytes->unit="caml_salsa_core"[@@noalloc]letsalsa20_corecounti=letl=64inifString.lengthi<>ltheninvalid_arg"input must be 16 blocks of 32 bits"elseleto=Bytes.createlinsalsa_corecountio;Bytes.unsafe_to_stringoletsalsa20_8_corei=salsa20_core4iletscrypt_block_mixbr=letb'=Bytes.create(String.lengthb)inletx=Bytes.create64inBytes.unsafe_blit_stringb((2*r-1)*64)x064;fori=0to2*r-1doletb_i=Bytes.unsafe_of_string(String.subb(i*64)64)inMirage_crypto.Uncommon.unsafe_xor_into(Bytes.unsafe_to_stringx)~src_off:0b_i~dst_off:064;Bytes.unsafe_blit_string(salsa20_8_core(Bytes.unsafe_to_stringb_i))0x064;letoffset=(imod2)lsl(max0(r/2-1))+i/2inBytes.blitx0b'(offset*64)64done;b'letscrypt_ro_mixb~r~n=letblen=r*128inletx=ref(Bytes.copyb)inletv=Bytes.create(blen*n)infori=0ton-1doBytes.unsafe_blit!x0v(blen*i)blen;x:=scrypt_block_mix(Bytes.unsafe_to_string!x)rdone;for_=0ton-1doletintegerifyx=letk=Bytes.get_int32_lex(128*r-64)inletn'=n-1inInt32.(to_int(logandk(of_intn')))inletj=integerify!xinMirage_crypto.Uncommon.unsafe_xor_into(Bytes.unsafe_to_stringv)~src_off:(blen*j)!x~dst_off:0blen;x:=scrypt_block_mix(Bytes.unsafe_to_string!x)r;done;!xletscrypt~password~salt~n~r~p~dk_len=letis_power_of_2x=(xland(x-1))=0inifn<=1theninvalid_arg"n must be larger than 1"elseifnot(is_power_of_2n)theninvalid_arg"n must be a power of 2"elseifp<=0theninvalid_arg"p must be a positive integer"elseifp>(Int64.to_int(Int64.div0xffffffffL4L)/r)theninvalid_arg"p too big"elseifdk_len<=0ltheninvalid_arg"derived key length must be a positive integer";letrecpartitionbblocks=function|0->blocks|i->letoff=(i-1)*r*128inletblock=Bytes.unsafe_of_string(String.subboff(r*128))inpartitionb(block::blocks)(i-1)inletblen=Int32.of_int(128*r*p)inletdk=Pbkdf.pbkdf2~prf:`SHA256~password~salt~count:1~dk_len:bleninletb=partitiondk[]pinletb'=List.map(scrypt_ro_mix~r~n)binletsalt=String.concat""(List.mapBytes.unsafe_to_stringb')inPbkdf.pbkdf2~prf:`SHA256~password~salt~count:1~dk_len