123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165(*****************************************************************************)(* *)(* 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. *)(* *)(*****************************************************************************)moduleSMap=Plonk.SMap(** Extension of the KZG_pack implementation with additional
types and functions used in by Distributed_prover *)moduleMake(Pack:Aggregation.Pack.Aggregator)(PC:Kzg.PC_for_distribution_sigwithtypeBasePC.Scalar.t=Pack.scalarandtypeCommitment.t=Pack.g1SMap.t)=structmoduleBasePC=Aggregation.Polynomial_commitment.Make_impl(Pack)(PC)moduleCommitment=structincludeBasePC.Commitmentletrecombinel=List.fold_leftPack.combine(List.hdl)(List.tll)letrecombine_prover_auxl=letcm=PC.Commitment.recombine(List.mapfstl)inletp_a=PC.Commitment.recombine_prover_aux(List.mapsndl)in(cm,p_a)letempty=Pack.empty_commitmentletempty_prover_aux=(PC.Commitment.empty,PC.Commitment.empty_prover_aux)endinclude(BasePC:moduletypeofBasePCwithmoduleCommitment:=Commitment)typeworker_msg=Scalar.t*stringlistlist[@@derivingrepr]typemain_prover_msg=Poly.tlist*Commitment.prover_auxlist[@@derivingrepr]typemain_prover_state=Public_parameters.prover*transcript*Scalar.t*querylist*Scalar.tSMap.tlist*main_prover_msgletmerge_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_prove_main1(pp:Public_parameters.prover)transcriptquery_listanswer_listsecret_listprover_aux_list=lettranscript=expand_with_queryquery_listtranscriptinlettranscript=expand_with_answeranswer_listtranscriptinletr,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)in(* The main thread simulates a worker, since it is the only one who knows
the information about t_map, g_map, plook_map. We need to pad a dummy
secret and a dummy prover_aux at the end, corresponding to f_map, which
the main thread does not have information about. *)letmain_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:Public_parameters.prover),transcript,r,query_list,s_list,main_msg)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=expand_with_proofprooftranscriptin(proof,transcript)endmoduleKzg_pack_impl=Make(Aggregation.Pack)(Kzg.Kzg_impl)