11#![ allow( clippy:: needless_range_loop) ]
2-
2+ use crate :: { bellman_ce , utils } ;
33use bellman_ce:: kate_commitment:: { Crs , CrsForMonomialForm } ;
4+ use bellman_ce:: pairing:: bn256;
5+ use bellman_ce:: pairing:: bn256:: Bn256 ;
6+ use bellman_ce:: pairing:: ff:: ScalarEngine ;
7+ use bellman_ce:: pairing:: { CurveAffine , Engine } ;
8+ use bellman_ce:: plonk:: better_better_cs:: cs:: PlonkCsWidth4WithNextStepAndCustomGatesParams ;
9+ use bellman_ce:: plonk:: better_better_cs:: cs:: ProvingAssembly ;
10+ use bellman_ce:: plonk:: better_better_cs:: cs:: TrivialAssembly ;
11+ use bellman_ce:: plonk:: better_better_cs:: cs:: Width4MainGateWithDNext ;
12+ use bellman_ce:: plonk:: better_better_cs:: cs:: { Circuit , Setup } ;
13+ use bellman_ce:: plonk:: better_better_cs:: setup:: VerificationKey ;
14+ use bellman_ce:: plonk:: better_better_cs:: verifier:: verify as core_verify;
15+ use bellman_ce:: plonk:: commitments:: transcript:: keccak_transcript:: RollingKeccakTranscript ;
416use bellman_ce:: plonk:: {
517 better_cs:: cs:: PlonkCsWidth4WithNextStepParams ,
618 better_cs:: keys:: { Proof as OldProof , VerificationKey as OldVerificationKey } ,
719} ;
8- use bellman_ce:: SynthesisError ;
9- use franklin_crypto:: bellman:: pairing:: bn256;
10- use franklin_crypto:: bellman:: pairing:: bn256:: Bn256 ;
11- use franklin_crypto:: bellman:: pairing:: ff:: ScalarEngine ;
12- use franklin_crypto:: bellman:: pairing:: { CurveAffine , Engine } ;
13- use franklin_crypto:: bellman:: plonk:: better_better_cs:: cs:: PlonkCsWidth4WithNextStepAndCustomGatesParams ;
14- use franklin_crypto:: bellman:: plonk:: better_better_cs:: cs:: ProvingAssembly ;
15- use franklin_crypto:: bellman:: plonk:: better_better_cs:: cs:: TrivialAssembly ;
16- use franklin_crypto:: bellman:: plonk:: better_better_cs:: cs:: Width4MainGateWithDNext ;
17- use franklin_crypto:: bellman:: plonk:: better_better_cs:: cs:: { Circuit , Setup } ;
18- use franklin_crypto:: bellman:: plonk:: better_better_cs:: setup:: VerificationKey ;
19- use franklin_crypto:: bellman:: plonk:: better_better_cs:: verifier:: verify as core_verify;
20- use franklin_crypto:: bellman:: plonk:: commitments:: transcript:: keccak_transcript:: RollingKeccakTranscript ;
21- use franklin_crypto:: bellman:: worker:: Worker ;
20+ use bellman_ce:: worker:: Worker ;
21+ use bellman_ce:: { Field , SynthesisError } ;
2222use franklin_crypto:: plonk:: circuit:: bigint:: field:: RnsParameters ;
2323use franklin_crypto:: plonk:: circuit:: verifier_circuit:: affine_point_wrapper:: aux_data:: { AuxData , BN256AuxData } ;
2424use franklin_crypto:: plonk:: circuit:: verifier_circuit:: data_structs:: IntoLimbedWitness ;
2525use franklin_crypto:: plonk:: circuit:: Width4WithCustomGates ;
2626use franklin_crypto:: rescue:: bn256:: Bn256RescueParams ;
2727use itertools:: Itertools ;
28- pub use recurisive_vk_codegen:: types:: { AggregatedProof , RecursiveVerificationKey } ;
29- use recursive_aggregation_circuit:: circuit:: {
28+ use recurisive_vk_codegen:: circuit:: {
3029 create_recursive_circuit_setup, create_recursive_circuit_vk_and_setup, create_vks_tree, make_aggregate,
3130 make_public_input_and_limbed_aggregate, RecursiveAggregationCircuitBn256 ,
3231} ;
32+ pub use recurisive_vk_codegen:: types:: { AggregatedProof , RecursiveVerificationKey } ;
3333
3434// only support depth<8. different depths don't really make performance different
3535const VK_TREE_DEPTH : usize = 7 ;
@@ -135,6 +135,42 @@ pub fn prove(
135135 } )
136136}
137137
138+ fn verify_subproof_limbs (
139+ proof : & AggregatedProof ,
140+ vk : & VerificationKey < Bn256 , RecursiveAggregationCircuitBn256 > ,
141+ ) -> Result < bool , SynthesisError > {
142+ let mut rns_params = RnsParameters :: < Bn256 , <Bn256 as Engine >:: Fq > :: new_for_field ( 68 , 110 , 4 ) ;
143+
144+ //keep the behavior same as recursive_aggregation_circuit
145+ rns_params. set_prefer_single_limb_allocation ( true ) ;
146+
147+ let aggr_limbs_nums: Vec < utils:: BigUint > = proof. aggr_limbs . iter ( ) . map ( utils:: fe_to_biguint) . collect ( ) ;
148+ //we need 4 Fr to build 2 G1Affine ...
149+ let num_consume = rns_params. num_limbs_for_in_field_representation ;
150+ assert_eq ! ( num_consume * 4 , aggr_limbs_nums. len( ) ) ;
151+
152+ let mut start = 0 ;
153+ let pg_x = utils:: witness_to_field ( & aggr_limbs_nums[ start..start + num_consume] , & rns_params) ;
154+ start += num_consume;
155+ let pg_y = utils:: witness_to_field ( & aggr_limbs_nums[ start..start + num_consume] , & rns_params) ;
156+ start += num_consume;
157+ let px_x = utils:: witness_to_field ( & aggr_limbs_nums[ start..start + num_consume] , & rns_params) ;
158+ start += num_consume;
159+ let px_y = utils:: witness_to_field ( & aggr_limbs_nums[ start..start + num_consume] , & rns_params) ;
160+
161+ let pair_with_generator = bn256:: G1Affine :: from_xy_checked ( pg_x, pg_y) . map_err ( |_| SynthesisError :: Unsatisfiable ) ?;
162+ let pair_with_x = bn256:: G1Affine :: from_xy_checked ( px_x, px_y) . map_err ( |_| SynthesisError :: Unsatisfiable ) ?;
163+
164+ let valid = Bn256 :: final_exponentiation ( & Bn256 :: miller_loop ( & [
165+ ( & pair_with_generator. prepare ( ) , & vk. g2_elements [ 0 ] . prepare ( ) ) ,
166+ ( & pair_with_x. prepare ( ) , & vk. g2_elements [ 1 ] . prepare ( ) ) ,
167+ ] ) )
168+ . ok_or ( SynthesisError :: Unsatisfiable ) ?
169+ == <Bn256 as Engine >:: Fqk :: one ( ) ;
170+
171+ Ok ( valid)
172+ }
173+
138174// verify a recursive proof by using a corresponding verification key
139175pub fn verify (
140176 vk : VerificationKey < Bn256 , RecursiveAggregationCircuitBn256 > ,
@@ -145,7 +181,15 @@ pub fn verify(
145181 inputs. push ( chunk) ;
146182 }
147183 log:: info!( "individual_inputs: {:#?}" , inputs) ;
148- core_verify :: < _ , _ , RollingKeccakTranscript < <Bn256 as ScalarEngine >:: Fr > > ( & vk, & aggregated_proof. proof , None )
184+ //notice in PlonkCore.sol the aggregate pairs from subproofs and recursive proofs are combined: 1 * inner + challenge * outer
185+ //and only one verify on pairing has been run to save some gas
186+ //here we just verify them respectively
187+ let valid = core_verify :: < _ , _ , RollingKeccakTranscript < <Bn256 as ScalarEngine >:: Fr > > ( & vk, & aggregated_proof. proof , None ) ?;
188+ if !valid {
189+ return Ok ( valid) ;
190+ }
191+ log:: info!( "aggregated proof is valid" ) ;
192+ verify_subproof_limbs ( & aggregated_proof, & vk)
149193}
150194
151195// export a verification key for a recursion circuit
0 commit comments