123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103moduleMain_Pack=Aggregation.Main_protocolmoduleL=Plompiler.LibCircuit(** Tells the meta-verification proof what to do with the public inputs
of the inner proofs *)moduletypeCircuitPI=sig(** number of public inputs in an individual inner proof *)valnb_inner:int(** total number of public inputs that are public for aPlonK *)valnb_outer:int(** predicate (in circuit form) on all of PI of the inner proofs and outer PI.
giving the argument [[x_1;x_2];[y_1;y_2]] means that x_1 ; x_2 are resp.
the fst and second PI of the first inner proof and y_1;y_2 the fst and snd
PI of the snd inner proof *)valcheck:switches:boolL.reprlist->outer:L.scalarL.reprlist->inner:L.scalarL.reprlistlist->boolL.reprL.t(** create outer from inner PI; note that the existence of this function
restricts the outer PI to be computable from the inner PI. *)valouter_of_inner:Main_Pack.scalarlistlist->Main_Pack.scalarlistendmoduletypeS=sigvalget_pi_module:string->(moduleCircuitPI)endmoduleNo_public_input:CircuitPI=structletnb_inner=0letnb_outer=0letcheck~switches:_~outer:_~inner:_=L.Bool.constanttrueletouter_of_inner_=[]endmoduleOne_public_input:CircuitPI=structletnb_inner=1letnb_outer=0letcheck~switches:_~outer:_~inner:_=L.Bool.constanttrueletouter_of_inner_=[]end(* PI_parameters module designed for a rollup. There are 2 public inputs
per proof, for the initial and final state respectively;
everything is hidden expect the initial state of the very first proof &
the final state of the very last proof. *)moduleRollup_example:CircuitPI=structletnb_inner=2letnb_outer=2(* /!\ Note that this function assumes that the first proof is not turned
off by the switches (ie the first switch is true);
If the first proof is turned off, this function will NOT return the
expected result. *)letcheck~switches~outer~inner=letopenLin(* we unroll the first iteration of the fold to start with a prec_out *)let*last_out,rel_inner_pi=fold2M(fun(prec_out,res)inner_piswitch->matchinner_piwith|[current_in;current_out]->(* if switch is true then we compare the roots and replace the
old root by the new one; else we fill [ok] with true and keep
the old root for next comparison. *)let*ok=let*n_switch=Bool.bnotswitchinlet*compare=equalprec_outcurrent_ininBool.born_switchcompareinlet*out=Bool.ifthenelseswitchcurrent_outprec_outinletres=ok::resinret(out,res)|_->failwith"Check_pi : invalid format for inner_pi.")(List.nth(List.hdinner)1,[])(List.tlinner)(List.tlswitches)inmatchouterwith|[first_root;last_root]->let*first_root=equalfirst_rootList.(hd(hdinner))inlet*last_root=equallast_rootlast_outinBool.band_list([first_root;last_root]@rel_inner_pi)|_->failwith"Check_pi : invalid format for outer_pi."letouter_of_innerinner_pi=letrecget_last=function|[[_;x]]->x|_::l->get_lastl|_->failwith"outer_of_inner : wrong inner_pi format"in[List.(hd(hdinner_pi));get_lastinner_pi]end