123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204(*****************************************************************************)(* *)(* 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. *)(* *)(*****************************************************************************)moduletypeRAW_STUBS=sigvalfinal_exponentiation:Bytes.t->Bytes.tvalmiller_loop_simple:Bytes.t->Bytes.t->Bytes.tvalpairing:Bytes.t->Bytes.t->Bytes.tvalmiller_loop_2:Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.tvalmiller_loop_3:Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.tvalmiller_loop_4:Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.tvalmiller_loop_5:Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.tvalmiller_loop_6:Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.t->Bytes.tendmoduleMake(G1:G1.UNCOMPRESSED)(G2:G2.UNCOMPRESSED)(GT:Fq12.T)(Stubs:RAW_STUBS):sigexceptionFailToComputeFinalExponentiationofGT.tvalmiller_loop:(G1.t*G2.t)list->GT.t(** Compute the miller loop on a single tuple of point *)valmiller_loop_simple:G1.t->G2.t->GT.t(** Compute a pairing result of a list of points *)valpairing:G1.t->G2.t->GT.t(** Compute the final exponentiation of the given point. Returns a [None] if
the point is null *)valfinal_exponentiation_opt:GT.t->GT.toption(** Compute the final exponentiation of the given point. Raise
[FailToComputeFinalExponentiation] if the point is null *)valfinal_exponentiation_exn:GT.t->GT.tend=structmoduleG1=G1moduleG2=G2moduleGT=GTexceptionFailToComputeFinalExponentiationofGT.tletmiller_loop_simple(g1:G1.t)(g2:G2.t):GT.t=letres=Stubs.miller_loop_simple(G1.to_bytesg1)(G2.to_bytesg2)inGT.of_bytes_exnresletpairing(g1:G1.t)(g2:G2.t):GT.t=letres=Stubs.pairing(G1.to_bytesg1)(G2.to_bytesg2)inGT.of_bytes_exnresletfinal_exponentiation_exn(e:GT.t):GT.t=ifGT.is_zeroethenraise(FailToComputeFinalExponentiatione)elseletres=Stubs.final_exponentiation(GT.to_bytese)inGT.of_bytes_exnresletfinal_exponentiation_opt(e:GT.t):GT.toption=ifGT.is_zeroethenNoneelseletres=Stubs.final_exponentiation(GT.to_bytese)inGT.of_bytes_optresletmiller_loop(xs:(G1.t*G2.t)list):GT.t=letrecfaccxs=matchxswith|[]->acc|[(g1,g2)]->GT.mul(miller_loop_simpleg1g2)acc|[(g1_1,g2_1);(g1_2,g2_2)]->letres=Stubs.miller_loop_2(G1.to_bytesg1_1)(G1.to_bytesg1_2)(G2.to_bytesg2_1)(G2.to_bytesg2_2)inGT.mul(GT.of_bytes_exnres)acc|[(g1_1,g2_1);(g1_2,g2_2);(g1_3,g2_3)]->letres=Stubs.miller_loop_3(G1.to_bytesg1_1)(G1.to_bytesg1_2)(G1.to_bytesg1_3)(G2.to_bytesg2_1)(G2.to_bytesg2_2)(G2.to_bytesg2_3)inGT.mul(GT.of_bytes_exnres)acc|[(g1_1,g2_1);(g1_2,g2_2);(g1_3,g2_3);(g1_4,g2_4)]->letres=Stubs.miller_loop_4(G1.to_bytesg1_1)(G1.to_bytesg1_2)(G1.to_bytesg1_3)(G1.to_bytesg1_4)(G2.to_bytesg2_1)(G2.to_bytesg2_2)(G2.to_bytesg2_3)(G2.to_bytesg2_4)inGT.mul(GT.of_bytes_exnres)acc|[(g1_1,g2_1);(g1_2,g2_2);(g1_3,g2_3);(g1_4,g2_4);(g1_5,g2_5)]->letres=Stubs.miller_loop_5(G1.to_bytesg1_1)(G1.to_bytesg1_2)(G1.to_bytesg1_3)(G1.to_bytesg1_4)(G1.to_bytesg1_5)(G2.to_bytesg2_1)(G2.to_bytesg2_2)(G2.to_bytesg2_3)(G2.to_bytesg2_4)(G2.to_bytesg2_5)inGT.mul(GT.of_bytes_exnres)acc|(g1_1,g2_1)::(g1_2,g2_2)::(g1_3,g2_3)::(g1_4,g2_4)::(g1_5,g2_5)::(g1_6,g2_6)::xs->letres=Stubs.miller_loop_6(G1.to_bytesg1_1)(G1.to_bytesg1_2)(G1.to_bytesg1_3)(G1.to_bytesg1_4)(G1.to_bytesg1_5)(G1.to_bytesg1_6)(G2.to_bytesg2_1)(G2.to_bytesg2_2)(G2.to_bytesg2_3)(G2.to_bytesg2_4)(G2.to_bytesg2_5)(G2.to_bytesg2_6)inletacc=GT.mul(GT.of_bytes_exnres)accinfaccxsinifList.lengthxs=0thenfailwith"Empty list of points given"elsefGT.onexsend