Skip to content
This repository was archived by the owner on Jul 5, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b360e3f
WIP keccak permutation
Brechtpd May 18, 2022
b759b75
Better theta lookup approach
Brechtpd May 21, 2022
715e7d9
WIP improvements
Brechtpd May 24, 2022
bf3196f
Better bit based implementation
Brechtpd May 26, 2022
eba76c9
WIP packed keccak
Brechtpd May 31, 2022
94f7cff
Packed absorb
Brechtpd Jun 2, 2022
0f3c7bd
Multi stage theta (first part)
Brechtpd Jun 7, 2022
e3bb83a
Fixes
Brechtpd Jun 8, 2022
b5c1e8b
Added better performing mode at certain circuit sizes
Brechtpd Jun 10, 2022
a1017ff
Generalized splitting
Brechtpd Jun 14, 2022
9a8ef7c
small improvements
Brechtpd Jun 15, 2022
7a7a778
fixes
Brechtpd Jun 15, 2022
939ac41
small improvements
Brechtpd Jun 18, 2022
ba17637
Added multi-row per round version
Brechtpd Jun 28, 2022
4912055
cleanup code
Brechtpd Jul 25, 2022
2efb725
Merge branch 'main' into keccak-playground
Brechtpd Jul 25, 2022
b33138e
Add padding on the witness side
Brechtpd Jul 28, 2022
9d7aa84
Preparations for padding + rlc squeeze in bit implementation
Brechtpd Aug 10, 2022
b62b39e
Feedback + packed squeeze
Brechtpd Aug 11, 2022
f48f09b
multi packed squeeze
Brechtpd Aug 13, 2022
5bc230a
Finish keccak implementations (added padding/data rlc/length)
Brechtpd Aug 17, 2022
3e7a0b8
cleanup code
Brechtpd Aug 17, 2022
7a33390
More accurate benchmark results by filling the full circuit
Brechtpd Aug 18, 2022
b3fbe87
more cleanup
Brechtpd Aug 18, 2022
dcec5f3
more cleanup
Brechtpd Aug 19, 2022
b1e65dc
Merge branch 'main' into keccak-playground
Brechtpd Aug 19, 2022
b26da7c
more cleanup
Brechtpd Aug 19, 2022
98febf1
cleanup
Brechtpd Aug 20, 2022
2aebc53
cleanup
Brechtpd Aug 23, 2022
29a0f6c
even more cleanup + feedback
Brechtpd Aug 24, 2022
42ded94
Merge remote-tracking branch 'origin' into keccak-playground
Brechtpd Aug 24, 2022
29e5390
Fix docs error
Brechtpd Aug 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ test_doc: ## Test the docs
test_benches: ## Compiles the benchmarks
@cargo test --verbose --release --all-features -p circuit-benchmarks --no-run

test-all: fmt doc clippy test_doc test_benches test ## Run all the CI checks locally (in your actual toolchain)
test-all: fmt doc clippy test_doc test_benches test ## Run all the CI checks locally (in your actual toolchain)

evm_bench: ## Run Evm Circuit benchmarks
@cargo test --profile bench bench_evm_circuit_prover -p circuit-benchmarks --features benches -- --nocapture
Expand All @@ -37,6 +37,15 @@ state_bench: ## Run State Circuit benchmarks
keccak_round_bench: ## Run State Circuit benchmarks
@cargo test --profile bench bench_keccak_round -p circuit-benchmarks --features benches -- --nocapture

bit_keccak_bench: ## Run Bit Keccak Circuit benchmarks
@cargo test --profile bench bench_bit_keccak_circuit_prover -p circuit-benchmarks --features benches -- --nocapture

packed_keccak_bench: ## Run Packed Keccak Circuit benchmarks
@cargo test --profile bench bench_packed_keccak_circuit_prover -p circuit-benchmarks --features benches -- --nocapture

packed_multi_keccak_bench: ## Run Packed Multi Keccak Circuit benchmarks
@cargo test --profile bench bench_packed_multi_keccak_circuit_prover -p circuit-benchmarks --features benches -- --nocapture

circuit_benches: evm_bench state_bench ## Run All Circuit benchmarks


Expand Down
82 changes: 82 additions & 0 deletions circuit-benchmarks/src/bit_keccak.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//! State circuit benchmarks

