@@ -36,7 +36,7 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
36
36
pub fn new ( bitwise_lookup_bus : BitwiseOperationLookupBus , self_bus_idx : usize ) -> Self {
37
37
Self {
38
38
bitwise_lookup_bus,
39
- row_idx_encoder : Encoder :: new ( 17 , 2 , false ) ,
39
+ row_idx_encoder : Encoder :: new ( C :: ROWS_PER_BLOCK , 2 , false ) ,
40
40
bus_idx : self_bus_idx,
41
41
_phantom : PhantomData ,
42
42
}
@@ -91,29 +91,35 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
91
91
92
92
self . row_idx_encoder
93
93
. eval ( builder, local_cols. flags . row_idx . to_slice ( ) . unwrap ( ) ) ;
94
- builder. assert_one (
95
- self . row_idx_encoder
96
- . contains_flag_range :: < AB > ( local_cols . flags . row_idx . to_slice ( ) . unwrap ( ) , 0 ..=17 ) ,
97
- ) ;
94
+ builder. assert_one ( self . row_idx_encoder . contains_flag_range :: < AB > (
95
+ local_cols . flags . row_idx . to_slice ( ) . unwrap ( ) ,
96
+ 0 ..=C :: ROWS_PER_BLOCK ,
97
+ ) ) ;
98
98
builder. assert_eq (
99
99
self . row_idx_encoder
100
100
. contains_flag_range :: < AB > ( local_cols. flags . row_idx . to_slice ( ) . unwrap ( ) , 0 ..=3 ) ,
101
101
* flags. is_first_4_rows ,
102
102
) ;
103
103
builder. assert_eq (
104
- self . row_idx_encoder
105
- . contains_flag_range :: < AB > ( local_cols. flags . row_idx . to_slice ( ) . unwrap ( ) , 0 ..=15 ) ,
104
+ self . row_idx_encoder . contains_flag_range :: < AB > (
105
+ local_cols. flags . row_idx . to_slice ( ) . unwrap ( ) ,
106
+ 0 ..=C :: ROUND_ROWS - 1 ,
107
+ ) ,
106
108
* flags. is_round_row ,
107
109
) ;
108
110
builder. assert_eq (
109
- self . row_idx_encoder
110
- . contains_flag :: < AB > ( local_cols. flags . row_idx . to_slice ( ) . unwrap ( ) , & [ 16 ] ) ,
111
+ self . row_idx_encoder . contains_flag :: < AB > (
112
+ local_cols. flags . row_idx . to_slice ( ) . unwrap ( ) ,
113
+ & [ C :: ROUND_ROWS ] ,
114
+ ) ,
111
115
* flags. is_digest_row ,
112
116
) ;
113
- // If padding row we want the row_idx to be 17
117
+ // If padding row we want the row_idx to be C::ROWS_PER_BLOCK
114
118
builder. assert_eq (
115
- self . row_idx_encoder
116
- . contains_flag :: < AB > ( local_cols. flags . row_idx . to_slice ( ) . unwrap ( ) , & [ 17 ] ) ,
119
+ self . row_idx_encoder . contains_flag :: < AB > (
120
+ local_cols. flags . row_idx . to_slice ( ) . unwrap ( ) ,
121
+ & [ C :: ROWS_PER_BLOCK ] ,
122
+ ) ,
117
123
flags. is_padding_row ( ) ,
118
124
) ;
119
125
@@ -131,13 +137,13 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
131
137
/// Implements constraints for a digest row that ensure proper state transitions between blocks
132
138
/// This validates that:
133
139
/// The work variables are correctly initialized for the next message block
134
- /// For the last message block, the initial state matches SHA256_H constants
140
+ /// For the last message block, the initial state matches SHA_H constants
135
141
fn eval_digest_row < AB : InteractionBuilder > (
136
142
& self ,
137
143
builder : & mut AB ,
138
144
local : ShaDigestColsRef < AB :: Var > ,
139
145
) {
140
- // Check that if this is the last row of a message or an inpadding row, the hash should be the [SHA256_H ]
146
+ // Check that if this is the last row of a message or an inpadding row, the hash should be the [SHA_H ]
141
147
for i in 0 ..C :: ROUNDS_PER_ROW {
142
148
let a = local. hash . a . row ( i) . mapv ( |x| x. into ( ) ) . to_vec ( ) ;
143
149
let e = local. hash . e . row ( i) . mapv ( |x| x. into ( ) ) . to_vec ( ) ;
@@ -146,7 +152,7 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
146
152
let a_limb = compose :: < AB :: Expr > ( & a[ j * 16 ..( j + 1 ) * 16 ] , 1 ) ;
147
153
let e_limb = compose :: < AB :: Expr > ( & e[ j * 16 ..( j + 1 ) * 16 ] , 1 ) ;
148
154
149
- // If it is a padding row or the last row of a message, the `hash` should be the [SHA256_H ]
155
+ // If it is a padding row or the last row of a message, the `hash` should be the [SHA_H ]
150
156
builder
151
157
. when (
152
158
local. flags . is_padding_row ( )
@@ -244,24 +250,24 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
244
250
// Constrin how much the row index changes by
245
251
// round->round: 1
246
252
// round->digest: 1
247
- // digest->round: -16 // TODO: sha512
253
+ // digest->round: -C::ROUND_ROWS
248
254
// digest->padding: 1
249
255
// padding->padding: 0
250
256
// Other transitions are not allowed by the above
251
257
let delta = * local_cols. flags . is_round_row * AB :: Expr :: ONE
252
258
+ * local_cols. flags . is_digest_row
253
259
* * next_cols. flags . is_round_row
254
- * AB :: Expr :: from_canonical_u32 ( 16 )
260
+ * AB :: Expr :: from_canonical_usize ( C :: ROUND_ROWS )
255
261
* AB :: Expr :: NEG_ONE
256
262
+ * local_cols. flags . is_digest_row * next_is_padding_row. clone ( ) * AB :: Expr :: ONE ;
257
263
258
264
let local_row_idx = self . row_idx_encoder . flag_with_val :: < AB > (
259
265
local_cols. flags . row_idx . to_slice ( ) . unwrap ( ) ,
260
- & ( 0 ..18 ) . map ( |i| ( i, i) ) . collect :: < Vec < _ > > ( ) ,
266
+ & ( 0 ..= C :: ROWS_PER_BLOCK ) . map ( |i| ( i, i) ) . collect :: < Vec < _ > > ( ) ,
261
267
) ;
262
268
let next_row_idx = self . row_idx_encoder . flag_with_val :: < AB > (
263
269
next_cols. flags . row_idx . to_slice ( ) . unwrap ( ) ,
264
- & ( 0 ..18 ) . map ( |i| ( i, i) ) . collect :: < Vec < _ > > ( ) ,
270
+ & ( 0 ..= C :: ROWS_PER_BLOCK ) . map ( |i| ( i, i) ) . collect :: < Vec < _ > > ( ) ,
265
271
) ;
266
272
267
273
builder
@@ -411,20 +417,22 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
411
417
}
412
418
413
419
// Constrain intermed for `next` row
414
- // We will only constrain intermed_12 for rows [3, 14 ], and let it unconstrained for other rows
420
+ // We will only constrain intermed_12 for rows [3, C::ROUND_ROWS - 1 ], and let it unconstrained for other rows
415
421
// Other rows should put the needed value in intermed_12 to make the below summation constraint hold
416
- let is_row_3_14 = self
417
- . row_idx_encoder
418
- . contains_flag_range :: < AB > ( next. flags . row_idx . to_slice ( ) . unwrap ( ) , 3 ..=14 ) ;
419
- // We will only constrain intermed_8 for rows [2, 13], and let it unconstrained for other rows
420
- let is_row_2_13 = self
421
- . row_idx_encoder
422
- . contains_flag_range :: < AB > ( next. flags . row_idx . to_slice ( ) . unwrap ( ) , 2 ..=13 ) ;
422
+ let is_row_intermed_12 = self . row_idx_encoder . contains_flag_range :: < AB > (
423
+ next. flags . row_idx . to_slice ( ) . unwrap ( ) ,
424
+ 3 ..=C :: ROUND_ROWS - 2 ,
425
+ ) ;
426
+ // We will only constrain intermed_8 for rows [2, C::ROUND_ROWS - 2], and let it unconstrained for other rows
427
+ let is_row_intermed_8 = self . row_idx_encoder . contains_flag_range :: < AB > (
428
+ next. flags . row_idx . to_slice ( ) . unwrap ( ) ,
429
+ 2 ..=C :: ROUND_ROWS - 3 ,
430
+ ) ;
423
431
for i in 0 ..C :: ROUNDS_PER_ROW {
424
432
// w_idx
425
433
let w_idx = w. row ( i) . mapv ( |x| x. into ( ) ) . to_vec ( ) ;
426
434
// sig_0(w_{idx+1})
427
- let sig_w = small_sig0_field :: < AB :: Expr > ( w. row ( i + 1 ) . as_slice ( ) . unwrap ( ) ) ;
435
+ let sig_w = small_sig0_field :: < AB :: Expr , C > ( w. row ( i + 1 ) . as_slice ( ) . unwrap ( ) ) ;
428
436
for j in 0 ..C :: WORD_U16S {
429
437
let w_idx_limb = compose :: < AB :: Expr > ( & w_idx[ j * 16 ..( j + 1 ) * 16 ] , 1 ) ;
430
438
let sig_w_limb = compose :: < AB :: Expr > ( & sig_w[ j * 16 ..( j + 1 ) * 16 ] , 1 ) ;
@@ -434,12 +442,12 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
434
442
w_idx_limb + sig_w_limb,
435
443
) ;
436
444
437
- builder. when ( is_row_2_13 . clone ( ) ) . assert_eq (
445
+ builder. when ( is_row_intermed_8 . clone ( ) ) . assert_eq (
438
446
next. schedule_helper . intermed_8 [ [ i, j] ] ,
439
447
local. schedule_helper . intermed_4 [ [ i, j] ] ,
440
448
) ;
441
449
442
- builder. when ( is_row_3_14 . clone ( ) ) . assert_eq (
450
+ builder. when ( is_row_intermed_12 . clone ( ) ) . assert_eq (
443
451
next. schedule_helper . intermed_12 [ [ i, j] ] ,
444
452
local. schedule_helper . intermed_8 [ [ i, j] ] ,
445
453
) ;
@@ -472,7 +480,7 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
472
480
constraint_word_addition :: < _ , C > (
473
481
// Note: here we can't do a conditional check because the degree of sum is already 3
474
482
& mut builder. when_transition ( ) ,
475
- & [ & small_sig1_field :: < AB :: Expr > (
483
+ & [ & small_sig1_field :: < AB :: Expr , C > (
476
484
w. row ( i + 2 ) . as_slice ( ) . unwrap ( ) ,
477
485
) ] ,
478
486
& [ & w_7, intermed_16. as_slice ( ) . unwrap ( ) ] ,
@@ -481,13 +489,13 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
481
489
) ;
482
490
483
491
for j in 0 ..C :: WORD_U16S {
484
- // When on rows 4..16 message schedule carries should be 0 or 1
485
- let is_row_4_15 = * next. flags . is_round_row - * next. flags . is_first_4_rows ;
492
+ // When on rows 4..C::ROUND_ROWS message schedule carries should be 0 or 1
493
+ let is_row_4_or_more = * next. flags . is_round_row - * next. flags . is_first_4_rows ;
486
494
builder
487
- . when ( is_row_4_15 . clone ( ) )
495
+ . when ( is_row_4_or_more . clone ( ) )
488
496
. assert_bool ( next. message_schedule . carry_or_buffer [ [ i, j * 2 ] ] ) ;
489
497
builder
490
- . when ( is_row_4_15 )
498
+ . when ( is_row_4_or_more )
491
499
. assert_bool ( next. message_schedule . carry_or_buffer [ [ i, j * 2 + 1 ] ] ) ;
492
500
// Constrain w being composed of bits
493
501
for j in 0 ..C :: WORD_BITS {
@@ -499,7 +507,7 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
499
507
}
500
508
}
501
509
502
- /// Constrain the work vars on `next` row according to the sha256 documentation
510
+ /// Constrain the work vars on `next` row according to the sha documentation
503
511
/// Refer to [https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf]
504
512
fn eval_work_vars < ' a , AB : InteractionBuilder > (
505
513
& self ,
@@ -536,11 +544,12 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
536
544
) * * next. flags . is_round_row
537
545
} )
538
546
. collect :: < Vec < _ > > ( ) ;
547
+
539
548
let k_limbs = ( 0 ..C :: WORD_U16S )
540
549
. map ( |j| {
541
550
self . row_idx_encoder . flag_with_val :: < AB > (
542
551
next. flags . row_idx . to_slice ( ) . unwrap ( ) ,
543
- & ( 0 ..16 )
552
+ & ( 0 ..C :: ROUND_ROWS )
544
553
. map ( |rw_idx| {
545
554
(
546
555
rw_idx,
@@ -559,13 +568,13 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
559
568
builder,
560
569
& [
561
570
e. row ( i) . mapv ( |x| x. into ( ) ) . as_slice ( ) . unwrap ( ) , // previous `h`
562
- & big_sig1_field :: < AB :: Expr > ( e. row ( i + 3 ) . as_slice ( ) . unwrap ( ) ) , // sig_1 of previous `e`
571
+ & big_sig1_field :: < AB :: Expr , C > ( e. row ( i + 3 ) . as_slice ( ) . unwrap ( ) ) , // sig_1 of previous `e`
563
572
& ch_field :: < AB :: Expr > (
564
573
e. row ( i + 3 ) . as_slice ( ) . unwrap ( ) ,
565
574
e. row ( i + 2 ) . as_slice ( ) . unwrap ( ) ,
566
575
e. row ( i + 1 ) . as_slice ( ) . unwrap ( ) ,
567
576
) , // Ch of previous `e`, `f`, `g`
568
- & big_sig0_field :: < AB :: Expr > ( a. row ( i + 3 ) . as_slice ( ) . unwrap ( ) ) , // sig_0 of previous `a`
577
+ & big_sig0_field :: < AB :: Expr , C > ( a. row ( i + 3 ) . as_slice ( ) . unwrap ( ) ) , // sig_0 of previous `a`
569
578
& maj_field :: < AB :: Expr > (
570
579
a. row ( i + 3 ) . as_slice ( ) . unwrap ( ) ,
571
580
a. row ( i + 2 ) . as_slice ( ) . unwrap ( ) ,
@@ -581,9 +590,9 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
581
590
constraint_word_addition :: < _ , C > (
582
591
builder,
583
592
& [
584
- & a. row ( i) . mapv ( |x| x. into ( ) ) . as_slice ( ) . unwrap ( ) , // previous `d`
585
- & e. row ( i) . mapv ( |x| x. into ( ) ) . as_slice ( ) . unwrap ( ) , // previous `h`
586
- & big_sig1_field :: < AB :: Expr > ( e. row ( i + 3 ) . as_slice ( ) . unwrap ( ) ) , // sig_1 of previous `e`
593
+ a. row ( i) . mapv ( |x| x. into ( ) ) . as_slice ( ) . unwrap ( ) , // previous `d`
594
+ e. row ( i) . mapv ( |x| x. into ( ) ) . as_slice ( ) . unwrap ( ) , // previous `h`
595
+ & big_sig1_field :: < AB :: Expr , C > ( e. row ( i + 3 ) . as_slice ( ) . unwrap ( ) ) , // sig_1 of previous `e`
587
596
& ch_field :: < AB :: Expr > (
588
597
e. row ( i + 3 ) . as_slice ( ) . unwrap ( ) ,
589
598
e. row ( i + 2 ) . as_slice ( ) . unwrap ( ) ,
0 commit comments