@@ -35,6 +35,7 @@ pub(crate) fn ecdsa_verify_no_pubkey_check<F: PrimeField, CF: PrimeField, SF: Pr
3535where
3636 GA : CurveAffineExt < Base = CF , ScalarExt = SF > ,
3737{
38+ let ecc_chip = EccChip :: < F , FpConfig < F , CF > > :: construct ( base_chip. clone ( ) ) ;
3839 let scalar_chip = FpConfig :: < F , SF > :: construct (
3940 base_chip. range . clone ( ) ,
4041 base_chip. limb_bits ,
8586 let u3_mul = {
8687 let generator = GA :: generator ( ) ;
8788 let neg_generator = -generator;
88- let ecc_chip = EccChip :: < F , FpConfig < F , CF > > :: construct ( base_chip. clone ( ) ) ;
8989 let generator = ecc_chip. assign_constant_point ( ctx, generator) ;
9090 let neg_generator = ecc_chip. assign_constant_point ( ctx, neg_generator) ;
9191 ecc_chip. select ( ctx, & neg_generator, & generator, & u1_is_one)
@@ -99,21 +99,50 @@ where
9999 // check
100100 // - (u1 + u3) * G
101101 // - u2 * pubkey + u3 * G
102- // are not negatives and not equal
102+ // are not equal
103103 //
104104 // TODO: Technically they could be equal for a valid signature, but this happens with
105105 // vanishing probability for an ECDSA signature constructed in a standard way
106106 // coordinates of u1_mul and u2_mul are in proper bigint form, and lie in but are not
107107 // constrained to [0, n) we therefore need hard inequality here
108- let u1_u2_x_eq = base_chip. is_equal ( ctx, & u1u3_mul. x , & u2_pk_u3_g. x ) ;
109- let u1_u2_not_neg = base_chip. range . gate ( ) . not ( ctx, Existing ( u1_u2_x_eq) ) ;
108+ let u1_u2_x_eq = ecc_chip. is_equal ( ctx, & u1u3_mul, & u2_pk_u3_g) ;
109+ let u1_u2_not_eq = base_chip. range . gate ( ) . not ( ctx, Existing ( u1_u2_x_eq) ) ;
110+
111+ // check u1*G and u2*pubkey are not negate of each other
112+ // that means the sum of
113+ // - (u1 + u3) * G
114+ // - u2 * pubkey + u3 * G
115+ // should not equal to 2u3 * G
116+ let u1_u2_not_neg = {
117+ // again we get 2u3*G from constant to avoid scalar_multiply
118+ let two_generator = GA :: generator ( ) ;
119+ let neg_two_generator = -two_generator;
120+ let two_generator = ecc_chip. assign_constant_point ( ctx, two_generator) ;
121+ let neg_two_generator = ecc_chip. assign_constant_point ( ctx, neg_two_generator) ;
122+ let two_u3_g = ecc_chip. select ( ctx, & neg_two_generator, & two_generator, & u1_is_one) ;
123+
124+ base_chip. enforce_less_than_p ( ctx, u1u3_mul. x ( ) ) ;
125+ base_chip. enforce_less_than_p ( ctx, u2_pk_u3_g. x ( ) ) ;
126+ // safe: we have already checked (u1 + u3) * G != u2 * pubkey + u3 * G
127+ let sum = ec_add_unequal ( base_chip, ctx, & u1u3_mul, & u2_pk_u3_g, false ) ;
128+
129+ let is_equal = ecc_chip. is_equal ( ctx, & sum, & two_u3_g) ;
130+ base_chip. range . gate ( ) . not ( ctx, Existing ( is_equal) )
131+ } ;
110132
111133 // compute (x1, y1) = u1 * G + u2 * pubkey and check (r mod n) == x1 as integers
112134 // which is basically u1u3_mul + u2_mul - u3_mul
113135 // WARNING: For optimization reasons, does not reduce x1 mod n, which is
114136 // invalid unless p is very close to n in size.
115- base_chip. enforce_less_than_p ( ctx, u1u3_mul. x ( ) ) ;
137+ //
138+ // WARNING: this may be trigger errors if
139+ // u1u3_mul == u2_mul
140+ // if r is sampled truly from random then this will not happen
141+ // to completely ensure the correctness we may need to sample u3 from random, but it is quite
142+ // costly.
116143 let sum = ec_add_unequal ( base_chip, ctx, & u1u3_mul, & u2_mul, false ) ;
144+ // safe: we have already checked u1G + u2 pk != 0
145+ // so u1G + u3G + u2pk != u3G
117146 let sum = ec_sub_unequal ( base_chip, ctx, & sum, & u3_mul, false ) ;
118147 let equal_check = base_chip. is_equal ( ctx, & sum. x , r) ;
119148
@@ -151,12 +180,16 @@ where
151180 let res4 = base_chip
152181 . range
153182 . gate ( )
154- . and ( ctx, Existing ( res3) , Existing ( u1_u2_not_neg ) ) ;
183+ . and ( ctx, Existing ( res3) , Existing ( u1_u2_not_eq ) ) ;
155184 let res5 = base_chip
156185 . range
157186 . gate ( )
158- . and ( ctx, Existing ( res4) , Existing ( equal_check) ) ;
159- ( res5, sum. y )
187+ . and ( ctx, Existing ( res4) , Existing ( u1_u2_not_neg) ) ;
188+ let res6 = base_chip
189+ . range
190+ . gate ( )
191+ . and ( ctx, Existing ( res5) , Existing ( equal_check) ) ;
192+ ( res6, sum. y )
160193}
161194
162195fn scalar_field_element_is_one < F : PrimeField , SF : PrimeField > (
0 commit comments