@ -1,17 +1,28 @@ 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																use   std ::{ collections ::HashMap ,   f32 ::consts ::E } ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																use   ark_ff ::PrimeField ; 
  
																 
																 
																use   ark_ff ::PrimeField ; 
  
															
														 
														
													
														
															
																 
																 
																use   ark_relations ::r1cs ::{ 
  
																 
																 
																use   ark_relations ::r1cs ::{ 
  
															
														 
														
													
														
															
																 
																 
																     ConstraintSynthesizer ,   ConstraintSystemRef ,   LinearCombination ,   SynthesisError ,   Variable , 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																     self ,   ConstraintSynthesizer ,   ConstraintSystemRef ,   LinearCombination ,   SynthesisError ,   Variable , 
  
															
														 
														
													
														
															
																 
																 
																} ; 
  
																 
																 
																} ; 
  
															
														 
														
													
														
															
																 
																 
																
 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																use   super ::R1CS ; 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																
 
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																use   color_eyre ::Result ; 
  
																 
																 
																use   color_eyre ::Result ; 
  
															
														 
														
													
														
															
																 
																 
																
 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																use   super ::R1CS ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																/// `self.public_inputs_indexes` stores already allocated public variables. We assume that:
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																///      1. `self.public_inputs_indexes` is sorted in the same order as circom's r1cs public inputs
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																///      2. the first element of `self.public_inputs_indexes` is the first element *after* the last non yet allocated public input
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																/// example:
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																///      if circom public values are [1, out1, out2, in1, in2] (where out and in denote public signals only)
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																///      and `self.public_inputs_indexes` is [Variable(2), Variable(3)]
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																///      then we will allocate Variable(1), Variable(out1), Variable(out2) and consider that
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																///      Variable(in1) and Variable(in2) are already allocated as Variable(2), Variable(3)
  
															
														 
														
													
														
															
																 
																 
																#[ derive(Clone, Debug) ] 
  
																 
																 
																#[ derive(Clone, Debug) ] 
  
															
														 
														
													
														
															
																 
																 
																pub   struct  CircomCircuit < F : PrimeField >   { 
  
																 
																 
																pub   struct  CircomCircuit < F : PrimeField >   { 
  
															
														 
														
													
														
															
																 
																 
																     pub   r1cs : R1CS < F > , 
  
																 
																 
																     pub   r1cs : R1CS < F > , 
  
															
														 
														
													
														
															
																 
																 
																     pub   witness : Option < Vec < F > > , 
  
																 
																 
																     pub   witness : Option < Vec < F > > , 
  
															
														 
														
													
														
															
																 
																 
																     pub   inputs_already_allocated : bool , 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																     pub   public_inputs_indexes : Vec < Variable > , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																     pub   allocate_inputs_as_witnesses : bool , 
  
															
														 
														
													
														
															
																 
																 
																} 
  
																 
																 
																} 
  
															
														 
														
													
														
															
																 
																 
																
 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																impl < F : PrimeField >   CircomCircuit < F >   { 
  
																 
																 
																impl < F : PrimeField >   CircomCircuit < F >   { 
  
															
														 
														
													
												
													
														
															
																
																	
																	
																	
																		
																			 
																		 
																	
																 
																@ -31,58 +42,111 @@ impl ConstraintSynthesizer for CircomCircuit {    
															
														 
														
													
														
															
																 
																 
																         let   witness   =   & self . witness ; 
  
																 
																 
																         let   witness   =   & self . witness ; 
  
															
														 
														
													
														
															
																 
																 
																         let   wire_mapping   =   & self . r1cs . wire_mapping ; 
  
																 
																 
																         let   wire_mapping   =   & self . r1cs . wire_mapping ; 
  
															
														 
														
													
														
															
																 
																 
																
 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																         // Start from 1 because Arkworks implicitly allocates One for the first input
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																         if   ! self . inputs_already_allocated   { 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																             for   i   in   1 . . self . r1cs . num_inputs   { 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																                 cs . new_input_variable ( | |   { 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																                     Ok ( match   witness   { 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																                         None   = >   F ::from ( 1 u32 ) , 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																                         Some ( w )   = >   match   wire_mapping   { 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																                             Some ( m )   = >   w [ m [ i ] ] , 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																                             None   = >   w [ i ] , 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																                         } , 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																                     } ) 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																                 } ) ? ; 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																             } 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         // Since our cs might already have allocated constraints,
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         // We store a mapping between circom's defined indexes and the newly obtained cs indexes
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   mut   circom_index_to_cs_index   =   HashMap ::new ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         // constant 1 at idx 0 is already allocated by arkworks
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         circom_index_to_cs_index . insert ( 0 ,   Variable ::One ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         // length pub inputs - constant 1 (already allocated by arkworks) - length already allocated pub inputs
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   n_non_allocated_inputs   =   self . r1cs . num_inputs   -   1   -   self . public_inputs_indexes . len ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         // allocate non-allocated inputs and update mapping
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         for   circom_public_input_index   in   1 . . = n_non_allocated_inputs   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             let   variable   =   match   self . allocate_inputs_as_witnesses   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 true   = >   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                     let   witness_var   =   Variable ::Witness ( cs . num_witness_variables ( ) ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                     cs . new_witness_variable ( | |   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                         Ok ( match   witness   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                             None   = >   F ::from ( 1 u32 ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                             Some ( w )   = >   match   wire_mapping   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                                 Some ( m )   = >   w [ m [ circom_public_input_index ] ] , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                                 None   = >   w [ circom_public_input_index ] , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                             } , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                         } ) 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                     } ) ? ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                     witness_var 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 } 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 false   = >   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                     let   instance_var   =   Variable ::Instance ( cs . num_instance_variables ( ) ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                     cs . new_input_variable ( | |   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                         Ok ( match   witness   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                             None   = >   F ::from ( 1 u32 ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                             Some ( w )   = >   match   wire_mapping   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                                 Some ( m )   = >   w [ m [ circom_public_input_index ] ] , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                                 None   = >   w [ circom_public_input_index ] , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                             } , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                         } ) 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                     } ) ? ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                     instance_var 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 } 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             } ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             circom_index_to_cs_index . insert ( circom_public_input_index ,   variable ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         } 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         // update mapping with already allocated public inputs
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         for   circom_public_input_index   in   ( n_non_allocated_inputs   +   1 ) . . self . r1cs . num_inputs   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             let   access_input_index   =   circom_public_input_index   -   n_non_allocated_inputs   -   1 ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             circom_index_to_cs_index . insert ( 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 circom_public_input_index , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 self . public_inputs_indexes [ access_input_index ] , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             ) ; 
  
															
														 
														
													
														
															
																 
																 
																         } 
  
																 
																 
																         } 
  
															
														 
														
													
														
															
																 
																 
																
 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         match   ( 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             circom_index_to_cs_index . get ( & 0 ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             circom_index_to_cs_index . len ( ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         )   = =   ( Some ( & Variable ::One ) ,   self . r1cs . num_inputs ) 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             true   = >   Ok ( ( ) ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             false   = >   Err ( SynthesisError ::Unsatisfiable ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         } ? ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																         for   i   in   0 . . self . r1cs . num_aux   { 
  
																 
																 
																         for   i   in   0 . . self . r1cs . num_aux   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             let   circom_defined_r1cs_index   =   i   +   self . r1cs . num_inputs ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             circom_index_to_cs_index . insert ( 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 circom_defined_r1cs_index , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 Variable ::Witness ( cs . num_witness_variables ( ) ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             ) ; 
  
															
														 
														
													
														
															
																 
																 
																             cs . new_witness_variable ( | |   { 
  
																 
																 
																             cs . new_witness_variable ( | |   { 
  
															
														 
														
													
														
															
																 
																 
																                 Ok ( match   witness   { 
  
																 
																 
																                 Ok ( match   witness   { 
  
															
														 
														
													
														
															
																 
																 
																                     None   = >   F ::from ( 1 u32 ) , 
  
																 
																 
																                     None   = >   F ::from ( 1 u32 ) , 
  
															
														 
														
													
														
															
																 
																 
																                     Some ( w )   = >   match   wire_mapping   { 
  
																 
																 
																                     Some ( w )   = >   match   wire_mapping   { 
  
															
														 
														
													
														
															
																 
																 
																                         Some ( m )   = >   w [ m [ i   +   self . r1cs . num_inputs ] ] , 
  
																 
																 
																                         Some ( m )   = >   w [ m [ i   +   self . r1cs . num_inputs ] ] , 
  
															
														 
														
													
														
															
																 
																 
																                         None   = >   w [ i   +   self . r1cs . num_inputs ] , 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                         None   = >   w [ circom_defined_r1cs_index ] , 
  
															
														 
														
													
														
															
																 
																 
																                     } , 
  
																 
																 
																                     } , 
  
															
														 
														
													
														
															
																 
																 
																                 } ) 
  
																 
																 
																                 } ) 
  
															
														 
														
													
														
															
																 
																 
																             } ) ? ; 
  
																 
																 
																             } ) ? ; 
  
															
														 
														
													
														
															
																 
																 
																         } 
  
																 
																 
																         } 
  
															
														 
														
													
														
															
																 
																 
																
 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																         let   make_index   =   | index |   { 
  
																 
																 
																         let   make_index   =   | index |   { 
  
															
														 
														
													
														
															
																 
																 
																             if   index   <   self . r1cs . num_inputs   { 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																                 Variable ::Instance ( index ) 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																             }   else   { 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																                 Variable ::Witness ( index   -   self . r1cs . num_inputs ) 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																             } 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             let   new_index   =   match   circom_index_to_cs_index . get ( & index )   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 Some ( i )   = >   Ok ( * i ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 None   = >   Err ( SynthesisError ::AssignmentMissing ) ,  
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             } ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             Ok ( new_index ? ) 
  
															
														 
														
													
														
															
																 
																 
																         } ; 
  
																 
																 
																         } ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																         let   make_lc   =   | lc_data : & [ ( usize ,   F ) ] |   { 
  
																 
																 
																         let   make_lc   =   | lc_data : & [ ( usize ,   F ) ] |   { 
  
															
														 
														
													
														
															
																 
																 
																             lc_data . iter ( ) . fold ( 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             lc_data . iter ( ) . try_ fold( 
  
															
														 
														
													
														
															
																 
																 
																                 LinearCombination ::< F > ::zero ( ) , 
  
																 
																 
																                 LinearCombination ::< F > ::zero ( ) , 
  
															
														 
														
													
														
															
																 
																 
																                 | lc : LinearCombination < F > ,   ( index ,   coeff ) |   lc   +   ( * coeff ,   make_index ( * index ) ) , 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 | lc : LinearCombination < F > ,   ( index ,   coeff ) |   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                     let   r1cs_index   =   make_index ( * index ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                     match   r1cs_index   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                         Ok ( r1cs_index )   = >   Ok ( lc   +   ( * coeff ,   r1cs_index ) ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                         Err ( e )   = >   Err ( e ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                     } 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 } , 
  
															
														 
														
													
														
															
																 
																 
																             ) 
  
																 
																 
																             ) 
  
															
														 
														
													
														
															
																 
																 
																         } ; 
  
																 
																 
																         } ; 
  
															
														 
														
													
														
															
																 
																 
																
 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																         let   skip   =   if   self . inputs_already_allocated   { 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																             self . r1cs . num_inputs 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																         }   else   { 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																             0 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																         } ; 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																         for   constraint   in   self . r1cs . constraints . iter ( ) . skip ( skip )   { 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																             cs . enforce_constraint ( 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																                 make_lc ( & constraint . 0 ) , 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																                 make_lc ( & constraint . 1 ) , 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																                 make_lc ( & constraint . 2 ) , 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																             ) ? ; 
  
																 
																 
																 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         for   constraint   in   self . r1cs . constraints . iter ( )   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             let   a   =   make_lc ( & constraint . 0 ) ? ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             let   b   =   make_lc ( & constraint . 1 ) ? ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             let   c   =   make_lc ( & constraint . 2 ) ? ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             let   res   =   cs . enforce_constraint ( a ,   b ,   c ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             res ? 
  
															
														 
														
													
														
															
																 
																 
																         } 
  
																 
																 
																         } 
  
															
														 
														
													
														
															
																 
																 
																
 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																         Ok ( ( ) ) 
  
																 
																 
																         Ok ( ( ) ) 
  
															
														 
														
													
												
													
														
															
																
																	
																	
																	
																		
																			 
																		 
																	
																 
																@ -95,6 +159,7 @@ mod tests { 
															
														 
														
													
														
															
																 
																 
																     use   crate ::{ CircomBuilder ,   CircomConfig } ; 
  
																 
																 
																     use   crate ::{ CircomBuilder ,   CircomConfig } ; 
  
															
														 
														
													
														
															
																 
																 
																     use   ark_bn254 ::Fr ; 
  
																 
																 
																     use   ark_bn254 ::Fr ; 
  
															
														 
														
													
														
															
																 
																 
																     use   ark_relations ::r1cs ::ConstraintSystem ; 
  
																 
																 
																     use   ark_relations ::r1cs ::ConstraintSystem ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																     use   num_bigint ::BigInt ; 
  
															
														 
														
													
														
															
																 
																 
																
 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																     #[ test ] 
  
																 
																 
																     #[ test ] 
  
															
														 
														
													
														
															
																 
																 
																     fn  satisfied ( )   { 
  
																 
																 
																     fn  satisfied ( )   { 
  
															
														 
														
													
												
													
														
															
																
																	
																	
																	
																		
																			 
																		 
																	
																 
																@ -112,4 +177,148 @@ mod tests { 
															
														 
														
													
														
															
																 
																 
																         circom . generate_constraints ( cs . clone ( ) ) . unwrap ( ) ; 
  
																 
																 
																         circom . generate_constraints ( cs . clone ( ) ) . unwrap ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																         assert ! ( cs . is_satisfied ( ) . unwrap ( ) ) ; 
  
																 
																 
																         assert ! ( cs . is_satisfied ( ) . unwrap ( ) ) ; 
  
															
														 
														
													
														
															
																 
																 
																     } 
  
																 
																 
																     } 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																     #[ test ] 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																     fn  no_public_inputs_allocated ( )   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   mut   cfg   =   CircomConfig ::< Fr > ::new ( 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             "./test-vectors/mycircuit2.wasm" , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             "./test-vectors/mycircuit2.r1cs" , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         ) 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         . unwrap ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   inputs   =   vec ! [ 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             ( "a" . to_string ( ) ,   vec ! [ BigInt ::from ( 3 ) ] ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             ( "b" . to_string ( ) ,   vec ! [ BigInt ::from ( 3 ) ] ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             ( "c" . to_string ( ) ,   vec ! [ BigInt ::from ( 3 ) ] ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         ] ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   witness   =   cfg . wtns . calculate_witness_element ( inputs ,   true ) . unwrap ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         // satisfy with inputs as instance variables
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   mut   circom   =   CircomCircuit   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             r1cs : cfg . r1cs . clone ( ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             witness : Some ( witness . clone ( ) ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             public_inputs_indexes : vec ! [ ] , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             allocate_inputs_as_witnesses : false , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         } ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   cs   =   ConstraintSystem ::< Fr > ::new_ref ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         circom . clone ( ) . generate_constraints ( cs . clone ( ) ) . unwrap ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         assert_eq ! ( cs . num_witness_variables ( ) ,   2 ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         assert_eq ! ( cs . num_instance_variables ( ) ,   5 ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         assert ! ( cs . is_satisfied ( ) . unwrap ( ) ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         // satisfy with inputs as witness variables
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   cs   =   ConstraintSystem ::< Fr > ::new_ref ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         circom . allocate_inputs_as_witnesses   =   true ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         circom . generate_constraints ( cs . clone ( ) ) . unwrap ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         assert_eq ! ( cs . num_witness_variables ( ) ,   6 ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         assert_eq ! ( cs . num_instance_variables ( ) ,   1 ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         assert ! ( cs . is_satisfied ( ) . unwrap ( ) ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																     } 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																     #[ test ] 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																     fn  all_public_inputs_allocated ( )   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   mut   cfg   =   CircomConfig ::< Fr > ::new ( 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             "./test-vectors/mycircuit2.wasm" , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             "./test-vectors/mycircuit2.r1cs" , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         ) 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         . unwrap ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   inputs   =   vec ! [ 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             ( "a" . to_string ( ) ,   vec ! [ BigInt ::from ( 3 ) ] ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             ( "b" . to_string ( ) ,   vec ! [ BigInt ::from ( 3 ) ] ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             ( "c" . to_string ( ) ,   vec ! [ BigInt ::from ( 3 ) ] ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         ] ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   witness   =   cfg . wtns . calculate_witness_element ( inputs ,   true ) . unwrap ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         // satisfy with inputs as instance variables
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   mut   circom   =   CircomCircuit   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             r1cs : cfg . r1cs . clone ( ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             witness : Some ( witness . clone ( ) ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             public_inputs_indexes : vec ! [ ] , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             allocate_inputs_as_witnesses : false , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         } ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   cs   =   ConstraintSystem ::< Fr > ::new_ref ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         // allocate all public input variables (except 1) as instance variables and push their indexes
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         for   i   in   1 . . cfg . r1cs . num_inputs   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             circom 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 . public_inputs_indexes 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 . push ( Variable ::Instance ( cs . num_instance_variables ( ) ) ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             cs . new_input_variable ( | |   Ok ( witness [ i ] ) ) . unwrap ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         } 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         circom . clone ( ) . generate_constraints ( cs . clone ( ) ) . unwrap ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         assert_eq ! ( cs . num_witness_variables ( ) ,   2 ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         assert_eq ! ( cs . num_instance_variables ( ) ,   5 ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         assert ! ( cs . is_satisfied ( ) . unwrap ( ) ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																     } 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																     #[ test ] 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																     fn  some_public_inputs_allocated ( )   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   mut   cfg   =   CircomConfig ::< Fr > ::new ( 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             "./test-vectors/mycircuit2.wasm" , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             "./test-vectors/mycircuit2.r1cs" , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         ) 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         . unwrap ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   inputs   =   vec ! [ 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             ( "a" . to_string ( ) ,   vec ! [ BigInt ::from ( 3 ) ] ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             ( "b" . to_string ( ) ,   vec ! [ BigInt ::from ( 3 ) ] ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             ( "c" . to_string ( ) ,   vec ! [ BigInt ::from ( 3 ) ] ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         ] ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   witness   =   cfg . wtns . calculate_witness_element ( inputs ,   true ) . unwrap ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         // satisfy with inputs as instance variables
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   mut   circom   =   CircomCircuit   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             r1cs : cfg . r1cs . clone ( ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             witness : Some ( witness . clone ( ) ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             public_inputs_indexes : vec ! [ ] , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             allocate_inputs_as_witnesses : false , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         } ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   cs   =   ConstraintSystem ::< Fr > ::new_ref ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         // allocate all some input variables as instance variables and push their indexes
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         // recall that it should start with the first non-allocated public input
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         for   i   in   3 . . cfg . r1cs . num_inputs   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             circom 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 . public_inputs_indexes 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 . push ( Variable ::Instance ( cs . num_instance_variables ( ) ) ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             cs . new_input_variable ( | |   Ok ( witness [ i ] ) ) . unwrap ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         } 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         circom . clone ( ) . generate_constraints ( cs . clone ( ) ) . unwrap ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         assert_eq ! ( cs . num_witness_variables ( ) ,   2 ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         assert_eq ! ( cs . num_instance_variables ( ) ,   5 ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         assert ! ( cs . is_satisfied ( ) . unwrap ( ) ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         // re-init and now satisfy with inputs as witness variables
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   mut   circom   =   CircomCircuit   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             r1cs : cfg . r1cs . clone ( ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             witness : Some ( witness . clone ( ) ) , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             public_inputs_indexes : vec ! [ ] , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             allocate_inputs_as_witnesses : false , 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         } ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         let   cs   =   ConstraintSystem ::< Fr > ::new_ref ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         for   i   in   3 . . cfg . r1cs . num_inputs   { 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             circom 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 . public_inputs_indexes 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																                 . push ( Variable ::Instance ( cs . num_instance_variables ( ) ) ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																             cs . new_input_variable ( | |   Ok ( witness [ i ] ) ) . unwrap ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         } 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         circom . allocate_inputs_as_witnesses   =   true ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         circom . generate_constraints ( cs . clone ( ) ) . unwrap ( ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																
 
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         assert_eq ! ( cs . num_witness_variables ( ) ,   4 ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																         assert_eq ! ( cs . num_instance_variables ( ) ,   3 ) ; 
  
															
														 
														
													
														
															
																 
																 
																 
																 
																 
																     } 
  
															
														 
														
													
														
															
																 
																 
																} 
  
																 
																 
																}