Skip to content
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

Open
wants to merge 9 commits into
base: community-edition-nebra
Choose a base branch
from
Open

Conversation

SupremoUGH
Copy link

@SupremoUGH SupremoUGH commented Aug 24, 2023

Adds functions for the Saturn Keccak circuit. Goes together with: https://github.com/NebraZKP/Saturn/pull/99

@SupremoUGH SupremoUGH marked this pull request as ready for review August 24, 2023 16:41
Copy link
Collaborator

@dtebbs dtebbs left a 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());
Copy link
Collaborator

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?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the magic +4

Copy link
Author

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.

Copy link
Collaborator

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.

Copy link
Author

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`.
Copy link
Collaborator

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?

Copy link
Author

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why deleting this?

Copy link
Author

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)

@stechu
Copy link

stechu commented Sep 6, 2023

The test packed_multi_keccak_prover failed. It complains about:

        KeccakCircuitConfig::new(meta, challenge)

feed two argument, while where it defined:
https://github.com/NebraZKP/halo2-lib/blob/keccak_for_saturn/hashes/zkevm-keccak/src/keccak_packed_multi.rs#L873

only take one.

@stechu
Copy link

stechu commented Sep 6, 2023

Additional Q: where is keccak_phase0_with_flags getting used?

@@ -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`.
Copy link

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?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented

@stechu
Copy link

stechu commented Sep 6, 2023

I think I clicked approve accidentally.

@SupremoUGH
Copy link
Author

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.

I removed the testing module altogether, it doesn't make sense for us any longer. All relevant tests are in Saturn

@SupremoUGH SupremoUGH requested review from dtebbs and stechu September 20, 2023 20:00
Copy link
Collaborator

@dtebbs dtebbs left a 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());
Copy link
Collaborator

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.

Comment on lines +1725 to +1731
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;

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...)

Comment on lines +1956 to +1961
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;

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.

Comment on lines +1568 to +1569
pub fn set_row(&self, region: &mut Region<'_, F>, offset: usize, row: &KeccakRow<F>) {
self.set_row_with_flags(region, offset, row, &[]);

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?

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?

Comment on lines +289 to +312
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);
}
}
}

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants