diff --git a/CHANGELOG.md b/CHANGELOG.md index d84dc14..4a410f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.5.2] - Unreleased +### Added + +- `RingContext::new_without_blinding(ring_size)`: runtime replacement for the + removed `test-vectors` feature. Provers built from such a context generate + deterministic (non zero-knowledge) proofs, still valid for verifiers using + a regular context for the same ring size. + +### Changed + +- arkworks dependencies bumped to 0.6. + +### Removed + +- `test-vectors` feature. Cargo features are additive: any crate in the + dependency graph could enable it, silently disabling ring proof blinding + for every other user of the same build. + ### Security - The group identity is now rejected as a public key: its secret scalar is diff --git a/Cargo.toml b/Cargo.toml index 8e5e658..11da5bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,29 +11,30 @@ categories = ["cryptography", "no-std"] autobenches = false [dependencies] -ark-ec = { version = "0.5", default-features = false } -ark-ff = { version = "0.5", default-features = false } -ark-std = { version = "0.5", default-features = false } -ark-serialize = { version = "0.5", default-features = false } +ark-ec = { version = "0.6", default-features = false } +ark-ff = { version = "0.6", default-features = false } +ark-std = { version = "0.6", default-features = false } +ark-serialize = { version = "0.6", default-features = false } zeroize = { version = "1.8", default-features = false } digest = { version = "0.10", default-features = false } generic-array = { version = "0.14", default-features = false } sha2 = { version = "0.10", default-features = false } sha3 = { version = "0.10", default-features = false, optional = true } rayon = { version = "1.10", default-features = false, optional = true } -w3f-ring-proof = { version = "0.0.8", default-features = false, optional = true } +# TODO: switch back to a crates.io version once `Domain::without_blinding` is released +w3f-ring-proof = { git = "https://github.com/paritytech/ring-proof", rev = "501c18a58c383a8f38abe7f4ae0648a0a68583e9", default-features = false, optional = true } # Curves -ark-secp256r1 = { version = "0.5", default-features = false, optional = true } -ark-ed25519 = { version = "0.5", default-features = false, optional = true } -ark-ed-on-bls12-381 = { version = "0.5", default-features = false, optional = true } -ark-ed-on-bls12-381-bandersnatch = { version = "0.5", default-features = false, optional = true } -ark-bls12-381 = { version = "0.5", default-features = false, optional = true } -ark-ed-on-bn254 = { version = "0.5", default-features = false, optional = true } -ark-bn254 = { version = "0.5", default-features = false, optional = true } +ark-secp256r1 = { version = "0.6", default-features = false, optional = true } +ark-ed25519 = { version = "0.6", default-features = false, optional = true } +ark-ed-on-bls12-381 = { version = "0.6", default-features = false, optional = true } +ark-ed-on-bls12-381-bandersnatch = { version = "0.6", default-features = false, optional = true } +ark-bls12-381 = { version = "0.6", default-features = false, optional = true } +ark-ed-on-bn254 = { version = "0.6", default-features = false, optional = true } +ark-bn254 = { version = "0.6", default-features = false, optional = true } [dev-dependencies] -ark-std = { version = "0.5", default-features = false, features = ["getrandom"] } -ark-ed25519 = { version = "0.5" } +ark-std = { version = "0.6", default-features = false, features = ["getrandom"] } +ark-ed25519 = { version = "0.6" } hex = { version = "0.4" } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0" } @@ -106,8 +107,5 @@ asm = [ "sha2/asm", "sha3?/asm" ] -# Deterministic, no-zk, ring-proof (unsafe) -test-vectors = [ "w3f-ring-proof?/test-vectors" ] - [package.metadata.docs.rs] features = [ "full" ] diff --git a/README.md b/README.md index 7487bb2..f000934 100644 --- a/README.md +++ b/README.md @@ -233,12 +233,11 @@ let verifier_key = ring_setup.verifier_key_from_commitment(ring_commitment); ## Features - `default`: `std` -- `full`: Enables all features listed below except `secret-split`, `parallel`, `asm`, `test-vectors`. +- `full`: Enables all features listed below except `secret-split`, `parallel`, `asm`. - `secret-split`: Split-secret scalar multiplication. Secret scalar is split into the sum of two scalars, which randomly mutate but retain the same sum. Incurs 2x penalty in some internal sensible scalar multiplications, but provides side channel defenses. - `ring`: Ring-VRF for the curves supporting it. -- `test-vectors`: Deterministic ring-vrf proof. Useful for reproducible test vectors generation. ### Curves diff --git a/data/vectors-generate.sh b/data/vectors-generate.sh index 5120bda..0c175bc 100755 --- a/data/vectors-generate.sh +++ b/data/vectors-generate.sh @@ -6,7 +6,7 @@ mkdir -p vectors cargo test \ --lib \ --release \ - --features full,shake128,test-vectors \ + --features full,shake128 \ -- \ --nocapture \ --ignored diff --git a/src/lib.rs b/src/lib.rs index 1386fc1..f4414a3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,12 +65,11 @@ //! ## Features //! //! - `default`: `std` -//! - `full`: Enables all features listed below except `secret-split`, `parallel`, `asm`, `test-vectors`. +//! - `full`: Enables all features listed below except `secret-split`, `parallel`, `asm`. //! - `secret-split`: Split-secret scalar multiplication. Secret scalar is split into the sum //! of two scalars, which randomly mutate but retain the same sum. Incurs 2x penalty in some internal //! sensible scalar multiplications, but provides side channel defenses. //! - `ring`: Ring-VRF for the curves supporting it. -//! - `test-vectors`: Deterministic ring-vrf proof. Useful for reproducible test vectors generation. //! //! ### Curves //! diff --git a/src/ring.rs b/src/ring.rs index c7183bc..d09eb6a 100644 --- a/src/ring.rs +++ b/src/ring.rs @@ -95,8 +95,7 @@ pub trait RingSuite: pub type Kzg = ring_proof::pcs::kzg::KZG<::Pairing>; /// KZG commitment. -pub type PcsCommitment = - ring_proof::pcs::kzg::commitment::KzgCommitment<::Pairing>; +pub type PcsCommitment = as ring_proof::pcs::PCS>>::C; /// KZG Polynomial Commitment Scheme parameters. /// @@ -115,7 +114,7 @@ pub type PcsVerifierParams = as ring_proof::pcs::PcsParams>::RV /// /// Basically all the application specific parameters required to construct and /// verify the ring proof. -pub type PiopParams = ring_proof::PiopParams, CurveConfig>; +pub type PiopParams = ring_proof::PiopParams>>; /// Ring keys commitment. pub type RingCommitment = ring_proof::FixedColumnsCommitted, PcsCommitment>; @@ -261,9 +260,27 @@ pub struct RingContext { impl RingContext { /// Construct context for the given ring size. pub fn new(ring_size: usize) -> Self { + Self::construct(ring_size, true) + } + + /// Construct a context whose provers generate deterministic proofs. + /// + /// Column blinding is disabled: proofs are reproducible, thus NOT zero-knowledge, + /// but remain valid for verifiers using a regular context for the same ring size. + /// Useful for reproducible test vectors generation. + pub fn new_without_blinding(ring_size: usize) -> Self { + Self::construct(ring_size, false) + } + + fn construct(ring_size: usize, blinding: bool) -> Self { let domain_size = piop_domain_size::(ring_size); + let mut domain = + ring_proof::Domain::with_zk_rows(domain_size, ring_proof::piop::params::ZK_ROWS); + if !blinding { + domain = domain.without_blinding(); + } let piop_params = PiopParams::::setup( - ring_proof::Domain::new(domain_size, true), + domain, S::BLINDING_BASE .into_te() .expect("BLINDING_BASE must not be identity"), @@ -508,7 +525,7 @@ pub struct RingBuilderPcsParams(pub Vec>); // Under construction ring commitment. type PartialRingCommitment = - ring_proof::ring::Ring, ::Pairing, CurveConfig>; + ring_proof::ring::Ring, ::Pairing, TEAffine>>; /// Builder for incremental construction of ring verifier keys. /// @@ -1421,9 +1438,10 @@ pub(crate) mod testing { let mut ring_pks = common::random_vec::>(TEST_RING_SIZE, Some(rng)); ring_pks[prover_idx] = public.0; - let ring_ctx = ring_setup.ring_context(); + // Blinding is disabled to make the proof reproducible + let ring_ctx = RingContext::::new_without_blinding(TEST_RING_SIZE); let prover_key = ring_setup.prover_key(&ring_pks).unwrap(); - let prover = ring_ctx.ring_prover(prover_key, prover_idx); + let prover = ring_ctx.into_ring_prover(prover_key, prover_idx); let proof = secret.prove(io, ad, &prover); let verifier_key = ring_setup.verifier_key(&ring_pks).unwrap(); @@ -1483,7 +1501,8 @@ pub(crate) mod testing { let prover_idx = self.ring_pks.iter().position(|&pk| pk == public.0).unwrap(); - let ring_ctx = ring_setup.ring_context(); + // Blinding is disabled to reproduce the exact proof in the vector + let ring_ctx = RingContext::::new_without_blinding(TEST_RING_SIZE); let prover_key = ring_setup.prover_key(&self.ring_pks).unwrap(); let prover = ring_ctx.ring_prover(prover_key, prover_idx); @@ -1500,10 +1519,8 @@ pub(crate) mod testing { assert_eq!(p.0, p.1); } - #[cfg(feature = "test-vectors")] { - // Verify if the ring-proof matches. This check is performed only when - // deterministic proof generation is required for test vectors. + // Check if the (deterministic) ring proof matches let mut p = (Vec::new(), Vec::new()); self.ring_proof.serialize_compressed(&mut p.0).unwrap(); proof.ring_proof.serialize_compressed(&mut p.1).unwrap();