@@ -725,28 +725,29 @@ pub(crate) mod tests {
725
725
let shape = R1CSShape :: < G > :: new ( NUM_CONSTRAINTS , NUM_WITNESS , NUM_PUBLIC , & a, & b, & c) ?;
726
726
let X = to_field_elements :: < G > ( & [ 1 , 35 ] ) ;
727
727
let W = to_field_elements :: < G > ( & [ 3 , 9 , 27 , 30 ] ) ;
728
- let commitment_W = PedersenCommitment :: < G > :: commit ( & pp, & W ) ;
728
+ let commitment_W = PedersenCommitment :: < G > :: commit ( & pp, & W [ .. ] ) ;
729
729
730
- let instance = R1CSInstance :: < G , PedersenCommitment < G > > :: new ( & shape, & commitment_W, & X ) ?;
731
- let witness = R1CSWitness :: < G > :: new ( & shape, & W ) ?;
730
+ let instance =
731
+ R1CSInstance :: < G , PedersenCommitment < G > > :: new ( & shape, & commitment_W, & X [ ..] ) ?;
732
+ let witness = R1CSWitness :: < G > :: new ( & shape, & W [ ..] ) ?;
732
733
733
734
shape. is_satisfied ( & instance, & witness, & pp) ?;
734
735
735
736
// Change commitment.
736
737
let invalid_commitment = commitment_W. double ( ) ;
737
738
let instance =
738
- R1CSInstance :: < G , PedersenCommitment < G > > :: new ( & shape, & invalid_commitment, & X ) ?;
739
+ R1CSInstance :: < G , PedersenCommitment < G > > :: new ( & shape, & invalid_commitment, & X [ .. ] ) ?;
739
740
assert_eq ! (
740
741
shape. is_satisfied( & instance, & witness, & pp) ,
741
742
Err ( Error :: NotSatisfied )
742
743
) ;
743
744
744
745
// Provide invalid witness.
745
746
let invalid_W = to_field_elements :: < G > ( & [ 4 , 9 , 27 , 30 ] ) ;
746
- let commitment_invalid_W = PedersenCommitment :: < G > :: commit ( & pp, & W ) ;
747
+ let commitment_invalid_W = PedersenCommitment :: < G > :: commit ( & pp, & W [ .. ] ) ;
747
748
let instance =
748
- R1CSInstance :: < G , PedersenCommitment < G > > :: new ( & shape, & commitment_invalid_W, & X ) ?;
749
- let invalid_witness = R1CSWitness :: < G > :: new ( & shape, & invalid_W) ?;
749
+ R1CSInstance :: < G , PedersenCommitment < G > > :: new ( & shape, & commitment_invalid_W, & X [ .. ] ) ?;
750
+ let invalid_witness = R1CSWitness :: < G > :: new ( & shape, & invalid_W[ .. ] ) ?;
750
751
assert_eq ! (
751
752
shape. is_satisfied( & instance, & invalid_witness, & pp) ,
752
753
Err ( Error :: NotSatisfied )
@@ -755,7 +756,7 @@ pub(crate) mod tests {
755
756
// Provide invalid public input.
756
757
let invalid_X = to_field_elements :: < G > ( & [ 1 , 36 ] ) ;
757
758
let instance =
758
- R1CSInstance :: < G , PedersenCommitment < G > > :: new ( & shape, & commitment_W, & invalid_X) ?;
759
+ R1CSInstance :: < G , PedersenCommitment < G > > :: new ( & shape, & commitment_W, & invalid_X[ .. ] ) ?;
759
760
assert_eq ! (
760
761
shape. is_satisfied( & instance, & witness, & pp) ,
761
762
Err ( Error :: NotSatisfied )
@@ -784,10 +785,11 @@ pub(crate) mod tests {
784
785
785
786
let X = to_field_elements :: < G > ( & [ 1 , 35 ] ) ;
786
787
let W = to_field_elements :: < G > ( & [ 3 , 9 , 27 , 30 ] ) ;
787
- let commitment_W = PedersenCommitment :: < G > :: commit ( & pp, & W ) ;
788
+ let commitment_W = PedersenCommitment :: < G > :: commit ( & pp, & W [ .. ] ) ;
788
789
789
- let instance = R1CSInstance :: < G , PedersenCommitment < G > > :: new ( & shape, & commitment_W, & X ) ?;
790
- let witness = R1CSWitness :: < G > :: new ( & shape, & W ) ?;
790
+ let instance =
791
+ R1CSInstance :: < G , PedersenCommitment < G > > :: new ( & shape, & commitment_W, & X [ ..] ) ?;
792
+ let witness = R1CSWitness :: < G > :: new ( & shape, & W [ ..] ) ?;
791
793
792
794
let relaxed_instance = RelaxedR1CSInstance :: < G , PedersenCommitment < G > > :: from ( & instance) ;
793
795
let relaxed_witness = RelaxedR1CSWitness :: < G > :: from_r1cs_witness ( & shape, & witness) ;
@@ -818,10 +820,10 @@ pub(crate) mod tests {
818
820
819
821
let X = to_field_elements :: < G > ( & [ 1 , 35 ] ) ;
820
822
let W = to_field_elements :: < G > ( & [ 3 , 9 , 27 , 30 ] ) ;
821
- let commitment_W = PedersenCommitment :: < G > :: commit ( & pp, & W ) ;
823
+ let commitment_W = PedersenCommitment :: < G > :: commit ( & pp, & W [ .. ] ) ;
822
824
823
- let U2 = R1CSInstance :: < G , PedersenCommitment < G > > :: new ( & shape, & commitment_W, & X ) ?;
824
- let W2 = R1CSWitness :: < G > :: new ( & shape, & W ) ?;
825
+ let U2 = R1CSInstance :: < G , PedersenCommitment < G > > :: new ( & shape, & commitment_W, & X [ .. ] ) ?;
826
+ let W2 = R1CSWitness :: < G > :: new ( & shape, & W [ .. ] ) ?;
825
827
826
828
let U1 = RelaxedR1CSInstance :: < G , PedersenCommitment < G > > :: from ( & U2 ) ;
827
829
let W1 = RelaxedR1CSWitness :: < G > :: from_r1cs_witness ( & shape, & W2 ) ;
@@ -845,7 +847,7 @@ pub(crate) mod tests {
845
847
846
848
#[ test]
847
849
fn folded_with_relaxed_instance_is_satisfied ( ) -> Result < ( ) , Error > {
848
- let ( a , b , c ) = {
850
+ let ( matrix_a , matrix_b , matrix_c ) = {
849
851
(
850
852
to_field_sparse :: < G > ( A ) ,
851
853
to_field_sparse :: < G > ( B ) ,
@@ -856,35 +858,95 @@ pub(crate) mod tests {
856
858
const NUM_CONSTRAINTS : usize = 4 ;
857
859
const NUM_WITNESS : usize = 4 ;
858
860
const NUM_PUBLIC : usize = 2 ;
859
- const r : Scalar = Scalar :: ONE ;
861
+ let folding_scalar = Scalar :: from ( 2u64 ) ;
860
862
861
863
let pp = PedersenCommitment :: < G > :: setup ( NUM_WITNESS , b"test" , & ( ) ) ;
862
- let shape = R1CSShape :: < G > :: new ( NUM_CONSTRAINTS , NUM_WITNESS , NUM_PUBLIC , & a, & b, & c) ?;
863
-
864
- let X = to_field_elements :: < G > ( & [ 1 , 35 ] ) ;
865
- let W = to_field_elements :: < G > ( & [ 3 , 9 , 27 , 30 ] ) ;
866
- let commitment_W = PedersenCommitment :: < G > :: commit ( & pp, & W ) ;
867
-
868
- let u = R1CSInstance :: < G , PedersenCommitment < G > > :: new ( & shape, & commitment_W, & X ) ?;
869
- let w = R1CSWitness :: < G > :: new ( & shape, & W ) ?;
864
+ let shape = R1CSShape :: < G > :: new (
865
+ NUM_CONSTRAINTS ,
866
+ NUM_WITNESS ,
867
+ NUM_PUBLIC ,
868
+ & matrix_a,
869
+ & matrix_b,
870
+ & matrix_c,
871
+ ) ?;
872
+
873
+ // Create two different R1CS instances for the equation x³ + x + 5 = output
874
+ let create_instance = |input : i64 | -> Result <
875
+ ( R1CSInstance < G , PedersenCommitment < G > > , R1CSWitness < G > ) ,
876
+ Error ,
877
+ > {
878
+ let output = input * input * input + input + 5 ;
879
+ let witness_square = input * input;
880
+ let witness_cube = witness_square * input;
881
+ let witness_sum = witness_cube + input;
882
+
883
+ let public_inputs = to_field_elements :: < G > ( & [ 1 , output] ) ;
884
+ let witness_values =
885
+ to_field_elements :: < G > ( & [ input, witness_square, witness_cube, witness_sum] ) ;
886
+ let commitment = PedersenCommitment :: < G > :: commit ( & pp, & witness_values[ ..] ) ;
887
+
888
+ let instance = R1CSInstance :: < G , PedersenCommitment < G > > :: new (
889
+ & shape,
890
+ & commitment,
891
+ & public_inputs[ ..] ,
892
+ ) ?;
893
+ let witness = R1CSWitness :: < G > :: new ( & shape, & witness_values[ ..] ) ?;
894
+ Ok ( ( instance, witness) )
895
+ } ;
870
896
871
- let mut U1 = RelaxedR1CSInstance :: < G , PedersenCommitment < G > > :: from ( & u) ;
872
- let mut W1 = RelaxedR1CSWitness :: < G > :: from_r1cs_witness ( & shape, & w) ;
897
+ let ( instance_1, witness_1) = create_instance ( 3 ) ?;
898
+ let ( instance_2, witness_2) = create_instance ( -2 ) ?;
899
+
900
+ let relaxed_1 = RelaxedR1CSInstance :: < G , PedersenCommitment < G > > :: from ( & instance_1) ;
901
+ let relaxed_witness_1 = RelaxedR1CSWitness :: < G > :: from_r1cs_witness ( & shape, & witness_1) ;
902
+ let relaxed_2 = RelaxedR1CSInstance :: < G , PedersenCommitment < G > > :: from ( & instance_2) ;
903
+ let relaxed_witness_2 = RelaxedR1CSWitness :: < G > :: from_r1cs_witness ( & shape, & witness_2) ;
904
+
905
+ let ( cross_terms, commitment_t) = commit_T_with_relaxed (
906
+ & shape,
907
+ & pp,
908
+ & relaxed_1,
909
+ & relaxed_witness_1,
910
+ & relaxed_2,
911
+ & relaxed_witness_2,
912
+ ) ?;
913
+
914
+ let inputs_1: Vec < Scalar > =
915
+ [ relaxed_1. X . as_slice ( ) , relaxed_witness_1. W . as_slice ( ) ] . concat ( ) ;
916
+ let inputs_2: Vec < Scalar > =
917
+ [ relaxed_2. X . as_slice ( ) , relaxed_witness_2. W . as_slice ( ) ] . concat ( ) ;
918
+
919
+ let multiply_matrices = |inputs : & [ Scalar ] | {
920
+ (
921
+ shape. A . multiply_vec ( inputs) ,
922
+ shape. B . multiply_vec ( inputs) ,
923
+ shape. C . multiply_vec ( inputs) ,
924
+ )
925
+ } ;
873
926
874
- for _ in 0 ..3 {
875
- let ( T , comm_T) = commit_T ( & shape, & pp, & U1 , & W1 , & u, & w) ?;
876
- U1 = U1 . fold ( & u, & comm_T, & r) ?;
877
- W1 = W1 . fold ( & w, & T , & r) ?;
927
+ let ( az1, bz1, cz1) = multiply_matrices ( & inputs_1) ;
928
+ let ( az2, bz2, cz2) = multiply_matrices ( & inputs_2) ;
929
+
930
+ for i in 0 ..shape. num_constraints {
931
+ let expected = az1[ i] * bz2[ i] + az2[ i] * bz1[ i]
932
+ - relaxed_1. X [ 0 ] * cz2[ i]
933
+ - relaxed_2. X [ 0 ] * cz1[ i] ;
934
+ assert_eq ! (
935
+ cross_terms[ i] , expected,
936
+ "Cross-term computation incorrect at index {}" ,
937
+ i
938
+ ) ;
878
939
}
879
940
880
- let U2 = U1 . clone ( ) ;
881
- let W2 = W1 . clone ( ) ;
882
-
883
- let ( T , comm_T) = commit_T_with_relaxed ( & shape, & pp, & U1 , & W1 , & U2 , & W2 ) ?;
884
- let folded_U = U1 . fold_with_relaxed ( & U2 , & comm_T, & r) ?;
885
- let folded_W = W1 . fold_with_relaxed ( & W2 , & T , & r) ?;
941
+ let folded_instance =
942
+ relaxed_1. fold_with_relaxed ( & relaxed_2, & commitment_t, & folding_scalar) ?;
943
+ let folded_witness = relaxed_witness_1. fold_with_relaxed (
944
+ & relaxed_witness_2,
945
+ & cross_terms[ ..] ,
946
+ & folding_scalar,
947
+ ) ?;
948
+ shape. is_relaxed_satisfied ( & folded_instance, & folded_witness, & pp) ?;
886
949
887
- shape. is_relaxed_satisfied ( & folded_U, & folded_W, & pp) ?;
888
950
Ok ( ( ) )
889
951
}
890
952
}
0 commit comments