From 1b72cff9490e94ba19a88a7691f416530c7ed197 Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Fri, 12 Dec 2025 16:14:34 +0100 Subject: [PATCH 1/4] Improve ring-vrf ergonomics --- src/ring.rs | 87 +++++++++-------------------------------------------- 1 file changed, 14 insertions(+), 73 deletions(-) diff --git a/src/ring.rs b/src/ring.rs index d523181..b6a9bcb 100644 --- a/src/ring.rs +++ b/src/ring.rs @@ -91,11 +91,16 @@ const fn piop_domain_size_from_pcs_domain_size(pcs_domain_size: usize) -> usize } /// Ring suite. -pub trait RingSuite: PedersenSuite -where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig, - AffinePoint: TEMapping>, +/// +/// This trait provides the cryptographic primitives needed for ring VRF signatures. +/// All required bounds are expressed directly on the associated type for better ergonomics. +pub trait RingSuite: + PedersenSuite< + Affine: AffineRepr< + BaseField: ark_ff::PrimeField, + Config: TECurveConfig + Clone, + > + TEMapping<::Config>, + > { /// Pairing type. type Pairing: ark_ec::pairing::Pairing>; @@ -156,12 +161,7 @@ pub type RingBareProof = ring_proof::RingProof, Pcs>; /// - `pedersen_proof`: Key commitment and VRF correctness proof /// - `ring_proof`: Membership proof binding the commitment to the ring #[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] -pub struct Proof -where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig, - AffinePoint: TEMapping>, -{ +pub struct Proof { pub pedersen_proof: PedersenProof, pub ring_proof: RingBareProof, } @@ -170,12 +170,7 @@ where /// /// Implementors can create anonymous proofs that a VRF output /// is correctly derived using a secret key from a ring of public keys. -pub trait Prover -where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig, - AffinePoint: TEMapping>, -{ +pub trait Prover { /// Generate a proof for the given input/output and additional data. /// /// Creates a zero-knowledge proof that: @@ -199,12 +194,7 @@ where /// /// Implementors can verify anonymous proofs that a VRF output /// was derived using a secret key from a ring of public keys. -pub trait Verifier -where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig, - AffinePoint: TEMapping>, -{ +pub trait Verifier { /// Verify a proof for the given input/output and additional data. /// /// Verifies that: @@ -230,9 +220,6 @@ where impl Prover for Secret where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig, - AffinePoint: TEMapping>, { fn prove( &self, @@ -254,9 +241,6 @@ where impl Verifier for Public where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig, - AffinePoint: TEMapping>, { fn verify( input: Input, @@ -283,9 +267,6 @@ where #[derive(Clone)] pub struct RingProofParams where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { /// PCS parameters. pub pcs: PcsParams, @@ -295,9 +276,6 @@ where pub(crate) fn piop_params(domain_size: usize) -> PiopParams where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { PiopParams::::setup( ring_proof::Domain::new(domain_size, true), @@ -309,9 +287,6 @@ where impl RingProofParams where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { /// Construct deterministic ring proof params for the given ring size. /// @@ -465,9 +440,6 @@ where impl CanonicalSerialize for RingProofParams where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { fn serialize_with_mode( &self, @@ -484,9 +456,6 @@ where impl CanonicalDeserialize for RingProofParams where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { fn deserialize_with_mode( mut reader: R, @@ -508,9 +477,6 @@ where impl ark_serialize::Valid for RingProofParams where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { fn check(&self) -> Result<(), ark_serialize::SerializationError> { self.pcs.check() @@ -522,11 +488,7 @@ where /// Basically the SRS in Lagrangian form. /// Can be constructed via the `PcsParams::ck_with_lagrangian()` method. #[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] -pub struct RingBuilderPcsParams(pub Vec>) -where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>; +pub struct RingBuilderPcsParams(pub Vec>); // Under construction ring commitment. type PartialRingCommitment = @@ -541,9 +503,6 @@ type RawVerifierKey = as ring_proof::pcs::PcsParams>::RVK; #[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] pub struct RingVerifierKeyBuilder where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { partial: PartialRingCommitment, raw_vk: RawVerifierKey, @@ -557,9 +516,6 @@ pub type G2Affine = <::Pairing as Pairing>::G2Affine; /// Provides access to precomputed SRS elements needed for efficient ring operations. pub trait SrsLookup where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { fn lookup(&self, range: Range) -> Option>>; } @@ -567,9 +523,6 @@ where impl SrsLookup for F where F: Fn(Range) -> Option>>, - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { fn lookup(&self, range: Range) -> Option>> { self(range) @@ -578,9 +531,6 @@ where impl SrsLookup for &RingBuilderPcsParams where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { fn lookup(&self, range: Range) -> Option>> { if range.end > self.0.len() { @@ -592,9 +542,6 @@ where impl RingVerifierKeyBuilder where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { /// Create a new empty ring verifier key builder. /// @@ -744,7 +691,6 @@ pub(crate) mod testing { where BaseField: ark_ff::PrimeField, CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { let rng = &mut ark_std::test_rng(); let params = RingProofParams::::from_rand(TEST_RING_SIZE, rng); @@ -816,7 +762,6 @@ pub(crate) mod testing { where BaseField: ark_ff::PrimeField, CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { use crate::testing::{random_val, random_vec}; @@ -897,7 +842,6 @@ pub(crate) mod testing { where BaseField: ark_ff::PrimeField, CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { const SRS_FILE: &str; @@ -931,7 +875,6 @@ pub(crate) mod testing { where BaseField: ark_ff::PrimeField, CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { pub pedersen: pedersen::testing::TestVector, pub ring_pks: [AffinePoint; TEST_RING_SIZE], @@ -943,7 +886,6 @@ pub(crate) mod testing { where BaseField: ark_ff::PrimeField, CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("TestVector") @@ -958,7 +900,6 @@ pub(crate) mod testing { S: RingSuiteExt + std::fmt::Debug + 'static, BaseField: ark_ff::PrimeField, CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping>, { fn name() -> String { S::suite_name() + "_ring" From 078af87dcda4ae0fb85e7e1a42f25db6181466d5 Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Fri, 12 Dec 2025 16:14:49 +0100 Subject: [PATCH 2/4] Fmt --- src/ring.rs | 52 ++++++++++++------------------------------ src/utils/te_sw_map.rs | 2 +- 2 files changed, 15 insertions(+), 39 deletions(-) diff --git a/src/ring.rs b/src/ring.rs index b6a9bcb..1471709 100644 --- a/src/ring.rs +++ b/src/ring.rs @@ -96,11 +96,9 @@ const fn piop_domain_size_from_pcs_domain_size(pcs_domain_size: usize) -> usize /// All required bounds are expressed directly on the associated type for better ergonomics. pub trait RingSuite: PedersenSuite< - Affine: AffineRepr< - BaseField: ark_ff::PrimeField, - Config: TECurveConfig + Clone, - > + TEMapping<::Config>, - > + Affine: AffineRepr + + TEMapping<::Config>, +> { /// Pairing type. type Pairing: ark_ec::pairing::Pairing>; @@ -218,9 +216,7 @@ pub trait Verifier { ) -> Result<(), Error>; } -impl Prover for Secret -where -{ +impl Prover for Secret { fn prove( &self, input: Input, @@ -239,9 +235,7 @@ where } } -impl Verifier for Public -where -{ +impl Verifier for Public { fn verify( input: Input, output: Output, @@ -265,9 +259,7 @@ where /// - `pcs`: Polynomial Commitment Scheme parameters (KZG setup) /// - `piop`: Polynomial Interactive Oracle Proof parameters #[derive(Clone)] -pub struct RingProofParams -where -{ +pub struct RingProofParams { /// PCS parameters. pub pcs: PcsParams, /// PIOP parameters. @@ -285,9 +277,7 @@ where ) } -impl RingProofParams -where -{ +impl RingProofParams { /// Construct deterministic ring proof params for the given ring size. /// /// Creates parameters using a deterministic `ChaCha20Rng` seeded with `seed`. @@ -438,9 +428,7 @@ where } } -impl CanonicalSerialize for RingProofParams -where -{ +impl CanonicalSerialize for RingProofParams { fn serialize_with_mode( &self, mut writer: W, @@ -454,9 +442,7 @@ where } } -impl CanonicalDeserialize for RingProofParams -where -{ +impl CanonicalDeserialize for RingProofParams { fn deserialize_with_mode( mut reader: R, compress: ark_serialize::Compress, @@ -475,9 +461,7 @@ where } } -impl ark_serialize::Valid for RingProofParams -where -{ +impl ark_serialize::Valid for RingProofParams { fn check(&self) -> Result<(), ark_serialize::SerializationError> { self.pcs.check() } @@ -501,9 +485,7 @@ type RawVerifierKey = as ring_proof::pcs::PcsParams>::RVK; /// Allows constructing a verifier key by adding public keys in batches, /// which is useful for large rings or memory-constrained environments. #[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] -pub struct RingVerifierKeyBuilder -where -{ +pub struct RingVerifierKeyBuilder { partial: PartialRingCommitment, raw_vk: RawVerifierKey, } @@ -514,9 +496,7 @@ pub type G2Affine = <::Pairing as Pairing>::G2Affine; /// Trait for accessing Structured Reference String entries in Lagrangian basis. /// /// Provides access to precomputed SRS elements needed for efficient ring operations. -pub trait SrsLookup -where -{ +pub trait SrsLookup { fn lookup(&self, range: Range) -> Option>>; } @@ -529,9 +509,7 @@ where } } -impl SrsLookup for &RingBuilderPcsParams -where -{ +impl SrsLookup for &RingBuilderPcsParams { fn lookup(&self, range: Range) -> Option>> { if range.end > self.0.len() { return None; @@ -540,9 +518,7 @@ where } } -impl RingVerifierKeyBuilder -where -{ +impl RingVerifierKeyBuilder { /// Create a new empty ring verifier key builder. /// /// * `params` - Ring proof parameters diff --git a/src/utils/te_sw_map.rs b/src/utils/te_sw_map.rs index ea6d517..d7ed59f 100644 --- a/src/utils/te_sw_map.rs +++ b/src/utils/te_sw_map.rs @@ -4,9 +4,9 @@ //! allowing operations to be performed in the most convenient form for a given task. use ark_ec::{ + CurveConfig, short_weierstrass::{Affine as SWAffine, SWCurveConfig}, twisted_edwards::{Affine as TEAffine, MontCurveConfig, TECurveConfig}, - CurveConfig, }; use ark_ff::{Field, One}; use ark_std::borrow::Cow; From 72f913643b988c3c66a554c8ea662196f2e58d89 Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Fri, 12 Dec 2025 16:19:36 +0100 Subject: [PATCH 3/4] Update testing module --- src/ring.rs | 40 +++++++--------------------------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/src/ring.rs b/src/ring.rs index 1471709..bd26fbe 100644 --- a/src/ring.rs +++ b/src/ring.rs @@ -663,11 +663,7 @@ pub(crate) mod testing { } #[allow(unused)] - pub fn prove_verify() - where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - { + pub fn prove_verify() { let rng = &mut ark_std::test_rng(); let params = RingProofParams::::from_rand(TEST_RING_SIZE, rng); @@ -703,9 +699,7 @@ pub(crate) mod testing { #[allow(unused)] pub fn padding_check() where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping> + CheckPoint, + AffinePoint: CheckPoint, { // Check that point has been computed using the magic spell. assert_eq!(S::PADDING, S::data_to_point(PADDING_SEED).unwrap()); @@ -717,9 +711,7 @@ pub(crate) mod testing { #[allow(unused)] pub fn accumulator_base_check() where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - AffinePoint: TEMapping> + FindAccumulatorBase + CheckPoint, + AffinePoint: FindAccumulatorBase + CheckPoint, { // Check that point has been computed using the magic spell. assert_eq!( @@ -734,11 +726,7 @@ pub(crate) mod testing { } #[allow(unused)] - pub fn verifier_key_builder() - where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - { + pub fn verifier_key_builder() { use crate::testing::{random_val, random_vec}; let rng = &mut ark_std::test_rng(); @@ -814,11 +802,7 @@ pub(crate) mod testing { }; } - pub trait RingSuiteExt: RingSuite + crate::testing::SuiteExt - where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - { + pub trait RingSuiteExt: RingSuite + crate::testing::SuiteExt { const SRS_FILE: &str; fn params() -> &'static RingProofParams; @@ -847,22 +831,14 @@ pub(crate) mod testing { } } - pub struct TestVector - where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - { + pub struct TestVector { pub pedersen: pedersen::testing::TestVector, pub ring_pks: [AffinePoint; TEST_RING_SIZE], pub ring_pks_com: RingCommitment, pub ring_proof: RingBareProof, } - impl core::fmt::Debug for TestVector - where - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, - { + impl core::fmt::Debug for TestVector { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("TestVector") .field("pedersen", &self.pedersen) @@ -874,8 +850,6 @@ pub(crate) mod testing { impl common::TestVectorTrait for TestVector where S: RingSuiteExt + std::fmt::Debug + 'static, - BaseField: ark_ff::PrimeField, - CurveConfig: TECurveConfig + Clone, { fn name() -> String { S::suite_name() + "_ring" From b39967407b7ef6666b8c40a0a34c279ba58943fa Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Fri, 12 Dec 2025 16:23:52 +0100 Subject: [PATCH 4/4] Remove empty where clause --- src/ring.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ring.rs b/src/ring.rs index bd26fbe..15bc398 100644 --- a/src/ring.rs +++ b/src/ring.rs @@ -266,9 +266,7 @@ pub struct RingProofParams { pub piop: PiopParams, } -pub(crate) fn piop_params(domain_size: usize) -> PiopParams -where -{ +pub(crate) fn piop_params(domain_size: usize) -> PiopParams { PiopParams::::setup( ring_proof::Domain::new(domain_size, true), S::BLINDING_BASE.into_te(),