-
Notifications
You must be signed in to change notification settings - Fork 0
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 circuit #1
base: community-edition-nebra
Are you sure you want to change the base?
Conversation
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.
Overall makes sense, with a few little details that are not clear. I think a few comments could help clarify (even though the original code is pretty much devoid of comments), and it might be clearer to replace rather than copy the large phase0
function, if that's feasible.
I was also expecting to see some changes in the test files. (I get errors when running cargo test
- it's probably worth doing some basic checks).
It's not obvious to me whether the remaining code still makes sense in the context of some of these changes, but let's keep this diff as small as possible to make the changes obvious.
@@ -1189,7 +1212,9 @@ impl<F: Field> KeccakCircuitConfig<F> { | |||
} | |||
info!("- Post chi:"); | |||
info!("Lookups: {}", lookup_counter); | |||
info!("Columns: {}", cell_manager.get_width()); | |||
let width = cell_manager.get_width(); | |||
std::env::set_var("COL_TO_ENABLE", (width + 4).to_string()); |
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.
Could we have a comment explaining why this must be an env var, instead of something we pass as a param somewhere?
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.
Also the magic +4
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.
Basically I didn't want to break the functions' signatures, so I borrowed a page from their book. I agree ideally we should change the defn of CellManager, etc.
About the magic +4: I want to enforce copy constraints on the column on which the output bytes of keccak are stored. This happens 4 columns from now. Maybe I should define a constant and explain its meaning.
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.
Thanks. Yeah, constant couldn't hurt, but the main thing would be to add a comment in the code so the next reader will also understand.
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.
Now it is explained
@@ -1546,6 +1510,43 @@ impl<F: Field> KeccakCircuitConfig<F> { | |||
} | |||
} | |||
|
|||
/// Assigns the cells in `KeccakRow` to `region`. |
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.
Could you explain the extra with_flags
part here as well?
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.
Explained
@@ -121,7 +119,6 @@ fn packed_multi_keccak_simple() { | |||
verify::<Fr>(k, inputs, true); | |||
} | |||
|
|||
/// Cmdline: KECCAK_DEGREE=14 RUST_LOG=info cargo test -- --nocapture packed_multi_keccak_prover |
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.
why deleting this?
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.
I deleted the whole testing framework (all relevant tests are in Saturn)
The test KeccakCircuitConfig::new(meta, challenge) feed two argument, while where it defined: only take one. |
Additional Q: where is |
@@ -1954,6 +1950,350 @@ pub fn keccak_phase0<F: Field>( | |||
} | |||
} | |||
|
|||
/// Witness generation in `FirstPhase` for a keccak hash digest without | |||
/// computing RLCs, which are deferred to `SecondPhase`. |
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.
Can you comment here on what do the flags do?
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.
Commented
I think I clicked approve accidentally. |
I removed the testing module altogether, it doesn't make sense for us any longer. All relevant tests are in Saturn |
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.
That's a lot easier to reason about after the refactor. Thanks.
Just a couple of queries, but otherwise looks good.
@@ -1189,7 +1212,9 @@ impl<F: Field> KeccakCircuitConfig<F> { | |||
} | |||
info!("- Post chi:"); | |||
info!("Lookups: {}", lookup_counter); | |||
info!("Columns: {}", cell_manager.get_width()); | |||
let width = cell_manager.get_width(); | |||
std::env::set_var("COL_TO_ENABLE", (width + 4).to_string()); |
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.
Thanks. Yeah, constant couldn't hurt, but the main thing would be to add a comment in the code so the next reader will also understand.
let cell_offset = absorb_data.rotation as usize; | ||
let cell_column_idx = absorb_data.column_idx; | ||
// We compute the row index from the cell offset, the current | ||
// round and the current chunk | ||
let row_index = idx * (NUM_ROUNDS + 1) * num_rows_per_round | ||
+ round * num_rows_per_round | ||
+ cell_offset; |
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.
This computation happens in at least one other place so let's extract it into its own function.
(I know, I know, it seems futile to start doing this kind of thing when you've inherited a 400+ line function to begin with...)
let cell_offset = cell.rotation as usize; | ||
let cell_column_idx = cell.column_idx; | ||
// We compute the row index from the round number and the cell offset. | ||
let row_index = (num_chunks - 1) * (NUM_ROUNDS + 1) * num_rows_per_round | ||
+ round_number * num_rows_per_round | ||
+ cell_offset; |
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.
See above comment; make this its own function.
pub fn set_row(&self, region: &mut Region<'_, F>, offset: usize, row: &KeccakRow<F>) { | ||
self.set_row_with_flags(region, offset, row, &[]); |
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.
set_row_with_flags
returns a Vec<KeccakAssignedValue<F>>
, why don't we use it here?
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.
Or maybe my question is why set_row_with_flags
returns it?
if let Ok(num_flex_advice) = var("FLEX_GATE_NUM_ADVICE").map(|s| { | ||
s.parse::<usize>().expect("Cannot parse FLEX_GATE_NUM_ADVICE env var as usize") | ||
}) { | ||
let col_to_enable = | ||
if num_flex_advice == 1 { num_flex_advice + 1 } else { num_flex_advice + 2 }; | ||
if advice.index() == col_to_enable { | ||
meta.enable_equality(advice); | ||
} | ||
} | ||
// This is the column where the output bytes are stored. It happens at the last keccak column, | ||
// whose index will be shifted by the number of flex gate columns. | ||
if let Ok(last_keccak_column) = var("LAST_KECCAK_COLUMN").map(|s| { | ||
s.parse::<usize>().expect("Cannot parse LAST_KECCAK_COLUMN env var as usize") | ||
}) { | ||
if let Ok(num_flex_advice) = var("FLEX_GATE_NUM_ADVICE").map(|s| { | ||
s.parse::<usize>().expect("Cannot parse FLEX_GATE_NUM_ADVICE env var as usize") | ||
}) { | ||
let col_to_enable = last_keccak_column | ||
+ if num_flex_advice == 1 { num_flex_advice } else { num_flex_advice + 1 }; | ||
if advice.index() == col_to_enable { | ||
meta.enable_equality(advice); | ||
} | ||
} | ||
} |
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.
These two blocks are pretty similar, there's probably a function that could be abstracted out and called here. Maybe in the docs of that function you could elaborate a bit on what's going on, because I don't quite follow.
Adds functions for the Saturn Keccak circuit. Goes together with: https://github.com/NebraZKP/Saturn/pull/99