12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061moduletypeS=sigvalpbkdf1:password:Cstruct.t->salt:Cstruct.t->count:int->dk_len:int->Cstruct.tvalpbkdf2:password:Cstruct.t->salt:Cstruct.t->count:int->dk_len:int32->Cstruct.tendletcdivxy=(* This is lifted from Nocrypto.Uncommon.(//)
(formerly known as [cdiv]). It is part of the documented, publically
exposed _internal_ utility library not for public consumption, hence
the API break that prompted this copy-pasted function. *)ify<1thenraiseDivision_by_zeroelseifx>0then1+((x-1)/y)else0[@@inline]moduleMake(H:Mirage_crypto.Hash.S):S=structletpbkdf1~password~salt~count~dk_len=ifCstruct.lengthsalt<>8theninvalid_arg"salt should be 8 bytes"elseifcount<=0theninvalid_arg"count must be a positive integer"elseifdk_len<=0theninvalid_arg"derived key length must be a positive integer"elseifdk_len>H.digest_sizetheninvalid_arg"derived key too long"elseletrecloopt=function0->t|i->loop(H.digestt)(i-1)inCstruct.sub(loop(Cstruct.appendpasswordsalt)count)0dk_lenletpbkdf2~password~salt~count~dk_len=ifcount<=0theninvalid_arg"count must be a positive integer"elseifdk_len<=0ltheninvalid_arg"derived key length must be a positive integer"elseleth_len=H.digest_sizeanddk_len=Int32.to_intdk_leninletl=cdivdk_lenh_leninletr=dk_len-(l-1)*h_leninletblocki=letrecfuxor=function0->xor|j->letu=H.hmac~key:passworduinfu(Mirage_crypto.Uncommon.Cs.xorxoru)(j-1)inletint_i=Cstruct.create4inCstruct.BE.set_uint32int_i0(Int32.of_inti);letu_1=H.hmac~key:password(Cstruct.appendsaltint_i)infu_1u_1(count-1)inletrecloopblocks=function0->blocks|i->loop((blocki)::blocks)(i-1)inCstruct.concat(loop[Cstruct.sub(blockl)0r](l-1))endletpbkdf1~hash~password~salt~count~dk_len=letmoduleH=(val(Mirage_crypto.Hash.module_ofhash))inletmodulePBKDF=Make(H)inPBKDF.pbkdf1~password~salt~count~dk_lenletpbkdf2~prf~password~salt~count~dk_len=letmoduleH=(val(Mirage_crypto.Hash.module_ofprf))inletmodulePBKDF=Make(H)inPBKDF.pbkdf2~password~salt~count~dk_len