#[cfg(test)]
mod tests {
use ark_std::{end_timer, start_timer};
use halo2_proofs::plonk::{create_proof, keygen_pk, keygen_vk, verify_proof, SingleVerifier};
use halo2_proofs::{
pairing::bn256::{Bn256, G1Affine},
poly::commitment::{Params, ParamsVerifier},
transcript::{Blake2bRead, Blake2bWrite, Challenge255},
};
use rand::SeedableRng;
use rand_xorshift::XorShiftRng;
use std::env::var;
use zkevm_circuits::keccak_circuit::keccak_bit::KeccakBitCircuit;

#[cfg_attr(not(feature = "benches"), ignore)]
#[test]
fn bench_bit_keccak_circuit_prover() {
let degree: u32 = var("DEGREE")
.expect("No DEGREE env var was provided")
.parse()
.expect("Cannot parse DEGREE env var as u32");

// Create the circuit
let mut circuit = KeccakBitCircuit::new(2usize.pow(degree));

// Use the complete circuit
let inputs = vec![(0u8..135).collect::<Vec<_>>(); circuit.capacity()];
circuit.generate_witness(&inputs);

// Initialize the polynomial commitment parameters
let rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
0xbc, 0xe5,
]);

// Bench setup generation
let setup_message = format!("Setup generation with degree = {}", degree);
let start1 = start_timer!(|| setup_message);
let general_params: Params<G1Affine> = Params::<G1Affine>::unsafe_setup::<Bn256>(degree);
let verifier_params: ParamsVerifier<Bn256> =
general_params.verifier(degree as usize * 2).unwrap();
end_timer!(start1);

// Initialize the proving key
let vk = keygen_vk(&general_params, &circuit).expect("keygen_vk should not fail");
let pk = keygen_pk(&general_params, vk, &circuit).expect("keygen_pk should not fail");
// Create a proof
let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);

// Bench proof generation time
let proof_message = format!("Bit Keccak Proof generation with {} rows", degree);
let start2 = start_timer!(|| proof_message);
create_proof(
&general_params,
&pk,
&[circuit],
&[&[]],
rng,
&mut transcript,
)
.expect("proof generation should not fail");
let proof = transcript.finalize();
end_timer!(start2);

// Bench verification time
let start3 = start_timer!(|| "Keccak Proof verification");
let mut verifier_transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]);
let strategy = SingleVerifier::new(&verifier_params);

verify_proof(
&verifier_params,
pk.get_vk(),
strategy,
&[&[]],
&mut verifier_transcript,
)
.expect("failed to verify bench circuit");
end_timer!(start3);
}
}
12 changes: 12 additions & 0 deletions circuit-benchmarks/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,15 @@ pub mod tx_circuit;
#[cfg(test)]
#[cfg(feature = "benches")]
pub mod super_circuit;

#[cfg(test)]
#[cfg(feature = "benches")]
pub mod bit_keccak;

#[cfg(test)]
#[cfg(feature = "benches")]
pub mod packed_keccak;

#[cfg(test)]
#[cfg(feature = "benches")]
pub mod packed_multi_keccak;
82 changes: 82 additions & 0 deletions circuit-benchmarks/src/packed_keccak.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//! State circuit benchmarks

#[cfg(test)]
mod tests {
use ark_std::{end_timer, start_timer};
use halo2_proofs::plonk::{create_proof, keygen_pk, keygen_vk, verify_proof, SingleVerifier};
use halo2_proofs::{
pairing::bn256::{Bn256, G1Affine},
poly::commitment::{Params, ParamsVerifier},
transcript::{Blake2bRead, Blake2bWrite, Challenge255},
};
use rand::SeedableRng;
use rand_xorshift::XorShiftRng;
use std::env::var;
use zkevm_circuits::keccak_circuit::keccak_packed::KeccakPackedCircuit;

#[cfg_attr(not(feature = "benches"), ignore)]
#[test]
fn bench_packed_keccak_circuit_prover() {
let degree: u32 = var("DEGREE")
.expect("No DEGREE env var was provided")
.parse()
.expect("Cannot parse DEGREE env var as u32");

// Create the circuit
let mut circuit = KeccakPackedCircuit::new(2usize.pow(degree));

// Use the complete circuit
let inputs = vec![(0u8..135).collect::<Vec<_>>(); circuit.capacity()];
circuit.generate_witness(&inputs);

// Initialize the polynomial commitment parameters
let rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
0xbc, 0xe5,
]);

// Bench setup generation
let setup_message = format!("Setup generation with degree = {}", degree);
let start1 = start_timer!(|| setup_message);
let general_params: Params<G1Affine> = Params::<G1Affine>::unsafe_setup::<Bn256>(degree);
let verifier_params: ParamsVerifier<Bn256> =
general_params.verifier(degree as usize * 2).unwrap();
end_timer!(start1);

// Initialize the proving key
let vk = keygen_vk(&general_params, &circuit).expect("keygen_vk should not fail");
let pk = keygen_pk(&general_params, vk, &circuit).expect("keygen_pk should not fail");
// Create a proof
let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);

// Bench proof generation time
let proof_message = format!("Packed Keccak Proof generation with {} rows", degree);
let start2 = start_timer!(|| proof_message);
create_proof(
&general_params,
&pk,
&[circuit],
&[&[]],
rng,
&mut transcript,
)
.expect("proof generation should not fail");
let proof = transcript.finalize();
end_timer!(start2);

