zkevm-circuits
zkevm-circuits copied to clipboard
Keccak: error when `KECCAK_ROWS` is too big
https://github.com/privacy-scaling-explorations/zkevm-circuits/blob/ee1cfbdd15755371692a9bdb2e289fcf0c888860/zkevm-circuits/src/keccak_circuit/keccak_packed_multi.rs#L2056
When KECCAK_ROWS
is too big (say >30), in round NUM_ROUNDS
there are less rows than get_num_rows_per_round()
. It seems to be fixed if you change the line above to:
cell_values: regions[round]
.rows
.get(row_idx)
.unwrap_or(&vec![F::zero(); regions[round].rows[0].len()])
.clone()
It's probably not advisable to use such high rows per round because the gates access Rotation
s at all rows per round, but at least there will not be a mysterious error.
Also, I think a slightly more accurate capacity function is:
/// The number of keccak_f's that can be done in this circuit
///
/// `num_rows` should be number of usable rows without blinding factors aka `(1 << degree) - meta.minimum_rows()`
pub fn get_keccak_capacity(num_rows: usize) -> usize {
// - 1 because we have a dummy round at the very beginning of multi_keccak
// - NUM_WORDS_TO_ABSORB because `absorb_data_next` and `absorb_result_next` query `NUM_WORDS_TO_ABSORB * get_num_rows_per_round()` beyond any row where `q_absorb == 1`
(num_rows / get_num_rows_per_round() - 1 - NUM_WORDS_TO_ABSORB) / (NUM_ROUNDS + 1)
}
Ah thanks, never tested with KECCAK_ROWS
that large, depending on the lookup table height there is also a limit for some parts how many rows can actually bused per round. A fix similar to this would indeed be nice:
impl<F: FieldExt> KeccakRegion<F> {
...
pub(crate) fn get_row(&self, row_idx: usize) -> Vec<F> {
self.rows.get(row_idx).unwrap_or(&Vec::new()).clone()
}
}
...
cell_values: regions[round].get_row(row_idx),