From f067c094d55eb6c40717deec6bb552f49c4536b0 Mon Sep 17 00:00:00 2001 From: Armando Faz Date: Wed, 19 Nov 2025 17:32:51 -0800 Subject: [PATCH 1/5] Refactoring test directory. Ensures all tests run with the cargo test command, also in CI. --- .github/workflows/rust.yml | 6 +- src/codec.rs | 2 +- src/lib.rs | 8 +- src/tests/mod.rs | 5 - src/tests/spec/mod.rs | 7 -- .../relations/mod.rs | 118 ++---------------- {src/tests => tests}/spec/bls12_381.rs | 2 +- .../spec/custom_schnorr_protocol.rs | 8 +- tests/spec/mod.rs | 4 + {src/tests => tests}/spec/random.rs | 0 {src/tests => tests}/spec/rng.rs | 0 .../spec/vectors/duplexSpongeVectors.json | 0 .../spec/vectors/testSigmaProtocols.json | 0 .../spec_duplex_sponge.rs | 6 +- .../test_vectors.rs => tests/spec_vectors.rs | 16 +-- {src/tests => tests}/test_composition.rs | 8 +- tests/test_relations.rs | 110 ++++++++++++++++ .../test_validation_criteria.rs | 10 +- 18 files changed, 154 insertions(+), 156 deletions(-) delete mode 100644 src/tests/mod.rs delete mode 100644 src/tests/spec/mod.rs rename src/tests/test_relations.rs => tests/relations/mod.rs (79%) rename {src/tests => tests}/spec/bls12_381.rs (97%) rename {src/tests => tests}/spec/custom_schnorr_protocol.rs (94%) create mode 100644 tests/spec/mod.rs rename {src/tests => tests}/spec/random.rs (100%) rename {src/tests => tests}/spec/rng.rs (100%) rename {src/tests => tests}/spec/vectors/duplexSpongeVectors.json (100%) rename {src/tests => tests}/spec/vectors/testSigmaProtocols.json (100%) rename src/tests/spec/test_duplex_sponge.rs => tests/spec_duplex_sponge.rs (93%) rename src/tests/spec/test_vectors.rs => tests/spec_vectors.rs (91%) rename {src/tests => tests}/test_composition.rs (96%) create mode 100644 tests/test_relations.rs rename {src/tests => tests}/test_validation_criteria.rs (98%) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 431ead3..e42585f 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -24,14 +24,14 @@ jobs: - name: Build run: cargo build --verbose - name: Run tests - run: cargo test --verbose + run: cargo test --verbose --no-fail-fast - name: Run benchmark test # Run the msm benchmark, just to ensure it isn't broken. run: cargo bench --bench msm -- --quick no-std-check: runs-on: ubuntu-latest - + steps: - uses: actions/checkout@v3 - name: Install Rust toolchain @@ -76,4 +76,4 @@ jobs: - name: Build no_std (nightly) run: cargo +${{ matrix.toolchain }} build --no-default-features --verbose - name: Run tests (nightly) - run: cargo +${{ matrix.toolchain }} test --all-features --verbose + run: cargo +${{ matrix.toolchain }} test --all-features --verbose --no-fail-fast diff --git a/src/codec.rs b/src/codec.rs index 40a14e7..cd652c6 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -1,7 +1,7 @@ //! Encoding and decoding utilities for Fiat-Shamir and group operations. use crate::duplex_sponge::DuplexSpongeInterface; -pub use crate::duplex_sponge::{keccak::KeccakDuplexSponge, shake::ShakeDuplexSponge}; +use crate::duplex_sponge::{keccak::KeccakDuplexSponge, shake::ShakeDuplexSponge}; use alloc::vec; use ff::PrimeField; use group::prime::PrimeGroup; diff --git a/src/lib.rs b/src/lib.rs index 993d549..f66f988 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -72,17 +72,17 @@ extern crate alloc; pub mod codec; pub mod composition; pub mod errors; +pub mod group; pub mod linear_relation; pub mod traits; pub(crate) mod duplex_sponge; pub(crate) mod fiat_shamir; -pub(crate) mod group; pub(crate) mod schnorr_protocol; -#[cfg(test)] -pub mod tests; - +pub use duplex_sponge::{ + keccak::KeccakDuplexSponge, shake::ShakeDuplexSponge, DuplexSpongeInterface, +}; pub use fiat_shamir::Nizk; pub use group::msm::VariableMultiScalarMul; pub use linear_relation::LinearRelation; diff --git a/src/tests/mod.rs b/src/tests/mod.rs deleted file mode 100644 index abe503d..0000000 --- a/src/tests/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod spec; - -mod test_composition; -mod test_relations; -mod test_validation_criteria; diff --git a/src/tests/spec/mod.rs b/src/tests/spec/mod.rs deleted file mode 100644 index 6489fee..0000000 --- a/src/tests/spec/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -mod bls12_381; -mod custom_schnorr_protocol; -mod random; -pub mod rng; - -mod test_duplex_sponge; -mod test_vectors; diff --git a/src/tests/test_relations.rs b/tests/relations/mod.rs similarity index 79% rename from src/tests/test_relations.rs rename to tests/relations/mod.rs index 83dca64..2faa1cf 100644 --- a/src/tests/test_relations.rs +++ b/tests/relations/mod.rs @@ -2,9 +2,7 @@ use ff::Field; use group::prime::PrimeGroup; use rand::RngCore; -use crate::codec::Shake128DuplexSponge; -use crate::fiat_shamir::Nizk; -use crate::linear_relation::{CanonicalLinearRelation, LinearRelation, Sum}; +use sigma_proofs::linear_relation::{CanonicalLinearRelation, LinearRelation, Sum}; /// LinearMap for knowledge of a discrete logarithm relative to a fixed basepoint. #[allow(non_snake_case)] @@ -351,7 +349,7 @@ pub fn weird_linear_combination( (instance, witness) } -fn simple_subtractions( +pub fn simple_subtractions( mut rng: &mut R, ) -> (CanonicalLinearRelation, Vec) { let x = G::Scalar::random(&mut rng); @@ -370,7 +368,7 @@ fn simple_subtractions( (instance, witness) } -fn subtractions_with_shift( +pub fn subtractions_with_shift( rng: &mut R, ) -> (CanonicalLinearRelation, Vec) { let B = G::generator(); @@ -390,7 +388,7 @@ fn subtractions_with_shift( } #[allow(non_snake_case)] -fn cmz_wallet_spend_relation( +pub fn cmz_wallet_spend_relation( mut rng: &mut R, ) -> (CanonicalLinearRelation, Vec) { // Simulate the wallet spend relation from cmz @@ -435,7 +433,7 @@ fn cmz_wallet_spend_relation( (instance, witness) } -fn nested_affine_relation( +pub fn nested_affine_relation( mut rng: &mut R, ) -> (CanonicalLinearRelation, Vec) { let mut instance = LinearRelation::::new(); @@ -459,7 +457,7 @@ fn nested_affine_relation( (instance, witness) } -fn pedersen_commitment_equality( +pub fn pedersen_commitment_equality( rng: &mut R, ) -> (CanonicalLinearRelation, Vec) { let mut instance = LinearRelation::new(); @@ -482,7 +480,7 @@ fn pedersen_commitment_equality( (instance.canonical().unwrap(), witness) } -fn elgamal_subtraction( +pub fn elgamal_subtraction( rng: &mut R, ) -> (CanonicalLinearRelation, Vec) { let mut instance = LinearRelation::new(); @@ -509,105 +507,3 @@ fn elgamal_subtraction( (instance.canonical().unwrap(), witness) } - -#[test] -fn test_cmz_wallet_with_fee() { - use group::Group; - type G = bls12_381::G1Projective; - - let mut rng = rand::thread_rng(); - - // This version should fail with InvalidInstanceWitnessPair - // because it uses a scalar constant directly in the equation - let P_W = G::random(&mut rng); - let A = G::random(&mut rng); - - let n_balance = ::Scalar::random(&mut rng); - let i_price = ::Scalar::random(&mut rng); - let _fee = ::Scalar::from(5u64); - let z_w_balance = ::Scalar::random(&mut rng); - - let mut relation = LinearRelation::::new(); - - let var_n_balance = relation.allocate_scalar(); - let var_i_price = relation.allocate_scalar(); - let var_z_w_balance = relation.allocate_scalar(); - - let var_P_W = relation.allocate_element(); - let var_A = relation.allocate_element(); - - // This equation has a scalar constant (fee) which causes the error - let _var_C = relation.allocate_eq( - (var_n_balance + var_i_price + ::Scalar::from(5)) * var_P_W - + var_z_w_balance * var_A, - ); - - relation.set_elements([(var_P_W, P_W), (var_A, A)]); - relation - .compute_image(&[n_balance, i_price, z_w_balance]) - .unwrap(); - - // Try to convert to CanonicalLinearRelation - this should fail - let nizk = relation.into_nizk(b"session_identifier").unwrap(); - let result = nizk.prove_batchable(&vec![n_balance, i_price, z_w_balance], &mut rng); - assert!(result.is_ok()); - let proof = result.unwrap(); - let verify_result = nizk.verify_batchable(&proof); - assert!(verify_result.is_ok()); -} - -/// Generic helper function to test both relation correctness and NIZK functionality -#[test] -fn test_relations() { - type G = bls12_381::G1Projective; - - let instance_generators: Vec<(_, &'static dyn Fn(&mut _) -> _)> = vec![ - ("dlog", &discrete_logarithm), - ("shifted_dlog", &shifted_dlog), - ("dleq", &dleq), - ("shifted_dleq", &shifted_dleq), - ("pedersen_commitment", &pedersen_commitment), - ("twisted_pedersen_commitment", &twisted_pedersen_commitment), - ("pedersen_commitment_dleq", &pedersen_commitment_equality), - ("bbs_blind_commitment", &bbs_blind_commitment), - ("test_range", &test_range), - ("weird_linear_combination", &weird_linear_combination), - ("simple_subtractions", &simple_subtractions), - ("subtractions_with_shift", &subtractions_with_shift), - ("cmz_wallet_spend_relation", &cmz_wallet_spend_relation), - ("nested_affine_relation", &nested_affine_relation), - ("elgamal_public_subtract", &elgamal_subtraction), - ]; - - for (relation_name, relation_sampler) in instance_generators.iter() { - let mut rng = rand::thread_rng(); - let (canonical_relation, witness) = relation_sampler(&mut rng); - - // Test the NIZK protocol - let domain_sep = format!("test-fiat-shamir-{relation_name}") - .as_bytes() - .to_vec(); - let nizk = Nizk::, Shake128DuplexSponge>::new( - &domain_sep, - canonical_relation, - ); - - // Test both proof types - let proof_batchable = nizk - .prove_batchable(&witness, &mut rng) - .unwrap_or_else(|_| panic!("Failed to create batchable proof for {relation_name}")); - let proof_compact = nizk - .prove_compact(&witness, &mut rng) - .unwrap_or_else(|_| panic!("Failed to create compact proof for {relation_name}")); - - // Verify both proof types - assert!( - nizk.verify_batchable(&proof_batchable).is_ok(), - "Batchable proof verification failed for {relation_name}" - ); - assert!( - nizk.verify_compact(&proof_compact).is_ok(), - "Compact proof verification failed for {relation_name}" - ); - } -} diff --git a/src/tests/spec/bls12_381.rs b/tests/spec/bls12_381.rs similarity index 97% rename from src/tests/spec/bls12_381.rs rename to tests/spec/bls12_381.rs index 8dd97ed..74eaeed 100644 --- a/src/tests/spec/bls12_381.rs +++ b/tests/spec/bls12_381.rs @@ -6,7 +6,7 @@ use num_bigint::BigUint; use rand::{CryptoRng, Rng}; use subtle::CtOption; -use crate::tests::spec::random::{SInput, SRandom}; +use crate::spec::random::{SInput, SRandom}; impl SInput for G1Projective { fn scalar_from_hex_be(hex_str: &str) -> Option { diff --git a/src/tests/spec/custom_schnorr_protocol.rs b/tests/spec/custom_schnorr_protocol.rs similarity index 94% rename from src/tests/spec/custom_schnorr_protocol.rs rename to tests/spec/custom_schnorr_protocol.rs index 330d681..2f7bd87 100644 --- a/src/tests/spec/custom_schnorr_protocol.rs +++ b/tests/spec/custom_schnorr_protocol.rs @@ -1,10 +1,10 @@ use group::prime::PrimeGroup; use rand::{CryptoRng, Rng}; -use crate::errors::Error; -use crate::linear_relation::{CanonicalLinearRelation, LinearRelation}; -use crate::tests::spec::random::SRandom; -use crate::traits::{SigmaProtocol, SigmaProtocolSimulator}; +use crate::spec::random::SRandom; +use sigma_proofs::errors::Error; +use sigma_proofs::linear_relation::{CanonicalLinearRelation, LinearRelation}; +use sigma_proofs::traits::{SigmaProtocol, SigmaProtocolSimulator}; pub struct DeterministicSchnorrProof(pub CanonicalLinearRelation); diff --git a/tests/spec/mod.rs b/tests/spec/mod.rs new file mode 100644 index 0000000..d7d5496 --- /dev/null +++ b/tests/spec/mod.rs @@ -0,0 +1,4 @@ +mod bls12_381; +pub(crate) mod custom_schnorr_protocol; +mod random; +pub(crate) mod rng; diff --git a/src/tests/spec/random.rs b/tests/spec/random.rs similarity index 100% rename from src/tests/spec/random.rs rename to tests/spec/random.rs diff --git a/src/tests/spec/rng.rs b/tests/spec/rng.rs similarity index 100% rename from src/tests/spec/rng.rs rename to tests/spec/rng.rs diff --git a/src/tests/spec/vectors/duplexSpongeVectors.json b/tests/spec/vectors/duplexSpongeVectors.json similarity index 100% rename from src/tests/spec/vectors/duplexSpongeVectors.json rename to tests/spec/vectors/duplexSpongeVectors.json diff --git a/src/tests/spec/vectors/testSigmaProtocols.json b/tests/spec/vectors/testSigmaProtocols.json similarity index 100% rename from src/tests/spec/vectors/testSigmaProtocols.json rename to tests/spec/vectors/testSigmaProtocols.json diff --git a/src/tests/spec/test_duplex_sponge.rs b/tests/spec_duplex_sponge.rs similarity index 93% rename from src/tests/spec/test_duplex_sponge.rs rename to tests/spec_duplex_sponge.rs index 5482f46..bcae71c 100644 --- a/src/tests/spec/test_duplex_sponge.rs +++ b/tests/spec_duplex_sponge.rs @@ -1,8 +1,6 @@ -use crate::duplex_sponge::{ - keccak::KeccakDuplexSponge, shake::ShakeDuplexSponge, DuplexSpongeInterface, -}; use libtest_mimic::{Arguments, Failed, Trial}; use serde::{Deserialize, Serialize}; +use sigma_proofs::{DuplexSpongeInterface, KeccakDuplexSponge, ShakeDuplexSponge}; use std::collections::HashMap; #[derive(Debug, Deserialize, Serialize)] @@ -35,7 +33,7 @@ fn hex_decode(hex_str: &str) -> Vec { } fn load_test_vectors() -> HashMap { - let json_data = include_str!("./vectors/duplexSpongeVectors.json"); + let json_data = include_str!("./spec/vectors/duplexSpongeVectors.json"); serde_json::from_str(json_data).expect("Failed to parse test vectors JSON") } diff --git a/src/tests/spec/test_vectors.rs b/tests/spec_vectors.rs similarity index 91% rename from src/tests/spec/test_vectors.rs rename to tests/spec_vectors.rs index c21c9ca..632e224 100644 --- a/src/tests/spec/test_vectors.rs +++ b/tests/spec_vectors.rs @@ -3,10 +3,12 @@ use hex::FromHex; use json::JsonValue; use std::collections::HashMap; -use crate::codec::KeccakByteSchnorrCodec; -use crate::fiat_shamir::Nizk; -use crate::linear_relation::CanonicalLinearRelation; -use crate::tests::spec::{custom_schnorr_protocol::DeterministicSchnorrProof, rng::TestDRNG}; +use sigma_proofs::codec::KeccakByteSchnorrCodec; +use sigma_proofs::linear_relation::CanonicalLinearRelation; +use sigma_proofs::Nizk; + +mod spec; +use spec::{custom_schnorr_protocol::DeterministicSchnorrProof, rng::TestDRNG}; type SchnorrNizk = Nizk, KeccakByteSchnorrCodec>; @@ -58,7 +60,7 @@ fn test_spec_testvectors() { .expect("Failed to parse statement"); // Decode the witness from the test vector - let witness = crate::group::serialization::deserialize_scalars::( + let witness = sigma_proofs::group::serialization::deserialize_scalars::( &vector.witness, parsed_instance.num_scalars, ) @@ -78,7 +80,7 @@ fn test_spec_testvectors() { // Verify that the computed IV matches the test vector IV let protocol_id = b"draft-zkproof-fiat-shamir"; let instance_label = parsed_instance.label(); - let computed_iv = crate::codec::compute_iv::( + let computed_iv = sigma_proofs::codec::compute_iv::( protocol_id, &vector.session_id, &instance_label, @@ -111,7 +113,7 @@ fn test_spec_testvectors() { fn extract_vectors_new() -> Result, String> { use std::collections::HashMap; - let content = include_str!("./vectors/testSigmaProtocols.json"); + let content = include_str!("./spec/vectors/testSigmaProtocols.json"); let root: JsonValue = json::parse(content).map_err(|e| format!("JSON parsing error: {e}"))?; let mut vectors = HashMap::new(); diff --git a/src/tests/test_composition.rs b/tests/test_composition.rs similarity index 96% rename from src/tests/test_composition.rs rename to tests/test_composition.rs index 9d27318..613423d 100644 --- a/src/tests/test_composition.rs +++ b/tests/test_composition.rs @@ -1,10 +1,10 @@ -use curve25519_dalek::ristretto::RistrettoPoint; +use curve25519_dalek::ristretto::RistrettoPoint as G; use group::Group; -use super::test_relations::*; -use crate::composition::{ComposedRelation, ComposedWitness}; +use sigma_proofs::composition::{ComposedRelation, ComposedWitness}; -type G = RistrettoPoint; +mod relations; +pub use relations::*; #[allow(non_snake_case)] #[test] diff --git a/tests/test_relations.rs b/tests/test_relations.rs new file mode 100644 index 0000000..16ee074 --- /dev/null +++ b/tests/test_relations.rs @@ -0,0 +1,110 @@ +use ff::Field; + +use sigma_proofs::codec::Shake128DuplexSponge; +use sigma_proofs::linear_relation::{CanonicalLinearRelation, LinearRelation}; +use sigma_proofs::Nizk; + +mod relations; +use relations::*; + +#[test] +fn test_cmz_wallet_with_fee() { + use group::Group; + type G = bls12_381::G1Projective; + + let mut rng = rand::thread_rng(); + + // This version should fail with InvalidInstanceWitnessPair + // because it uses a scalar constant directly in the equation + let P_W = G::random(&mut rng); + let A = G::random(&mut rng); + + let n_balance = ::Scalar::random(&mut rng); + let i_price = ::Scalar::random(&mut rng); + let _fee = ::Scalar::from(5u64); + let z_w_balance = ::Scalar::random(&mut rng); + + let mut relation = LinearRelation::::new(); + + let var_n_balance = relation.allocate_scalar(); + let var_i_price = relation.allocate_scalar(); + let var_z_w_balance = relation.allocate_scalar(); + + let var_P_W = relation.allocate_element(); + let var_A = relation.allocate_element(); + + // This equation has a scalar constant (fee) which causes the error + let _var_C = relation.allocate_eq( + (var_n_balance + var_i_price + ::Scalar::from(5)) * var_P_W + + var_z_w_balance * var_A, + ); + + relation.set_elements([(var_P_W, P_W), (var_A, A)]); + relation + .compute_image(&[n_balance, i_price, z_w_balance]) + .unwrap(); + + // Try to convert to CanonicalLinearRelation - this should fail + let nizk = relation.into_nizk(b"session_identifier").unwrap(); + let result = nizk.prove_batchable(&vec![n_balance, i_price, z_w_balance], &mut rng); + assert!(result.is_ok()); + let proof = result.unwrap(); + let verify_result = nizk.verify_batchable(&proof); + assert!(verify_result.is_ok()); +} + +/// Generic helper function to test both relation correctness and NIZK functionality +#[test] +fn test_relations() { + type G = bls12_381::G1Projective; + + let instance_generators: Vec<(_, &'static dyn Fn(&mut _) -> _)> = vec![ + ("dlog", &discrete_logarithm), + ("shifted_dlog", &shifted_dlog), + ("dleq", &dleq), + ("shifted_dleq", &shifted_dleq), + ("pedersen_commitment", &pedersen_commitment), + ("twisted_pedersen_commitment", &twisted_pedersen_commitment), + ("pedersen_commitment_dleq", &pedersen_commitment_equality), + ("bbs_blind_commitment", &bbs_blind_commitment), + ("test_range", &test_range), + ("weird_linear_combination", &weird_linear_combination), + ("simple_subtractions", &simple_subtractions), + ("subtractions_with_shift", &subtractions_with_shift), + ("cmz_wallet_spend_relation", &cmz_wallet_spend_relation), + ("nested_affine_relation", &nested_affine_relation), + ("elgamal_public_subtract", &elgamal_subtraction), + ]; + + for (relation_name, relation_sampler) in instance_generators.iter() { + let mut rng = rand::thread_rng(); + let (canonical_relation, witness) = relation_sampler(&mut rng); + + // Test the NIZK protocol + let domain_sep = format!("test-fiat-shamir-{relation_name}") + .as_bytes() + .to_vec(); + let nizk = Nizk::, Shake128DuplexSponge>::new( + &domain_sep, + canonical_relation, + ); + + // Test both proof types + let proof_batchable = nizk + .prove_batchable(&witness, &mut rng) + .unwrap_or_else(|_| panic!("Failed to create batchable proof for {relation_name}")); + let proof_compact = nizk + .prove_compact(&witness, &mut rng) + .unwrap_or_else(|_| panic!("Failed to create compact proof for {relation_name}")); + + // Verify both proof types + assert!( + nizk.verify_batchable(&proof_batchable).is_ok(), + "Batchable proof verification failed for {relation_name}" + ); + assert!( + nizk.verify_compact(&proof_compact).is_ok(), + "Compact proof verification failed for {relation_name}" + ); + } +} diff --git a/src/tests/test_validation_criteria.rs b/tests/test_validation_criteria.rs similarity index 98% rename from src/tests/test_validation_criteria.rs rename to tests/test_validation_criteria.rs index fd45920..ba037f7 100644 --- a/src/tests/test_validation_criteria.rs +++ b/tests/test_validation_criteria.rs @@ -5,10 +5,10 @@ #[cfg(test)] mod instance_validation { - use crate::linear_relation::{CanonicalLinearRelation, LinearRelation}; use bls12_381::{G1Projective as G, Scalar}; use ff::Field; use group::Group; + use sigma_proofs::linear_relation::{CanonicalLinearRelation, LinearRelation}; #[test] fn test_unassigned_group_vars() { @@ -217,13 +217,13 @@ mod instance_validation { #[cfg(test)] mod proof_validation { - use crate::codec::KeccakByteSchnorrCodec; - use crate::composition::{ComposedRelation, ComposedWitness}; - use crate::fiat_shamir::Nizk; - use crate::linear_relation::{CanonicalLinearRelation, LinearRelation}; use bls12_381::{G1Projective as G, Scalar}; use ff::Field; use rand::RngCore; + use sigma_proofs::codec::KeccakByteSchnorrCodec; + use sigma_proofs::composition::{ComposedRelation, ComposedWitness}; + use sigma_proofs::linear_relation::{CanonicalLinearRelation, LinearRelation}; + use sigma_proofs::Nizk; type TestNizk = Nizk, KeccakByteSchnorrCodec>; From 5d25651b7b59ea8f5d037610eb3213c056655502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michele=20Orr=C3=B9?= Date: Fri, 21 Nov 2025 21:47:42 -0800 Subject: [PATCH 2/5] udpate tests/spec/vectors/testSigmaProtocols.json --- tests/spec/vectors/testSigmaProtocols.json | 30 +++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/spec/vectors/testSigmaProtocols.json b/tests/spec/vectors/testSigmaProtocols.json index 06cdd22..1576646 100644 --- a/tests/spec/vectors/testSigmaProtocols.json +++ b/tests/spec/vectors/testSigmaProtocols.json @@ -1,42 +1,42 @@ { "bbs_blind_commitment_computation": { + "Batchable Proof": "8c7090509cb33c86ee2457d1ffab3111fa1a7c9fc2ee532add24838e6aeaa4c1ab5ab243db2d35607590c0a219c134bc1625cc8be1c746bcb3cb08fe97b908ed2cac87152d70d0e29c187e503f6fa95f71c0dbabde943e3ab63fa04c277bfde5f7234ffee03bb25a54ef5db94ba5ff1516c5c42bf0d38087815407c6df12d3344e12d77a79c57e9bdf7fc319245299cd492b513fb0fa97114e507509a532a52298871a491a3709a7e1aa414ee021b31d", "Ciphersuite": "sigma/OWKeccak1600+Bls12381", - "IV": "2d6092334b5656415c6002ae1462c4bcba1a297cff209c6eede5834186944c7e", - "Proof": "8c7090509cb33c86ee2457d1ffab3111fa1a7c9fc2ee532add24838e6aeaa4c1ab5ab243db2d35607590c0a219c134bc55a1cfbcc16a3329533583ee0ee48988f2baaa236bc4fefc30dc17e7b0fcaa5d086aa31e5d45c5177c87ed38bf71f270626c1f6bc9d0d0d771f63ddb3a063f9130279c6ad641cb3536bc125e68e67a451035c4b054eb179cc0fe5a7c168938645503e256f3ee50b122e44c23d651c59a580a223c5872714bc08c672f04615f30", + "Proof": "3c381afe83881263c3e51bcb6aad39409ac6c787a5f04c666edb2fc4f4b1d7815ab9da2fea14007309c0261a58806d1577e06bdabc64ac6f810d0c4d69cee7b05283de734a0e895db3e180073d7b17edffef459a72a210f16e019456b42fc51106dd4e3f83a0f45adf45ecf6afbf8cce3109d7d8f766a21c0318dac5f8459772516cf2a463d777c19d4ee83ffe57ed67fe621afbecd787a1fe246443098094be", "SessionId": "6262735f626c696e645f636f6d6d69746d656e745f636f6d7075746174696f6e", - "Statement": "01000000000000000400000000000000010000000100000002000000020000000300000003000000040000008c38bc769a15a9b38335c732155d2ae373f87c7a986966b5ca95a8902fb6c2971cd0a3eddc54beedcb17c33ce6f96ee2b537255188baffeccd66d810bc5952bd1f887b215a32c6028d439c77722007dcc67dc88addc8fc1419eeb2a337a22336a8662bc3cf5d295960ed2e6df20ffd5a4d05c8ed10d6f872a9286fda210db31acc9dd5a7e988f65d09575f3997b8cdfba048221961233304dddf1ee09939bb646b322cc5d4646c1b2ff90fca056ef29720be065104cd43b5f17d3c35f48dd2cfa2561cd091db0302192aca13657010c86a101ba7f616f53ff5f71ba69d84e5062ce45094e2deea115175c78fc49bab62", + "Statement": "0100000004000000040000000000000000000000010000000100000002000000020000000300000003000000b537255188baffeccd66d810bc5952bd1f887b215a32c6028d439c77722007dcc67dc88addc8fc1419eeb2a337a22336a8662bc3cf5d295960ed2e6df20ffd5a4d05c8ed10d6f872a9286fda210db31acc9dd5a7e988f65d09575f3997b8cdfba048221961233304dddf1ee09939bb646b322cc5d4646c1b2ff90fca056ef29720be065104cd43b5f17d3c35f48dd2cfa2561cd091db0302192aca13657010c86a101ba7f616f53ff5f71ba69d84e5062ce45094e2deea115175c78fc49bab628c38bc769a15a9b38335c732155d2ae373f87c7a986966b5ca95a8902fb6c2971cd0a3eddc54beedcb17c33ce6f96ee2", "Witness": "62e3b38b436d705037a1954f1689674edbdef23bb7c0835f6a14320bf5668de8409945826e10a6fe36c3ce257246ae694efe54ae488badfd379e48c44ab2086f63d0453c8654db5feb745feeff5518e70aeb8224a27f660ef7b5d8ff1877fd2e14091668789158918aac10d2e3c1003a8a2aec035572ee03356d3045b9e38c3b" }, "discrete_logarithm": { + "Batchable Proof": "a8ba164c1cd96e6629165e1979f86430bfa8faad9b56172d792757e42e98d69e08e40025496bed79556b602a8428c511602226780a679f788087bc14d549973670d6b22ecaf6c80d2922e3182e1a946c", "Ciphersuite": "sigma/OWKeccak1600+Bls12381", - "IV": "38b534a4723cb384ab2a591ae05f9a80bd0a89929ad57300373124a72232d9cf", - "Proof": "a8ba164c1cd96e6629165e1979f86430bfa8faad9b56172d792757e42e98d69e08e40025496bed79556b602a8428c511565fbeda5e6a77ff2da1d62ea73c912a4170348e0f9ae74ed0e5acadb85603ce", + "Proof": "5c64d17c9ee9d22f6f0eeef742ae22122cf847a89e215409e4fdd3378353e3726dd0475b820382391bc7282ff9df0fecaa52675a63da863e891ad34d10ebd9fb", "SessionId": "64697363726574655f6c6f6761726974686d", - "Statement": "0100000000000000010000000000000001000000b537255188baffeccd66d810bc5952bd1f887b215a32c6028d439c77722007dcc67dc88addc8fc1419eeb2a337a2233697f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb", + "Statement": "010000000100000001000000000000000000000097f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bbb537255188baffeccd66d810bc5952bd1f887b215a32c6028d439c77722007dcc67dc88addc8fc1419eeb2a337a22336", "Witness": "2c7538adafe40d6f0f111f344e46f02c16c338d5be2b3abb620a8ee35d194350" }, "dleq": { + "Batchable Proof": "a8ba164c1cd96e6629165e1979f86430bfa8faad9b56172d792757e42e98d69e08e40025496bed79556b602a8428c511b2028b870f588e8a374d45535bba6a6d97b9142a6c4eb3b9e22d9700aa08a3616a0d2969852447e1e790c520ec11997634e397f0a66aa7e28b1f76acaef2c11012a02b7d84699e0190f54f13ca71b592", "Ciphersuite": "sigma/OWKeccak1600+Bls12381", - "IV": "43cdf06cd869b9f3b0558f15215934a6d3ad9ee1f91fb2cfd67dd4ff5c9e3841", - "Proof": "a8ba164c1cd96e6629165e1979f86430bfa8faad9b56172d792757e42e98d69e08e40025496bed79556b602a8428c511b2028b870f588e8a374d45535bba6a6d97b9142a6c4eb3b9e22d9700aa08a3616a0d2969852447e1e790c520ec1199764b53d20f18521328bd4eff086199abdc38a98806eae12b3960195cb13c936fe9", + "Proof": "082745ee1fe233275708a14848d55c740f0261d8750827be85aafe0595333da028a582c331d8d224171246779566a2610d5448a01181cb2d0b3a645894e15220", "SessionId": "646c6571", - "Statement": "020000000000000001000000000000000100000002000000010000000000000003000000a8662bc3cf5d295960ed2e6df20ffd5a4d05c8ed10d6f872a9286fda210db31acc9dd5a7e988f65d09575f3997b8cdfb97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bbb4483f8d8655b8448a187ba1a98aa146145f862d5bb0c1f4561a14260cce8d55f4d43e3da1863fdf9dc4fdf859f28b9fb537255188baffeccd66d810bc5952bd1f887b215a32c6028d439c77722007dcc67dc88addc8fc1419eeb2a337a22336", + "Statement": "02000000010000000100000000000000000000000300000001000000000000000200000097f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bba8662bc3cf5d295960ed2e6df20ffd5a4d05c8ed10d6f872a9286fda210db31acc9dd5a7e988f65d09575f3997b8cdfbb537255188baffeccd66d810bc5952bd1f887b215a32c6028d439c77722007dcc67dc88addc8fc1419eeb2a337a22336b4483f8d8655b8448a187ba1a98aa146145f862d5bb0c1f4561a14260cce8d55f4d43e3da1863fdf9dc4fdf859f28b9f", "Witness": "5c18c45b445e82400e1c9198e5929495504a21e6d3956329f56a09f9a0f1666f" }, "pedersen_commitment": { + "Batchable Proof": "9899a74231316713e9527d401f333231316ad97062e9e37ef636ff536535029b24b89947e621867004ec5b0108cb82ac734e792c8e6612ba5bbb478a60043b105b3a6041f52fafe46492032576a0758564d1be052d918fca57222b2e918975229e5abcefcaa73cba5523c9f41fba2b76", "Ciphersuite": "sigma/OWKeccak1600+Bls12381", - "IV": "8c0aa98fe74e3cb40e590852d028b3f93f67c30867d8d385fa25b419ed105370", - "Proof": "9899a74231316713e9527d401f333231316ad97062e9e37ef636ff536535029b24b89947e621867004ec5b0108cb82ac4632735876cbf55e4f9e820c8ea865ea30151725be7765f7a98335a4c1c24f760487fe6b1dad76022cb9553437c5d52405af756e1a484063691751b84d926a1d", + "Proof": "2bc3744f34c93a070722523a5b38ed7b60453e480b0d9238ed2cf071f00aab0f554e402fc538a16b3a02ca6bb5fa951b4f7d8f426eb3bbc707c3bb4c2a8e7983593412f80f8bd4e597bdb6a5a3a7122238e7df2951f55e27b96b98251001ea06", "SessionId": "706564657273656e5f636f6d6d69746d656e74", - "Statement": "010000000000000002000000000000000100000001000000020000008dc806cea8183a52d50d9a525942c0310f0b34eadcce52a40d06e7057043544c62026c0ec24cea8b822ae68c6c33a2d597f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bbb537255188baffeccd66d810bc5952bd1f887b215a32c6028d439c77722007dcc67dc88addc8fc1419eeb2a337a22336", + "Statement": "0100000002000000020000000000000000000000010000000100000097f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bbb537255188baffeccd66d810bc5952bd1f887b215a32c6028d439c77722007dcc67dc88addc8fc1419eeb2a337a223368dc806cea8183a52d50d9a525942c0310f0b34eadcce52a40d06e7057043544c62026c0ec24cea8b822ae68c6c33a2d5", "Witness": "5c18c45b445e82400e1c9198e5929495504a21e6d3956329f56a09f9a0f1666f38c3532866f2be8b864b5c3739af40703153b939716a80e6a47793c041267fbf" }, "pedersen_commitment_dleq": { + "Batchable Proof": "a2a4fb6a89b811dfe9608638afb316fad66d1454641c2ef76fa3ffea578f98d5df92ef5f50029d2ebdbf51ef8721ed8cadcaabd57762ff7a03fe34460ab60013e16cce171ddb2e1855d25f180c6ad6b525b36a9d5e7f53cd7385abadf3b361a569593eef1c7d53c10177269b3022fa5fb15f383a5ce4e2ff97086b1c8b70b0760bfa367ebe37359f40bc801e50cf67f2b291a65560e34b323c2ce3934b607bdf", "Ciphersuite": "sigma/OWKeccak1600+Bls12381", - "IV": "bc6e1c921aae67f9feac6da5e97f51cbad77372c81eefdbf59cf76ebf5c53c97", - "Proof": "a2a4fb6a89b811dfe9608638afb316fad66d1454641c2ef76fa3ffea578f98d5df92ef5f50029d2ebdbf51ef8721ed8cadcaabd57762ff7a03fe34460ab60013e16cce171ddb2e1855d25f180c6ad6b525b36a9d5e7f53cd7385abadf3b361a5029f2053df85af6fed0bafdbed778a15839dee96e7cd4868eb630c5938f8942c1d08dabc914fd83fd5f2e47adc94426669b111be8fb1829d7534bb1874f4773e", + "Proof": "0f836764c565624f9e7b8a9429d75235197bd5631a129836237d945f83e8d3103c0cd961d44c7905b116c799e3c58b8b319604c7cbd15dbfcad2ce4c711760992b500ccac95601be42fec4950fce30fd6d6df2a15aefd427f40048e6bf72da92", "SessionId": "706564657273656e5f636f6d6d69746d656e745f646c6571", - "Statement": "0200000000000000020000000000000001000000010000000200000003000000020000000000000004000000010000000500000082c9b34528286ef1c4a7dd8a3b02a9edfc9adc49d3034f0c90d7927ce1de8ccc7a80bf877c291faf90832fa7b5f86904b537255188baffeccd66d810bc5952bd1f887b215a32c6028d439c77722007dcc67dc88addc8fc1419eeb2a337a22336a8662bc3cf5d295960ed2e6df20ffd5a4d05c8ed10d6f872a9286fda210db31acc9dd5a7e988f65d09575f3997b8cdfb9719cfef2f3c2cd0dfb3cf4b6cb3cb1504ab86f98c26d81192f4d73c5ce72118d3924b19119a64d7dc9aea75661c1488a048221961233304dddf1ee09939bb646b322cc5d4646c1b2ff90fca056ef29720be065104cd43b5f17d3c35f48dd2cfa2561cd091db0302192aca13657010c86a101ba7f616f53ff5f71ba69d84e5062ce45094e2deea115175c78fc49bab62", + "Statement": "02000000020000000200000000000000000000000100000001000000050000000200000000000000030000000100000004000000b537255188baffeccd66d810bc5952bd1f887b215a32c6028d439c77722007dcc67dc88addc8fc1419eeb2a337a22336a8662bc3cf5d295960ed2e6df20ffd5a4d05c8ed10d6f872a9286fda210db31acc9dd5a7e988f65d09575f3997b8cdfb82c9b34528286ef1c4a7dd8a3b02a9edfc9adc49d3034f0c90d7927ce1de8ccc7a80bf877c291faf90832fa7b5f86904a048221961233304dddf1ee09939bb646b322cc5d4646c1b2ff90fca056ef29720be065104cd43b5f17d3c35f48dd2cfa2561cd091db0302192aca13657010c86a101ba7f616f53ff5f71ba69d84e5062ce45094e2deea115175c78fc49bab629719cfef2f3c2cd0dfb3cf4b6cb3cb1504ab86f98c26d81192f4d73c5ce72118d3924b19119a64d7dc9aea75661c1488", "Witness": "409945826e10a6fe36c3ce257246ae694efe54ae488badfd379e48c44ab2086f63d0453c8654db5feb745feeff5518e70aeb8224a27f660ef7b5d8ff1877fd2e" } } \ No newline at end of file From a962c24a0d4c64469f28131fc45148a44bb319eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michele=20Orr=C3=B9?= Date: Fri, 21 Nov 2025 21:48:24 -0800 Subject: [PATCH 3/5] fix: allow(non_snake_case) for functions using EC notation. --- tests/relations/mod.rs | 6 ++++++ tests/test_relations.rs | 1 + tests/test_validation_criteria.rs | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/tests/relations/mod.rs b/tests/relations/mod.rs index 2faa1cf..4a69156 100644 --- a/tests/relations/mod.rs +++ b/tests/relations/mod.rs @@ -321,6 +321,7 @@ pub fn bbs_blind_commitment( } /// LinearMap for the user's specific relation: A * 1 + gen__disj1_x_r * B +#[allow(non_snake_case)] pub fn weird_linear_combination( rng: &mut R, ) -> (CanonicalLinearRelation, Vec) { @@ -349,6 +350,7 @@ pub fn weird_linear_combination( (instance, witness) } +#[allow(non_snake_case)] pub fn simple_subtractions( mut rng: &mut R, ) -> (CanonicalLinearRelation, Vec) { @@ -368,6 +370,7 @@ pub fn simple_subtractions( (instance, witness) } +#[allow(non_snake_case)] pub fn subtractions_with_shift( rng: &mut R, ) -> (CanonicalLinearRelation, Vec) { @@ -433,6 +436,7 @@ pub fn cmz_wallet_spend_relation( (instance, witness) } +#[allow(non_snake_case)] pub fn nested_affine_relation( mut rng: &mut R, ) -> (CanonicalLinearRelation, Vec) { @@ -457,6 +461,7 @@ pub fn nested_affine_relation( (instance, witness) } +#[allow(non_snake_case)] pub fn pedersen_commitment_equality( rng: &mut R, ) -> (CanonicalLinearRelation, Vec) { @@ -480,6 +485,7 @@ pub fn pedersen_commitment_equality( (instance.canonical().unwrap(), witness) } +#[allow(non_snake_case)] pub fn elgamal_subtraction( rng: &mut R, ) -> (CanonicalLinearRelation, Vec) { diff --git a/tests/test_relations.rs b/tests/test_relations.rs index 16ee074..bdcd42e 100644 --- a/tests/test_relations.rs +++ b/tests/test_relations.rs @@ -8,6 +8,7 @@ mod relations; use relations::*; #[test] +#[allow(non_snake_case)] fn test_cmz_wallet_with_fee() { use group::Group; type G = bls12_381::G1Projective; diff --git a/tests/test_validation_criteria.rs b/tests/test_validation_criteria.rs index ba037f7..08fa5ce 100644 --- a/tests/test_validation_criteria.rs +++ b/tests/test_validation_criteria.rs @@ -32,6 +32,7 @@ mod instance_validation { } #[test] + #[allow(non_snake_case)] fn test_zero_image() { // Create a linear relation with zero elements in the image // 0 = x * G (which is invalid) @@ -108,6 +109,7 @@ mod instance_validation { } #[test] + #[allow(non_snake_case)] fn test_empty_string() { let rng = &mut rand::thread_rng(); let relation = LinearRelation::::new(); @@ -123,6 +125,7 @@ mod instance_validation { } #[test] + #[allow(non_snake_case)] fn test_statement_without_witness() { let pub_scalar = Scalar::from(42); let A = G::generator(); @@ -185,6 +188,7 @@ mod instance_validation { } #[test] + #[allow(non_snake_case)] fn test_statement_with_trivial_image() { let mut rng = rand::thread_rng(); let mut linear_relation = LinearRelation::new(); @@ -385,6 +389,7 @@ mod proof_validation { } #[test] + #[allow(non_snake_case)] fn test_or_relation() { // This test reproduces the issue from sigma_compiler's simple_or test // where an OR relation fails verification when using the wrong branch From 73e4cdf9a0206bf6953c958f3ac077bd52162283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michele=20Orr=C3=B9?= Date: Fri, 21 Nov 2025 22:24:07 -0800 Subject: [PATCH 4/5] fix unit-tests and update test vectors --- src/codec.rs | 22 +++++++++++++----- src/composition.rs | 10 +++++---- src/fiat_shamir.rs | 2 +- src/schnorr_protocol.rs | 7 ++++-- src/traits.rs | 2 +- tests/relations/mod.rs | 32 +++++++++++++-------------- tests/spec/custom_schnorr_protocol.rs | 2 +- tests/spec_vectors.rs | 26 +++++----------------- 8 files changed, 51 insertions(+), 52 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index cd652c6..7f81825 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -23,7 +23,11 @@ pub trait Codec { type Challenge; /// Generates an empty codec that can be identified by a domain separator. - fn new(protocol_identifier: &[u8], session_identifier: &[u8], instance_label: &[u8]) -> Self; + fn new( + protocol_identifier: &[u8; 64], + session_identifier: &[u8], + instance_label: &[u8], + ) -> Self; /// Allows for precomputed initialization of the codec with a specific IV. fn from_iv(iv: [u8; 64]) -> Self; @@ -65,12 +69,11 @@ fn length_to_bytes(x: usize) -> [u8; WORD_SIZE] { /// This function computes a deterministic IV from the protocol identifier, /// session identifier, and instance label using the specified duplex sponge. pub fn compute_iv( - protocol_id: &[u8], + protocol_id: &[u8; 64], session_id: &[u8], instance_label: &[u8], ) -> [u8; 64] { let mut tmp = H::new([0u8; 64]); - tmp.absorb(&length_to_bytes(protocol_id.len())); tmp.absorb(protocol_id); tmp.absorb(&length_to_bytes(session_id.len())); tmp.absorb(session_id); @@ -86,9 +89,16 @@ where { type Challenge = G::Scalar; - fn new(protocol_id: &[u8], session_id: &[u8], instance_label: &[u8]) -> Self { - let iv = compute_iv::(protocol_id, session_id, instance_label); - Self::from_iv(iv) + fn new(protocol_id: &[u8; 64], session_id: &[u8], instance_label: &[u8]) -> Self { + let mut hasher = H::new(*protocol_id); + hasher.absorb(&length_to_bytes(session_id.len())); + hasher.absorb(session_id); + hasher.absorb(&length_to_bytes(instance_label.len())); + hasher.absorb(instance_label); + Self { + hasher, + _marker: core::marker::PhantomData, + } } fn from_iv(iv: [u8; 64]) -> Self { diff --git a/src/composition.rs b/src/composition.rs index c3d689e..f29a091 100644 --- a/src/composition.rs +++ b/src/composition.rs @@ -556,7 +556,7 @@ impl SigmaProtocol } } - fn protocol_identifier(&self) -> impl AsRef<[u8]> { + fn protocol_identifier(&self) -> [u8; 64] { let mut hasher = Sha3_256::new(); match self { @@ -569,19 +569,21 @@ impl SigmaProtocol let mut hasher = Sha3_256::new(); hasher.update([1u8; 32]); for p in protocols { - hasher.update(p.protocol_identifier()); + hasher.update(p.protocol_identifier().as_ref()); } } ComposedRelation::Or(protocols) => { let mut hasher = Sha3_256::new(); hasher.update([2u8; 32]); for p in protocols { - hasher.update(p.protocol_identifier()); + hasher.update(p.protocol_identifier().as_ref()); } } } - hasher.finalize() + let mut protocol_id = [0u8; 64]; + (&mut protocol_id[..32]).clone_from_slice(&hasher.finalize()); + protocol_id } fn serialize_response(&self, response: &Self::Response) -> Vec { diff --git a/src/fiat_shamir.rs b/src/fiat_shamir.rs index 28c69d7..a525d26 100644 --- a/src/fiat_shamir.rs +++ b/src/fiat_shamir.rs @@ -68,7 +68,7 @@ where /// A new [`Nizk`] that can generate and verify non-interactive proofs. pub fn new(session_identifier: &[u8], interactive_proof: P) -> Self { let hash_state = C::new( - interactive_proof.protocol_identifier().as_ref(), + &interactive_proof.protocol_identifier(), session_identifier, interactive_proof.instance_label().as_ref(), ); diff --git a/src/schnorr_protocol.rs b/src/schnorr_protocol.rs index ea54e74..1fb9bad 100644 --- a/src/schnorr_protocol.rs +++ b/src/schnorr_protocol.rs @@ -233,8 +233,11 @@ impl SigmaProtocol for CanonicalLinearRelation { self.label() } - fn protocol_identifier(&self) -> impl AsRef<[u8]> { - b"draft-zkproof-fiat-shamir" + fn protocol_identifier(&self) -> [u8; 64] { + const PROTOCOL_ID: &[u8; 32] = b"ietf sigma proof linear relation"; + let mut protocol_id = [0; 64]; + protocol_id[..32].clone_from_slice(PROTOCOL_ID); + protocol_id } } diff --git a/src/traits.rs b/src/traits.rs index f669656..a7deefb 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -98,7 +98,7 @@ pub trait SigmaProtocol { /// Deserializes a response from bytes. fn deserialize_response(&self, data: &[u8]) -> Result; - fn protocol_identifier(&self) -> impl AsRef<[u8]>; + fn protocol_identifier(&self) -> [u8; 64]; fn instance_label(&self) -> impl AsRef<[u8]>; } diff --git a/tests/relations/mod.rs b/tests/relations/mod.rs index 4a69156..7c02813 100644 --- a/tests/relations/mod.rs +++ b/tests/relations/mod.rs @@ -182,27 +182,25 @@ pub fn range_instance_generation( let [var_G, var_H] = instance.allocate_elements(); let [var_x, var_r] = instance.allocate_scalars(); let vars_b = instance.allocate_scalars_vec(bases.len()); - let vars_s = instance.allocate_scalars_vec(bases.len() - 1); + let vars_s = instance.allocate_scalars_vec(bases.len()); let var_s2 = instance.allocate_scalars_vec(bases.len()); let var_Ds = instance.allocate_elements_vec(bases.len()); // `var_C` is a Pedersen commitment to `var_x`. let var_C = instance.allocate_eq(var_x * var_G + var_r * var_H); // `var_Ds[i]` are bit commitments... - for i in 1..bases.len() { + for i in 0..bases.len() { instance.append_equation(var_Ds[i], vars_b[i] * var_G + vars_s[i] * var_H); instance.append_equation(var_Ds[i], vars_b[i] * var_Ds[i] + var_s2[i] * var_H); } // ... satisfying that sum(Ds[i] * bases[i]) = C instance.append_equation( - var_Ds[0], - var_C - - var_G * G::Scalar::from(range.start) - - (1..bases.len()) + var_C, + var_G * G::Scalar::from(range.start) + + (0..bases.len()) .map(|i| var_Ds[i] * G::Scalar::from(bases[i])) .sum::>(), ); - instance.append_equation(var_Ds[0], vars_b[0] * var_Ds[0] + var_s2[0] * var_H); // Compute the witness let r = G::Scalar::random(&mut rng); @@ -492,24 +490,26 @@ pub fn elgamal_subtraction( let mut instance = LinearRelation::new(); let [dk, a, r] = instance.allocate_scalars(); let [ek, C, D, H, G] = instance.allocate_elements(); - let v = G::Scalar::from(100); instance.append_equation(ek, dk * H); instance.append_equation(D, r * H); instance.append_equation(C, r * ek + a * G); - instance.append_equation(C, G * v + dk * D + a * G); + instance.append_equation(C, dk * D + a * G); - // set dk for testing to - let witness = vec![ - G::Scalar::from(4242), - G::Scalar::from(1000), - G::Scalar::random(&mut *rng), - ]; + let witness_dk = G::Scalar::from(4242); + let witness_a = G::Scalar::from(1000); + let witness_r = G::Scalar::random(&mut *rng); + let witness = vec![witness_dk, witness_a, witness_r]; + + // Assign group elements consistent with the witness so compute_image is unnecessary. let alt_gen = G::random(&mut *rng); instance.set_elements([(G, G::generator()), (H, alt_gen)]); - instance.compute_image(&witness).unwrap(); + let ek_val = alt_gen * witness_dk; + let D_val = alt_gen * witness_r; + let C_val = ek_val * witness_r + G::generator() * witness_a; + instance.set_elements([(ek, ek_val), (D, D_val), (C, C_val)]); (instance.canonical().unwrap(), witness) } diff --git a/tests/spec/custom_schnorr_protocol.rs b/tests/spec/custom_schnorr_protocol.rs index 2f7bd87..b0b11cd 100644 --- a/tests/spec/custom_schnorr_protocol.rs +++ b/tests/spec/custom_schnorr_protocol.rs @@ -88,7 +88,7 @@ impl SigmaProtocol for DeterministicSchnorrProof { self.0.instance_label() } - fn protocol_identifier(&self) -> impl AsRef<[u8]> { + fn protocol_identifier(&self) -> [u8; 64] { self.0.protocol_identifier() } } diff --git a/tests/spec_vectors.rs b/tests/spec_vectors.rs index 632e224..21231f5 100644 --- a/tests/spec_vectors.rs +++ b/tests/spec_vectors.rs @@ -18,7 +18,6 @@ struct TestVector { session_id: Vec, statement: Vec, witness: Vec, - iv: Vec, proof: Vec, } @@ -78,17 +77,10 @@ fn test_spec_testvectors() { let nizk = SchnorrNizk::new(&vector.session_id, protocol); // Verify that the computed IV matches the test vector IV - let protocol_id = b"draft-zkproof-fiat-shamir"; - let instance_label = parsed_instance.label(); - let computed_iv = sigma_proofs::codec::compute_iv::( - protocol_id, - &vector.session_id, - &instance_label, - ); - assert_eq!( - computed_iv, - vector.iv.as_slice(), - "Computed IV doesn't match test vector IV for {test_name}" + // Ensure the provided test vector proof verifies. + assert!( + nizk.verify_batchable(&vector.proof).is_ok(), + "Fiat-Shamir Schnorr proof from vectors did not verify for {test_name}" ); // Generate proof with the proof generation RNG @@ -145,15 +137,8 @@ fn extract_vectors_new() -> Result, String> { ) .map_err(|e| format!("Invalid hex in Witness for {name}: {e}"))?; - let iv = Vec::from_hex( - obj["IV"] - .as_str() - .ok_or_else(|| format!("IV field not found for {name}"))?, - ) - .map_err(|e| format!("Invalid hex in IV for {name}: {e}"))?; - let proof = Vec::from_hex( - obj["Proof"] + obj["Batchable Proof"] .as_str() .ok_or_else(|| format!("Proof field not found for {name}"))?, ) @@ -166,7 +151,6 @@ fn extract_vectors_new() -> Result, String> { session_id, statement, witness, - iv, proof, }, ); From 68915261af7e08953b6cfb3a2100228c7ccf360b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michele=20Orr=C3=B9?= Date: Fri, 21 Nov 2025 23:07:14 -0800 Subject: [PATCH 5/5] cargo clippy --fix --- src/composition.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/composition.rs b/src/composition.rs index f29a091..a16859f 100644 --- a/src/composition.rs +++ b/src/composition.rs @@ -582,7 +582,7 @@ impl SigmaProtocol } let mut protocol_id = [0u8; 64]; - (&mut protocol_id[..32]).clone_from_slice(&hasher.finalize()); + protocol_id[..32].clone_from_slice(&hasher.finalize()); protocol_id }