@@ -3,7 +3,7 @@ use crate::{
33 common:: { NEXT_INPUTS_LANES , PERMUTATION , ROUND_CONSTANTS } ,
44 keccak_arith:: * ,
55 permutation:: {
6- base_conversion:: BaseConversionConfig , iota_b9 :: IotaB9Config , mixing:: MixingConfig ,
6+ base_conversion:: BaseConversionConfig , iota :: IotaConfig , mixing:: MixingConfig ,
77 pi:: pi_gate_permutation, rho:: RhoConfig , tables:: FromBase9TableConfig , theta:: ThetaConfig ,
88 xi:: XiConfig ,
99 } ,
@@ -22,7 +22,7 @@ pub struct KeccakFConfig<F: Field> {
2222 theta_config : ThetaConfig < F > ,
2323 rho_config : RhoConfig < F > ,
2424 xi_config : XiConfig < F > ,
25- iota_b9_config : IotaB9Config < F > ,
25+ iota_config : IotaConfig < F > ,
2626 from_b9_table : FromBase9TableConfig < F > ,
2727 base_conversion_config : BaseConversionConfig < F > ,
2828 mixing_config : MixingConfig < F > ,
@@ -44,6 +44,7 @@ impl<F: Field> KeccakFConfig<F> {
4444 . try_into ( )
4545 . unwrap ( ) ;
4646
47+ let flag = meta. advice_column ( ) ;
4748 let fixed = [
4849 meta. fixed_column ( ) ,
4950 meta. fixed_column ( ) ,
@@ -56,22 +57,7 @@ impl<F: Field> KeccakFConfig<F> {
5657 let rho_config = RhoConfig :: configure ( meta, state, fixed) ;
5758 // xi
5859 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 ] ) ;
7561
7662 // Allocate space for the activation flag of the base_conversion.
7763 let base_conv_activator = meta. advice_column ( ) ;
@@ -90,15 +76,8 @@ impl<F: Field> KeccakFConfig<F> {
9076
9177 // Mixing will make sure that the flag is binary constrained and that
9278 // 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) ;
10281
10382 // Allocate the `out state correctness` gate selector
10483 let q_out = meta. selector ( ) ;
@@ -120,7 +99,7 @@ impl<F: Field> KeccakFConfig<F> {
12099 theta_config,
121100 rho_config,
122101 xi_config,
123- iota_b9_config ,
102+ iota_config ,
124103 from_b9_table,
125104 base_conversion_config,
126105 mixing_config,
@@ -146,7 +125,7 @@ impl<F: Field> KeccakFConfig<F> {
146125 let mut state = in_state;
147126
148127 // First 23 rounds
149- for ( round_idx, round_val ) in ROUND_CONSTANTS . iter ( ) . enumerate ( ) . take ( PERMUTATION ) {
128+ for round_idx in 0 .. PERMUTATION {
150129 // State in base-13
151130 // theta
152131 state = {
@@ -160,10 +139,7 @@ impl<F: Field> KeccakFConfig<F> {
160139 } ;
161140
162141 // 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) ?;
167143 // Outputs in base-9 which is what Pi requires
168144
169145 // Apply Pi permutation
@@ -185,15 +161,9 @@ impl<F: Field> KeccakFConfig<F> {
185161 }
186162
187163 // 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) ?;
197167
198168 // The resulting state is in Base-9 now. We now convert it to
199169 // base_13 which is what Theta requires again at the
@@ -231,8 +201,6 @@ impl<F: Field> KeccakFConfig<F> {
231201 state_bigint_to_field ( mix_res) ,
232202 flag,
233203 next_mixing,
234- // Last round = PERMUTATION - 1
235- PERMUTATION - 1 ,
236204 ) ?;
237205
238206 self . constrain_out_state ( layouter, & mix_res, out_state)
@@ -297,7 +265,7 @@ impl<F: Field> KeccakFConfig<F> {
297265#[ cfg( test) ]
298266mod tests {
299267 use super :: * ;
300- use crate :: common:: { State , NEXT_INPUTS_LANES , ROUND_CONSTANTS } ;
268+ use crate :: common:: { State , NEXT_INPUTS_LANES } ;
301269 use crate :: gate_helpers:: biguint_to_f;
302270 use halo2_proofs:: circuit:: Layouter ;
303271 use halo2_proofs:: pairing:: bn256:: Fr as Fp ;
@@ -415,16 +383,6 @@ mod tests {
415383 let next_input_fp: [ Fp ; NEXT_INPUTS_LANES ] =
416384 state_bigint_to_field ( StateBigInt :: from ( next_input) ) ;
417385
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-
428386 // When we pass no `mixing_inputs`, we perform the full keccak round
429387 // ending with Mixing executing IotaB9
430388 {
@@ -437,12 +395,7 @@ mod tests {
437395 is_mixing : false ,
438396 } ;
439397
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 ( ) ;
446399
447400 assert_eq ! ( prover. verify( ) , Ok ( ( ) ) ) ;
448401
@@ -454,13 +407,20 @@ mod tests {
454407 next_mixing : None ,
455408 is_mixing : true ,
456409 } ;
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+ }
464424
465425 assert ! ( prover. verify( ) . is_err( ) ) ;
466426 }
@@ -475,12 +435,7 @@ mod tests {
475435 is_mixing : true ,
476436 } ;
477437
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 ( ) ;
484439
485440 assert_eq ! ( prover. verify( ) , Ok ( ( ) ) ) ;
486441
@@ -493,8 +448,7 @@ mod tests {
493448 is_mixing : true ,
494449 } ;
495450
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 ( ) ;
498452
499453 assert ! ( prover. verify( ) . is_err( ) ) ;
500454 }
0 commit comments