Skip to content

Commit

Permalink
[feat] implement CircuitExt for KeccakComponentShardCircuit (#198)
Browse files Browse the repository at this point in the history
* chore: import `snark-verifier-sdk`

* feat: implement `CircuitExt` for `KeccakComponentShardCircuit`

so it can be aggregated by `snark-verifier-sdk`

* chore: derive `Serialize` for keccak circuit params
  • Loading branch information
jonathanpwang authored Oct 22, 2023
1 parent ca498e5 commit 2e996ae
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 14 deletions.
2 changes: 1 addition & 1 deletion halo2-base/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ num-integer = "0.1"
num-traits = "0.2"
rand_chacha = "0.3"
rustc-hash = "1.1"
rayon = "1.7"
rayon = "1.8"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
log = "0.4"
Expand Down
13 changes: 7 additions & 6 deletions hashes/zkevm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ num-bigint = { version = "0.4" }
halo2-base = { path = "../../halo2-base", default-features = false, features = [
"test-utils",
] }
rayon = "1.7"
serde = { version = "1.0", features = ["derive"] }
rayon = "1.8"
sha3 = "0.10.8"
# always included but without features to use Native poseidon
snark-verifier = { git = "https://github.com/axiom-crypto/snark-verifier.git", branch = "develop", default-features = false }
# always included but without features to use Native poseidon and get CircuitExt trait
snark-verifier-sdk = { git = "https://github.com/axiom-crypto/snark-verifier.git", branch = "develop", default-features = false }
getset = "0.1.2"

[dev-dependencies]
Expand All @@ -35,9 +36,9 @@ test-case = "3.1.0"

[features]
default = ["halo2-axiom", "display"]
display = ["halo2-base/display", "snark-verifier/display"]
halo2-pse = ["halo2-base/halo2-pse", "snark-verifier/halo2-pse"]
halo2-axiom = ["halo2-base/halo2-axiom", "snark-verifier/halo2-axiom"]
display = ["snark-verifier-sdk/display"]
halo2-pse = ["halo2-base/halo2-pse"]
halo2-axiom = ["halo2-base/halo2-axiom"]
jemallocator = ["halo2-base/jemallocator"]
mimalloc = ["halo2-base/mimalloc"]
asm = ["halo2-base/asm"]
47 changes: 44 additions & 3 deletions hashes/zkevm/src/keccak/component/circuit/shard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use crate::{
get_words_to_witness_multipliers, num_poseidon_absorb_per_keccak_f,
num_word_per_witness,
},
output::{dummy_circuit_output, KeccakCircuitOutput},
output::{
calculate_circuit_outputs_commit, dummy_circuit_output,
multi_inputs_to_circuit_outputs, KeccakCircuitOutput,
},
param::*,
},
vanilla::{
Expand Down Expand Up @@ -38,6 +41,8 @@ use halo2_base::{
QuantumCell::Constant,
};
use itertools::Itertools;
use serde::{Deserialize, Serialize};
use snark_verifier_sdk::CircuitExt;

/// Keccak Component Shard Circuit
#[derive(Getters)]
Expand All @@ -58,7 +63,7 @@ pub struct KeccakComponentShardCircuit<F: Field> {
}

/// Parameters of KeccakComponentCircuit.
#[derive(Default, Clone, CopyGetters)]
#[derive(Default, Clone, CopyGetters, Serialize, Deserialize)]
pub struct KeccakComponentShardCircuitParams {
/// This circuit has 2^k rows.
#[getset(get_copy = "pub")]
Expand Down Expand Up @@ -89,7 +94,7 @@ impl KeccakComponentShardCircuitParams {
) -> Self {
assert!(1 << k > num_unusable_row, "Number of unusable rows must be less than 2^k");
let max_rows = (1 << k) - num_unusable_row;
// Derived from [crate::keccak::native_circuit::keccak_packed_multi::get_keccak_capacity].
// Derived from [crate::keccak::vanilla::keccak_packed_multi::get_keccak_capacity].
let rows_per_round = max_rows / (capacity * (NUM_ROUNDS + 1) + 1 + NUM_WORDS_TO_ABSORB);
assert!(rows_per_round > 0, "No enough rows for the speficied capacity");
let keccak_circuit_params = KeccakConfigParams { k: k as u32, rows_per_round };
Expand Down Expand Up @@ -516,3 +521,39 @@ pub fn transmute_keccak_assigned_to_virtual<F: Field>(
})
.collect()
}

impl<F: Field> CircuitExt<F> for KeccakComponentShardCircuit<F> {
fn instances(&self) -> Vec<Vec<F>> {
let circuit_outputs = multi_inputs_to_circuit_outputs(&self.inputs, self.params.capacity);
if self.params.publish_raw_outputs {
vec![
circuit_outputs.iter().map(|o| o.key).collect(),
circuit_outputs.iter().map(|o| o.hash_lo).collect(),
circuit_outputs.iter().map(|o| o.hash_hi).collect(),
]
} else {
vec![vec![calculate_circuit_outputs_commit(&circuit_outputs)]]
}
}

fn num_instance(&self) -> Vec<usize> {
if self.params.publish_raw_outputs {
vec![self.params.capacity; OUTPUT_NUM_COL_RAW]
} else {
vec![1; OUTPUT_NUM_COL_COMMIT]
}
}

fn accumulator_indices() -> Option<Vec<(usize, usize)>> {
None
}

fn selectors(config: &Self::Config) -> Vec<halo2_base::halo2_proofs::plonk::Selector> {
// the vanilla keccak circuit does not use selectors
// this is from the BaseCircuitBuilder
config.base_circuit_config.gate().basic_gates[0]
.iter()
.map(|basic| basic.q_enable)
.collect()
}
}
2 changes: 1 addition & 1 deletion hashes/zkevm/src/keccak/component/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use halo2_base::{
};
use itertools::Itertools;
use num_bigint::BigUint;
use snark_verifier::loader::native::NativeLoader;
use snark_verifier_sdk::{snark_verifier, NativeLoader};

use crate::{
keccak::vanilla::{keccak_packed_multi::get_num_keccak_f, param::*},
Expand Down
2 changes: 1 addition & 1 deletion hashes/zkevm/src/keccak/component/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use super::{encode::encode_native_input, param::*};
use crate::{keccak::vanilla::keccak_packed_multi::get_num_keccak_f, util::eth_types::Field};
use itertools::Itertools;
use sha3::{Digest, Keccak256};
use snark_verifier::loader::native::NativeLoader;
use snark_verifier_sdk::{snark_verifier, NativeLoader};

/// Witnesses to be exposed as circuit outputs.
#[derive(Clone, Copy, PartialEq, Debug)]
Expand Down
5 changes: 3 additions & 2 deletions hashes/zkevm/src/keccak/vanilla/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use halo2_base::utils::halo2::{raw_assign_advice, raw_assign_fixed};
use itertools::Itertools;
use log::{debug, info};
use rayon::prelude::{IntoParallelRefIterator, ParallelIterator};
use serde::{Deserialize, Serialize};
use std::marker::PhantomData;

pub mod cell_manager;
Expand All @@ -30,7 +31,7 @@ pub mod util;
pub mod witness;

/// Configuration parameters to define [`KeccakCircuitConfig`]
#[derive(Copy, Clone, Debug, Default)]
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize)]
pub struct KeccakConfigParams {
/// The circuit degree, i.e., circuit has 2<sup>k</sup> rows
pub k: u32,
Expand Down Expand Up @@ -635,7 +636,7 @@ impl<F: Field> KeccakCircuitConfig<F> {
});
// Logically here we want !q_input[cur] && !start_new_hash(cur) ==> bytes_left[cur + num_rows_per_round] == bytes_left[cur]
// In practice, in order to save a degree we use !(q_input[cur] ^ start_new_hash(cur)) ==> bytes_left[cur + num_rows_per_round] == bytes_left[cur]
// When q_input[cur] is true, the above constraint q_input[cur] ==> bytes_left[cur + num_rows_per_round] + word_len == bytes_left[cur] has
// When q_input[cur] is true, the above constraint q_input[cur] ==> bytes_left[cur + num_rows_per_round] + word_len == bytes_left[cur] has
// already been enabled. Even is_final in start_new_hash(cur) is true, it's just over-constrainted.
// Note: At the first row of any round except the last round, is_final could be either true or false.
cb.condition(not::expr(q(q_input, meta) + start_new_hash(meta, Rotation::cur())), |cb| {
Expand Down

0 comments on commit 2e996ae

Please sign in to comment.