1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798(*****************************************************************************)(* *)(* MIT License *)(* Copyright (c) 2022 Nomadic Labs <contact@nomadic-labs.com> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)moduletypeS=sigtypescalarvalpowers:int->scalar->scalararrayvalbatch:scalar->scalarlist->scalarvalbuild_quadratic_non_residues:int->scalararrayvalrandom_fr_list:Bytes.t->int->scalarlist*Bytes.tvalrandom_fr:Bytes.t->scalar*Bytes.tendmoduleMake(Scalar:Bls.Scalar_sig):Swithtypescalar=Scalar.t=struct(* convert int to Fr scalar (algo based on fast exponentiation model) *)typescalar=Scalar.tletsucc=Scalar.(addone)(* computes [| 1; x; x²; x³; ...; xᵈ⁻¹ |] *)letpowersdx=Utils.build_arrayScalar.oneScalar.(mulx)d(* [batch x l] adds the elements of l scaled by ascending powers of x *)letbatchxl=List.fold_left(funaccy->Scalar.((x*acc)+y))Scalar.zero(List.revl)(* quadratic non-residues for Sid *)letbuild_quadratic_non_residueslen=letis_nonresiduen=Z.(equal(Scalar.legendre_symboln)Z.(-one))inletrecnextn=succn|>funn->ifis_nonresiduenthennelsenextninUtils.build_arrayScalar.onenextlenletz_to_bytesn=Z.to_bitsn|>Bytes.of_string(*
* a is the element to hash
* to_bytes_func, add, one is the function of conversion to_bytes, the function of addition, the one compatible with a type
* returns x ∈ F built from the hash of a
* if hash a not in F, returns hash (a+1) until its value belongs to F
*)letrechash_to_Fra=letb=z_to_bytesainlethashed_b=Utils.Hash.hash_bytes[b]inassert(Bytes.lengthhashed_b=32);letx_fr=Scalar.of_bytes_opthashed_binmatchx_frwith|Somea->a(* x_fr can be converted *)|None->hash_to_Fr(Z.succa)letgenerate_random_fr?state()=(matchstatewithNone->()|Somes->Random.set_states);letn0=Z.of_int64@@Random.int64Int64.max_intinletn1=Z.of_int64@@Random.int64Int64.max_intinletn2=Z.of_int64@@Random.int64Int64.max_intinletn3=Z.of_int64@@Random.int64Int64.max_intinletn1_64=Z.(n1lsl64)inletn2_128=Z.(n2lsl128)inletn3_192=Z.(n3lsl192)inletgamma_z=Z.(n0+n1_64+n2_128+n3_192)inletgamma_fr=hash_to_Frgamma_zingamma_fr(* generate nb_values scalar of Fr based on seed transcript *)letrandom_fr_listtranscriptnb_values=lettranscript_array,hashed_transcript=Utils.Hash.bytes_to_seedtranscriptinRandom.full_inittranscript_array;(List.initnb_values(fun_->generate_random_fr()),hashed_transcript)letrandom_frtranscript=letl,hashed_transcript=random_fr_listtranscript1in(List.hdl,hashed_transcript)end