@@ -44,9 +44,11 @@ pub trait WitnessGenerator<F: Field>: InstanceGenerator<F> {
44
44
#[ derive( Debug , Clone ) ]
45
45
pub struct ConstraintSystem < F : Field > {
46
46
/// The mode in which the constraint system is operating. `self` can either
47
- /// be in setup mode (i.e., `self.mode == SynthesisMode::Setup`) or in
48
- /// proving mode (i.e., `self.mode == SynthesisMode::Prove`). If we are
49
- /// in proving mode, then we have the additional option of whether or
47
+ /// be in setup mode (`self.mode == SynthesisMode::Setup`), in
48
+ /// proving mode (`self.mode == SynthesisMode::Prove`), or in verifying mode
49
+ /// (`self.mode == SynthesisMode::Verify`).
50
+ ///
51
+ /// If we are in proving mode, then we have the additional option of whether or
50
52
/// not to construct the A, B, and C matrices of the constraint system
51
53
/// (see below).
52
54
pub mode : SynthesisMode ,
@@ -99,14 +101,17 @@ pub enum SynthesisMode {
99
101
/// Indicate to the `ConstraintSystem` that it should only generate
100
102
/// constraint matrices and not populate the variable assignments.
101
103
Setup ,
102
- /// Indicate to the `ConstraintSystem` that it populate the variable
104
+ /// Indicate to the `ConstraintSystem` that it should populate the witnessvariable
103
105
/// assignments. If additionally `construct_matrices == true`, then generate
104
106
/// the matrices as in the `Setup` case.
105
107
Prove {
106
108
/// If `construct_matrices == true`, then generate
107
109
/// the matrices as in the `Setup` case.
108
110
construct_matrices : bool ,
109
111
} ,
112
+ /// Indicate to the `ConstraintSystem` that it populate the instance variable
113
+ /// assignments.
114
+ Verify ,
110
115
}
111
116
112
117
/// Defines the parameter to optimize for a `ConstraintSystem`.
@@ -181,6 +186,11 @@ impl<F: Field> ConstraintSystem<F> {
181
186
self . mode == SynthesisMode :: Setup
182
187
}
183
188
189
+ /// Check whether `self.mode == SynthesisMode::Verify`.
190
+ pub fn is_in_verify_mode ( & self ) -> bool {
191
+ self . mode == SynthesisMode :: Verify
192
+ }
193
+
184
194
/// Check whether this constraint system aims to optimize weight,
185
195
/// number of constraints, or neither.
186
196
pub fn optimization_goal ( & self ) -> OptimizationGoal {
@@ -204,6 +214,7 @@ impl<F: Field> ConstraintSystem<F> {
204
214
match self . mode {
205
215
SynthesisMode :: Setup => true ,
206
216
SynthesisMode :: Prove { construct_matrices } => construct_matrices,
217
+ SynthesisMode :: Verify => false ,
207
218
}
208
219
}
209
220
@@ -230,6 +241,8 @@ impl<F: Field> ConstraintSystem<F> {
230
241
let index = self . num_instance_variables ;
231
242
self . num_instance_variables += 1 ;
232
243
244
+ // Only generate instance variable assignments when `self.mode` is either
245
+ // `SynthesisMode::Prove` or `SynthesisMode::Verify`.
233
246
if !self . is_in_setup_mode ( ) {
234
247
self . instance_assignment . push ( f ( ) ?) ;
235
248
}
@@ -245,7 +258,7 @@ impl<F: Field> ConstraintSystem<F> {
245
258
let index = self . num_witness_variables ;
246
259
self . num_witness_variables += 1 ;
247
260
248
- if !self . is_in_setup_mode ( ) {
261
+ if !( self . is_in_setup_mode ( ) || self . is_in_verify_mode ( ) ) {
249
262
self . witness_assignment . push ( f ( ) ?) ;
250
263
}
251
264
Ok ( Variable :: Witness ( index) )
@@ -278,13 +291,14 @@ impl<F: Field> ConstraintSystem<F> {
278
291
self . a_constraints . push ( a_index) ;
279
292
self . b_constraints . push ( b_index) ;
280
293
self . c_constraints . push ( c_index) ;
294
+ #[ cfg( feature = "std" ) ]
295
+ {
296
+ let trace = ConstraintTrace :: capture ( ) ;
297
+ self . constraint_traces . push ( trace) ;
298
+ }
281
299
}
282
300
self . num_constraints += 1 ;
283
- #[ cfg( feature = "std" ) ]
284
- {
285
- let trace = ConstraintTrace :: capture ( ) ;
286
- self . constraint_traces . push ( trace) ;
287
- }
301
+
288
302
Ok ( ( ) )
289
303
}
290
304
@@ -538,10 +552,7 @@ impl<F: Field> ConstraintSystem<F> {
538
552
/// after all symbolic LCs have been inlined into the places that they
539
553
/// are used.
540
554
pub fn to_matrices ( & self ) -> Option < ConstraintMatrices < F > > {
541
- if let SynthesisMode :: Prove {
542
- construct_matrices : false ,
543
- } = self . mode
544
- {
555
+ if !self . should_construct_matrices ( ) {
545
556
None
546
557
} else {
547
558
let a: Vec < _ > = self
@@ -601,7 +612,7 @@ impl<F: Field> ConstraintSystem<F> {
601
612
/// the first unsatisfied constraint. If `self.is_in_setup_mode()`, outputs
602
613
/// `Err(())`.
603
614
pub fn which_is_unsatisfied ( & self ) -> crate :: r1cs:: Result < Option < String > > {
604
- if self . is_in_setup_mode ( ) {
615
+ if self . is_in_setup_mode ( ) || self . is_in_verify_mode ( ) {
605
616
Err ( SynthesisError :: AssignmentMissing )
606
617
} else {
607
618
for i in 0 ..self . num_constraints {
@@ -753,7 +764,7 @@ impl<F: Field> ConstraintSystemRef<F> {
753
764
754
765
/// Consumes self to return the inner `ConstraintSystem<F>`. Returns
755
766
/// `None` if `Self::CS` is `None` or if any other references to
756
- /// `Self::CS` exist.
767
+ /// `Self::CS` exist.
757
768
pub fn into_inner ( self ) -> Option < ConstraintSystem < F > > {
758
769
match self {
759
770
Self :: CS ( a) => Rc :: try_unwrap ( a) . ok ( ) . map ( |s| s. into_inner ( ) ) ,
@@ -791,6 +802,13 @@ impl<F: Field> ConstraintSystemRef<F> {
791
802
. map_or ( false , |cs| cs. borrow ( ) . is_in_setup_mode ( ) )
792
803
}
793
804
805
+ /// Check whether `self.mode == SynthesisMode::Verify`.
806
+ #[ inline]
807
+ pub fn is_in_verify_mode ( & self ) -> bool {
808
+ self . inner ( )
809
+ . map_or ( false , |cs| cs. borrow ( ) . is_in_verify_mode ( ) )
810
+ }
811
+
794
812
/// Returns the number of constraints.
795
813
#[ inline]
796
814
pub fn num_constraints ( & self ) -> usize {
@@ -864,7 +882,7 @@ impl<F: Field> ConstraintSystemRef<F> {
864
882
self . inner ( )
865
883
. ok_or ( SynthesisError :: MissingCS )
866
884
. and_then ( |cs| {
867
- if !self . is_in_setup_mode ( ) {
885
+ if !( self . is_in_setup_mode ( ) || self . is_in_verify_mode ( ) ) {
868
886
// This is needed to avoid double-borrows, because `f`
869
887
// might itself mutably borrow `cs` (eg: `f = || g.value()`).
870
888
let value = f ( ) ;
0 commit comments