diff --git a/Cargo.toml b/Cargo.toml index 233bf95ad0..f29445e5e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "halo2_frontend", "halo2_middleware", "halo2_backend", - "p3_frontend", + "halo2_debug", + "p3_frontend" ] resolver = "2" diff --git a/halo2_backend/Cargo.toml b/halo2_backend/Cargo.toml index 7b24994c36..7f9982756f 100644 --- a/halo2_backend/Cargo.toml +++ b/halo2_backend/Cargo.toml @@ -46,6 +46,7 @@ gumdrop = "0.8" proptest = "1" rand_core = { version = "0.6", default-features = false, features = ["getrandom"] } serde_json = "1" +halo2_debug = { path = "../halo2_debug" } [target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dev-dependencies] getrandom = { version = "0.2", features = ["js"] } diff --git a/halo2_backend/src/arithmetic.rs b/halo2_backend/src/arithmetic.rs index ebdcae1e58..5e7a384503 100644 --- a/halo2_backend/src/arithmetic.rs +++ b/halo2_backend/src/arithmetic.rs @@ -254,15 +254,13 @@ pub(crate) fn powers(base: F) -> impl Iterator { std::iter::successors(Some(F::ONE), move |power| Some(base * power)) } -#[cfg(test)] -use rand_core::OsRng; - #[cfg(test)] use halo2curves::pasta::Fp; #[test] fn test_lagrange_interpolate() { - let rng = OsRng; + use halo2_debug::test_rng; + let rng = test_rng(); let points = (0..5).map(|_| Fp::random(rng)).collect::>(); let evals = (0..5).map(|_| Fp::random(rng)).collect::>(); diff --git a/halo2_backend/src/poly/commitment.rs b/halo2_backend/src/poly/commitment.rs index fb11099150..f85170c3ed 100644 --- a/halo2_backend/src/poly/commitment.rs +++ b/halo2_backend/src/poly/commitment.rs @@ -30,7 +30,7 @@ pub trait CommitmentScheme { type ParamsVerifier: for<'params> ParamsVerifier<'params, Self::Curve>; /// Wrapper for parameter generator - fn new_params(k: u32) -> Self::ParamsProver; + fn new_params(k: u32, rng: impl RngCore) -> Self::ParamsProver; /// Wrapper for parameter reader fn read_params(reader: &mut R) -> io::Result; @@ -69,7 +69,7 @@ pub trait Params: Sized + Clone + Debug { /// Parameters for circuit synthesis and prover parameters. pub trait ParamsProver: Params { /// Returns new instance of parameters - fn new(k: u32) -> Self; + fn new(k: u32, rng: impl RngCore) -> Self; /// This computes a commitment to a polynomial described by the provided /// slice of coefficients. The commitment may be blinded by the blinding diff --git a/halo2_backend/src/poly/domain.rs b/halo2_backend/src/poly/domain.rs index dabc797da4..1da8a03608 100644 --- a/halo2_backend/src/poly/domain.rs +++ b/halo2_backend/src/poly/domain.rs @@ -477,13 +477,12 @@ pub struct PinnedEvaluationDomain<'a, F: Field> { #[test] fn test_rotate() { - use rand_core::OsRng; - use crate::arithmetic::eval_polynomial; + use halo2_debug::test_rng; use halo2curves::pasta::pallas::Scalar; let domain = EvaluationDomain::::new(1, 3); - let rng = OsRng; + let rng = test_rng(); let mut poly = domain.empty_lagrange(); assert_eq!(poly.len(), 8); @@ -518,9 +517,8 @@ fn test_rotate() { #[test] fn test_l_i() { - use rand_core::OsRng; - use crate::arithmetic::{eval_polynomial, lagrange_interpolate}; + use halo2_debug::test_rng; use halo2curves::pasta::pallas::Scalar; let domain = EvaluationDomain::::new(1, 3); @@ -536,7 +534,7 @@ fn test_l_i() { l.push(l_i); } - let x = Scalar::random(OsRng); + let x = Scalar::random(test_rng()); let xn = x.pow([8]); let evaluations = domain.l_i_range(x, xn, -7..=7); diff --git a/halo2_backend/src/poly/ipa/commitment.rs b/halo2_backend/src/poly/ipa/commitment.rs index e1436e28c5..05940b106d 100644 --- a/halo2_backend/src/poly/ipa/commitment.rs +++ b/halo2_backend/src/poly/ipa/commitment.rs @@ -11,6 +11,7 @@ use crate::poly::{Coeff, LagrangeCoeff, Polynomial}; use group::{Curve, Group}; use halo2_middleware::zal::traits::MsmAccel; +use rand_core::RngCore; use std::marker::PhantomData; mod prover; @@ -45,8 +46,8 @@ impl CommitmentScheme for IPACommitmentScheme { type ParamsProver = ParamsIPA; type ParamsVerifier = ParamsVerifierIPA; - fn new_params(k: u32) -> Self::ParamsProver { - ParamsIPA::new(k) + fn new_params(k: u32, rng: impl RngCore) -> Self::ParamsProver { + ParamsIPA::new(k, rng) } fn read_params(reader: &mut R) -> io::Result { @@ -150,7 +151,7 @@ impl Params for ParamsIPA { impl ParamsProver for ParamsIPA { /// Initializes parameters for the curve, given a random oracle to draw /// points from. - fn new(k: u32) -> Self { + fn new(k: u32, _: impl RngCore) -> Self { // This is usually a limitation on the curve, but we also want 32-bit // architectures to be supported. assert!(k < 32); @@ -240,6 +241,7 @@ mod test { use crate::poly::ipa::msm::MSMIPA; use group::Curve; + use halo2_debug::test_rng; use halo2_middleware::ff::Field; use halo2_middleware::zal::impls::H2cEngine; @@ -247,13 +249,11 @@ mod test { fn test_commit_lagrange_epaffine() { const K: u32 = 6; - use rand_core::OsRng; - use crate::poly::EvaluationDomain; use halo2curves::pasta::{EpAffine, Fq}; let engine = H2cEngine::new(); - let params = ParamsIPA::::new(K); + let params = ParamsIPA::::new(K, test_rng()); let domain = EvaluationDomain::new(1, K); let mut a = domain.empty_lagrange(); @@ -264,7 +264,7 @@ mod test { let b = domain.lagrange_to_coeff(a.clone()); - let alpha = Blind(Fq::random(OsRng)); + let alpha = Blind(Fq::random(test_rng())); assert_eq!( params.commit(&engine, &b, alpha), @@ -276,13 +276,11 @@ mod test { fn test_commit_lagrange_eqaffine() { const K: u32 = 6; - use rand_core::OsRng; - use crate::poly::EvaluationDomain; use halo2curves::pasta::{EqAffine, Fp}; let engine = H2cEngine::new(); - let params: ParamsIPA = ParamsIPA::::new(K); + let params: ParamsIPA = ParamsIPA::::new(K, test_rng()); let domain = EvaluationDomain::new(1, K); let mut a = domain.empty_lagrange(); @@ -293,7 +291,7 @@ mod test { let b = domain.lagrange_to_coeff(a.clone()); - let alpha = Blind(Fp::random(OsRng)); + let alpha = Blind(Fp::random(test_rng())); assert_eq!( params.commit(&engine, &b, alpha), @@ -306,7 +304,6 @@ mod test { const K: u32 = 6; use halo2_middleware::ff::Field; - use rand_core::OsRng; use super::super::commitment::{Blind, Params}; use crate::arithmetic::eval_polynomial; @@ -319,10 +316,10 @@ mod test { use crate::transcript::TranscriptReadBuffer; use crate::transcript::TranscriptWriterBuffer; - let rng = OsRng; + let rng = test_rng(); let engine = H2cEngine::new(); - let params = ParamsIPA::::new(K); + let params = ParamsIPA::::new(K, test_rng()); let mut params_buffer = vec![]; as Params<_>>::write(¶ms, &mut params_buffer).unwrap(); let params: ParamsIPA = Params::read::<_>(&mut ¶ms_buffer[..]).unwrap(); diff --git a/halo2_backend/src/poly/ipa/msm.rs b/halo2_backend/src/poly/ipa/msm.rs index b2869e9dd0..17e97151cc 100644 --- a/halo2_backend/src/poly/ipa/msm.rs +++ b/halo2_backend/src/poly/ipa/msm.rs @@ -222,6 +222,7 @@ mod tests { commitment::{ParamsProver, MSM}, ipa::{commitment::ParamsIPA, msm::MSMIPA}, }; + use halo2_debug::test_rng; use halo2_middleware::zal::impls::H2cEngine; use halo2curves::{ pasta::{Ep, EpAffine, Fp, Fq}, @@ -234,7 +235,7 @@ mod tests { let base_viol = base + base; let engine = H2cEngine::new(); - let params = ParamsIPA::new(4); + let params = ParamsIPA::new(4, test_rng()); let mut a: MSMIPA = MSMIPA::new(¶ms); a.append_term(Fq::one(), base); // a = [1] P diff --git a/halo2_backend/src/poly/kzg/commitment.rs b/halo2_backend/src/poly/kzg/commitment.rs index 3bb0e5669f..324a38050a 100644 --- a/halo2_backend/src/poly/kzg/commitment.rs +++ b/halo2_backend/src/poly/kzg/commitment.rs @@ -8,7 +8,7 @@ use halo2_middleware::ff::{Field, PrimeField}; use halo2_middleware::zal::traits::MsmAccel; use halo2curves::pairing::Engine; use halo2curves::{CurveAffine, CurveExt}; -use rand_core::{OsRng, RngCore}; +use rand_core::RngCore; use std::fmt::Debug; use std::marker::PhantomData; @@ -139,8 +139,8 @@ where type ParamsProver = ParamsKZG; type ParamsVerifier = ParamsVerifierKZG; - fn new_params(k: u32) -> Self::ParamsProver { - ParamsKZG::new(k) + fn new_params(k: u32, rng: impl RngCore) -> Self::ParamsProver { + ParamsKZG::new(k, rng) } fn read_params(reader: &mut R) -> io::Result { @@ -429,8 +429,8 @@ where E::G1: CurveExt, E::G2Affine: SerdeCurveAffine, { - fn new(k: u32) -> Self { - Self::setup(k, OsRng) + fn new(k: u32, rng: impl RngCore) -> Self { + Self::setup(k, rng) } fn commit( @@ -453,6 +453,7 @@ mod test { use crate::poly::commitment::ParamsProver; use crate::poly::commitment::{Blind, Params}; use crate::poly::kzg::commitment::ParamsKZG; + use halo2_debug::test_rng; use halo2_middleware::ff::Field; use halo2_middleware::zal::impls::H2cEngine; @@ -460,13 +461,11 @@ mod test { fn test_commit_lagrange() { const K: u32 = 6; - use rand_core::OsRng; - use crate::poly::EvaluationDomain; use halo2curves::bn256::{Bn256, Fr}; let engine = H2cEngine::new(); - let params = ParamsKZG::::new(K); + let params = ParamsKZG::::new(K, test_rng()); let domain = EvaluationDomain::new(1, K); let mut a = domain.empty_lagrange(); @@ -477,7 +476,7 @@ mod test { let b = domain.lagrange_to_coeff(a.clone()); - let alpha = Blind(Fr::random(OsRng)); + let alpha = Blind(Fr::random(test_rng())); assert_eq!( params.commit(&engine, &b, alpha), @@ -492,7 +491,7 @@ mod test { use super::super::commitment::Params; use halo2curves::bn256::Bn256; - let params0 = ParamsKZG::::new(K); + let params0 = ParamsKZG::::new(K, test_rng()); let mut data = vec![]; as Params<_>>::write(¶ms0, &mut data).unwrap(); let params1: ParamsKZG = Params::read::<_>(&mut &data[..]).unwrap(); diff --git a/halo2_backend/src/poly/multiopen_test.rs b/halo2_backend/src/poly/multiopen_test.rs index e907d0134c..58eff2702e 100644 --- a/halo2_backend/src/poly/multiopen_test.rs +++ b/halo2_backend/src/poly/multiopen_test.rs @@ -15,9 +15,9 @@ mod test { TranscriptReadBuffer, TranscriptWriterBuffer, }; use group::Curve; + use halo2_debug::test_rng; use halo2_middleware::ff::WithSmallOrderMulGroup; use halo2_middleware::zal::{impls::H2cEngine, traits::MsmAccel}; - use rand_core::OsRng; #[test] fn test_roundtrip_ipa() { @@ -29,7 +29,7 @@ mod test { const K: u32 = 4; let engine = H2cEngine::new(); - let params = ParamsIPA::::new(K); + let params = ParamsIPA::::new(K, test_rng()); let proof = create_proof::< IPACommitmentScheme, @@ -67,7 +67,7 @@ mod test { const K: u32 = 4; let engine = H2cEngine::new(); - let params = ParamsIPA::::new(K); + let params = ParamsIPA::::new(K, test_rng()); let proof = create_proof::< IPACommitmentScheme, @@ -105,7 +105,7 @@ mod test { const K: u32 = 4; let engine = H2cEngine::new(); - let params = ParamsKZG::::new(K); + let params = ParamsKZG::::new(K, test_rng()); let proof = create_proof::<_, ProverGWC<_>, _, Blake2bWrite<_, _, Challenge255<_>>>( &engine, ¶ms, @@ -138,7 +138,7 @@ mod test { const K: u32 = 4; let engine = H2cEngine::new(); - let params = ParamsKZG::::new(K); + let params = ParamsKZG::::new(K, test_rng()); let proof = create_proof::< KZGCommitmentScheme, @@ -256,7 +256,7 @@ mod test { let mut transcript = T::init(vec![]); - let blind = Blind::new(&mut OsRng); + let blind = Blind::new(&mut test_rng()); let a = params.commit(engine, &ax, blind).to_affine(); let b = params.commit(engine, &bx, blind).to_affine(); let c = params.commit(engine, &cx, blind).to_affine(); @@ -297,7 +297,7 @@ mod test { let prover = P::new(params); prover - .create_proof(&mut OsRng, &mut transcript, queries) + .create_proof(&mut test_rng(), &mut transcript, queries) .unwrap(); transcript.finalize() diff --git a/halo2_debug/Cargo.toml b/halo2_debug/Cargo.toml new file mode 100644 index 0000000000..9e71ffdcc3 --- /dev/null +++ b/halo2_debug/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "halo2_debug" +version = "0.3.0" +authors = [ + "Privacy Scaling Explorations team", +] +edition = "2021" +rust-version = "1.66.0" +description = """ +Halo2 Debug. This package contains utilities for debugging and testing within +the halo2 ecosystem. +""" +license = "MIT OR Apache-2.0" +repository = "https://github.com/privacy-scaling-explorations/halo2" +documentation = "https://privacy-scaling-explorations.github.io/halo2/" +categories = ["cryptography"] +keywords = ["halo", "proofs", "zkp", "zkSNARKs"] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs", "--html-in-header", "katex-header.html"] + +[dependencies] +tiny-keccak = { version = "2.0.2", features=["keccak"] } +hex = "0.4.3" +rand_core = "0.6.4" diff --git a/halo2_debug/src/lib.rs b/halo2_debug/src/lib.rs new file mode 100644 index 0000000000..f8a6fc01ac --- /dev/null +++ b/halo2_debug/src/lib.rs @@ -0,0 +1,36 @@ +use rand_core::block::BlockRng; +use rand_core::block::BlockRngCore; +use rand_core::OsRng; +use tiny_keccak::Hasher; + +/// One number generator, that can be used as a deterministic Rng, outputing fixed values. +pub struct OneNg {} + +impl BlockRngCore for OneNg { + type Item = u32; + type Results = [u32; 16]; + + fn generate(&mut self, results: &mut Self::Results) { + for elem in results.iter_mut() { + *elem = 1; + } + } +} + +pub fn one_rng() -> BlockRng { + BlockRng::::new(OneNg {}) +} + +/// Random number generator for testing +pub fn test_rng() -> OsRng { + OsRng +} + +/// Gets the hex representation of the keccak hash of the input data +pub fn keccak_hex>(data: D) -> String { + let mut hash = [0u8; 32]; + let mut hasher = tiny_keccak::Keccak::v256(); + hasher.update(data.as_ref()); + hasher.finalize(&mut hash); + hex::encode(hash) +} diff --git a/halo2_frontend/Cargo.toml b/halo2_frontend/Cargo.toml index 3714c7dca7..b5fc50ad0e 100644 --- a/halo2_frontend/Cargo.toml +++ b/halo2_frontend/Cargo.toml @@ -60,7 +60,6 @@ bits = ["halo2curves/bits"] gadget-traces = ["backtrace"] thread-safe-region = [] circuit-params = [] -heap-profiling = [] cost-estimator = ["serde", "serde_derive"] derive_serde = ["halo2curves/derive_serde"] diff --git a/halo2_middleware/Cargo.toml b/halo2_middleware/Cargo.toml index 1c24c77c69..4dc95df702 100644 --- a/halo2_middleware/Cargo.toml +++ b/halo2_middleware/Cargo.toml @@ -35,7 +35,7 @@ rayon = "1.8" ark-std = { version = "0.3" } proptest = "1" group = "0.13" -rand_xorshift = "0.3.0" +rand_chacha = "0.3.0" rand_core = "0.6.4" [lib] diff --git a/halo2_middleware/src/zal.rs b/halo2_middleware/src/zal.rs index 5d376e3e5b..11bbb6aa51 100644 --- a/halo2_middleware/src/zal.rs +++ b/halo2_middleware/src/zal.rs @@ -257,11 +257,11 @@ mod test { use ark_std::{end_timer, start_timer}; use ff::Field; use group::{Curve, Group}; + use rand_chacha::ChaCha20Rng; use rand_core::SeedableRng; - use rand_xorshift::XorShiftRng; fn gen_points_scalars(k: usize) -> (Vec, Vec) { - let mut rng = XorShiftRng::seed_from_u64(3141592u64); + let mut rng = ChaCha20Rng::seed_from_u64(3141592u64); let points = (0..1 << k) .map(|_| C::Curve::random(&mut rng)) diff --git a/halo2_proofs/Cargo.toml b/halo2_proofs/Cargo.toml index a68f422934..e7b20e0120 100644 --- a/halo2_proofs/Cargo.toml +++ b/halo2_proofs/Cargo.toml @@ -44,6 +44,7 @@ harness = false halo2_middleware = { path = "../halo2_middleware" } halo2_backend = { path = "../halo2_backend" } halo2_frontend = { path = "../halo2_frontend" } +halo2_debug = { path = "../halo2_debug" } halo2curves = { version = "0.6.1", default-features = false } rand_core = { version = "0.6", default-features = false, features = ["getrandom"] } plotters = { version = "0.3.0", default-features = false, optional = true } @@ -59,7 +60,6 @@ assert_matches = "1.5" criterion = "0.3" gumdrop = "0.8" proptest = "1" -dhat = "0.3.2" serde_json = "1" [target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dev-dependencies] @@ -81,7 +81,6 @@ thread-safe-region = ["halo2_frontend/thread-safe-region"] sanity-checks = ["halo2_backend/sanity-checks"] batch = ["rand_core/getrandom", "halo2_backend/batch"] circuit-params = ["halo2_frontend/circuit-params"] -heap-profiling = ["halo2_frontend/heap-profiling"] cost-estimator = ["halo2_frontend/cost-estimator"] derive_serde = ["halo2curves/derive_serde", "halo2_frontend/derive_serde", "halo2_backend/derive_serde"] diff --git a/halo2_proofs/benches/plonk.rs b/halo2_proofs/benches/plonk.rs index ac531f1c53..919766b97d 100644 --- a/halo2_proofs/benches/plonk.rs +++ b/halo2_proofs/benches/plonk.rs @@ -2,12 +2,12 @@ extern crate criterion; use group::ff::Field; +use halo2_debug::test_rng; use halo2_proofs::circuit::{Cell, Layouter, SimpleFloorPlanner, Value}; use halo2_proofs::plonk::*; use halo2_proofs::poly::{commitment::ParamsProver, Rotation}; use halo2_proofs::transcript::{Blake2bRead, Blake2bWrite, Challenge255}; use halo2curves::pasta::{EqAffine, Fp}; -use rand_core::OsRng; use halo2_proofs::{ poly::{ @@ -268,7 +268,7 @@ fn criterion_benchmark(c: &mut Criterion) { } fn keygen(k: u32) -> (ParamsIPA, ProvingKey) { - let params: ParamsIPA = ParamsIPA::new(k); + let params: ParamsIPA = ParamsIPA::new(k, test_rng()); let empty_circuit: MyCircuit = MyCircuit { a: Value::unknown(), k, @@ -279,7 +279,7 @@ fn criterion_benchmark(c: &mut Criterion) { } fn prover(k: u32, params: &ParamsIPA, pk: &ProvingKey) -> Vec { - let rng = OsRng; + let rng = test_rng(); let circuit: MyCircuit = MyCircuit { a: Value::known(Fp::random(rng)), diff --git a/halo2_proofs/examples/circuit-layout.rs b/halo2_proofs/examples/circuit-layout.rs index 3127faa1a9..ad5629d80d 100644 --- a/halo2_proofs/examples/circuit-layout.rs +++ b/halo2_proofs/examples/circuit-layout.rs @@ -5,7 +5,6 @@ use halo2_proofs::{ poly::Rotation, }; use halo2curves::pasta::Fp; -use rand_core::OsRng; use std::marker::PhantomData; /// This represents an advice column at a certain row in the ConstraintSystem @@ -296,7 +295,7 @@ impl Circuit for MyCircuit { fn main() { // Prepare the circuit you want to render. // You don't need to include any witness variables. - let a = Fp::random(OsRng); + let a = Fp::random(halo2_debug::test_rng()); let instance = Fp::one() + Fp::one(); let lookup_table = vec![instance, a, a, Fp::zero()]; let circuit: MyCircuit = MyCircuit { diff --git a/halo2_proofs/examples/two-chip.rs b/halo2_proofs/examples/two-chip.rs index b0b614cb60..507bf920b1 100644 --- a/halo2_proofs/examples/two-chip.rs +++ b/halo2_proofs/examples/two-chip.rs @@ -1,5 +1,6 @@ use std::marker::PhantomData; +use halo2_debug::test_rng; use halo2_proofs::{ arithmetic::Field, circuit::{AssignedCell, Chip, Layouter, Region, SimpleFloorPlanner, Value}, @@ -500,7 +501,6 @@ impl Circuit for MyCircuit { fn main() { use halo2_proofs::dev::MockProver; use halo2curves::pasta::Fp; - use rand_core::OsRng; // ANCHOR: test-circuit // The number of rows in our circuit cannot exceed 2^k. Since our example @@ -508,7 +508,7 @@ fn main() { let k = 4; // Prepare the private and public inputs to the circuit! - let rng = OsRng; + let rng = test_rng(); let a = Fp::random(rng); let b = Fp::random(rng); let c = Fp::random(rng); diff --git a/halo2_proofs/src/plonk/prover.rs b/halo2_proofs/src/plonk/prover.rs index 133df4da40..4362226da6 100644 --- a/halo2_proofs/src/plonk/prover.rs +++ b/halo2_proofs/src/plonk/prover.rs @@ -108,9 +108,9 @@ fn test_create_proof() { }, transcript::{Blake2bWrite, Challenge255, TranscriptWriterBuffer}, }; + use halo2_debug::test_rng; use halo2_middleware::ff::Field; use halo2curves::bn256::Bn256; - use rand_core::OsRng; #[derive(Clone, Copy)] struct MyCircuit; @@ -136,7 +136,7 @@ fn test_create_proof() { } } - let params: ParamsKZG = ParamsKZG::setup(3, OsRng); + let params: ParamsKZG = ParamsKZG::setup(3, test_rng()); let vk = keygen_vk(¶ms, &MyCircuit).expect("keygen_vk should not fail"); let pk = keygen_pk(¶ms, vk, &MyCircuit).expect("keygen_pk should not fail"); let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); @@ -147,7 +147,7 @@ fn test_create_proof() { &pk, &[MyCircuit, MyCircuit], &[], - OsRng, + test_rng(), &mut transcript, ); assert!(matches!( @@ -161,7 +161,7 @@ fn test_create_proof() { &pk, &[MyCircuit, MyCircuit], &[&[], &[]], - OsRng, + test_rng(), &mut transcript, ) .expect("proof generation should not fail"); @@ -178,9 +178,9 @@ fn test_create_proof_custom() { }, transcript::{Blake2bWrite, Challenge255, TranscriptWriterBuffer}, }; + use halo2_debug::test_rng; use halo2_middleware::ff::Field; use halo2curves::bn256::Bn256; - use rand_core::OsRng; #[derive(Clone, Copy)] struct MyCircuit; @@ -206,7 +206,7 @@ fn test_create_proof_custom() { } } - let params: ParamsKZG = ParamsKZG::setup(3, OsRng); + let params: ParamsKZG = ParamsKZG::setup(3, test_rng()); let compress_selectors = true; let vk = keygen_vk_custom(¶ms, &MyCircuit, compress_selectors) .expect("keygen_vk_custom should not fail"); @@ -221,7 +221,7 @@ fn test_create_proof_custom() { &pk, &[MyCircuit, MyCircuit], &[&[], &[]], - OsRng, + test_rng(), &mut transcript, ) .expect("proof generation should not fail"); diff --git a/halo2_proofs/tests/compress_selectors.rs b/halo2_proofs/tests/compress_selectors.rs index ec87354fc2..6e62125059 100644 --- a/halo2_proofs/tests/compress_selectors.rs +++ b/halo2_proofs/tests/compress_selectors.rs @@ -10,6 +10,7 @@ use halo2_proofs::poly::Rotation; use halo2_backend::transcript::{ Blake2bRead, Blake2bWrite, Challenge255, TranscriptReadBuffer, TranscriptWriterBuffer, }; +use halo2_debug::{keccak_hex, one_rng}; use halo2_middleware::zal::impls::{H2cEngine, PlonkEngineConfig}; use halo2_proofs::arithmetic::Field; use halo2_proofs::plonk::{ @@ -20,22 +21,6 @@ use halo2_proofs::poly::kzg::commitment::{KZGCommitmentScheme, ParamsKZG}; use halo2_proofs::poly::kzg::multiopen::{ProverSHPLONK, VerifierSHPLONK}; use halo2_proofs::poly::kzg::strategy::SingleStrategy; use halo2curves::bn256::{Bn256, Fr, G1Affine}; -use rand_core::block::BlockRng; -use rand_core::block::BlockRngCore; - -// One number generator, that can be used as a deterministic Rng, outputing fixed values. -pub struct OneNg {} - -impl BlockRngCore for OneNg { - type Item = u32; - type Results = [u32; 16]; - - fn generate(&mut self, results: &mut Self::Results) { - for elem in results.iter_mut() { - *elem = 1; - } - } -} #[derive(Debug, Clone)] struct MyCircuitConfig { @@ -344,7 +329,7 @@ impl Circuit for MyCircuit { fn test_mycircuit( vk_keygen_compress_selectors: bool, pk_keygen_compress_selectors: bool, -) -> Result<(), halo2_proofs::plonk::Error> { +) -> Result, halo2_proofs::plonk::Error> { let engine = PlonkEngineConfig::new() .set_curve::() .set_msm(H2cEngine::new()) @@ -357,7 +342,7 @@ fn test_mycircuit( }; // Setup - let mut rng = BlockRng::new(OneNg {}); + let mut rng = one_rng(); let params = ParamsKZG::::setup(k, &mut rng); let verifier_params = params.verifier_params(); let vk = keygen_vk_custom(¶ms, &circuit, vk_keygen_compress_selectors)?; @@ -395,7 +380,9 @@ fn test_mycircuit( &[instances_slice], &mut verifier_transcript, ) - .map_err(halo2_proofs::plonk::Error::Backend) + .map_err(halo2_proofs::plonk::Error::Backend)?; + + Ok(proof) } /* @@ -436,12 +423,25 @@ How the `compress_selectors` works in `MyCircuit` under the hood: */ #[test] -fn test_success() { +#[allow(unused_variables)] +fn test_success() -> Result<(), halo2_proofs::plonk::Error> { // vk & pk keygen both WITH compress - assert!(test_mycircuit(true, true).is_ok()); + let proof = test_mycircuit(true, true)?; + #[cfg(not(coverage))] + assert_eq!( + "8083f3ecb002d25d66682a08581d9dfdf9c621e7d290db62238f8bc7b671eb1b", + keccak_hex(proof), + ); // vk & pk keygen both WITHOUT compress - assert!(test_mycircuit(false, false).is_ok()); + let proof = test_mycircuit(false, false)?; + #[cfg(not(coverage))] + assert_eq!( + "dbb85c029aa10ad0d5aa3f9711472f39dfe67cd82dc27a66ea403ad0ec499dc9", + keccak_hex(proof), + ); + + Ok(()) } #[should_panic] diff --git a/halo2_proofs/tests/frontend_backend_split.rs b/halo2_proofs/tests/frontend_backend_split.rs index 127d8552e0..88bf439250 100644 --- a/halo2_proofs/tests/frontend_backend_split.rs +++ b/halo2_proofs/tests/frontend_backend_split.rs @@ -1,10 +1,6 @@ #![allow(clippy::many_single_char_names)] #![allow(clippy::op_ref)] -#[cfg(feature = "heap-profiling")] -#[global_allocator] -static ALLOC: dhat::Alloc = dhat::Alloc; - use halo2_backend::{ plonk::{ keygen::{keygen_pk, keygen_vk}, @@ -15,6 +11,7 @@ use halo2_backend::{ Blake2bRead, Blake2bWrite, Challenge255, TranscriptReadBuffer, TranscriptWriterBuffer, }, }; +use halo2_debug::one_rng; use halo2_frontend::{ circuit::{ compile_circuit, AssignedCell, Layouter, Region, SimpleFloorPlanner, Value, @@ -470,22 +467,6 @@ use halo2_proofs::poly::kzg::commitment::{KZGCommitmentScheme, ParamsKZG}; use halo2_proofs::poly::kzg::multiopen::{ProverSHPLONK, VerifierSHPLONK}; use halo2_proofs::poly::kzg::strategy::SingleStrategy; use halo2curves::bn256::{Bn256, Fr, G1Affine}; -use rand_core::block::BlockRng; -use rand_core::block::BlockRngCore; - -// One number generator, that can be used as a deterministic Rng, outputing fixed values. -struct OneNg {} - -impl BlockRngCore for OneNg { - type Item = u32; - type Results = [u32; 16]; - - fn generate(&mut self, results: &mut Self::Results) { - for elem in results.iter_mut() { - *elem = 1; - } - } -} #[test] fn test_mycircuit_mock() { @@ -504,9 +485,6 @@ const WIDTH_FACTOR: usize = 1; #[test] fn test_mycircuit_full_legacy() { - #[cfg(all(feature = "heap-profiling", not(coverage)))] - let _profiler = dhat::Profiler::new_heap(); - use halo2_proofs::plonk::{ create_proof, keygen_pk as keygen_pk_legacy, keygen_vk as keygen_vk_legacy, }; @@ -515,7 +493,7 @@ fn test_mycircuit_full_legacy() { let circuit: MyCircuit = MyCircuit::new(k, 42); // Setup - let mut rng = BlockRng::new(OneNg {}); + let mut rng = one_rng(); let params = ParamsKZG::::setup(k, &mut rng); let start = Instant::now(); let vk = keygen_vk_legacy(¶ms, &circuit).expect("keygen_vk should not fail"); @@ -559,25 +537,29 @@ fn test_mycircuit_full_legacy() { ) .expect("verify succeeds"); println!("Verify: {:?}", start.elapsed()); + + // TODO: Check why the proof is different + #[cfg(all(feature = "thread-safe-region", not(coverage)))] + assert_eq!( + "c5c11281474b586795a5d97bdefeee80456d2921584b3a8b00523eebd49f2fac", + halo2_debug::keccak_hex(proof), + ); } #[test] fn test_mycircuit_full_split() { use halo2_middleware::zal::impls::{H2cEngine, PlonkEngineConfig}; - #[cfg(all(feature = "heap-profiling", not(coverage)))] - let _profiler = dhat::Profiler::new_heap(); - let engine = PlonkEngineConfig::new() .set_curve::() .set_msm(H2cEngine::new()) .build(); let k = K; let circuit: MyCircuit = MyCircuit::new(k, 42); - let (compiled_circuit, config, cs) = compile_circuit(k, &circuit, false).unwrap(); + let (compiled_circuit, config, cs) = compile_circuit(k, &circuit, true).unwrap(); // Setup - let mut rng = BlockRng::new(OneNg {}); + let mut rng = one_rng(); let params = ParamsKZG::::setup(k, &mut rng); let start = Instant::now(); let vk = keygen_vk(¶ms, &compiled_circuit).expect("keygen_vk should not fail"); @@ -639,4 +621,11 @@ fn test_mycircuit_full_split() { ) .expect("verify succeeds"); println!("Verify: {:?}", start.elapsed()); + + // TODO: Check why the proof is different + #[cfg(all(feature = "thread-safe-region", not(coverage)))] + assert_eq!( + "c5c11281474b586795a5d97bdefeee80456d2921584b3a8b00523eebd49f2fac", + halo2_debug::keccak_hex(proof), + ); } diff --git a/halo2_proofs/tests/plonk_api.rs b/halo2_proofs/tests/plonk_api.rs index e44484e514..6926175188 100644 --- a/halo2_proofs/tests/plonk_api.rs +++ b/halo2_proofs/tests/plonk_api.rs @@ -3,6 +3,8 @@ use assert_matches::assert_matches; use ff::{FromUniformBytes, WithSmallOrderMulGroup}; +use halo2_debug::test_rng; +use halo2_debug::{keccak_hex, one_rng}; use halo2_middleware::zal::{ impls::{PlonkEngine, PlonkEngineConfig}, traits::MsmAccel, @@ -22,7 +24,7 @@ use halo2_proofs::transcript::{ Blake2bRead, Blake2bWrite, Challenge255, EncodedChallenge, TranscriptReadBuffer, TranscriptWriterBuffer, }; -use rand_core::{OsRng, RngCore}; +use rand_core::RngCore; use std::marker::PhantomData; #[test] @@ -436,7 +438,7 @@ fn plonk_api() { // Check that we get an error if we try to initialize the proving key with a value of // k that is too small for the minimum required number of rows. - let much_too_small_params= <$scheme as CommitmentScheme>::ParamsProver::new(1); + let much_too_small_params= <$scheme as CommitmentScheme>::ParamsProver::new(1, test_rng()); assert_matches!( keygen_vk(&much_too_small_params, &empty_circuit), Err(Error::Frontend(ErrorFront::NotEnoughRowsAvailable { @@ -446,7 +448,7 @@ fn plonk_api() { // Check that we get an error if we try to initialize the proving key with a value of // k that is too small for the number of rows the circuit uses. - let slightly_too_small_params = <$scheme as CommitmentScheme>::ParamsProver::new(K-1); + let slightly_too_small_params = <$scheme as CommitmentScheme>::ParamsProver::new(K-1, test_rng()); assert_matches!( keygen_vk(&slightly_too_small_params, &empty_circuit), Err(Error::Frontend(ErrorFront::NotEnoughRowsAvailable { @@ -578,15 +580,16 @@ fn plonk_api() { use halo2curves::bn256::Bn256; type Scheme = KZGCommitmentScheme; + bad_keys!(Scheme); - let params = ParamsKZG::::new(K); - let rng = OsRng; + let mut rng = one_rng(); + let params = ParamsKZG::::new(K, &mut rng); let pk = keygen::>(¶ms); let proof = create_proof::<_, ProverGWC<_>, _, _, Blake2bWrite<_, _, Challenge255<_>>>( - rng, ¶ms, &pk, + &mut rng, ¶ms, &pk, ); let verifier_params = params.verifier_params(); @@ -598,6 +601,11 @@ fn plonk_api() { Blake2bRead<_, _, Challenge255<_>>, AccumulatorStrategy<_>, >(&verifier_params, pk.get_vk(), &proof[..]); + + assert_eq!( + "07382b50df5d591f5f54f99b09577f971986e4c343e8d050fb064432fda4be95", + keccak_hex(proof), + ); } fn test_plonk_api_shplonk() { @@ -609,8 +617,8 @@ fn plonk_api() { type Scheme = KZGCommitmentScheme; bad_keys!(Scheme); - let params = ParamsKZG::::new(K); - let rng = OsRng; + let mut rng = one_rng(); + let params = ParamsKZG::::new(K, &mut rng); let pk = keygen::>(¶ms); @@ -627,6 +635,11 @@ fn plonk_api() { Blake2bRead<_, _, Challenge255<_>>, AccumulatorStrategy<_>, >(&verifier_params, pk.get_vk(), &proof[..]); + + assert_eq!( + "32bb491e0f52a10f3361fc0aea6ea5aee3128f431e0fb846338e501c810dba49", + keccak_hex(proof), + ); } fn test_plonk_api_ipa() { @@ -638,13 +651,13 @@ fn plonk_api() { type Scheme = IPACommitmentScheme; bad_keys!(Scheme); - let params = ParamsIPA::::new(K); - let rng = OsRng; + let mut rng = one_rng(); + let params = ParamsIPA::::new(K, &mut rng); let pk = keygen::>(¶ms); let proof = create_proof::<_, ProverIPA<_>, _, _, Blake2bWrite<_, _, Challenge255<_>>>( - rng, ¶ms, &pk, + &mut rng, ¶ms, &pk, ); let verifier_params = params; diff --git a/halo2_proofs/tests/serialization.rs b/halo2_proofs/tests/serialization.rs index 93e98989e0..f8f123134b 100644 --- a/halo2_proofs/tests/serialization.rs +++ b/halo2_proofs/tests/serialization.rs @@ -4,6 +4,7 @@ use std::{ }; use ff::Field; +use halo2_debug::{keccak_hex, one_rng}; use halo2_proofs::{ circuit::{Layouter, SimpleFloorPlanner, Value}, plonk::{ @@ -24,7 +25,6 @@ use halo2_proofs::{ SerdeFormat, }; use halo2curves::bn256::{Bn256, Fr, G1Affine}; -use rand_core::OsRng; #[derive(Clone, Copy)] struct StandardPlonkConfig { @@ -131,8 +131,11 @@ impl Circuit for StandardPlonk { #[test] fn test_serialization() { let k = 4; - let circuit = StandardPlonk(Fr::random(OsRng)); - let params = ParamsKZG::::setup(k, OsRng); + + let mut rng = one_rng(); + + let circuit = StandardPlonk(Fr::random(&mut rng)); + let params = ParamsKZG::::setup(k, &mut rng); let compress_selectors = true; let vk = keygen_vk_custom(¶ms, &circuit, compress_selectors).expect("vk should not fail"); let pk = keygen_pk(¶ms, vk, &circuit).expect("pk should not fail"); @@ -165,14 +168,7 @@ fn test_serialization() { _, Blake2bWrite, G1Affine, Challenge255<_>>, _, - >( - ¶ms, - &pk, - &[circuit], - &[instances], - OsRng, - &mut transcript, - ) + >(¶ms, &pk, &[circuit], &[instances], rng, &mut transcript) .expect("prover should not fail"); let proof = transcript.finalize(); @@ -193,4 +189,9 @@ fn test_serialization() { &mut transcript ) .is_ok()); + + assert_eq!( + "09e497a9a52d56f23d3f2cf832b5849a1ebbaab2086dec90144b3eb1a38b5331", + keccak_hex(proof), + ) } diff --git a/halo2_proofs/tests/shuffle.rs b/halo2_proofs/tests/shuffle.rs index 7ecfb49edc..78bd83273b 100644 --- a/halo2_proofs/tests/shuffle.rs +++ b/halo2_proofs/tests/shuffle.rs @@ -1,4 +1,5 @@ use ff::{BatchInvert, FromUniformBytes}; +use halo2_debug::{keccak_hex, one_rng}; use halo2_proofs::{ arithmetic::{CurveAffine, Field}, circuit::{floor_planner::V1, Layouter, Value}, @@ -18,7 +19,8 @@ use halo2_proofs::{ Blake2bRead, Blake2bWrite, Challenge255, TranscriptReadBuffer, TranscriptWriterBuffer, }, }; -use rand_core::{OsRng, RngCore}; +use rand_chacha::ChaCha20Rng; +use rand_core::{RngCore, SeedableRng}; use std::iter; fn rand_2d_array(rng: &mut R) -> [[F; H]; W] { @@ -273,10 +275,13 @@ fn test_prover( k: u32, circuit: MyCircuit, expected: bool, -) where +) -> Vec +where C::Scalar: FromUniformBytes<64>, { - let params = ParamsIPA::::new(k); + let mut rng = one_rng(); + + let params = ParamsIPA::::new(k, &mut rng); let vk = keygen_vk(¶ms, &circuit).unwrap(); let pk = keygen_pk(¶ms, vk, &circuit).unwrap(); @@ -288,7 +293,7 @@ fn test_prover( &pk, &[circuit], &[&[]], - OsRng, + rng, &mut transcript, ) .expect("proof generation should not fail"); @@ -312,6 +317,8 @@ fn test_prover( }; assert_eq!(accepted, expected); + + proof } #[test] @@ -320,11 +327,16 @@ fn test_shuffle() { const H: usize = 32; const K: u32 = 8; - let circuit = &MyCircuit::<_, W, H>::rand(&mut OsRng); + let mut shuffle_rng = ChaCha20Rng::seed_from_u64(0xdeadbeef); + let circuit = &MyCircuit::<_, W, H>::rand(&mut shuffle_rng); { test_mock_prover(K, circuit.clone(), Ok(())); - test_prover::(K, circuit.clone(), true); + let proof = test_prover::(K, circuit.clone(), true); + assert_eq!( + "dba3dbe7a83a719ec028317511e260b8c8e6207dc62b2d1ecd8ba0fa6ddc39ed", + keccak_hex(proof), + ); } #[cfg(not(feature = "sanity-checks"))] @@ -348,6 +360,10 @@ fn test_shuffle() { }, )]), ); - test_prover::(K, circuit, false); + let proof = test_prover::(K, circuit, false); + assert_eq!( + "0b4e97f2d561fae56fe893333eba2df5228c78e80f8bd7c509d4d40d127dff92", + keccak_hex(proof), + ); } } diff --git a/halo2_proofs/tests/shuffle_api.rs b/halo2_proofs/tests/shuffle_api.rs index e7034e6f36..2ff64e69bb 100644 --- a/halo2_proofs/tests/shuffle_api.rs +++ b/halo2_proofs/tests/shuffle_api.rs @@ -1,6 +1,7 @@ use std::{marker::PhantomData, vec}; use ff::FromUniformBytes; +use halo2_debug::{keccak_hex, one_rng}; use halo2_proofs::{ arithmetic::Field, circuit::{Layouter, SimpleFloorPlanner, Value}, @@ -23,7 +24,6 @@ use halo2_proofs::{ }, }; use halo2curves::{pasta::EqAffine, CurveAffine}; -use rand_core::OsRng; struct ShuffleChip { config: ShuffleConfig, @@ -148,11 +148,13 @@ impl Circuit for MyCircuit { } } -fn test_prover(k: u32, circuit: MyCircuit, expected: bool) +fn test_prover(k: u32, circuit: MyCircuit, expected: bool) -> Vec where C::Scalar: FromUniformBytes<64>, { - let params = ParamsIPA::::new(k); + let mut rng = one_rng(); + + let params = ParamsIPA::::new(k, &mut rng); let vk = keygen_vk(¶ms, &circuit).unwrap(); let pk = keygen_pk(¶ms, vk, &circuit).unwrap(); @@ -164,7 +166,7 @@ where &pk, &[circuit], &[&[]], - OsRng, + rng, &mut transcript, ) .expect("proof generation should not fail"); @@ -188,6 +190,8 @@ where }; assert_eq!(accepted, expected); + + proof } #[test] @@ -213,5 +217,10 @@ fn test_shuffle_api() { }; let prover = MockProver::run(K, &circuit, vec![]).unwrap(); prover.assert_satisfied(); - test_prover::(K, circuit, true); + let proof = test_prover::(K, circuit, true); + + assert_eq!( + "10866a2a15d9cf36b36045277cae71057702f61a41ef56b04f813c30a5f8daa0", + keccak_hex(proof), + ); } diff --git a/halo2_proofs/tests/vector-ops-unblinded.rs b/halo2_proofs/tests/vector-ops-unblinded.rs index 01c24fef4d..b90fa98360 100644 --- a/halo2_proofs/tests/vector-ops-unblinded.rs +++ b/halo2_proofs/tests/vector-ops-unblinded.rs @@ -4,6 +4,7 @@ use std::marker::PhantomData; use ff::FromUniformBytes; +use halo2_debug::{keccak_hex, one_rng}; use halo2_proofs::{ arithmetic::{CurveAffine, Field}, circuit::{AssignedCell, Chip, Layouter, Region, SimpleFloorPlanner, Value}, @@ -21,7 +22,6 @@ use halo2_proofs::{ Blake2bRead, Blake2bWrite, Challenge255, TranscriptReadBuffer, TranscriptWriterBuffer, }, }; -use rand_core::OsRng; // ANCHOR: instructions trait NumericInstructions: Chip { @@ -475,7 +475,9 @@ fn test_prover( where C::Scalar: FromUniformBytes<64>, { - let params = ParamsIPA::::new(k); + let mut rng = one_rng(); + + let params = ParamsIPA::::new(k, &mut rng); let vk = keygen_vk(¶ms, &circuit).unwrap(); let pk = keygen_pk(¶ms, vk, &circuit).unwrap(); @@ -487,7 +489,7 @@ where &pk, &[circuit], &[&[&instances]], - OsRng, + rng, &mut transcript, ) .expect("proof generation should not fail"); @@ -545,8 +547,17 @@ fn test_vector_ops_unbinded() { // the commitments will be the first columns of the proof transcript so we can compare them easily let proof_1 = test_prover::(k, mul_circuit, true, c_mul); + assert_eq!( + "845349549e3776ba45e5bc03d44fd44f8e65f6338e8b7b8975dcc4f310094bf3", + keccak_hex(&proof_1), + ); + // the commitments will be the first columns of the proof transcript so we can compare them easily let proof_2 = test_prover::(k, add_circuit, true, c_add); + assert_eq!( + "55f4b12e359be5541f539f74ae2b4afd2206160609faa1b902d90e91bfd4a641", + keccak_hex(&proof_2), + ); // the commitments will be the first columns of the proof transcript so we can compare them easily // here we compare the first 10 bytes of the commitments