123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176(*****************************************************************************)(* *)(* 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. *)(* *)(*****************************************************************************)openKzg.BlsopenKzg.UtilsmoduleSMap=Kzg.SMapmoduletypeSuper_PC_sig=sigincludePolynomial_commitment.PC_for_distribution_sigtypeprover_aux={r:Scalar.t;s_list:Scalar.tSMap.tlist}valprove_super_aggregation:Public_parameters.prover->Transcript.t->Poly.tSMap.tlist->Commitment.prover_auxlist->querylist->Scalar.tSMap.tSMap.tlist->(proof*prover_aux)*Transcript.tvalverify_super_aggregation:Public_parameters.verifier->Transcript.t->Commitment.tlist->querylist->Scalar.tSMap.tlist->proof->bool*Scalar.t*Transcript.tend(** Extension of the KZG_pack implementation with additional
types and functions used in by Distributed_prover *)moduleKzg_pack_impl=structmodulePack=Aggregation.PackmodulePC=Polynomial_commitment.Kzg_implmoduleBasePC=Aggregation.Polynomial_commitment.Make_impl(PC)include(BasePC:moduletypeofBasePC)typeworker_msg=Scalar.t*stringlistlist[@@derivingrepr]typemain_prover_msg=Poly.tlist*Commitment.prover_auxlist[@@derivingrepr]typemain_prover_state=Public_parameters.prover*Transcript.t*Scalar.t*querylist*Scalar.tSMap.tlist*main_prover_msgtypepartial_prover_aux={r:Scalar.t;s_list:Scalar.tSMap.tlist}letmerge_answers:answerlist->answer=letopenSMapinList.fold_left(union(fun_km1m2->Some(union_disjointm1m2)))emptyletdistributed_prove_workerf_map_listprover_aux_list(r,poly_keys_list)=letgen_powersrl=List.mapi(funix->(x,Scalar.powr@@Z.of_inti))l|>SMap.of_listinletr_powers_list=List.map(gen_powersr)poly_keys_listinletf_list=List.map2(funf_mapr_map->letpolys=SMap.bindingsf_mapinletcoeffs=List.map(fun(name,_)->SMap.findnamer_map)polysinPoly.linear(List.mapsndpolys)coeffs)f_map_listr_powers_listin(f_list,prover_aux_list)letdistributed_expand_transcripttranscriptquery_listanswer_list=lettranscript=Transcript.list_expandquery_tquery_listtranscriptinTranscript.list_expandanswer_tanswer_listtranscriptletdistributed_prove_main1(pp:Public_parameters.prover)transcriptquery_listanswer_listsecret_listprover_aux_list:worker_msg*main_prover_state=letr,transcript=Fr_generation.random_frtranscriptinlets_list=List.map(batch_answersr)answer_listinletget_keysmap_map=SMap.fold(fun_macc->SMap.union(fun__x->Somex)macc)map_mapSMap.empty|>SMap.bindings|>List.mapfstinletpoly_keys_list=List.mapget_keysanswer_listinletworker_message=(r,poly_keys_list)inletmain_msg=distributed_prove_workersecret_listprover_aux_listworker_messageinletstate=(pp,transcript,r,query_list,s_list,main_msg)in(worker_message,state)letdistributed_prove_main2((pp,transcript,r,query_list,s_list,main_msg):main_prover_state)worker_msg_list=letworker_msg_list=main_msg::worker_msg_listinletf_list_list=List.mapfstworker_msg_listinletf_list=Plonk.List.mapn(List.fold_leftPoly.addPoly.zero)f_list_listinletprover_aux_list_list=List.mapsndworker_msg_listinletprover_aux_list=Plonk.List.mapnCommitment.recombine_prover_auxprover_aux_list_listin(* [cmts_list] is a list of G1.t SMap.t, containing the PC commitments to
every polynomial (note that PC.Commitment.t = Bls12_381.G1.t SMap.t) *)letcmts_list=List.map(fun(cmts,_prover_aux)->List.mapsnd@@SMap.bindingscmts|>Array.of_list)prover_aux_listin(* [packed_values] has type [G1.t list] and it is the result of batching
each map in [cmt_list] with powers of [r].
[pack_proof] asserts that [packed_values] was correctly computed. *)let(packed_values,pack_proof),transcript=Pack.provepp.pp_pack_provertranscriptrcmts_listin(* prepare [f_list] and [s_list], the batched version of [f_map_list]
polys and [answer_list] (using randomness [r]) by selecting a dummy
name for them [string_of_int i] in order to call the underlying PC *)letf_map_list=List.mapi(funil->SMap.singleton(string_of_inti)l)f_listinlets_map_list=List.mapi(funim->SMap.map(funs->SMap.singleton(string_of_inti)s)m)s_listinletprover_aux_list=List.mapsndprover_aux_listin(* call the underlying PC prover on the batched polynomials/evaluations
the verifier will verify such proof using [packed_values] as the
commitments *)letpc_proof,transcript=PC.provepp.pp_pc_provertranscriptf_map_listprover_aux_listquery_lists_map_listinletproof={pc_proof;packed_values;pack_proof}inlettranscript=Transcript.expandproof_tprooftranscriptin(proof,transcript,{s_list;r})end