1
- use std:: { cell:: RefCell , iter, rc:: Rc , sync :: Arc } ;
1
+ use std:: { cell:: RefCell , iter, rc:: Rc } ;
2
2
3
3
use itertools:: { zip_eq, Itertools } ;
4
- use num_bigint_dig :: BigUint ;
5
- use num_traits:: One ;
4
+ use num_bigint :: BigUint ;
5
+ use num_traits:: { One , Zero } ;
6
6
use openvm_circuit:: arch:: {
7
7
AdapterAirContext , AdapterRuntimeContext , DynAdapterInterface , DynArray , MinimalInstruction ,
8
8
Result , VmAdapterInterface , VmCoreAir , VmCoreChip ,
9
9
} ;
10
10
use openvm_circuit_primitives:: {
11
11
bigint:: utils:: big_uint_to_num_limbs,
12
- var_range:: { VariableRangeCheckerBus , VariableRangeCheckerChip } ,
12
+ var_range:: { SharedVariableRangeCheckerChip , VariableRangeCheckerBus } ,
13
13
SubAir , TraceSubRowGenerator ,
14
14
} ;
15
- use openvm_ecc_transpiler:: Rv32WeierstrassOpcode ;
15
+ use openvm_ecc_transpiler:: Rv32EdwardsOpcode ;
16
16
use openvm_instructions:: instruction:: Instruction ;
17
17
use openvm_mod_circuit_builder:: {
18
18
utils:: { biguint_to_limbs_vec, limbs_to_biguint} ,
@@ -51,9 +51,6 @@ impl TeEcAddCoreAir {
51
51
let builder = ExprBuilder :: new ( config, range_bus. range_max_bits ) ;
52
52
let builder = Rc :: new ( RefCell :: new ( builder) ) ;
53
53
54
- // TODO: do the setup row, if needed
55
- // might have to define a CoreChip and CoreAir
56
-
57
54
let x1 = ExprBuilder :: new_input ( builder. clone ( ) ) ;
58
55
let y1 = ExprBuilder :: new_input ( builder. clone ( ) ) ;
59
56
let x2 = ExprBuilder :: new_input ( builder. clone ( ) ) ;
@@ -76,11 +73,9 @@ impl TeEcAddCoreAir {
76
73
77
74
let builder = builder. borrow ( ) . clone ( ) ;
78
75
79
- let expr = FieldExpr :: new_with_setup_values (
80
- builder,
81
- range_bus,
82
- true ,
83
- vec ! [ a_biguint. clone( ) , d_biguint. clone( ) ] ,
76
+ let expr = FieldExpr :: new (
77
+ builder, range_bus, true ,
78
+ //vec![a_biguint.clone(), d_biguint.clone()],
84
79
) ;
85
80
Self {
86
81
expr,
@@ -117,8 +112,7 @@ where
117
112
) -> AdapterAirContext < AB :: Expr , I > {
118
113
assert_eq ! ( local. len( ) , BaseAir :: <AB :: F >:: width( & self . expr) ) ;
119
114
120
- // TODO
121
- //self.expr.eval(builder, local);
115
+ self . expr . eval ( builder, local) ;
122
116
123
117
let FieldExprCols {
124
118
is_valid,
@@ -131,7 +125,6 @@ where
131
125
assert_eq ! ( vars. len( ) , 12 ) ;
132
126
assert_eq ! ( flags. len( ) , 1 ) ;
133
127
134
- //let reads: Vec<AB::Expr> = inputs.into_iter().flatten().map(Into::into).collect();
135
128
let reads: Vec < AB :: Expr > = inputs
136
129
. clone ( )
137
130
. into_iter ( )
@@ -148,35 +141,15 @@ where
148
141
let is_setup = is_valid - flags[ 0 ] ;
149
142
builder. assert_bool ( is_setup. clone ( ) ) ;
150
143
let local_opcode_idx = flags[ 0 ]
151
- * AB :: Expr :: from_canonical_usize ( Rv32WeierstrassOpcode :: EC_DOUBLE as usize )
144
+ * AB :: Expr :: from_canonical_usize ( Rv32EdwardsOpcode :: EC_ADD as usize )
152
145
+ is_setup. clone ( )
153
- * AB :: Expr :: from_canonical_usize ( Rv32WeierstrassOpcode :: SETUP_EC_DOUBLE as usize ) ;
154
-
155
- let dbg = iter:: empty ( )
156
- . chain ( self . expr . builder . prime_limbs . clone ( ) )
157
- . chain ( big_uint_to_num_limbs (
158
- & self . a_biguint ,
159
- self . expr . builder . limb_bits ,
160
- self . expr . builder . num_limbs ,
161
- ) )
162
- . chain ( big_uint_to_num_limbs (
163
- & self . d_biguint ,
164
- self . expr . builder . limb_bits ,
165
- self . expr . builder . num_limbs ,
166
- ) )
167
- . collect_vec ( ) ;
168
- println ! ( "dbg: {:?}" , dbg) ;
146
+ * AB :: Expr :: from_canonical_usize ( Rv32EdwardsOpcode :: SETUP_EC_ADD as usize ) ;
169
147
170
- // when is_setup, assert `reads` equals `(modulus, a)`
148
+ // when is_setup, assert `reads` equals `(modulus, a, d, 0 )`
171
149
for ( lhs, & rhs) in zip_eq (
172
- //&reads,
173
- inputs
174
- . into_iter ( )
175
- . flatten ( )
176
- . map ( Into :: into)
177
- . take ( 1 * self . expr . builder . num_limbs ) ,
178
- iter:: empty ( ) . chain ( & self . expr . builder . prime_limbs ) ,
179
- /*
150
+ & reads,
151
+ iter:: empty ( )
152
+ . chain ( & self . expr . builder . prime_limbs )
180
153
. chain ( & big_uint_to_num_limbs (
181
154
& self . a_biguint ,
182
155
self . expr . builder . limb_bits ,
@@ -186,13 +159,12 @@ where
186
159
& self . d_biguint ,
187
160
self . expr . builder . limb_bits ,
188
161
self . expr . builder . num_limbs ,
162
+ ) )
163
+ . chain ( & big_uint_to_num_limbs (
164
+ & BigUint :: zero ( ) ,
165
+ self . expr . builder . limb_bits ,
166
+ self . expr . builder . num_limbs ,
189
167
) ) ,
190
- .chain(&big_uint_to_num_limbs(
191
- &BigUint::default(),
192
- self.expr.builder.limb_bits,
193
- self.expr.builder.num_limbs,
194
- )),
195
- */
196
168
) {
197
169
builder
198
170
. when ( is_setup. clone ( ) )
@@ -212,17 +184,21 @@ where
212
184
} ;
213
185
ctx. into ( )
214
186
}
187
+
188
+ fn start_offset ( & self ) -> usize {
189
+ self . offset
190
+ }
215
191
}
216
192
217
193
pub struct TeEcAddCoreChip {
218
194
pub air : TeEcAddCoreAir ,
219
- pub range_checker : Arc < VariableRangeCheckerChip > ,
195
+ pub range_checker : SharedVariableRangeCheckerChip ,
220
196
}
221
197
222
198
impl TeEcAddCoreChip {
223
199
pub fn new (
224
200
config : ExprBuilderConfig ,
225
- range_checker : Arc < VariableRangeCheckerChip > ,
201
+ range_checker : SharedVariableRangeCheckerChip ,
226
202
a_biguint : BigUint ,
227
203
d_biguint : BigUint ,
228
204
offset : usize ,
@@ -243,7 +219,7 @@ pub struct TeEcAddCoreRecord {
243
219
pub x2 : BigUint ,
244
220
#[ serde_as( as = "DisplayFromStr" ) ]
245
221
pub y2 : BigUint ,
246
- pub is_double_flag : bool ,
222
+ pub is_add_flag : bool ,
247
223
}
248
224
249
225
impl < F : PrimeField32 , I > VmCoreChip < F , I > for TeEcAddCoreChip
@@ -291,7 +267,7 @@ where
291
267
let x2_biguint = limbs_to_biguint ( & x2, limb_bits) ;
292
268
let y2_biguint = limbs_to_biguint ( & y2, limb_bits) ;
293
269
294
- let is_double_flag = local_opcode_idx == Rv32WeierstrassOpcode :: EC_DOUBLE as usize ;
270
+ let is_add_flag = local_opcode_idx == Rv32EdwardsOpcode :: EC_ADD as usize ;
295
271
296
272
let vars = self . air . expr . execute (
297
273
vec ! [
@@ -300,7 +276,7 @@ where
300
276
x2_biguint. clone( ) ,
301
277
y2_biguint. clone( ) ,
302
278
] ,
303
- vec ! [ is_double_flag ] ,
279
+ vec ! [ is_add_flag ] ,
304
280
) ;
305
281
assert_eq ! ( vars. len( ) , 12 ) ;
306
282
@@ -323,7 +299,7 @@ where
323
299
y1 : y1_biguint,
324
300
x2 : x2_biguint,
325
301
y2 : y2_biguint,
326
- is_double_flag ,
302
+ is_add_flag ,
327
303
} ,
328
304
) )
329
305
}
@@ -335,9 +311,9 @@ where
335
311
fn generate_trace_row ( & self , row_slice : & mut [ F ] , record : Self :: Record ) {
336
312
self . air . expr . generate_subrow (
337
313
(
338
- & self . range_checker ,
314
+ self . range_checker . as_ref ( ) ,
339
315
vec ! [ record. x1, record. y1, record. x2, record. y2] ,
340
- vec ! [ record. is_double_flag ] ,
316
+ vec ! [ record. is_add_flag ] ,
341
317
) ,
342
318
row_slice,
343
319
) ;
@@ -354,15 +330,42 @@ where
354
330
}
355
331
let core_width = <Self :: Air as BaseAir < F > >:: width ( & self . air ) ;
356
332
let adapter_width = trace. width ( ) - core_width;
357
- // We will be setting is_valid = 0. That forces is_double to be 0 (otherwise setup will be -1).
358
- // So the computation is like doing setup.
359
- // Thus we will copy over the first row (which is a setup row) and set is_valid = 0.
360
- let first_row = trace. rows ( ) . nth ( 0 ) . unwrap ( ) . collect :: < Vec < _ > > ( ) ;
361
- let first_row_core = first_row. split_at ( adapter_width) . 1 ;
333
+ let dummy_row = self . generate_dummy_trace_row ( adapter_width, core_width) ;
362
334
for row in trace. rows_mut ( ) . skip ( num_records) {
363
- let core_row = row. split_at_mut ( adapter_width) . 1 ;
364
- core_row. copy_from_slice ( first_row_core) ;
365
- core_row[ 0 ] = F :: ZERO ; // is_valid = 0
335
+ row. copy_from_slice ( & dummy_row) ;
366
336
}
367
337
}
368
338
}
339
+
340
+ impl TeEcAddCoreChip {
341
+ // We will be setting is_valid = 0. That forces is_add to be 0 (otherwise setup will be -1).
342
+ // We generate a dummy row with is_add = 0, then we set is_valid = 0.
343
+ fn generate_dummy_trace_row < F : PrimeField32 > (
344
+ & self ,
345
+ adapter_width : usize ,
346
+ core_width : usize ,
347
+ ) -> Vec < F > {
348
+ let record = TeEcAddCoreRecord {
349
+ x1 : BigUint :: zero ( ) ,
350
+ y1 : BigUint :: zero ( ) ,
351
+ x2 : BigUint :: zero ( ) ,
352
+ y2 : BigUint :: zero ( ) ,
353
+ is_add_flag : false ,
354
+ } ;
355
+ let mut row = vec ! [ F :: ZERO ; adapter_width + core_width] ;
356
+ let core_row = & mut row[ adapter_width..] ;
357
+ // We **do not** want this trace row to update the range checker
358
+ // so we must create a temporary range checker
359
+ let tmp_range_checker = SharedVariableRangeCheckerChip :: new ( self . range_checker . bus ( ) ) ;
360
+ self . air . expr . generate_subrow (
361
+ (
362
+ tmp_range_checker. as_ref ( ) ,
363
+ vec ! [ record. x1, record. y1, record. x2, record. y2] ,
364
+ vec ! [ record. is_add_flag] ,
365
+ ) ,
366
+ core_row,
367
+ ) ;
368
+ core_row[ 0 ] = F :: ZERO ; // is_valid = 0
369
+ row
370
+ }
371
+ }
0 commit comments