123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245(*****************************************************************************)(* *)(* Copyright (c) 2020-2021 Danny Willems <be.danny.willems@gmail.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. *)(* *)(*****************************************************************************)moduleStubs=Blst_bindings.StubsG2(Blst_stubs)moduleG2=structtypet=Blst_bindings.Types.blst_g2_tCtypes.ptrexceptionNot_on_curveofBytes.tletsize_in_bytes=192moduleScalar=Frletempty()=Blst_bindings.Types.allocate_g2()letcheck_bytesbs=letbuffer=Blst_bindings.Types.allocate_g2_affine()inStubs.deserializebuffer(Ctypes.ocaml_bytes_startbs)=0letof_bytes_optbs=letbuffer_affine=Blst_bindings.Types.allocate_g2_affine()inifBytes.lengthbs<>size_in_bytesthenNoneelseletres=Stubs.deserializebuffer_affine(Ctypes.ocaml_bytes_startbs)inifres=0then(letbuffer=Blst_bindings.Types.allocate_g2()inStubs.from_affinebufferbuffer_affine;letis_in_prime_subgroup=Stubs.in_g2bufferinifis_in_prime_subgroupthenSomebufferelseNone)elseNoneletof_bytes_exnbs=matchof_bytes_optbswithNone->raise(Not_on_curvebs)|Somep->pletof_compressed_bytes_optbs=letbuffer_affine=Blst_bindings.Types.allocate_g2_affine()inletres=Stubs.uncompressbuffer_affine(Ctypes.ocaml_bytes_startbs)inifres=0then(letbuffer=Blst_bindings.Types.allocate_g2()inStubs.from_affinebufferbuffer_affine;letis_in_prime_subgroup=Stubs.in_g2bufferinifis_in_prime_subgroupthenSomebufferelseNone)elseNoneletof_compressed_bytes_exnbs=matchof_compressed_bytes_optbswith|None->raise(Not_on_curvebs)|Somep->pletzero=letbytes=Bytes.of_string"\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"inof_compressed_bytes_exnbytesletone=letbytes=Bytes.of_string"\147\224+`Rq\159`}\172\211\160\136'OeYk\208\208\153 \
\182\026\181\218a\187\220\127PI3L\241\018\019\148]W\229\172}\005]\004+~\002J\162\178\240\143\n\
\145&\b\005'-\197\016Q\198\228z\212\250@;\
\002\180Q\011dz\227\209w\011\172\003&\168\005\187\239\212\128V\200\193!\189\184"inof_compressed_bytes_exnbytesletto_bytesp=letbuffer=Bytes.makesize_in_bytes'\000'inStubs.serialize(Ctypes.ocaml_bytes_startbuffer)p;bufferletto_compressed_bytesp=letbuffer=Bytes.make(size_in_bytes/2)'\000'inStubs.compress(Ctypes.ocaml_bytes_startbuffer)p;bufferletaddxy=(* dadd must be used to be complete. add does not work when it is the same
point
*)letbuffer=Blst_bindings.Types.allocate_g2()inStubs.daddbufferxy;bufferletdoublex=letbuffer=Blst_bindings.Types.allocate_g2()inStubs.doublebufferx;bufferletmul_bitsgbytes=letbuffer=Blst_bindings.Types.allocate_g2()inStubs.multbufferg(Ctypes.ocaml_bytes_startbytes)(Unsigned.Size_t.of_int(Bytes.lengthbytes*8));bufferletmulgn=letbytes=Fr.to_bytesninmul_bitsgbytesletb=letbuffer=Blst_bindings.Types.allocate_fq2()inletfq_four=Fq.(one+one+one+one)inBlst_bindings.Types.fq2_assignbufferfq_fourfq_four;bufferletclear_cofactorp=letbytes=Z.of_string_base16"5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5"inletbytes=Bytes.of_string(Z.to_bitsbytes)inletres=mul_bitspbytesinresletrecrandom?state()=(matchstatewithNone->()|Somestate->Random.set_statestate);letx=Fq2.random()inletxx=Fq2.(x*x)inletxxx=Fq2.(x*xx)inletxxx_plus_b=Fq2.(xxx+b)inlety_opt=Fq2.sqrt_optxxx_plus_binmatchy_optwith|None->random()|Somey->lety=ifRandom.bool()thenyelseFq2.negateyinletp_affine=Blst_bindings.Types.allocate_g2_affine()inBlst_bindings.Types.g2_affine_set_xp_affinex;Blst_bindings.Types.g2_affine_set_yp_affiney;letp=Blst_bindings.Types.allocate_g2()inStubs.from_affinepp_affine;letp=clear_cofactorpinpleteqg1g2=Stubs.equalg1g2letis_zerox=eqxzeroletorder_minus_one=Scalar.(negateone)letnegateg=letbuffer=Blst_bindings.Types.g2_copyginStubs.cnegbuffertrue;bufferletof_z_opt~x~y=let(x1,x2)=xinlet(y1,y2)=yinletp_affine=Blst_bindings.Types.allocate_g2_affine()inletx1=Fq.of_zx1inletx2=Fq.of_zx2inlety1=Fq.of_zy1inlety2=Fq.of_zy2inletx=Blst_bindings.Types.allocate_fq2()inlety=Blst_bindings.Types.allocate_fq2()inBlst_bindings.Types.fq2_assignxx1x2;Blst_bindings.Types.fq2_assignyy1y2;Blst_bindings.Types.g2_affine_set_xp_affinex;Blst_bindings.Types.g2_affine_set_yp_affiney;letp=Blst_bindings.Types.allocate_g2()inStubs.from_affinepp_affine;letis_ok=Stubs.in_g2pinifis_okthenSomepelseNoneletfft~domain~points=letmoduleM=structtypegroup=ttypescalar=Scalar.tletzero=zeroletmul=mulletadd=addletsubxy=addx(negatey)letinverse_exn_scalar=Scalar.inverse_exnletscalar_of_z=Scalar.of_zendinFft.fft(moduleM)~domain~pointsletifft~domain~points=letmoduleM=structtypegroup=ttypescalar=Scalar.tletzero=zeroletmul=mulletadd=addletsubxy=addx(negatey)letinverse_exn_scalar=Scalar.inverse_exnletscalar_of_z=Scalar.of_zendinFft.ifft(moduleM)~domain~pointslethash_to_curvemessagedst=letmessage_length=Bytes.lengthmessageinletdst_length=Bytes.lengthdstinletbuffer=Blst_bindings.Types.allocate_g2()inStubs.hash_to_curvebuffer(Ctypes.ocaml_bytes_startmessage)(Unsigned.Size_t.of_intmessage_length)(Ctypes.ocaml_bytes_startdst)(Unsigned.Size_t.of_intdst_length)(Ctypes.ocaml_bytes_startBytes.empty)Unsigned.Size_t.zero;bufferendincludeG2