@@ -3,7 +3,7 @@ use crate::{
3
3
common:: { NEXT_INPUTS_LANES , PERMUTATION , ROUND_CONSTANTS } ,
4
4
keccak_arith:: * ,
5
5
permutation:: {
6
- base_conversion:: BaseConversionConfig , iota_b9 :: IotaB9Config , mixing:: MixingConfig ,
6
+ base_conversion:: BaseConversionConfig , iota :: IotaConfig , mixing:: MixingConfig ,
7
7
pi:: pi_gate_permutation, rho:: RhoConfig , tables:: FromBase9TableConfig , theta:: ThetaConfig ,
8
8
xi:: XiConfig ,
9
9
} ,
@@ -22,7 +22,7 @@ pub struct KeccakFConfig<F: Field> {
22
22
theta_config : ThetaConfig < F > ,
23
23
rho_config : RhoConfig < F > ,
24
24
xi_config : XiConfig < F > ,
25
- iota_b9_config : IotaB9Config < F > ,
25
+ iota_config : IotaConfig < F > ,
26
26
from_b9_table : FromBase9TableConfig < F > ,
27
27
base_conversion_config : BaseConversionConfig < F > ,
28
28
mixing_config : MixingConfig < F > ,
@@ -44,6 +44,7 @@ impl<F: Field> KeccakFConfig<F> {
44
44
. try_into ( )
45
45
. unwrap ( ) ;
46
46
47
+ let flag = meta. advice_column ( ) ;
47
48
let fixed = [
48
49
meta. fixed_column ( ) ,
49
50
meta. fixed_column ( ) ,
@@ -56,22 +57,7 @@ impl<F: Field> KeccakFConfig<F> {
56
57
let rho_config = RhoConfig :: configure ( meta, state, fixed) ;
57
58
// xi
58
59
let xi_config = XiConfig :: configure ( meta. selector ( ) , meta, state) ;
59
-
60
- // Allocate space for the round constants in base-9 which is an
61
- // instance column
62
- let round_ctant_b9 = meta. advice_column ( ) ;
63
- meta. enable_equality ( round_ctant_b9) ;
64
- let round_constants_b9 = meta. instance_column ( ) ;
65
-
66
- // Allocate space for the round constants in base-13 which is an
67
- // instance column
68
- let round_ctant_b13 = meta. advice_column ( ) ;
69
- meta. enable_equality ( round_ctant_b13) ;
70
- let round_constants_b13 = meta. instance_column ( ) ;
71
-
72
- // Iotab9
73
- let iota_b9_config =
74
- IotaB9Config :: configure ( meta, state, round_ctant_b9, round_constants_b9) ;
60
+ let iota_config = IotaConfig :: configure ( meta, state[ 0 ] , flag, fixed[ 0 ] ) ;
75
61
76
62
// Allocate space for the activation flag of the base_conversion.
77
63
let base_conv_activator = meta. advice_column ( ) ;
@@ -90,15 +76,8 @@ impl<F: Field> KeccakFConfig<F> {
90
76
91
77
// Mixing will make sure that the flag is binary constrained and that
92
78
// the out state matches the expected result.
93
- let mixing_config = MixingConfig :: configure (
94
- meta,
95
- & from_b9_table,
96
- round_ctant_b9,
97
- round_ctant_b13,
98
- round_constants_b9,
99
- round_constants_b13,
100
- state,
101
- ) ;
79
+ let mixing_config =
80
+ MixingConfig :: configure ( meta, & from_b9_table, iota_config. clone ( ) , state) ;
102
81
103
82
// Allocate the `out state correctness` gate selector
104
83
let q_out = meta. selector ( ) ;
@@ -120,7 +99,7 @@ impl<F: Field> KeccakFConfig<F> {
120
99
theta_config,
121
100
rho_config,
122
101
xi_config,
123
- iota_b9_config ,
102
+ iota_config ,
124
103
from_b9_table,
125
104
base_conversion_config,
126
105
mixing_config,
@@ -146,7 +125,7 @@ impl<F: Field> KeccakFConfig<F> {
146
125
let mut state = in_state;
147
126
148
127
// First 23 rounds
149
- for ( round_idx, round_val ) in ROUND_CONSTANTS . iter ( ) . enumerate ( ) . take ( PERMUTATION ) {
128
+ for round_idx in 0 .. PERMUTATION {
150
129
// State in base-13
151
130
// theta
152
131
state = {
@@ -160,10 +139,7 @@ impl<F: Field> KeccakFConfig<F> {
160
139
} ;
161
140
162
141
// rho
163
- state = {
164
- // assignment
165
- self . rho_config . assign_rotation_checks ( layouter, & state) ?
166
- } ;
142
+ state = self . rho_config . assign_rotation_checks ( layouter, & state) ?;
167
143
// Outputs in base-9 which is what Pi requires
168
144
169
145
// Apply Pi permutation
@@ -185,15 +161,9 @@ impl<F: Field> KeccakFConfig<F> {
185
161
}
186
162
187
163
// iota_b9
188
- state = {
189
- let out_state = KeccakFArith :: iota_b9 (
190
- & state_to_biguint ( split_state_cells ( state. clone ( ) ) ) ,
191
- * round_val,
192
- ) ;
193
- let out_state = state_bigint_to_field ( out_state) ;
194
- self . iota_b9_config
195
- . not_last_round ( layouter, & state, out_state, round_idx) ?
196
- } ;
164
+ state[ 0 ] = self
165
+ . iota_config
166
+ . assign_round_b9 ( layouter, state[ 0 ] . clone ( ) , round_idx) ?;
197
167
198
168
// The resulting state is in Base-9 now. We now convert it to
199
169
// base_13 which is what Theta requires again at the
@@ -231,8 +201,6 @@ impl<F: Field> KeccakFConfig<F> {
231
201
state_bigint_to_field ( mix_res) ,
232
202
flag,
233
203
next_mixing,
234
- // Last round = PERMUTATION - 1
235
- PERMUTATION - 1 ,
236
204
) ?;
237
205
238
206
self . constrain_out_state ( layouter, & mix_res, out_state)
@@ -297,7 +265,7 @@ impl<F: Field> KeccakFConfig<F> {
297
265
#[ cfg( test) ]
298
266
mod tests {
299
267
use super :: * ;
300
- use crate :: common:: { State , NEXT_INPUTS_LANES , ROUND_CONSTANTS } ;
268
+ use crate :: common:: { State , NEXT_INPUTS_LANES } ;
301
269
use crate :: gate_helpers:: biguint_to_f;
302
270
use halo2_proofs:: circuit:: Layouter ;
303
271
use halo2_proofs:: pairing:: bn256:: Fr as Fp ;
@@ -415,16 +383,6 @@ mod tests {
415
383
let next_input_fp: [ Fp ; NEXT_INPUTS_LANES ] =
416
384
state_bigint_to_field ( StateBigInt :: from ( next_input) ) ;
417
385
418
- let constants_b13: Vec < Fp > = ROUND_CONSTANTS
419
- . iter ( )
420
- . map ( |num| biguint_to_f ( & convert_b2_to_b13 ( * num) ) )
421
- . collect ( ) ;
422
-
423
- let constants_b9: Vec < Fp > = ROUND_CONSTANTS
424
- . iter ( )
425
- . map ( |num| biguint_to_f ( & convert_b2_to_b9 ( * num) ) )
426
- . collect ( ) ;
427
-
428
386
// When we pass no `mixing_inputs`, we perform the full keccak round
429
387
// ending with Mixing executing IotaB9
430
388
{
@@ -437,12 +395,7 @@ mod tests {
437
395
is_mixing : false ,
438
396
} ;
439
397
440
- let prover = MockProver :: < Fp > :: run (
441
- 17 ,
442
- & circuit,
443
- vec ! [ constants_b9. clone( ) , constants_b13. clone( ) ] ,
444
- )
445
- . unwrap ( ) ;
398
+ let prover = MockProver :: < Fp > :: run ( 17 , & circuit, vec ! [ ] ) . unwrap ( ) ;
446
399
447
400
assert_eq ! ( prover. verify( ) , Ok ( ( ) ) ) ;
448
401
@@ -454,13 +407,20 @@ mod tests {
454
407
next_mixing : None ,
455
408
is_mixing : true ,
456
409
} ;
457
-
458
- let prover = MockProver :: < Fp > :: run (
459
- 17 ,
460
- & circuit,
461
- vec ! [ constants_b9. clone( ) , constants_b13. clone( ) ] ,
462
- )
463
- . unwrap ( ) ;
410
+ let k = 17 ;
411
+ let prover = MockProver :: < Fp > :: run ( k, & circuit, vec ! [ ] ) . unwrap ( ) ;
412
+
413
+ #[ cfg( feature = "dev-graph" ) ]
414
+ {
415
+ use plotters:: prelude:: * ;
416
+ let root = BitMapBackend :: new ( "keccak-f.png" , ( 1024 , 16384 ) ) . into_drawing_area ( ) ;
417
+ root. fill ( & WHITE ) . unwrap ( ) ;
418
+ let root = root. titled ( "Keccak-F" , ( "sans-serif" , 60 ) ) . unwrap ( ) ;
419
+ halo2_proofs:: dev:: CircuitLayout :: default ( )
420
+ . show_labels ( false )
421
+ . render ( k, & circuit, & root)
422
+ . unwrap ( ) ;
423
+ }
464
424
465
425
assert ! ( prover. verify( ) . is_err( ) ) ;
466
426
}
@@ -475,12 +435,7 @@ mod tests {
475
435
is_mixing : true ,
476
436
} ;
477
437
478
- let prover = MockProver :: < Fp > :: run (
479
- 17 ,
480
- & circuit,
481
- vec ! [ constants_b9. clone( ) , constants_b13. clone( ) ] ,
482
- )
483
- . unwrap ( ) ;
438
+ let prover = MockProver :: < Fp > :: run ( 17 , & circuit, vec ! [ ] ) . unwrap ( ) ;
484
439
485
440
assert_eq ! ( prover. verify( ) , Ok ( ( ) ) ) ;
486
441
@@ -493,8 +448,7 @@ mod tests {
493
448
is_mixing : true ,
494
449
} ;
495
450
496
- let prover =
497
- MockProver :: < Fp > :: run ( 17 , & circuit, vec ! [ constants_b9, constants_b13] ) . unwrap ( ) ;
451
+ let prover = MockProver :: < Fp > :: run ( 17 , & circuit, vec ! [ ] ) . unwrap ( ) ;
498
452
499
453
assert ! ( prover. verify( ) . is_err( ) ) ;
500
454
}
0 commit comments