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

Deterministic tests #349

Merged
merged 9 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
3 changes: 3 additions & 0 deletions halo2_debug/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ ff = "0.13"
halo2curves = { version = "0.6.1", default-features = false }
num-bigint = "0.4.5"
halo2_middleware = { path = "../halo2_middleware" }
tiny-keccak = { version = "2.0.2", features=["keccak"] }
hex = "0.4.3"
rand_core = "0.6.4"
30 changes: 30 additions & 0 deletions halo2_debug/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,31 @@
use rand_core::block::BlockRng;
use rand_core::block::BlockRngCore;
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<OneNg> {
BlockRng::<OneNg>::new(OneNg {})
}

ed255 marked this conversation as resolved.
Show resolved Hide resolved
/// Gets the hex representation of the keccak hash of the input data
pub fn keccak_hex<D: AsRef<[u8]>>(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)
}
pub mod display;
1 change: 0 additions & 1 deletion halo2_frontend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]

Expand Down
2 changes: 1 addition & 1 deletion halo2_proofs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ 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"]
vector-tests = []
Copy link
Member

Choose a reason for hiding this comment

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

We need to make sure this feature is enabled on test in the CI (this way we can detect the PRs that change the proof output). Is this the case?
If not, maybe we can add vector-tests as a default feature?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think that this can be removed at all now, just keeping not(coverage) , let's me check again.

Copy link
Member Author

Choose a reason for hiding this comment

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

@ed255 the main point here is that results can differ when turning some features (like circuit-params), so we want a feature that is only activated when we test it with --all-features. I keep it as is.

Copy link
Member

Choose a reason for hiding this comment

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

I see, but then we're not testing this in the CI. We're only testing these sets of features:

  • batch,dev-graph,gadget-traces
  • batch,dev-graph,gadget-traces,test-dev-graph,thread-safe-region,sanity-checks,circuit-params

I think we should have a job in the CI that runs the tests with vector-tests enabled.

Copy link
Member Author

Choose a reason for hiding this comment

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

Another option is to change the "all features" in CI to --all-features instead "--features batch,dev-graph,gadget-traces,test-dev-graph,thread-safe-region,sanity-checks,circuit-params". Not sure, testing with --all-features is more straighforward that specifying them manually if there's no conflicting options.


[lib]
bench = false
Expand Down
1 change: 0 additions & 1 deletion halo2_proofs/src/plonk/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ where
}
Ok(prover.create_proof()?)
}

/// This creates a proof for the provided `circuit` when given the public
/// parameters `params` and the proving key [`ProvingKey`] that was
/// generated previously for the same circuit. The provided `instances`
Expand Down
44 changes: 22 additions & 22 deletions halo2_proofs/tests/compress_selectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::marker::PhantomData;

