Skip to content
This repository was archived by the owner on Jul 5, 2024. It is now read-only.

Commit 394f3d6

Browse files
Iota refactor (#538)
* update plotting * iota refactor * fix mixing * rm iota_b9 and iota_b13 * clippy * fix keccak-f test * add doc * minor: rm instance * Update keccak256/src/permutation/iota.rs Co-authored-by: Carlos Pérez <37264926+CPerezz@users.noreply.github.com> * simplify constants Co-authored-by: Carlos Pérez <37264926+CPerezz@users.noreply.github.com>
1 parent 323a4f2 commit 394f3d6

File tree

7 files changed

+263
-1101
lines changed

7 files changed

+263
-1101
lines changed

keccak256/src/permutation.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
pub(crate) mod absorb;
44
pub(crate) mod base_conversion;
55
pub mod circuit;
6-
pub(crate) mod iota_b13;
7-
pub(crate) mod iota_b9;
6+
pub(crate) mod iota;
87
pub(crate) mod mixing;
98
pub(crate) mod pi;
109
pub(crate) mod rho;

keccak256/src/permutation/circuit.rs

Lines changed: 30 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
298266
mod 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

Comments
 (0)