use crate::{
interpreters::keccak::column::{ColumnAlias as KeccakColumn, Steps::*, PAD_SUFFIX_LEN},
lookups::LookupTableIDs,
};
use ark_ff::Field;
use kimchi::circuits::polynomials::keccak::constants::{
DIM, KECCAK_COLS, QUARTERS, RATE_IN_BYTES, STATE_LEN,
};
pub mod column;
pub mod constraints;
pub mod environment;
pub mod helpers;
pub mod interpreter;
#[cfg(test)]
pub mod tests;
pub mod witness;
pub use column::{Absorbs, Sponges, Steps};
pub(crate) const HASH_BITLENGTH: usize = 256;
pub(crate) const HASH_BYTELENGTH: usize = HASH_BITLENGTH / 8;
pub(crate) const WORD_LENGTH_IN_BITS: usize = 64;
pub(crate) const ZKVM_KECCAK_COLS_CURR: usize = KECCAK_COLS;
pub(crate) const ZKVM_KECCAK_COLS_NEXT: usize = STATE_LEN;
pub(crate) const WORDS_IN_HASH: usize = HASH_BITLENGTH / WORD_LENGTH_IN_BITS;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Error {
Constraint(Constraint),
Lookup(LookupTableIDs),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Constraint {
BooleanityPadding(usize),
AbsorbZeroPad(usize),
AbsorbRootZero(usize),
AbsorbXor(usize),
AbsorbShifts(usize),
PadAtEnd,
PaddingSuffix(usize),
SqueezeShifts(usize),
ThetaWordC(usize),
ThetaRotatedC(usize),
ThetaQuotientC(usize),
ThetaShiftsC(usize, usize),
PiRhoWordE(usize, usize),
PiRhoRotatedE(usize, usize),
PiRhoShiftsE(usize, usize, usize),
ChiShiftsB(usize, usize, usize),
ChiShiftsSum(usize, usize, usize),
IotaStateG(usize),
}
pub fn standardize(opcode: Steps) -> Steps {
if let Round(_) = opcode {
Round(0)
} else {
opcode
}
}
fn grid_index(length: usize, i: usize, y: usize, x: usize, q: usize) -> usize {
match length {
5 => x,
20 => q + QUARTERS * x,
80 => q + QUARTERS * (x + DIM * i),
100 => q + QUARTERS * (x + DIM * y),
400 => q + QUARTERS * (x + DIM * (y + DIM * i)),
_ => panic!("Invalid grid size"),
}
}
pub fn pad_blocks<F: Field>(pad_bytelength: usize) -> [F; PAD_SUFFIX_LEN] {
assert!(pad_bytelength > 0, "Padding length must be at least 1 byte");
assert!(
pad_bytelength <= 136,
"Padding length must be at most 136 bytes",
);
let mut blocks = [F::zero(); PAD_SUFFIX_LEN];
let mut pad = [F::zero(); RATE_IN_BYTES];
pad[RATE_IN_BYTES - pad_bytelength] = F::one();
pad[RATE_IN_BYTES - 1] += F::from(0x80u8);
blocks[0] = pad
.iter()
.take(12)
.fold(F::zero(), |acc, x| acc * F::from(256u32) + *x);
for (i, block) in blocks.iter_mut().enumerate().take(5).skip(1) {
*block = pad
.iter()
.skip(12 + (i - 1) * 31)
.take(31)
.fold(F::zero(), |acc, x| acc * F::from(256u32) + *x);
}
blocks
}