@@ -16,12 +16,16 @@ use {
1616 utils:: sumcheck:: calculate_evaluations_over_boolean_hypercube_for_eq, PublicInputs ,
1717 WhirR1CSProof , WhirR1CSScheme ,
1818 } ,
19- provekit_prover:: { prove_from_alphas, run_zk_sumcheck_prover, WhirR1CSCommitment } ,
19+ provekit_prover:: {
20+ prove_from_alphas_ctx, run_zk_sumcheck_prover, ProveFromAlphasCtx , SparkQueryData ,
21+ WhirR1CSCommitment ,
22+ } ,
2023 tracing:: instrument,
2124 whir:: { algebra:: embedding:: Identity , transcript:: ProverState } ,
2225} ;
2326
2427pub trait MavrosR1CSProver {
28+ #[ allow( clippy:: too_many_arguments) ]
2529 fn prove_mavros (
2630 & self ,
2731 merlin : ProverState < TranscriptSponge > ,
@@ -32,58 +36,128 @@ pub trait MavrosR1CSProver {
3236 constraints_layout : ConstraintsLayout ,
3337 binary : & [ u64 ] ,
3438 ) -> Result < WhirR1CSProof > ;
39+
40+ /// Like [`Self::prove_mavros`], but also produces the SPARK query data as
41+ /// a side output (the transcript is identical either way).
42+ #[ allow( clippy:: too_many_arguments) ]
43+ fn prove_mavros_with_spark (
44+ & self ,
45+ merlin : ProverState < TranscriptSponge > ,
46+ witgen : WitgenResult ,
47+ commitments : Vec < WhirR1CSCommitment < Bn254Field > > ,
48+ public_inputs : & PublicInputs < FieldElement > ,
49+ witness_layout : WitnessLayout ,
50+ constraints_layout : ConstraintsLayout ,
51+ binary : & [ u64 ] ,
52+ ) -> Result < ( WhirR1CSProof , SparkQueryData < Bn254Field > ) > ;
3553}
3654
3755impl MavrosR1CSProver for WhirR1CSScheme < Bn254Field > {
3856 #[ instrument( skip_all) ]
3957 fn prove_mavros (
4058 & self ,
41- mut merlin : ProverState < TranscriptSponge > ,
59+ merlin : ProverState < TranscriptSponge > ,
4260 witgen : WitgenResult ,
4361 commitments : Vec < WhirR1CSCommitment < Bn254Field > > ,
4462 public_inputs : & PublicInputs < FieldElement > ,
4563 witness_layout : WitnessLayout ,
4664 constraints_layout : ConstraintsLayout ,
4765 binary : & [ u64 ] ,
4866 ) -> Result < WhirR1CSProof > {
49- ensure ! ( !commitments. is_empty( ) , "Need at least one commitment" ) ;
50-
51- let blinding = commitments[ 0 ]
52- . blinding
53- . as_ref ( )
54- . ok_or_else ( || anyhow:: anyhow!( "c1 must carry blinding state" ) ) ?;
55-
56- // `g` is committed separately in the extension field; open `blinding_eval`
57- // against the blinding vector (g flattened at offset 0).
58- let ( alpha, blinding_eval) = run_zk_sumcheck_prover (
59- & Identity :: new ( ) ,
60- [ witgen. out_a , witgen. out_b , witgen. out_c ] ,
61- & mut merlin,
62- self . m_0 ,
63- & blinding. polynomial ,
64- & blinding. vector ,
65- ) ;
66-
67- let eq_alpha =
68- calculate_evaluations_over_boolean_hypercube_for_eq ( & alpha, 1 << alpha. len ( ) ) ;
69- let ( ad_a, ad_b, ad_c, _) = run_ad (
70- binary,
71- & eq_alpha[ ..constraints_layout. size ( ) ] ,
67+ let ( proof, _) = prove_mavros_inner (
68+ self ,
69+ merlin,
70+ witgen,
71+ commitments,
72+ public_inputs,
7273 witness_layout,
7374 constraints_layout,
75+ binary,
76+ false ,
7477 ) ?;
75- let alphas = [ ad_a, ad_b, ad_c] ;
76-
77- let blinding_weights = expand_powers :: < 4 , _ > ( & alpha) ;
78+ Ok ( proof)
79+ }
7880
79- prove_from_alphas (
81+ #[ instrument( skip_all) ]
82+ fn prove_mavros_with_spark (
83+ & self ,
84+ merlin : ProverState < TranscriptSponge > ,
85+ witgen : WitgenResult ,
86+ commitments : Vec < WhirR1CSCommitment < Bn254Field > > ,
87+ public_inputs : & PublicInputs < FieldElement > ,
88+ witness_layout : WitnessLayout ,
89+ constraints_layout : ConstraintsLayout ,
90+ binary : & [ u64 ] ,
91+ ) -> Result < ( WhirR1CSProof , SparkQueryData < Bn254Field > ) > {
92+ let ( proof, queries) = prove_mavros_inner (
8093 self ,
8194 merlin,
95+ witgen,
96+ commitments,
97+ public_inputs,
98+ witness_layout,
99+ constraints_layout,
100+ binary,
101+ true ,
102+ ) ?;
103+ let queries = queries
104+ . ok_or_else ( || anyhow:: anyhow!( "SPARK query data must be produced when requested" ) ) ?;
105+ Ok ( ( proof, queries) )
106+ }
107+ }
108+
109+ #[ instrument( skip_all) ]
110+ #[ allow( clippy:: too_many_arguments) ]
111+ fn prove_mavros_inner (
112+ scheme : & WhirR1CSScheme < Bn254Field > ,
113+ mut merlin : ProverState < TranscriptSponge > ,
114+ witgen : WitgenResult ,
115+ commitments : Vec < WhirR1CSCommitment < Bn254Field > > ,
116+ public_inputs : & PublicInputs < FieldElement > ,
117+ witness_layout : WitnessLayout ,
118+ constraints_layout : ConstraintsLayout ,
119+ binary : & [ u64 ] ,
120+ produce_spark_query : bool ,
121+ ) -> Result < ( WhirR1CSProof , Option < SparkQueryData < Bn254Field > > ) > {
122+ ensure ! ( !commitments. is_empty( ) , "Need at least one commitment" ) ;
123+
124+ let blinding = commitments[ 0 ]
125+ . blinding
126+ . as_ref ( )
127+ . ok_or_else ( || anyhow:: anyhow!( "c1 must carry blinding state" ) ) ?;
128+
129+ // `g` is committed separately in the extension field; open `blinding_eval`
130+ // against the blinding vector (g flattened at offset 0).
131+ let ( alpha, blinding_eval) = run_zk_sumcheck_prover (
132+ & Identity :: new ( ) ,
133+ [ witgen. out_a , witgen. out_b , witgen. out_c ] ,
134+ & mut merlin,
135+ scheme. m_0 ,
136+ & blinding. polynomial ,
137+ & blinding. vector ,
138+ ) ;
139+
140+ let eq_alpha = calculate_evaluations_over_boolean_hypercube_for_eq ( & alpha, 1 << alpha. len ( ) ) ;
141+ let ( ad_a, ad_b, ad_c, _) = run_ad (
142+ binary,
143+ & eq_alpha[ ..constraints_layout. size ( ) ] ,
144+ witness_layout,
145+ constraints_layout,
146+ ) ?;
147+ let alphas = [ ad_a, ad_b, ad_c] ;
148+
149+ let blinding_weights = expand_powers :: < 4 , _ > ( & alpha) ;
150+
151+ prove_from_alphas_ctx (
152+ scheme,
153+ merlin,
154+ ProveFromAlphasCtx {
82155 alphas,
83156 blinding_eval,
84157 blinding_weights,
85158 commitments,
86- public_inputs,
87- )
88- }
159+ spark_row : produce_spark_query. then_some ( alpha) ,
160+ } ,
161+ public_inputs,
162+ )
89163}
0 commit comments