// Bench verification time
let start3 = start_timer!(|| "Keccak Proof verification");
let mut verifier_transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]);
let strategy = SingleVerifier::new(&verifier_params);

verify_proof(
&verifier_params,
pk.get_vk(),
strategy,
&[&[]],
&mut verifier_transcript,
)
.expect("failed to verify bench circuit");
end_timer!(start3);
}
}
82 changes: 82 additions & 0 deletions circuit-benchmarks/src/packed_multi_keccak.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//! State circuit benchmarks

#[cfg(test)]
mod tests {
use ark_std::{end_timer, start_timer};
use halo2_proofs::plonk::{create_proof, keygen_pk, keygen_vk, verify_proof, SingleVerifier};
use halo2_proofs::{
pairing::bn256::{Bn256, G1Affine},
poly::commitment::{Params, ParamsVerifier},
transcript::{Blake2bRead, Blake2bWrite, Challenge255},
};
use rand::SeedableRng;
use rand_xorshift::XorShiftRng;
use std::env::var;
use zkevm_circuits::keccak_circuit::keccak_packed_multi::KeccakPackedCircuit;

#[cfg_attr(not(feature = "benches"), ignore)]
#[test]
fn bench_packed_multi_keccak_circuit_prover() {
let degree: u32 = var("DEGREE")
.expect("No DEGREE env var was provided")
.parse()
.expect("Cannot parse DEGREE env var as u32");

// Create the circuit
let mut circuit = KeccakPackedCircuit::new(2usize.pow(degree));

// Use the complete circuit
let inputs = vec![(0u8..135).collect::<Vec<_>>(); circuit.capacity()];
circuit.generate_witness(&inputs);

// Initialize the polynomial commitment parameters
let rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
0xbc, 0xe5,
]);

// Bench setup generation
let setup_message = format!("Setup generation with degree = {}", degree);
let start1 = start_timer!(|| setup_message);
let general_params: Params<G1Affine> = Params::<G1Affine>::unsafe_setup::<Bn256>(degree);
let verifier_params: ParamsVerifier<Bn256> =
general_params.verifier(degree as usize * 2).unwrap();
end_timer!(start1);

// Initialize the proving key
let vk = keygen_vk(&general_params, &circuit).expect("keygen_vk should not fail");
let pk = keygen_pk(&general_params, vk, &circuit).expect("keygen_pk should not fail");
// Create a proof
let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);

// Bench proof generation time
let proof_message = format!("Packed Keccak Multi Proof generation with {} rows", degree);
let start2 = start_timer!(|| proof_message);
create_proof(
&general_params,
&pk,
&[circuit],
&[&[]],
rng,
&mut transcript,
)
.expect("proof generation should not fail");
let proof = transcript.finalize();
end_timer!(start2);

// Bench verification time
let start3 = start_timer!(|| "Keccak Proof verification");
let mut verifier_transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]);
let strategy = SingleVerifier::new(&verifier_params);

verify_proof(
&verifier_params,
pk.get_vk(),
strategy,
&[&[]],
&mut verifier_transcript,
)
.expect("failed to verify bench circuit");
end_timer!(start3);
}
}
17 changes: 17 additions & 0 deletions gadgets/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,23 @@ pub mod not {
}
}

/// Returns `a ^ b`.
/// `a` and `b` needs to be boolean
pub mod xor {
use crate::util::Expr;
use halo2_proofs::{arithmetic::FieldExt, plonk::Expression};

/// Returns an expression that represents the XOR of the given expression.
pub fn expr<F: FieldExt, E: Expr<F>>(a: E, b: E) -> Expression<F> {
a.expr() + b.expr() - 2.expr() * a.expr() * b.expr()
}

/// Returns a value that represents the XOR of the given value.
pub fn value<F: FieldExt>(a: F, b: F) -> F {
a + b - F::from(2u64) * a * b
}
}

/// Returns `when_true` when `selector == 1`, and returns `when_false` when
/// `selector == 0`. `selector` needs to be boolean.
pub mod select {
Expand Down
4 changes: 4 additions & 0 deletions zkevm-circuits/src/evm_circuit/util/constraint_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,10 @@ impl<F: Field> BaseConstraintBuilder<F> {
.clone()
.into_iter()
.map(|(name, constraint)| (name, selector.clone() * constraint))
.filter(|(name, constraint)| {
self.validate_degree(constraint.degree(), name);
true
})
.collect()
}
}
Expand Down
10 changes: 10 additions & 0 deletions zkevm-circuits/src/keccak_circuit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//! The keccak circuit implementation.

/// Keccak bit
pub mod keccak_bit;
/// Keccak packed
pub mod keccak_packed;
/// Keccak packed multi
pub mod keccak_packed_multi;
/// Util
pub mod util;
Loading