use ff::PrimeField;
use halo2_debug::display::expr_disp_names;
use halo2_debug::one_rng;
use halo2_frontend::circuit::compile_circuit;
use halo2_frontend::plonk::Error;
use halo2_proofs::circuit::{Cell, Layouter, SimpleFloorPlanner, Value};
Expand All @@ -23,22 +24,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 {
Expand Down Expand Up @@ -351,7 +336,7 @@ impl<F: Field> Circuit<F> for MyCircuit<F> {
fn test_mycircuit(
vk_keygen_compress_selectors: bool,
pk_keygen_compress_selectors: bool,
) -> Result<(), halo2_proofs::plonk::Error> {
) -> Result<Vec<u8>, halo2_proofs::plonk::Error> {
let engine = PlonkEngineConfig::new()
.set_curve::<G1Affine>()
.set_msm(H2cEngine::new())
Expand All @@ -363,8 +348,9 @@ fn test_mycircuit(
constant: Fr::one(),
};

let mut rng = one_rng();

// Setup
let mut rng = BlockRng::new(OneNg {});
let params = ParamsKZG::<Bn256>::setup(k, &mut rng);
let verifier_params = params.verifier_params();
let vk = keygen_vk_custom(&params, &circuit, vk_keygen_compress_selectors)?;
Expand Down Expand Up @@ -398,7 +384,9 @@ fn test_mycircuit(
instances.as_slice(),
&mut verifier_transcript,
)
.map_err(halo2_proofs::plonk::Error::Backend)
.map_err(halo2_proofs::plonk::Error::Backend)?;

Ok(proof)
}

/*
Expand Down Expand Up @@ -496,12 +484,24 @@ fn test_compress_gates() {
}

#[test]
fn test_success() {
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(all(feature = "vector-tests", not(coverage)))]
assert_eq!(
"d0f9083017f4ef79cb2b2c4efef297572177ea59a0290eecc5ada2a594d2e32a",
halo2_debug::keccak_hex(_proof),
adria0 marked this conversation as resolved.
Show resolved Hide resolved
);

// vk & pk keygen both WITHOUT compress
assert!(test_mycircuit(false, false).is_ok());
let _proof = test_mycircuit(false, false)?;
#[cfg(all(feature = "vector-tests", not(coverage)))]
assert_eq!(
"705caf13656b7ee48c69fb8f64499d341514f302c3c781c5b6f1391d7790a5d6",
halo2_debug::keccak_hex(_proof),
);

Ok(())
}

#[should_panic]
Expand Down
45 changes: 16 additions & 29 deletions halo2_proofs/tests/frontend_backend_split.rs
Original file line number Diff line number Diff line change
@@ -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},
Expand All @@ -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,
Expand Down Expand Up @@ -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() {
Expand All @@ -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,
};
Expand All @@ -515,7 +493,7 @@ fn test_mycircuit_full_legacy() {
let circuit: MyCircuit<Fr, WIDTH_FACTOR> = MyCircuit::new(k, 42);

// Setup
let mut rng = BlockRng::new(OneNg {});
let mut rng = one_rng();
let params = ParamsKZG::<Bn256>::setup(k, &mut rng);
let start = Instant::now();
let vk = keygen_vk_legacy(&params, &circuit).expect("keygen_vk should not fail");
Expand Down Expand Up @@ -555,25 +533,28 @@ fn test_mycircuit_full_legacy() {
)
.expect("verify succeeds");
println!("Verify: {:?}", start.elapsed());

#[cfg(all(feature = "vector-tests", 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::<G1Affine>()
.set_msm(H2cEngine::new())
.build();
let k = K;
let circuit: MyCircuit<Fr, WIDTH_FACTOR> = 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::<Bn256>::setup(k, &mut rng);
let start = Instant::now();
let vk = keygen_vk(&params, &compiled_circuit).expect("keygen_vk should not fail");
Expand Down Expand Up @@ -630,4 +611,10 @@ instances.clone(),
)
.expect("verify succeeds");
println!("Verify: {:?}", start.elapsed());

#[cfg(all(feature = "vector-tests", not(coverage)))]
assert_eq!(
"c5c11281474b586795a5d97bdefeee80456d2921584b3a8b00523eebd49f2fac",
halo2_debug::keccak_hex(proof),
);
}
30 changes: 22 additions & 8 deletions halo2_proofs/tests/plonk_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use assert_matches::assert_matches;
use ff::{FromUniformBytes, WithSmallOrderMulGroup};
use halo2_debug::one_rng;
use halo2_middleware::zal::{
impls::{PlonkEngine, PlonkEngineConfig},
traits::MsmAccel,
Expand All @@ -22,7 +23,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]
Expand Down Expand Up @@ -573,15 +574,16 @@ fn plonk_api() {
use halo2curves::bn256::Bn256;

type Scheme = KZGCommitmentScheme<Bn256>;

bad_keys!(Scheme);

let params = ParamsKZG::<Bn256>::new(K);
let rng = OsRng;
let mut rng = one_rng();

let params = ParamsKZG::<Bn256>::setup(K, &mut rng);
let pk = keygen::<KZGCommitmentScheme<_>>(&params);

let proof = create_proof::<_, ProverGWC<_>, _, _, Blake2bWrite<_, _, Challenge255<_>>>(
rng, &params, &pk,
&mut rng, &params, &pk,
);

let verifier_params = params.verifier_params();
Expand All @@ -593,6 +595,12 @@ fn plonk_api() {
Blake2bRead<_, _, Challenge255<_>>,
AccumulatorStrategy<_>,
>(&verifier_params, pk.get_vk(), &proof[..]);

#[cfg(all(feature = "vector-tests", not(coverage)))]
assert_eq!(
"50969312b469ebbc528e6c765e8483b53c92292028a85afda22fa83a7b76c667",
halo2_debug::keccak_hex(proof),
);
}

fn test_plonk_api_shplonk() {
Expand All @@ -604,8 +612,8 @@ fn plonk_api() {
type Scheme = KZGCommitmentScheme<Bn256>;
bad_keys!(Scheme);

let params = ParamsKZG::<Bn256>::new(K);
let rng = OsRng;
let mut rng = one_rng();
let params = ParamsKZG::<Bn256>::setup(K, &mut rng);

let pk = keygen::<KZGCommitmentScheme<_>>(&params);

Expand All @@ -622,6 +630,12 @@ fn plonk_api() {
Blake2bRead<_, _, Challenge255<_>>,
AccumulatorStrategy<_>,
>(&verifier_params, pk.get_vk(), &proof[..]);

#[cfg(all(feature = "vector-tests", not(coverage)))]
assert_eq!(
"ade2d9dae7d02871c63d0a80bc0e09d536138e49b4925c62046e2e86cb288bc3",
halo2_debug::keccak_hex(proof),
);
}

fn test_plonk_api_ipa() {
Expand All @@ -633,13 +647,13 @@ fn plonk_api() {
type Scheme = IPACommitmentScheme<EqAffine>;
bad_keys!(Scheme);

let mut rng = one_rng();
let params = ParamsIPA::<EqAffine>::new(K);
let rng = OsRng;

let pk = keygen::<IPACommitmentScheme<EqAffine>>(&params);

let proof = create_proof::<_, ProverIPA<_>, _, _, Blake2bWrite<_, _, Challenge255<_>>>(
rng, &params, &pk,
&mut rng, &params, &pk,
);

let verifier_params = params;
Expand Down
Loading
Loading