1
1
use alloc:: vec;
2
2
3
- use halo2_proofs:: plonk:: Expression ;
4
3
use halo2_proofs:: {
5
4
halo2curves:: bn256:: Fr ,
6
- plonk:: { Advice , Column , ConstraintSystem , Constraints , Error , Selector } ,
5
+ plonk:: { Advice , Column , ConstraintSystem , Constraints , Error , Expression , Selector } ,
7
6
poly:: Rotation ,
8
7
} ;
9
8
use macros:: embeddable;
@@ -88,16 +87,13 @@ impl Gate for ScalarMultiplyGate {
88
87
let next_result_z = vc. query_advice ( result[ 2 ] , Rotation ( ADVICE_OFFSET + 1 ) ) ;
89
88
90
89
let input = GrumpkinPoint :: new ( input_x, input_y, input_z) ;
91
- let result = GrumpkinPoint :: new ( result_x. clone ( ) , result_y. clone ( ) , result_z. clone ( ) ) ;
90
+ let result = GrumpkinPoint :: new ( result_x. clone ( ) , result_y. clone ( ) , result_z. clone ( ) ) ;
92
91
93
92
let GrumpkinPoint {
94
93
x : added_x,
95
94
y : added_y,
96
95
z : added_z,
97
- } = curve_arithmetic:: points_add (
98
- result,
99
- input. clone ( ) ,
100
- ) ;
96
+ } = curve_arithmetic:: points_add ( result, input. clone ( ) ) ;
101
97
102
98
let GrumpkinPoint {
103
99
x : doubled_x,
@@ -109,11 +105,23 @@ impl Gate for ScalarMultiplyGate {
109
105
vc. query_selector ( selector) ,
110
106
vec ! [
111
107
// `bit` is a valid bit
112
- ( "bit is a binary value" , bit. clone( ) * ( Expression :: Constant ( Fr :: one( ) ) - bit. clone( ) ) ) ,
108
+ (
109
+ "bit is a binary value" ,
110
+ bit. clone( ) * ( Expression :: Constant ( Fr :: one( ) ) - bit. clone( ) ) ,
111
+ ) ,
113
112
// next_result = input + result (if bit == 1) else result
114
- ( "x: next_result = input + result if bit == 1 else result" , next_result_x - bit. clone ( ) * ( added_x - result_x. clone ( ) ) - result_x) ,
115
- ( "y: next_result = input + result if bit == 1 else result" , next_result_y - bit. clone ( ) * ( added_y - result_y. clone ( ) ) - result_y) ,
116
- ( "z: next_result = input + result if bit == 1 else result" , next_result_z - bit. clone ( ) * ( added_z - result_z. clone ( ) ) - result_z) ,
113
+ (
114
+ "x: next_result = input + result if bit == 1 else result" ,
115
+ next_result_x - bit. clone( ) * ( added_x - result_x. clone( ) ) - result_x,
116
+ ) ,
117
+ (
118
+ "y: next_result = input + result if bit == 1 else result" ,
119
+ next_result_y - bit. clone( ) * ( added_y - result_y. clone( ) ) - result_y,
120
+ ) ,
121
+ (
122
+ "z: next_result = input + result if bit == 1 else result" ,
123
+ next_result_z - bit. clone( ) * ( added_z - result_z. clone( ) ) - result_z,
124
+ ) ,
117
125
// next_input = 2 * input
118
126
( "x: next_input = 2 * input" , next_input_x - doubled_x) ,
119
127
( "y: next_input = 2 * input" , next_input_y - doubled_y) ,
@@ -264,4 +272,25 @@ mod tests {
264
272
} )
265
273
. is_ok( ) ) ;
266
274
}
275
+
276
+ #[ test]
277
+ fn bit_is_invalid ( ) {
278
+ let rng = rng ( ) ;
279
+ let bit = Fr :: from_u128 ( 2 ) ;
280
+
281
+ let input = G1 :: random ( rng. clone ( ) ) . into ( ) ;
282
+ let result = G1 :: random ( rng. clone ( ) ) . into ( ) ;
283
+
284
+ let next_input = curve_arithmetic:: point_double ( input) ;
285
+ let next_result = curve_arithmetic:: points_add ( input, result) ;
286
+
287
+ assert ! ( verify( ScalarMultiplyGateInput {
288
+ bit,
289
+ input,
290
+ result,
291
+ next_input,
292
+ next_result
293
+ } )
294
+ . is_err( ) ) ;
295
+ }
267
296
}
0 commit comments