12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879moduleMakePedersenHash(Ec:Ec_sig.BASE)(Params:sigvalgenerators:Ec.tlistvalchunks_per_generator:intend)=structlethashiterator=letreccompute_m_jaccj=ifj=Params.chunks_per_generator+1then(acc,false)elseleta_opt=Iterator.Bit.nextiteratorin(* end of the bit stream, we do not continue, the boolean means we
processed the entire bitstring
*)ifOption.is_nonea_optthen(acc,true)elseleta=Option.valuea_opt~default:0inletb=Option.value(Iterator.Bit.nextiterator)~default:0inletc=Option.value(Iterator.Bit.nextiterator)~default:0inletenc_m_j=(1-(2*c))*(1+a+(2*b))in(* <M_i> accumulated *)letenc_m_j=Ec.Scalar.of_z(Z.of_intenc_m_j)inletpower=Ec.Scalar.powEc.Scalar.(one+one)(Z.of_int(4*(j-1)))inletacc=Ec.Scalar.addacc(Ec.Scalar.mulenc_m_jpower)incompute_m_jacc(j+1)inletreccompute_segment_i_incrementalacc_resgenerators=matchgeneratorswith|[]->raise(Invalid_argument"Not enough generators")|generator::generators->letsum_m_j,fully_processed=compute_m_jEc.Scalar.zero1in(* compute segment i *)letm_i=Ec.(mulgeneratorsum_m_j)inletacc_res=Ec.(addm_iacc_res)iniffully_processedthenacc_reselsecompute_segment_i_incrementalacc_resgeneratorsincompute_segment_i_incrementalEc.zeroParams.generatorsendmoduleZcash=MakePedersenHash(Jubjub.AffineEdwards)(struct(* generators from
https://github.com/zcash/librustzcash/blob/de1345a1c2f10b0843ab1f1ea6463b2330fdc673/zcash_primitives/src/constants.rs#L146 *)letgenerators=lettmp=[("0x73c016a42ded9578b5ea25de7ec0e3782f0c718f6f0fbadd194e42926f661b51","0x289e87a2d3521b5779c9166b837edc5ef9472e8bc04e463277bfabd432243cca");("0x15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e","0x015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891");("0x664321a58246e2f6eb69ae39f5c84210bae8e5c46641ae5c76d6f7c2b67fc475","0x362e1500d24eee9ee000a46c8e8ce8538bb22a7f1784b49880ed502c9793d457");("0x323a6548ce9d9876edc5f4a9cff29fd57d02d50e654b87f24c767804c1c4a2cc","0x2f7ee40c4b56cad891070acbd8d947b75103afa1a11f6a8584714beca33570e9");("0x3bd2666000b5479689b64b4e03362796efd5931305f2f0bf46809430657f82d1","0x494bc52103ab9d0a397832381406c9e5b3b9d8095859d14c99968299c3658aef");("0x63447b2ba31bb28ada049746d76d3ee51d9e5ca21135ff6fcb3c023258d32079","0x64ec4689e8bfb6e564cdb1070a136a28a80200d2c66b13a7436082119f8d629a")]inList.map(fun(u,v)->Jubjub.AffineEdwards.from_coordinates_exn~u:(Jubjub.AffineEdwards.Base.of_stringu)~v:(Jubjub.AffineEdwards.Base.of_stringv))tmpletchunks_per_generator=63end)