@@ -258,7 +258,7 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
258
258
// If a row is not enabled (fixed), it is not in an event.
259
259
// TODO: not currently possible due to API limitations.
260
260
// (1.expr() - enabled.expr()) * is_event.expr(),
261
-
261
+
262
262
// If a row is anything but padding (filler of the table), it is in an event.
263
263
enabled. expr( )
264
264
* ( ( 1 . expr( ) - is_event. expr( ) )
@@ -290,7 +290,6 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
290
290
meta. query_advice ( is_last, Rotation :: cur ( ) ) ,
291
291
) ;
292
292
cb. require_boolean ( "mask is boolean" , meta. query_advice ( mask, Rotation :: cur ( ) ) ) ;
293
- cb. require_boolean ( "front_mask is boolean" , meta. query_advice ( front_mask, Rotation :: cur ( ) ) ) ;
294
293
cb. require_zero (
295
294
"is_first == 0 when q_step == 0" ,
296
295
and:: expr ( [
@@ -321,17 +320,6 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
321
320
322
321
// Whether this row is part of a memory or log word.
323
322
let is_word = meta. query_advice ( is_memory, Rotation :: cur ( ) ) + meta. query_advice ( is_tx_log, Rotation :: cur ( ) ) ;
324
-
325
- cb. condition (
326
- is_continue. expr ( ) ,
327
- |cb| {
328
- cb. require_equal (
329
- "bytes_left == bytes_left_next + 1 for non-last step" ,
330
- meta. query_advice ( bytes_left, Rotation :: cur ( ) ) ,
331
- meta. query_advice ( bytes_left, Rotation ( 2 ) ) + 1 . expr ( ) ,
332
- ) ;
333
- } ,
334
- ) ;
335
323
336
324
cb. condition (
337
325
and:: expr ( [
@@ -417,23 +405,43 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
417
405
}
418
406
) ;
419
407
420
- // The address is incremented by 1, except in the front mask because the row address has not caught up with the address of the event yet.
421
- cb. condition ( not_last_two_rows. expr ( ) ,
422
- |cb| {
408
+ let front_mask_next = meta. query_advice ( front_mask, Rotation ( 2 ) ) ;
409
+ let front_mask = meta. query_advice ( front_mask, Rotation :: cur ( ) ) ;
410
+ cb. require_boolean ( "front_mask is boolean" , front_mask. expr ( ) ) ;
411
+
412
+ cb. require_zero ( "front_mask=1 implies mask=1" ,
413
+ and:: expr ( [
414
+ front_mask. expr ( ) ,
415
+ not:: expr ( meta. query_advice ( mask, Rotation :: cur ( ) ) ) ,
416
+ ] ) ,
417
+ ) ;
418
+
419
+ cb. condition ( not:: expr ( is_word_continue. is_lt ( meta, None ) ) , |cb| {
420
+ // The first 31 bytes may be front_mask, but at least the 32nd byte is not masked.
421
+ cb. require_zero ( "front_mask = 0 by the end of the first word" , front_mask. expr ( ) ) ;
422
+ } ) ;
423
423
424
- let addr_diff = not:: expr ( meta. query_advice ( front_mask, Rotation :: cur ( ) ) ) ;
424
+ cb. condition ( is_continue. expr ( ) ,
425
+ |cb| {
425
426
427
+ cb. require_boolean ( "front_mask can go from 1 to 0" , front_mask. expr ( ) - front_mask_next) ;
428
+
429
+ // The address is incremented by 1, except in the front mask because the row address has not caught up with the address of the event yet.
430
+ let addr_diff = not:: expr ( front_mask. expr ( ) ) ;
426
431
cb. require_equal (
427
- "rows[0].addr + 1 == rows[2].addr" ,
432
+ "rows[0].addr + !front_mask == rows[2].addr" ,
428
433
meta. query_advice ( addr, Rotation :: cur ( ) ) + addr_diff,
429
434
meta. query_advice ( addr, Rotation ( 2 ) ) ,
430
435
) ;
431
- } ,
432
- ) ;
433
436
434
- cb. condition (
435
- not_last_two_rows. expr ( ) * is_event,
436
- |cb| {
437
+ // The byte count including mask always decrements.
438
+ cb. require_equal (
439
+ "bytes_left == bytes_left_next + 1 for non-last step" ,
440
+ meta. query_advice ( bytes_left, Rotation :: cur ( ) ) ,
441
+ meta. query_advice ( bytes_left, Rotation ( 2 ) ) + 1 . expr ( ) ,
442
+ ) ;
443
+
444
+ // Forward other fields to the next step.
437
445
cb. require_equal (
438
446
"rows[0].id == rows[2].id" ,
439
447
meta. query_advice ( id, Rotation :: cur ( ) ) ,
@@ -444,7 +452,6 @@ impl<F: Field> SubCircuitConfig<F> for CopyCircuitConfig<F> {
444
452
tag. value ( Rotation :: cur ( ) ) ( meta) ,
445
453
tag. value ( Rotation ( 2 ) ) ( meta) ,
446
454
) ;
447
-
448
455
cb. require_equal (
449
456
"rows[0].src_addr_end == rows[2].src_addr_end for non-last step" ,
450
457
meta. query_advice ( src_addr_end, Rotation :: cur ( ) ) ,
@@ -789,12 +796,12 @@ impl<F: Field> CopyCircuitConfig<F> {
789
796
. iter ( )
790
797
. zip_eq ( table_row)
791
798
{
792
- region. assign_advice (
793
- || format ! ( "{label} at row: {offset}" ) ,
794
- column,
795
- * offset,
796
- || value,
797
- ) ?;
799
+ region. assign_advice (
800
+ || format ! ( "{label} at row: {offset}" ) ,
801
+ column,
802
+ * offset,
803
+ || value,
804
+ ) ?;
798
805
}
799
806
800
807
// q_step
0 commit comments