-
Notifications
You must be signed in to change notification settings - Fork 34
Keccak-f[1600] gate #919
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Keccak-f[1600] gate #919
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,11 @@ | ||
| ethsign circuit | ||
| -- | ||
| Number of gates: 264472 | ||
| Number of evaluation instructions: 310572 | ||
| Number of AND constraints: 359966 | ||
| Number of gates: 258954 | ||
| Number of evaluation instructions: 305054 | ||
| Number of AND constraints: 355646 | ||
| Number of MUL constraints: 25458 | ||
| Length of value vec: 524288 | ||
| Constants: 82 | ||
| Inout: 29 | ||
| Witness: 42 | ||
| Internal: 479997 | ||
| Internal: 475677 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,11 @@ | ||
| hash_based_sig circuit | ||
| -- | ||
| Number of gates: 3986883 | ||
| Number of evaluation instructions: 4076982 | ||
| Number of AND constraints: 4022460 | ||
| Number of gates: 1421013 | ||
| Number of evaluation instructions: 1511112 | ||
| Number of AND constraints: 2013660 | ||
| Number of MUL constraints: 0 | ||
| Length of value vec: 4194304 | ||
| Length of value vec: 2097152 | ||
| Constants: 376 | ||
| Inout: 20 | ||
| Witness: 29886 | ||
| Internal: 3978540 | ||
| Internal: 1969740 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,11 @@ | ||
| keccak circuit | ||
| -- | ||
| Number of gates: 27625 | ||
| Number of evaluation instructions: 27625 | ||
| Number of AND constraints: 27625 | ||
| Number of gates: 35 | ||
| Number of evaluation instructions: 35 | ||
| Number of AND constraints: 6025 | ||
| Number of MUL constraints: 0 | ||
| Length of value vec: 32768 | ||
| Length of value vec: 8192 | ||
| Constants: 23 | ||
| Inout: 50 | ||
| Witness: 0 | ||
| Internal: 27600 | ||
| Internal: 6000 |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,5 +1,7 @@ | ||||||||||||||||||||||||
| //! Bytecode interpreter for circuit evaluation | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| use std::array; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| use binius_core::{ValueIndex, ValueVec, Word}; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| use crate::compiler::{circuit::PopulateError, hints::HintRegistry}; | ||||||||||||||||||||||||
|
|
@@ -135,6 +137,9 @@ impl<'a> Interpreter<'a> { | |||||||||||||||||||||||
| 0x64 => self.exec_assert_false(ctx), | ||||||||||||||||||||||||
| 0x65 => self.exec_assert_true(ctx), | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // High level intrinsics | ||||||||||||||||||||||||
| 0x70 => self.exec_keccakf1600(ctx), | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // Hint calls | ||||||||||||||||||||||||
| 0x80 => self.exec_hint(ctx), | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -451,6 +456,61 @@ impl<'a> Interpreter<'a> { | |||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| fn exec_keccakf1600(&mut self, ctx: &mut ExecutionContext<'_>) { | ||||||||||||||||||||||||
| let mut a: [Word; 25] = array::from_fn(|_| { | ||||||||||||||||||||||||
| let reg = self.read_reg(); | ||||||||||||||||||||||||
| self.load(ctx, reg) | ||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| use super::gate::keccakf1600::{CONSTS, R}; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| fn idx(x: usize, y: usize) -> usize { | ||||||||||||||||||||||||
| (x % 5) + 5 * (y % 5) | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| fn rot(amount: u32, value: Word) -> Word { | ||||||||||||||||||||||||
| value.rotr(64 - amount) | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // ι round constants occupy first 24 words of Keccakf1600 gate constants | ||||||||||||||||||||||||
| for &round_constant in &CONSTS[..24] { | ||||||||||||||||||||||||
| // θ | ||||||||||||||||||||||||
| let c: [Word; 5] = | ||||||||||||||||||||||||
| array::from_fn(|i| (0..5).fold(Word::ZERO, |acc, j| acc ^ a[idx(i, j)])); | ||||||||||||||||||||||||
| let d: [Word; 5] = array::from_fn(|i| c[(i + 4) % 5] ^ rot(1, c[(i + 1) % 5])); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| for i in 0..25 { | ||||||||||||||||||||||||
| a[i] = a[i] ^ d[i % 5]; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // ρ & π | ||||||||||||||||||||||||
| let mut b = [Word::ZERO; 25]; | ||||||||||||||||||||||||
| for x in 0..5 { | ||||||||||||||||||||||||
| for y in 0..5 { | ||||||||||||||||||||||||
| let i = idx(x, y); | ||||||||||||||||||||||||
| b[idx(y, 2 * x + 3 * y)] = rot(R[i], a[i]); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // χ | ||||||||||||||||||||||||
| for x in 0..5 { | ||||||||||||||||||||||||
| for y in 0..5 { | ||||||||||||||||||||||||
| let i = idx(x, y); | ||||||||||||||||||||||||
| a[i] = b[i] ^ !b[idx(x + 1, y)] & b[idx(x + 2, y)]; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // ι | ||||||||||||||||||||||||
| a[0] = a[0] ^ round_constant; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // writeback | ||||||||||||||||||||||||
| for val in a { | ||||||||||||||||||||||||
| let reg = self.read_reg(); | ||||||||||||||||||||||||
| self.store(ctx, reg, val); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
Comment on lines
+507
to
+510
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical Bug: Incorrect State Writeback in Keccak-f[1600] Implementation There's a significant issue with the state writeback logic in the for &round_constant in &CONSTS[..24] {
// θ, ρ, π, χ, ι steps...
// writeback - THIS IS THE PROBLEM
for val in a {
let reg = self.read_reg();
self.store(ctx, reg, val);
}
}This is incorrect because:
The writeback loop should be moved outside and after the round loop, so it executes only once after all 24 rounds are complete: for &round_constant in &CONSTS[..24] {
// θ, ρ, π, χ, ι steps...
}
// writeback (only once, after all rounds)
for val in a {
let reg = self.read_reg();
self.store(ctx, reg, val);
}This change will ensure the correct final state is written to the output registers.
Suggested change
Spotted by Diamond
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @onesk WDYT? |
||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // Hint execution | ||||||||||||||||||||||||
| fn exec_hint(&mut self, ctx: &mut ExecutionContext<'_>) { | ||||||||||||||||||||||||
| let hint_id = self.read_u32() as usize; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: Is there a reason not to reuse the public
idxfunction from keccakf1600?