From d119afd7ef38d10448f6f9c5083afda18a61c634 Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 30 May 2024 13:00:44 +0200 Subject: [PATCH 1/6] Ring proof compat layer for edwards form --- src/lib.rs | 7 +- src/ring2.rs | 225 +++++++++++++++++++++++++++++++++++++ src/suites/bandersnatch.rs | 117 +++++++++++++++++++ 3 files changed, 347 insertions(+), 2 deletions(-) create mode 100644 src/ring2.rs diff --git a/src/lib.rs b/src/lib.rs index feb6946..e1dc963 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,6 +30,8 @@ pub mod utils; #[cfg(feature = "ring")] pub mod ring; +#[cfg(feature = "ring")] +pub mod ring2; #[cfg(test)] mod testing; @@ -41,10 +43,11 @@ pub mod prelude { pub use ark_std; } -pub type ScalarField = <::Affine as AffineRepr>::ScalarField; -pub type BaseField = <::Affine as AffineRepr>::BaseField; pub type AffinePoint = ::Affine; +pub type BaseField = as AffineRepr>::BaseField; +pub type ScalarField = as AffineRepr>::ScalarField; + pub type HashOutput = digest::Output<::Hasher>; /// Verification error(s) diff --git a/src/ring2.rs b/src/ring2.rs new file mode 100644 index 0000000..b40775c --- /dev/null +++ b/src/ring2.rs @@ -0,0 +1,225 @@ +use crate::*; +use ark_ec::{ + short_weierstrass::SWCurveConfig, twisted_edwards::TECurveConfig, AffineRepr, CurveConfig, +}; +use pedersen::{PedersenSuite, Proof as PedersenProof}; + +pub trait RingSuite2: PedersenSuite { + type Pairing: ark_ec::pairing::Pairing>; + // type Config: CurveConfig; + + const COMPLEMENT_POINT: AffinePoint; +} + +type Curve = <::Affine as AffineRepr>::Config; + +/// KZG Polynomial Commitment Scheme. +type Pcs = fflonk::pcs::kzg::KZG<::Pairing>; + +/// KZG Setup Parameters. +/// +/// Basically the powers of tau URS. +type PcsParams = fflonk::pcs::kzg::urs::URS<::Pairing>; + +type PairingScalarField = <::Pairing as ark_ec::pairing::Pairing>::ScalarField; + +// pub type ProverKey = ring_proof::ProverKey, Pcs, AffinePoint>; +pub type ProverKey = ring_proof::ProverKey< + PairingScalarField, + Pcs, + ark_ec::short_weierstrass::Affine>, +>; + +pub type VerifierKey = ring_proof::VerifierKey, Pcs>; + +pub type Prover = ring_proof::ring_prover::RingProver, Pcs, Curve>; + +pub type Verifier = + ring_proof::ring_verifier::RingVerifier, Pcs, Curve>; + +pub type RingProof = ring_proof::RingProof, Pcs>; + +pub type PiopParams = ring_proof::PiopParams, Curve>; + +pub trait Pairing: ark_ec::pairing::Pairing> {} + +#[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] +pub struct Proof +where + BaseField: ark_ff::PrimeField, +{ + pub pedersen_proof: PedersenProof, + pub ring_proof: RingProof, +} + +pub trait RingProver +where + BaseField: ark_ff::PrimeField, + Curve: SWCurveConfig, +{ + /// Generate a proof for the given input/output and user additional data. + fn prove( + &self, + input: Input, + output: Output, + ad: impl AsRef<[u8]>, + prover: &Prover, + ) -> Proof; +} + +pub trait RingVerifier +where + BaseField: ark_ff::PrimeField, + Curve: SWCurveConfig, +{ + /// Verify a proof for the given input/output and user additional data. + fn verify( + input: Input, + output: Output, + ad: impl AsRef<[u8]>, + sig: &Proof, + verifier: &Verifier, + ) -> Result<(), Error>; +} + +impl RingProver for Secret +where + BaseField: ark_ff::PrimeField, + Curve: SWCurveConfig, +{ + fn prove( + &self, + input: Input, + output: Output, + ad: impl AsRef<[u8]>, + ring_prover: &Prover, + ) -> Proof { + use crate::pedersen::PedersenProver; + let (pedersen_proof, secret_blinding) = + >::prove(self, input, output, ad); + let ring_proof = ring_prover.prove(secret_blinding); + Proof { + pedersen_proof, + ring_proof, + } + } +} + +impl RingVerifier for Public +where + BaseField: ark_ff::PrimeField, + Curve: SWCurveConfig, + AffinePoint: SwMap>, +{ + fn verify( + input: Input, + output: Output, + ad: impl AsRef<[u8]>, + sig: &Proof, + verifier: &Verifier, + ) -> Result<(), Error> { + use crate::pedersen::PedersenVerifier; + >::verify(input, output, ad, &sig.pedersen_proof)?; + let key_commitment = sig.pedersen_proof.key_commitment().to_sw(); + if !verifier.verify_ring_proof(sig.ring_proof.clone(), key_commitment) { + return Err(Error::VerificationFailure); + } + Ok(()) + } +} + +#[derive(Clone)] +pub struct RingContext +where + BaseField: ark_ff::PrimeField, + Curve: SWCurveConfig + Clone, +{ + pub pcs_params: PcsParams, + pub piop_params: PiopParams, + pub domain_size: usize, +} + +impl RingContext +where + BaseField: ark_ff::PrimeField, + Curve: SWCurveConfig + Clone, + AffinePoint: SwMap>, +{ + pub fn from_seed(domain_size: usize, seed: [u8; 32]) -> Self { + use ark_std::rand::SeedableRng; + let mut rng = rand_chacha::ChaCha20Rng::from_seed(seed); + Self::new_random(domain_size, &mut rng) + } + + pub fn new_random(domain_size: usize, rng: &mut R) -> Self { + use fflonk::pcs::PCS; + + let pcs_params = >::setup(3 * domain_size, rng); + let piop_params = make_piop_params::(domain_size); + Self { + pcs_params, + piop_params, + domain_size, + } + } + + pub fn prover_key(&self, pks: Vec>) -> ProverKey { + let pks: Vec<_> = pks.into_iter().map(|p| p.to_sw()).collect(); + ring_proof::index(self.pcs_params.clone(), &self.piop_params, pks).0 + } + + pub fn verifier_key(&self, pks: Vec>) -> VerifierKey { + let pks: Vec<_> = pks.into_iter().map(|p| p.to_sw()).collect(); + ring_proof::index(self.pcs_params.clone(), &self.piop_params, pks).1 + } + + pub fn prover(&self, prover_key: ProverKey, key_index: usize) -> Prover { + >::init( + prover_key, + self.piop_params.clone(), + key_index, + merlin::Transcript::new(b"ring-vrf"), + ) + } + + pub fn verifier(&self, verifier_key: VerifierKey) -> Verifier { + >::init( + verifier_key, + self.piop_params.clone(), + merlin::Transcript::new(b"ring-vrf"), + ) + } +} + +trait SwMap { + fn to_sw(self) -> ark_ec::short_weierstrass::Affine; +} + +impl SwMap for ark_ec::short_weierstrass::Affine { + fn to_sw(self) -> ark_ec::short_weierstrass::Affine { + self + } +} + +impl SwMap for ark_ec::twisted_edwards::Affine { + fn to_sw(self) -> ark_ec::short_weierstrass::Affine { + // println!("{:?}", self); + let res = utils::ark_next::map_te_to_sw(&self).unwrap(); + // println!("{:?}", res); + res + } +} + +fn make_piop_params(domain_size: usize) -> PiopParams +where + BaseField: ark_ff::PrimeField, + Curve: SWCurveConfig, + AffinePoint: SwMap>, +{ + let domain = ring_proof::Domain::new(domain_size, true); + PiopParams::::setup( + domain, + S::BLINDING_BASE.to_sw(), + S::COMPLEMENT_POINT.to_sw(), + ) +} diff --git a/src/suites/bandersnatch.rs b/src/suites/bandersnatch.rs index a070049..b3c5d51 100644 --- a/src/suites/bandersnatch.rs +++ b/src/suites/bandersnatch.rs @@ -113,6 +113,60 @@ pub mod weierstrass { pub type Prover = ring::Prover; pub type Verifier = ring::Verifier; pub type Proof = ring::Proof; + + impl ring2::RingSuite2 for BandersnatchSha512 { + type Pairing = ark_bls12_381::Bls12_381; + + /// A point on the curve not belonging to the prime order subgroup. + /// + /// Found using `ring_proof::find_complement_point::()` function. + const COMPLEMENT_POINT: AffinePoint = { + const X: BaseField = MontFp!("0"); + const Y: BaseField = MontFp!( + "11982629110561008531870698410380659621661946968466267969586599013782997959645" + ); + AffinePoint::new_unchecked(X, Y) + }; + } + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + fn smoke() { + type S = BandersnatchSha512; + use ring2::{RingContext, RingProver, RingVerifier}; + use testing::{random_val, random_vec, TEST_SEED}; + + let rng = &mut ark_std::test_rng(); + let domain_size = 1024; + let ring_ctx = RingContext::::new_random(domain_size, rng); + + let secret = Secret::from_seed(TEST_SEED); + let public = secret.public(); + let input = Input::from(random_val(Some(rng))); + let output = secret.output(input); + + let keyset_size = ring_ctx.piop_params.keyset_part_size; + + let prover_idx = 3; + let mut pks = random_vec::(keyset_size, Some(rng)); + pks[prover_idx] = public.0; + + let prover_key = ring_ctx.prover_key(pks.clone()); + let prover = ring_ctx.prover(prover_key, prover_idx); + let proof = secret.prove(input, output, b"foo", &prover); + let mut buf = Vec::new(); + proof.serialize_compressed(&mut buf).unwrap(); + println!("RING PROOF LEN: {}", buf.len()); + + let verifier_key = ring_ctx.verifier_key(pks); + let verifier = ring_ctx.verifier(verifier_key); + let result = Public::verify(input, output, b"foo", &proof, &verifier); + assert!(result.is_ok()); + } + } } } @@ -136,6 +190,7 @@ pub mod edwards { } impl PedersenSuite for BandersnatchSha512Edwards { + /// Found mapping the `BLINDING_BASE` of `weierstrass` module using the `utils::map_sw_to_te` const BLINDING_BASE: AffinePoint = { const X: BaseField = MontFp!( "14576224270591906826192118712803723445031237947873156025406837473427562701854" @@ -146,6 +201,68 @@ pub mod edwards { AffinePoint::new_unchecked(X, Y) }; } + + #[cfg(feature = "ring")] + pub mod ring { + use super::*; + use crate::ring2::RingSuite2; + + impl RingSuite2 for BandersnatchSha512Edwards { + type Pairing = ark_bls12_381::Bls12_381; + + /// A point on the curve not belonging to the prime order subgroup. + /// + /// Found mapping the `COMPLEMENT_POINT` of `weierstrass` module using the `utils::map_sw_to_te` + const COMPLEMENT_POINT: AffinePoint = { + const X: BaseField = MontFp!( + "3955725774225903122339172568337849452553276548604445833196164961773358506589" + ); + const Y: BaseField = MontFp!( + "29870564530691725960104983716673293929719207405660860235233811770612192692323" + ); + AffinePoint::new_unchecked(X, Y) + }; + } + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + fn smoke() { + type S = BandersnatchSha512Edwards; + use ring2::{RingContext, RingProver, RingVerifier}; + use testing::{random_val, random_vec, TEST_SEED}; + + let rng = &mut ark_std::test_rng(); + let domain_size = 1024; + let ring_ctx = RingContext::::new_random(domain_size, rng); + + let secret = Secret::from_seed(TEST_SEED); + let public = secret.public(); + let input = Input::from(random_val(Some(rng))); + let output = secret.output(input); + + let keyset_size = ring_ctx.piop_params.keyset_part_size; + + let prover_idx = 3; + let mut pks = random_vec::(keyset_size, Some(rng)); + pks[prover_idx] = public.0; + + let prover_key = ring_ctx.prover_key(pks.clone()); + let prover = ring_ctx.prover(prover_key, prover_idx); + let proof = secret.prove(input, output, b"foo", &prover); + let mut buf = Vec::new(); + proof.serialize_compressed(&mut buf).unwrap(); + println!("RING PROOF LEN: {}", buf.len()); + + let verifier_key = ring_ctx.verifier_key(pks); + let verifier = ring_ctx.verifier(verifier_key); + let result = Public::verify(input, output, b"foo", &proof, &verifier); + assert!(result.is_ok()); + } + } + } } // sage: q = 52435875175126190479447740508185965837690552500527637822603658699938581184513 From 05823a353acb2e52ef7668c20c0e2d454077dc1a Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 30 May 2024 16:23:51 +0200 Subject: [PATCH 2/6] Remove old implementation --- src/lib.rs | 2 - src/ring.rs | 131 +++++++++------------------- src/{ring2.rs => ring_old.rs} | 158 ++++++++++++++++++++++------------ src/suites/bandersnatch.rs | 122 ++++---------------------- src/testing.rs | 13 +-- 5 files changed, 166 insertions(+), 260 deletions(-) rename src/{ring2.rs => ring_old.rs} (52%) diff --git a/src/lib.rs b/src/lib.rs index e1dc963..fd53bb6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,8 +30,6 @@ pub mod utils; #[cfg(feature = "ring")] pub mod ring; -#[cfg(feature = "ring")] -pub mod ring2; #[cfg(test)] mod testing; diff --git a/src/ring.rs b/src/ring.rs index e0081d4..36be8f5 100644 --- a/src/ring.rs +++ b/src/ring.rs @@ -1,21 +1,14 @@ use crate::*; -use ark_ec::{short_weierstrass::SWCurveConfig, CurveConfig}; -use ark_serialize::{Compress, Read, SerializationError, Valid, Validate, Write}; +use ark_ec::{short_weierstrass::SWCurveConfig, AffineRepr}; use pedersen::{PedersenSuite, Proof as PedersenProof}; -// Ring proof assumes: -// 1. Points over the whole curve group (not just the prime subgroup). -// 2. Short weierstrass form. -pub trait RingSuite: - PedersenSuite> -{ - type Config: SWCurveConfig; +pub trait RingSuite: PedersenSuite { type Pairing: ark_ec::pairing::Pairing>; const COMPLEMENT_POINT: AffinePoint; } -type Curve = ::Config; +pub type Curve = <::Affine as AffineRepr>::Config; /// KZG Polynomial Commitment Scheme. type Pcs = fflonk::pcs::kzg::KZG<::Pairing>; @@ -27,7 +20,12 @@ type PcsParams = fflonk::pcs::kzg::urs::URS<::Pairing>; type PairingScalarField = <::Pairing as ark_ec::pairing::Pairing>::ScalarField; -pub type ProverKey = ring_proof::ProverKey, Pcs, AffinePoint>; +// pub type ProverKey = ring_proof::ProverKey, Pcs, AffinePoint>; +pub type ProverKey = ring_proof::ProverKey< + PairingScalarField, + Pcs, + ark_ec::short_weierstrass::Affine>, +>; pub type VerifierKey = ring_proof::VerifierKey, Pcs>; @@ -45,7 +43,7 @@ pub trait Pairing: ark_ec::pairing::Pairing where - ::BaseField: ark_ff::PrimeField, + BaseField: ark_ff::PrimeField, { pub pedersen_proof: PedersenProof, pub ring_proof: RingProof, @@ -53,8 +51,8 @@ where pub trait RingProver where + BaseField: ark_ff::PrimeField, Curve: SWCurveConfig, - as CurveConfig>::BaseField: ark_ff::PrimeField, { /// Generate a proof for the given input/output and user additional data. fn prove( @@ -68,8 +66,8 @@ where pub trait RingVerifier where + BaseField: ark_ff::PrimeField, Curve: SWCurveConfig, - as CurveConfig>::BaseField: ark_ff::PrimeField, { /// Verify a proof for the given input/output and user additional data. fn verify( @@ -83,8 +81,8 @@ where impl RingProver for Secret where + BaseField: ark_ff::PrimeField, Curve: SWCurveConfig, - as CurveConfig>::BaseField: ark_ff::PrimeField, { fn prove( &self, @@ -106,8 +104,9 @@ where impl RingVerifier for Public where + BaseField: ark_ff::PrimeField, Curve: SWCurveConfig, - as CurveConfig>::BaseField: ark_ff::PrimeField, + AffinePoint: SwMap>, { fn verify( input: Input, @@ -118,7 +117,7 @@ where ) -> Result<(), Error> { use crate::pedersen::PedersenVerifier; >::verify(input, output, ad, &sig.pedersen_proof)?; - let key_commitment = sig.pedersen_proof.key_commitment(); + let key_commitment = sig.pedersen_proof.key_commitment().to_sw(); if !verifier.verify_ring_proof(sig.ring_proof.clone(), key_commitment) { return Err(Error::VerificationFailure); } @@ -129,8 +128,8 @@ where #[derive(Clone)] pub struct RingContext where + BaseField: ark_ff::PrimeField, Curve: SWCurveConfig + Clone, - as CurveConfig>::BaseField: ark_ff::PrimeField, { pub pcs_params: PcsParams, pub piop_params: PiopParams, @@ -139,8 +138,9 @@ where impl RingContext where + BaseField: ark_ff::PrimeField, Curve: SWCurveConfig + Clone, - as CurveConfig>::BaseField: ark_ff::PrimeField, + AffinePoint: SwMap>, { pub fn from_seed(domain_size: usize, seed: [u8; 32]) -> Self { use ark_std::rand::SeedableRng; @@ -160,19 +160,13 @@ where } } - pub fn domain_size(&self) -> usize { - self.domain_size - } - - pub fn keyset_max_size(&self) -> usize { - self.piop_params.keyset_part_size - } - pub fn prover_key(&self, pks: Vec>) -> ProverKey { + let pks: Vec<_> = pks.into_iter().map(|p| p.to_sw()).collect(); ring_proof::index(self.pcs_params.clone(), &self.piop_params, pks).0 } pub fn verifier_key(&self, pks: Vec>) -> VerifierKey { + let pks: Vec<_> = pks.into_iter().map(|p| p.to_sw()).collect(); ring_proof::index(self.pcs_params.clone(), &self.piop_params, pks).1 } @@ -194,82 +188,35 @@ where } } -impl CanonicalSerialize for RingContext -where - Curve: SWCurveConfig + Clone, - as CurveConfig>::BaseField: ark_ff::PrimeField, -{ - fn serialize_with_mode( - &self, - mut writer: W, - compress: Compress, - ) -> Result<(), SerializationError> { - self.domain_size.serialize_compressed(&mut writer)?; - self.pcs_params.serialize_with_mode(&mut writer, compress)?; - Ok(()) - } +pub trait SwMap { + fn to_sw(self) -> ark_ec::short_weierstrass::Affine; +} - fn serialized_size(&self, compress: Compress) -> usize { - self.domain_size.compressed_size() + self.pcs_params.serialized_size(compress) +impl SwMap for ark_ec::short_weierstrass::Affine { + fn to_sw(self) -> ark_ec::short_weierstrass::Affine { + self } } -impl CanonicalDeserialize for RingContext -where - Curve: SWCurveConfig + Clone, - as CurveConfig>::BaseField: ark_ff::PrimeField, -{ - fn deserialize_with_mode( - mut reader: R, - compress: Compress, - validate: Validate, - ) -> Result { - let domain_size = ::deserialize_compressed(&mut reader)?; - let piop_params = make_piop_params::(domain_size); - let pcs_params = as CanonicalDeserialize>::deserialize_with_mode( - &mut reader, - compress, - validate, - )?; - Ok(RingContext { - piop_params, - pcs_params, - domain_size, - }) +impl SwMap for ark_ec::twisted_edwards::Affine { + fn to_sw(self) -> ark_ec::short_weierstrass::Affine { + // println!("{:?}", self); + let res = utils::ark_next::map_te_to_sw(&self).unwrap(); + // println!("{:?}", res); + res } } fn make_piop_params(domain_size: usize) -> PiopParams where + BaseField: ark_ff::PrimeField, Curve: SWCurveConfig, - as CurveConfig>::BaseField: ark_ff::PrimeField, + AffinePoint: SwMap>, { let domain = ring_proof::Domain::new(domain_size, true); - PiopParams::::setup(domain, S::BLINDING_BASE, S::COMPLEMENT_POINT) -} - -pub fn make_ring_verifier( - verifier_key: VerifierKey, - domain_size: usize, -) -> Verifier -where - Curve: SWCurveConfig, - as CurveConfig>::BaseField: ark_ff::PrimeField, -{ - let piop_params = make_piop_params::(domain_size); - >::init( - verifier_key, - piop_params, - merlin::Transcript::new(b"ring-vrf"), + PiopParams::::setup( + domain, + S::BLINDING_BASE.to_sw(), + S::COMPLEMENT_POINT.to_sw(), ) } - -impl Valid for RingContext -where - Curve: SWCurveConfig + Clone, - as CurveConfig>::BaseField: ark_ff::PrimeField, -{ - fn check(&self) -> Result<(), SerializationError> { - self.pcs_params.check() - } -} diff --git a/src/ring2.rs b/src/ring_old.rs similarity index 52% rename from src/ring2.rs rename to src/ring_old.rs index b40775c..e0081d4 100644 --- a/src/ring2.rs +++ b/src/ring_old.rs @@ -1,34 +1,33 @@ use crate::*; -use ark_ec::{ - short_weierstrass::SWCurveConfig, twisted_edwards::TECurveConfig, AffineRepr, CurveConfig, -}; +use ark_ec::{short_weierstrass::SWCurveConfig, CurveConfig}; +use ark_serialize::{Compress, Read, SerializationError, Valid, Validate, Write}; use pedersen::{PedersenSuite, Proof as PedersenProof}; -pub trait RingSuite2: PedersenSuite { +// Ring proof assumes: +// 1. Points over the whole curve group (not just the prime subgroup). +// 2. Short weierstrass form. +pub trait RingSuite: + PedersenSuite> +{ + type Config: SWCurveConfig; type Pairing: ark_ec::pairing::Pairing>; - // type Config: CurveConfig; const COMPLEMENT_POINT: AffinePoint; } -type Curve = <::Affine as AffineRepr>::Config; +type Curve = ::Config; /// KZG Polynomial Commitment Scheme. -type Pcs = fflonk::pcs::kzg::KZG<::Pairing>; +type Pcs = fflonk::pcs::kzg::KZG<::Pairing>; /// KZG Setup Parameters. /// /// Basically the powers of tau URS. -type PcsParams = fflonk::pcs::kzg::urs::URS<::Pairing>; +type PcsParams = fflonk::pcs::kzg::urs::URS<::Pairing>; -type PairingScalarField = <::Pairing as ark_ec::pairing::Pairing>::ScalarField; +type PairingScalarField = <::Pairing as ark_ec::pairing::Pairing>::ScalarField; -// pub type ProverKey = ring_proof::ProverKey, Pcs, AffinePoint>; -pub type ProverKey = ring_proof::ProverKey< - PairingScalarField, - Pcs, - ark_ec::short_weierstrass::Affine>, ->; +pub type ProverKey = ring_proof::ProverKey, Pcs, AffinePoint>; pub type VerifierKey = ring_proof::VerifierKey, Pcs>; @@ -41,21 +40,21 @@ pub type RingProof = ring_proof::RingProof, Pcs>; pub type PiopParams = ring_proof::PiopParams, Curve>; -pub trait Pairing: ark_ec::pairing::Pairing> {} +pub trait Pairing: ark_ec::pairing::Pairing> {} #[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] -pub struct Proof +pub struct Proof where - BaseField: ark_ff::PrimeField, + ::BaseField: ark_ff::PrimeField, { pub pedersen_proof: PedersenProof, pub ring_proof: RingProof, } -pub trait RingProver +pub trait RingProver where - BaseField: ark_ff::PrimeField, Curve: SWCurveConfig, + as CurveConfig>::BaseField: ark_ff::PrimeField, { /// Generate a proof for the given input/output and user additional data. fn prove( @@ -67,10 +66,10 @@ where ) -> Proof; } -pub trait RingVerifier +pub trait RingVerifier where - BaseField: ark_ff::PrimeField, Curve: SWCurveConfig, + as CurveConfig>::BaseField: ark_ff::PrimeField, { /// Verify a proof for the given input/output and user additional data. fn verify( @@ -82,10 +81,10 @@ where ) -> Result<(), Error>; } -impl RingProver for Secret +impl RingProver for Secret where - BaseField: ark_ff::PrimeField, Curve: SWCurveConfig, + as CurveConfig>::BaseField: ark_ff::PrimeField, { fn prove( &self, @@ -105,11 +104,10 @@ where } } -impl RingVerifier for Public +impl RingVerifier for Public where - BaseField: ark_ff::PrimeField, Curve: SWCurveConfig, - AffinePoint: SwMap>, + as CurveConfig>::BaseField: ark_ff::PrimeField, { fn verify( input: Input, @@ -120,7 +118,7 @@ where ) -> Result<(), Error> { use crate::pedersen::PedersenVerifier; >::verify(input, output, ad, &sig.pedersen_proof)?; - let key_commitment = sig.pedersen_proof.key_commitment().to_sw(); + let key_commitment = sig.pedersen_proof.key_commitment(); if !verifier.verify_ring_proof(sig.ring_proof.clone(), key_commitment) { return Err(Error::VerificationFailure); } @@ -129,21 +127,20 @@ where } #[derive(Clone)] -pub struct RingContext +pub struct RingContext where - BaseField: ark_ff::PrimeField, Curve: SWCurveConfig + Clone, + as CurveConfig>::BaseField: ark_ff::PrimeField, { pub pcs_params: PcsParams, pub piop_params: PiopParams, pub domain_size: usize, } -impl RingContext +impl RingContext where - BaseField: ark_ff::PrimeField, Curve: SWCurveConfig + Clone, - AffinePoint: SwMap>, + as CurveConfig>::BaseField: ark_ff::PrimeField, { pub fn from_seed(domain_size: usize, seed: [u8; 32]) -> Self { use ark_std::rand::SeedableRng; @@ -163,13 +160,19 @@ where } } + pub fn domain_size(&self) -> usize { + self.domain_size + } + + pub fn keyset_max_size(&self) -> usize { + self.piop_params.keyset_part_size + } + pub fn prover_key(&self, pks: Vec>) -> ProverKey { - let pks: Vec<_> = pks.into_iter().map(|p| p.to_sw()).collect(); ring_proof::index(self.pcs_params.clone(), &self.piop_params, pks).0 } pub fn verifier_key(&self, pks: Vec>) -> VerifierKey { - let pks: Vec<_> = pks.into_iter().map(|p| p.to_sw()).collect(); ring_proof::index(self.pcs_params.clone(), &self.piop_params, pks).1 } @@ -191,35 +194,82 @@ where } } -trait SwMap { - fn to_sw(self) -> ark_ec::short_weierstrass::Affine; -} +impl CanonicalSerialize for RingContext +where + Curve: SWCurveConfig + Clone, + as CurveConfig>::BaseField: ark_ff::PrimeField, +{ + fn serialize_with_mode( + &self, + mut writer: W, + compress: Compress, + ) -> Result<(), SerializationError> { + self.domain_size.serialize_compressed(&mut writer)?; + self.pcs_params.serialize_with_mode(&mut writer, compress)?; + Ok(()) + } -impl SwMap for ark_ec::short_weierstrass::Affine { - fn to_sw(self) -> ark_ec::short_weierstrass::Affine { - self + fn serialized_size(&self, compress: Compress) -> usize { + self.domain_size.compressed_size() + self.pcs_params.serialized_size(compress) } } -impl SwMap for ark_ec::twisted_edwards::Affine { - fn to_sw(self) -> ark_ec::short_weierstrass::Affine { - // println!("{:?}", self); - let res = utils::ark_next::map_te_to_sw(&self).unwrap(); - // println!("{:?}", res); - res +impl CanonicalDeserialize for RingContext +where + Curve: SWCurveConfig + Clone, + as CurveConfig>::BaseField: ark_ff::PrimeField, +{ + fn deserialize_with_mode( + mut reader: R, + compress: Compress, + validate: Validate, + ) -> Result { + let domain_size = ::deserialize_compressed(&mut reader)?; + let piop_params = make_piop_params::(domain_size); + let pcs_params = as CanonicalDeserialize>::deserialize_with_mode( + &mut reader, + compress, + validate, + )?; + Ok(RingContext { + piop_params, + pcs_params, + domain_size, + }) } } -fn make_piop_params(domain_size: usize) -> PiopParams +fn make_piop_params(domain_size: usize) -> PiopParams where - BaseField: ark_ff::PrimeField, Curve: SWCurveConfig, - AffinePoint: SwMap>, + as CurveConfig>::BaseField: ark_ff::PrimeField, { let domain = ring_proof::Domain::new(domain_size, true); - PiopParams::::setup( - domain, - S::BLINDING_BASE.to_sw(), - S::COMPLEMENT_POINT.to_sw(), + PiopParams::::setup(domain, S::BLINDING_BASE, S::COMPLEMENT_POINT) +} + +pub fn make_ring_verifier( + verifier_key: VerifierKey, + domain_size: usize, +) -> Verifier +where + Curve: SWCurveConfig, + as CurveConfig>::BaseField: ark_ff::PrimeField, +{ + let piop_params = make_piop_params::(domain_size); + >::init( + verifier_key, + piop_params, + merlin::Transcript::new(b"ring-vrf"), ) } + +impl Valid for RingContext +where + Curve: SWCurveConfig + Clone, + as CurveConfig>::BaseField: ark_ff::PrimeField, +{ + fn check(&self) -> Result<(), SerializationError> { + self.pcs_params.check() + } +} diff --git a/src/suites/bandersnatch.rs b/src/suites/bandersnatch.rs index b3c5d51..4d6978c 100644 --- a/src/suites/bandersnatch.rs +++ b/src/suites/bandersnatch.rs @@ -88,12 +88,15 @@ pub mod weierstrass { #[cfg(feature = "ring")] pub mod ring { use super::*; - use crate::ring; + use crate::ring as ring_suite; - impl ring::Pairing for ark_bls12_381::Bls12_381 {} + pub type RingContext = ring_suite::RingContext; + pub type VerifierKey = ring_suite::VerifierKey; + pub type Prover = ring_suite::Prover; + pub type Verifier = ring_suite::Verifier; + pub type Proof = ring_suite::Proof; - impl ring::RingSuite for BandersnatchSha512 { - type Config = ark_ed_on_bls12_381_bandersnatch::SWConfig; + impl ring_suite::RingSuite for BandersnatchSha512 { type Pairing = ark_bls12_381::Bls12_381; /// A point on the curve not belonging to the prime order subgroup. @@ -107,66 +110,6 @@ pub mod weierstrass { AffinePoint::new_unchecked(X, Y) }; } - - pub type RingContext = ring::RingContext; - pub type VerifierKey = ring::VerifierKey; - pub type Prover = ring::Prover; - pub type Verifier = ring::Verifier; - pub type Proof = ring::Proof; - - impl ring2::RingSuite2 for BandersnatchSha512 { - type Pairing = ark_bls12_381::Bls12_381; - - /// A point on the curve not belonging to the prime order subgroup. - /// - /// Found using `ring_proof::find_complement_point::()` function. - const COMPLEMENT_POINT: AffinePoint = { - const X: BaseField = MontFp!("0"); - const Y: BaseField = MontFp!( - "11982629110561008531870698410380659621661946968466267969586599013782997959645" - ); - AffinePoint::new_unchecked(X, Y) - }; - } - - #[cfg(test)] - mod tests { - use super::*; - - #[test] - fn smoke() { - type S = BandersnatchSha512; - use ring2::{RingContext, RingProver, RingVerifier}; - use testing::{random_val, random_vec, TEST_SEED}; - - let rng = &mut ark_std::test_rng(); - let domain_size = 1024; - let ring_ctx = RingContext::::new_random(domain_size, rng); - - let secret = Secret::from_seed(TEST_SEED); - let public = secret.public(); - let input = Input::from(random_val(Some(rng))); - let output = secret.output(input); - - let keyset_size = ring_ctx.piop_params.keyset_part_size; - - let prover_idx = 3; - let mut pks = random_vec::(keyset_size, Some(rng)); - pks[prover_idx] = public.0; - - let prover_key = ring_ctx.prover_key(pks.clone()); - let prover = ring_ctx.prover(prover_key, prover_idx); - let proof = secret.prove(input, output, b"foo", &prover); - let mut buf = Vec::new(); - proof.serialize_compressed(&mut buf).unwrap(); - println!("RING PROOF LEN: {}", buf.len()); - - let verifier_key = ring_ctx.verifier_key(pks); - let verifier = ring_ctx.verifier(verifier_key); - let result = Public::verify(input, output, b"foo", &proof, &verifier); - assert!(result.is_ok()); - } - } } } @@ -179,7 +122,7 @@ pub mod edwards { suite_types!(BandersnatchSha512Edwards); #[cfg(test)] - suite_tests!(BandersnatchSha512Edwards); + suite_tests!(BandersnatchSha512Edwards, true); impl Suite for BandersnatchSha512Edwards { const SUITE_ID: u8 = CUSTOM_SUITE_ID_FLAG | 0x04; @@ -205,9 +148,15 @@ pub mod edwards { #[cfg(feature = "ring")] pub mod ring { use super::*; - use crate::ring2::RingSuite2; + use crate::ring as ring_suite; - impl RingSuite2 for BandersnatchSha512Edwards { + pub type RingContext = ring_suite::RingContext; + pub type VerifierKey = ring_suite::VerifierKey; + pub type Prover = ring_suite::Prover; + pub type Verifier = ring_suite::Verifier; + pub type Proof = ring_suite::Proof; + + impl ring_suite::RingSuite for BandersnatchSha512Edwards { type Pairing = ark_bls12_381::Bls12_381; /// A point on the curve not belonging to the prime order subgroup. @@ -223,45 +172,6 @@ pub mod edwards { AffinePoint::new_unchecked(X, Y) }; } - - #[cfg(test)] - mod tests { - use super::*; - - #[test] - fn smoke() { - type S = BandersnatchSha512Edwards; - use ring2::{RingContext, RingProver, RingVerifier}; - use testing::{random_val, random_vec, TEST_SEED}; - - let rng = &mut ark_std::test_rng(); - let domain_size = 1024; - let ring_ctx = RingContext::::new_random(domain_size, rng); - - let secret = Secret::from_seed(TEST_SEED); - let public = secret.public(); - let input = Input::from(random_val(Some(rng))); - let output = secret.output(input); - - let keyset_size = ring_ctx.piop_params.keyset_part_size; - - let prover_idx = 3; - let mut pks = random_vec::(keyset_size, Some(rng)); - pks[prover_idx] = public.0; - - let prover_key = ring_ctx.prover_key(pks.clone()); - let prover = ring_ctx.prover(prover_key, prover_idx); - let proof = secret.prove(input, output, b"foo", &prover); - let mut buf = Vec::new(); - proof.serialize_compressed(&mut buf).unwrap(); - println!("RING PROOF LEN: {}", buf.len()); - - let verifier_key = ring_ctx.verifier_key(pks); - let verifier = ring_ctx.verifier(verifier_key); - let result = Public::verify(input, output, b"foo", &proof, &verifier); - assert!(result.is_ok()); - } - } } } diff --git a/src/testing.rs b/src/testing.rs index 9e5ab82..8cd3312 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -69,8 +69,9 @@ pub fn pedersen_prove_verify() { #[cfg(feature = "ring")] pub fn ring_prove_verify() where - S::Config: ark_ec::short_weierstrass::SWCurveConfig + Clone, - ::BaseField: ark_ff::PrimeField, + BaseField: ark_ff::PrimeField, + crate::ring::Curve: ark_ec::short_weierstrass::SWCurveConfig + Clone, + AffinePoint: crate::ring::SwMap>, { use crate::ring::{RingContext, RingProver, RingVerifier}; @@ -106,7 +107,7 @@ where macro_rules! suite_tests { ($suite:ident, $build_ring:ident) => { suite_tests!($suite); - ring_suite_tests!($build_ring); + ring_suite_tests!($suite, $build_ring); }; ($suite:ident) => { #[test] @@ -123,12 +124,12 @@ macro_rules! suite_tests { #[macro_export] macro_rules! ring_suite_tests { - (true) => { + ($suite:ident, true) => { #[cfg(feature = "ring")] #[test] fn ring_prove_verify() { - $crate::testing::ring_prove_verify::() + $crate::testing::ring_prove_verify::<$suite>() } }; - (false) => {}; + ($suite:ident, false) => {}; } From e1f1a61b5e7c4a655bd70944adebbd1bac634dbd Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 30 May 2024 17:17:27 +0200 Subject: [PATCH 3/6] Some cleanup --- src/ietf.rs | 8 ++-- src/lib.rs | 1 + src/pedersen.rs | 8 ++-- src/ring.rs | 90 ++++++++++++++++++-------------------- src/suites/bandersnatch.rs | 28 +++++++----- src/testing.rs | 16 +++---- 6 files changed, 76 insertions(+), 75 deletions(-) diff --git a/src/ietf.rs b/src/ietf.rs index a91e2fc..e7b0adc 100644 --- a/src/ietf.rs +++ b/src/ietf.rs @@ -69,12 +69,12 @@ impl ark_serialize::Valid for Proof { } } -pub trait IetfProver { +pub trait Prover { /// Generate a proof for the given input/output and user additional data. fn prove(&self, input: Input, output: Output, ad: impl AsRef<[u8]>) -> Proof; } -pub trait IetfVerifier { +pub trait Verifier { /// Verify a proof for the given input/output and user additional data. fn verify( &self, @@ -85,7 +85,7 @@ pub trait IetfVerifier { ) -> Result<(), Error>; } -impl IetfProver for Secret { +impl Prover for Secret { fn prove(&self, input: Input, output: Output, ad: impl AsRef<[u8]>) -> Proof { let k = S::nonce(&self.scalar, input); let k_b = (S::Affine::generator() * k).into_affine(); @@ -101,7 +101,7 @@ impl IetfProver for Secret { } } -impl IetfVerifier for Public { +impl Verifier for Public { fn verify( &self, input: Input, diff --git a/src/lib.rs b/src/lib.rs index fd53bb6..7bf1bda 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,6 +45,7 @@ pub type AffinePoint = ::Affine; pub type BaseField = as AffineRepr>::BaseField; pub type ScalarField = as AffineRepr>::ScalarField; +pub type CurveConfig = as AffineRepr>::Config; pub type HashOutput = digest::Output<::Hasher>; diff --git a/src/pedersen.rs b/src/pedersen.rs index fc11f9e..7bc6d86 100644 --- a/src/pedersen.rs +++ b/src/pedersen.rs @@ -20,7 +20,7 @@ impl Proof { } } -pub trait PedersenProver { +pub trait Prover { /// Generate a proof for the given input/output and user additional data. /// /// Returns the proof together with the associated blinding factor. @@ -32,7 +32,7 @@ pub trait PedersenProver { ) -> (Proof, ScalarField); } -pub trait PedersenVerifier { +pub trait Verifier { /// Verify a proof for the given input/output and user additional data. fn verify( input: Input, @@ -42,7 +42,7 @@ pub trait PedersenVerifier { ) -> Result<(), Error>; } -impl PedersenProver for Secret { +impl Prover for Secret { fn prove( &self, input: Input, @@ -81,7 +81,7 @@ impl PedersenProver for Secret { } } -impl PedersenVerifier for Public { +impl Verifier for Public { fn verify( input: Input, output: Output, diff --git a/src/ring.rs b/src/ring.rs index 36be8f5..66a4ad7 100644 --- a/src/ring.rs +++ b/src/ring.rs @@ -1,5 +1,5 @@ use crate::*; -use ark_ec::{short_weierstrass::SWCurveConfig, AffineRepr}; +use ark_ec::short_weierstrass::SWCurveConfig; use pedersen::{PedersenSuite, Proof as PedersenProof}; pub trait RingSuite: PedersenSuite { @@ -8,8 +8,6 @@ pub trait RingSuite: PedersenSuite { const COMPLEMENT_POINT: AffinePoint; } -pub type Curve = <::Affine as AffineRepr>::Config; - /// KZG Polynomial Commitment Scheme. type Pcs = fflonk::pcs::kzg::KZG<::Pairing>; @@ -20,25 +18,23 @@ type PcsParams = fflonk::pcs::kzg::urs::URS<::Pairing>; type PairingScalarField = <::Pairing as ark_ec::pairing::Pairing>::ScalarField; -// pub type ProverKey = ring_proof::ProverKey, Pcs, AffinePoint>; pub type ProverKey = ring_proof::ProverKey< PairingScalarField, Pcs, - ark_ec::short_weierstrass::Affine>, + ark_ec::short_weierstrass::Affine>, >; pub type VerifierKey = ring_proof::VerifierKey, Pcs>; -pub type Prover = ring_proof::ring_prover::RingProver, Pcs, Curve>; +pub type RingProver = + ring_proof::ring_prover::RingProver, Pcs, CurveConfig>; -pub type Verifier = - ring_proof::ring_verifier::RingVerifier, Pcs, Curve>; +pub type RingVerifier = + ring_proof::ring_verifier::RingVerifier, Pcs, CurveConfig>; pub type RingProof = ring_proof::RingProof, Pcs>; -pub type PiopParams = ring_proof::PiopParams, Curve>; - -pub trait Pairing: ark_ec::pairing::Pairing> {} +pub type PiopParams = ring_proof::PiopParams, CurveConfig>; #[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] pub struct Proof @@ -49,10 +45,10 @@ where pub ring_proof: RingProof, } -pub trait RingProver +pub trait Prover where BaseField: ark_ff::PrimeField, - Curve: SWCurveConfig, + CurveConfig: SWCurveConfig, { /// Generate a proof for the given input/output and user additional data. fn prove( @@ -60,38 +56,23 @@ where input: Input, output: Output, ad: impl AsRef<[u8]>, - prover: &Prover, + prover: &RingProver, ) -> Proof; } -pub trait RingVerifier -where - BaseField: ark_ff::PrimeField, - Curve: SWCurveConfig, -{ - /// Verify a proof for the given input/output and user additional data. - fn verify( - input: Input, - output: Output, - ad: impl AsRef<[u8]>, - sig: &Proof, - verifier: &Verifier, - ) -> Result<(), Error>; -} - -impl RingProver for Secret +impl Prover for Secret where BaseField: ark_ff::PrimeField, - Curve: SWCurveConfig, + CurveConfig: SWCurveConfig, { fn prove( &self, input: Input, output: Output, ad: impl AsRef<[u8]>, - ring_prover: &Prover, + ring_prover: &RingProver, ) -> Proof { - use crate::pedersen::PedersenProver; + use pedersen::Prover as PedersenProver; let (pedersen_proof, secret_blinding) = >::prove(self, input, output, ad); let ring_proof = ring_prover.prove(secret_blinding); @@ -102,20 +83,35 @@ where } } -impl RingVerifier for Public +pub trait Verifier +where + BaseField: ark_ff::PrimeField, + CurveConfig: SWCurveConfig, +{ + /// Verify a proof for the given input/output and user additional data. + fn verify( + input: Input, + output: Output, + ad: impl AsRef<[u8]>, + sig: &Proof, + verifier: &RingVerifier, + ) -> Result<(), Error>; +} + +impl Verifier for Public where BaseField: ark_ff::PrimeField, - Curve: SWCurveConfig, - AffinePoint: SwMap>, + CurveConfig: SWCurveConfig, + AffinePoint: SwMap>, { fn verify( input: Input, output: Output, ad: impl AsRef<[u8]>, sig: &Proof, - verifier: &Verifier, + verifier: &RingVerifier, ) -> Result<(), Error> { - use crate::pedersen::PedersenVerifier; + use pedersen::Verifier as PedersenVerifier; >::verify(input, output, ad, &sig.pedersen_proof)?; let key_commitment = sig.pedersen_proof.key_commitment().to_sw(); if !verifier.verify_ring_proof(sig.ring_proof.clone(), key_commitment) { @@ -129,7 +125,7 @@ where pub struct RingContext where BaseField: ark_ff::PrimeField, - Curve: SWCurveConfig + Clone, + CurveConfig: SWCurveConfig + Clone, { pub pcs_params: PcsParams, pub piop_params: PiopParams, @@ -139,8 +135,8 @@ where impl RingContext where BaseField: ark_ff::PrimeField, - Curve: SWCurveConfig + Clone, - AffinePoint: SwMap>, + CurveConfig: SWCurveConfig + Clone, + AffinePoint: SwMap>, { pub fn from_seed(domain_size: usize, seed: [u8; 32]) -> Self { use ark_std::rand::SeedableRng; @@ -170,8 +166,8 @@ where ring_proof::index(self.pcs_params.clone(), &self.piop_params, pks).1 } - pub fn prover(&self, prover_key: ProverKey, key_index: usize) -> Prover { - >::init( + pub fn prover(&self, prover_key: ProverKey, key_index: usize) -> RingProver { + RingProver::::init( prover_key, self.piop_params.clone(), key_index, @@ -179,8 +175,8 @@ where ) } - pub fn verifier(&self, verifier_key: VerifierKey) -> Verifier { - >::init( + pub fn verifier(&self, verifier_key: VerifierKey) -> RingVerifier { + RingVerifier::::init( verifier_key, self.piop_params.clone(), merlin::Transcript::new(b"ring-vrf"), @@ -210,8 +206,8 @@ impl SwMap for ark_ec::twisted_edwards::Affine fn make_piop_params(domain_size: usize) -> PiopParams where BaseField: ark_ff::PrimeField, - Curve: SWCurveConfig, - AffinePoint: SwMap>, + CurveConfig: SWCurveConfig, + AffinePoint: SwMap>, { let domain = ring_proof::Domain::new(domain_size, true); PiopParams::::setup( diff --git a/src/suites/bandersnatch.rs b/src/suites/bandersnatch.rs index 4d6978c..6873c1c 100644 --- a/src/suites/bandersnatch.rs +++ b/src/suites/bandersnatch.rs @@ -62,9 +62,6 @@ pub mod weierstrass { suite_types!(BandersnatchSha512); - #[cfg(test)] - suite_tests!(BandersnatchSha512, true); - impl Suite for BandersnatchSha512 { const SUITE_ID: u8 = CUSTOM_SUITE_ID_FLAG | 0x03; const CHALLENGE_LEN: usize = 32; @@ -86,14 +83,14 @@ pub mod weierstrass { } #[cfg(feature = "ring")] - pub mod ring { + mod ring_defs { use super::*; use crate::ring as ring_suite; pub type RingContext = ring_suite::RingContext; pub type VerifierKey = ring_suite::VerifierKey; - pub type Prover = ring_suite::Prover; - pub type Verifier = ring_suite::Verifier; + pub type RingProver = ring_suite::RingProver; + pub type RingVerifier = ring_suite::RingVerifier; pub type Proof = ring_suite::Proof; impl ring_suite::RingSuite for BandersnatchSha512 { @@ -111,6 +108,11 @@ pub mod weierstrass { }; } } + #[cfg(feature = "ring")] + pub use ring_defs::*; + + #[cfg(test)] + suite_tests!(BandersnatchSha512, true); } pub mod edwards { @@ -121,9 +123,6 @@ pub mod edwards { suite_types!(BandersnatchSha512Edwards); - #[cfg(test)] - suite_tests!(BandersnatchSha512Edwards, true); - impl Suite for BandersnatchSha512Edwards { const SUITE_ID: u8 = CUSTOM_SUITE_ID_FLAG | 0x04; const CHALLENGE_LEN: usize = 32; @@ -146,14 +145,14 @@ pub mod edwards { } #[cfg(feature = "ring")] - pub mod ring { + mod ring_defs { use super::*; use crate::ring as ring_suite; pub type RingContext = ring_suite::RingContext; pub type VerifierKey = ring_suite::VerifierKey; - pub type Prover = ring_suite::Prover; - pub type Verifier = ring_suite::Verifier; + pub type RingProver = ring_suite::RingProver; + pub type RingVerifier = ring_suite::RingVerifier; pub type Proof = ring_suite::Proof; impl ring_suite::RingSuite for BandersnatchSha512Edwards { @@ -173,6 +172,11 @@ pub mod edwards { }; } } + #[cfg(feature = "ring")] + pub use ring_defs::*; + + #[cfg(test)] + suite_tests!(BandersnatchSha512Edwards, true); } // sage: q = 52435875175126190479447740508185965837690552500527637822603658699938581184513 diff --git a/src/testing.rs b/src/testing.rs index 8cd3312..ad980d6 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -36,8 +36,8 @@ pub fn random_val(rng: Option<&mut dyn RngCore>) -> T { T::rand(rng) } -pub fn ietf_prove_verify() { - use crate::ietf::{IetfProver, IetfVerifier}; +pub fn ietf_prove_verify() { + use ietf::{Prover, Verifier}; let secret = Secret::::from_seed(TEST_SEED); let public = secret.public(); @@ -49,8 +49,8 @@ pub fn ietf_prove_verify() { assert!(result.is_ok()); } -pub fn pedersen_prove_verify() { - use crate::pedersen::{PedersenProver, PedersenVerifier}; +pub fn pedersen_prove_verify() { + use pedersen::{Prover, Verifier}; let secret = Secret::::from_seed(TEST_SEED); let input = Input::from(random_val(None)); @@ -67,13 +67,13 @@ pub fn pedersen_prove_verify() { } #[cfg(feature = "ring")] -pub fn ring_prove_verify() +pub fn ring_prove_verify() where BaseField: ark_ff::PrimeField, - crate::ring::Curve: ark_ec::short_weierstrass::SWCurveConfig + Clone, - AffinePoint: crate::ring::SwMap>, + CurveConfig: ark_ec::short_weierstrass::SWCurveConfig + Clone, + AffinePoint: ring::SwMap>, { - use crate::ring::{RingContext, RingProver, RingVerifier}; + use ring::{Prover, RingContext, Verifier}; let rng = &mut ark_std::test_rng(); let domain_size = 1024; From e9aa4220b90f9bbc09050f9fe9345f8e4c9f7489 Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 30 May 2024 17:44:31 +0200 Subject: [PATCH 4/6] Remove old implementation --- src/ring_old.rs | 275 ------------------------------------------------ 1 file changed, 275 deletions(-) delete mode 100644 src/ring_old.rs diff --git a/src/ring_old.rs b/src/ring_old.rs deleted file mode 100644 index e0081d4..0000000 --- a/src/ring_old.rs +++ /dev/null @@ -1,275 +0,0 @@ -use crate::*; -use ark_ec::{short_weierstrass::SWCurveConfig, CurveConfig}; -use ark_serialize::{Compress, Read, SerializationError, Valid, Validate, Write}; -use pedersen::{PedersenSuite, Proof as PedersenProof}; - -// Ring proof assumes: -// 1. Points over the whole curve group (not just the prime subgroup). -// 2. Short weierstrass form. -pub trait RingSuite: - PedersenSuite> -{ - type Config: SWCurveConfig; - type Pairing: ark_ec::pairing::Pairing>; - - const COMPLEMENT_POINT: AffinePoint; -} - -type Curve = ::Config; - -/// KZG Polynomial Commitment Scheme. -type Pcs = fflonk::pcs::kzg::KZG<::Pairing>; - -/// KZG Setup Parameters. -/// -/// Basically the powers of tau URS. -type PcsParams = fflonk::pcs::kzg::urs::URS<::Pairing>; - -type PairingScalarField = <::Pairing as ark_ec::pairing::Pairing>::ScalarField; - -pub type ProverKey = ring_proof::ProverKey, Pcs, AffinePoint>; - -pub type VerifierKey = ring_proof::VerifierKey, Pcs>; - -pub type Prover = ring_proof::ring_prover::RingProver, Pcs, Curve>; - -pub type Verifier = - ring_proof::ring_verifier::RingVerifier, Pcs, Curve>; - -pub type RingProof = ring_proof::RingProof, Pcs>; - -pub type PiopParams = ring_proof::PiopParams, Curve>; - -pub trait Pairing: ark_ec::pairing::Pairing> {} - -#[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] -pub struct Proof -where - ::BaseField: ark_ff::PrimeField, -{ - pub pedersen_proof: PedersenProof, - pub ring_proof: RingProof, -} - -pub trait RingProver -where - Curve: SWCurveConfig, - as CurveConfig>::BaseField: ark_ff::PrimeField, -{ - /// Generate a proof for the given input/output and user additional data. - fn prove( - &self, - input: Input, - output: Output, - ad: impl AsRef<[u8]>, - prover: &Prover, - ) -> Proof; -} - -pub trait RingVerifier -where - Curve: SWCurveConfig, - as CurveConfig>::BaseField: ark_ff::PrimeField, -{ - /// Verify a proof for the given input/output and user additional data. - fn verify( - input: Input, - output: Output, - ad: impl AsRef<[u8]>, - sig: &Proof, - verifier: &Verifier, - ) -> Result<(), Error>; -} - -impl RingProver for Secret -where - Curve: SWCurveConfig, - as CurveConfig>::BaseField: ark_ff::PrimeField, -{ - fn prove( - &self, - input: Input, - output: Output, - ad: impl AsRef<[u8]>, - ring_prover: &Prover, - ) -> Proof { - use crate::pedersen::PedersenProver; - let (pedersen_proof, secret_blinding) = - >::prove(self, input, output, ad); - let ring_proof = ring_prover.prove(secret_blinding); - Proof { - pedersen_proof, - ring_proof, - } - } -} - -impl RingVerifier for Public -where - Curve: SWCurveConfig, - as CurveConfig>::BaseField: ark_ff::PrimeField, -{ - fn verify( - input: Input, - output: Output, - ad: impl AsRef<[u8]>, - sig: &Proof, - verifier: &Verifier, - ) -> Result<(), Error> { - use crate::pedersen::PedersenVerifier; - >::verify(input, output, ad, &sig.pedersen_proof)?; - let key_commitment = sig.pedersen_proof.key_commitment(); - if !verifier.verify_ring_proof(sig.ring_proof.clone(), key_commitment) { - return Err(Error::VerificationFailure); - } - Ok(()) - } -} - -#[derive(Clone)] -pub struct RingContext -where - Curve: SWCurveConfig + Clone, - as CurveConfig>::BaseField: ark_ff::PrimeField, -{ - pub pcs_params: PcsParams, - pub piop_params: PiopParams, - pub domain_size: usize, -} - -impl RingContext -where - Curve: SWCurveConfig + Clone, - as CurveConfig>::BaseField: ark_ff::PrimeField, -{ - pub fn from_seed(domain_size: usize, seed: [u8; 32]) -> Self { - use ark_std::rand::SeedableRng; - let mut rng = rand_chacha::ChaCha20Rng::from_seed(seed); - Self::new_random(domain_size, &mut rng) - } - - pub fn new_random(domain_size: usize, rng: &mut R) -> Self { - use fflonk::pcs::PCS; - - let pcs_params = >::setup(3 * domain_size, rng); - let piop_params = make_piop_params::(domain_size); - Self { - pcs_params, - piop_params, - domain_size, - } - } - - pub fn domain_size(&self) -> usize { - self.domain_size - } - - pub fn keyset_max_size(&self) -> usize { - self.piop_params.keyset_part_size - } - - pub fn prover_key(&self, pks: Vec>) -> ProverKey { - ring_proof::index(self.pcs_params.clone(), &self.piop_params, pks).0 - } - - pub fn verifier_key(&self, pks: Vec>) -> VerifierKey { - ring_proof::index(self.pcs_params.clone(), &self.piop_params, pks).1 - } - - pub fn prover(&self, prover_key: ProverKey, key_index: usize) -> Prover { - >::init( - prover_key, - self.piop_params.clone(), - key_index, - merlin::Transcript::new(b"ring-vrf"), - ) - } - - pub fn verifier(&self, verifier_key: VerifierKey) -> Verifier { - >::init( - verifier_key, - self.piop_params.clone(), - merlin::Transcript::new(b"ring-vrf"), - ) - } -} - -impl CanonicalSerialize for RingContext -where - Curve: SWCurveConfig + Clone, - as CurveConfig>::BaseField: ark_ff::PrimeField, -{ - fn serialize_with_mode( - &self, - mut writer: W, - compress: Compress, - ) -> Result<(), SerializationError> { - self.domain_size.serialize_compressed(&mut writer)?; - self.pcs_params.serialize_with_mode(&mut writer, compress)?; - Ok(()) - } - - fn serialized_size(&self, compress: Compress) -> usize { - self.domain_size.compressed_size() + self.pcs_params.serialized_size(compress) - } -} - -impl CanonicalDeserialize for RingContext -where - Curve: SWCurveConfig + Clone, - as CurveConfig>::BaseField: ark_ff::PrimeField, -{ - fn deserialize_with_mode( - mut reader: R, - compress: Compress, - validate: Validate, - ) -> Result { - let domain_size = ::deserialize_compressed(&mut reader)?; - let piop_params = make_piop_params::(domain_size); - let pcs_params = as CanonicalDeserialize>::deserialize_with_mode( - &mut reader, - compress, - validate, - )?; - Ok(RingContext { - piop_params, - pcs_params, - domain_size, - }) - } -} - -fn make_piop_params(domain_size: usize) -> PiopParams -where - Curve: SWCurveConfig, - as CurveConfig>::BaseField: ark_ff::PrimeField, -{ - let domain = ring_proof::Domain::new(domain_size, true); - PiopParams::::setup(domain, S::BLINDING_BASE, S::COMPLEMENT_POINT) -} - -pub fn make_ring_verifier( - verifier_key: VerifierKey, - domain_size: usize, -) -> Verifier -where - Curve: SWCurveConfig, - as CurveConfig>::BaseField: ark_ff::PrimeField, -{ - let piop_params = make_piop_params::(domain_size); - >::init( - verifier_key, - piop_params, - merlin::Transcript::new(b"ring-vrf"), - ) -} - -impl Valid for RingContext -where - Curve: SWCurveConfig + Clone, - as CurveConfig>::BaseField: ark_ff::PrimeField, -{ - fn check(&self) -> Result<(), SerializationError> { - self.pcs_params.check() - } -} From bcdcd0f3f7e6823395471a8eea0396648922498d Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 30 May 2024 18:31:16 +0200 Subject: [PATCH 5/6] Nits --- src/ring.rs | 43 +++++++++++++++++++++++++------------------ src/testing.rs | 2 +- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/ring.rs b/src/ring.rs index 66a4ad7..7b8ee55 100644 --- a/src/ring.rs +++ b/src/ring.rs @@ -102,7 +102,7 @@ impl Verifier for Public where BaseField: ark_ff::PrimeField, CurveConfig: SWCurveConfig, - AffinePoint: SwMap>, + AffinePoint: IntoSW>, { fn verify( input: Input, @@ -113,7 +113,7 @@ where ) -> Result<(), Error> { use pedersen::Verifier as PedersenVerifier; >::verify(input, output, ad, &sig.pedersen_proof)?; - let key_commitment = sig.pedersen_proof.key_commitment().to_sw(); + let key_commitment = sig.pedersen_proof.key_commitment().into_sw(); if !verifier.verify_ring_proof(sig.ring_proof.clone(), key_commitment) { return Err(Error::VerificationFailure); } @@ -136,7 +136,7 @@ impl RingContext where BaseField: ark_ff::PrimeField, CurveConfig: SWCurveConfig + Clone, - AffinePoint: SwMap>, + AffinePoint: IntoSW>, { pub fn from_seed(domain_size: usize, seed: [u8; 32]) -> Self { use ark_std::rand::SeedableRng; @@ -156,13 +156,21 @@ where } } + pub fn domain_size(&self) -> usize { + self.domain_size + } + + pub fn keyset_max_size(&self) -> usize { + self.piop_params.keyset_part_size + } + pub fn prover_key(&self, pks: Vec>) -> ProverKey { - let pks: Vec<_> = pks.into_iter().map(|p| p.to_sw()).collect(); + let pks = pks.iter().map(|p| p.into_sw()).collect(); ring_proof::index(self.pcs_params.clone(), &self.piop_params, pks).0 } pub fn verifier_key(&self, pks: Vec>) -> VerifierKey { - let pks: Vec<_> = pks.into_iter().map(|p| p.to_sw()).collect(); + let pks: Vec<_> = pks.iter().map(|p| p.into_sw()).collect(); ring_proof::index(self.pcs_params.clone(), &self.piop_params, pks).1 } @@ -184,22 +192,21 @@ where } } -pub trait SwMap { - fn to_sw(self) -> ark_ec::short_weierstrass::Affine; +pub trait IntoSW { + fn into_sw(self) -> ark_ec::short_weierstrass::Affine; } -impl SwMap for ark_ec::short_weierstrass::Affine { - fn to_sw(self) -> ark_ec::short_weierstrass::Affine { +impl IntoSW for ark_ec::short_weierstrass::Affine { + fn into_sw(self) -> ark_ec::short_weierstrass::Affine { self } } -impl SwMap for ark_ec::twisted_edwards::Affine { - fn to_sw(self) -> ark_ec::short_weierstrass::Affine { - // println!("{:?}", self); - let res = utils::ark_next::map_te_to_sw(&self).unwrap(); - // println!("{:?}", res); - res +impl IntoSW for ark_ec::twisted_edwards::Affine { + fn into_sw(self) -> ark_ec::short_weierstrass::Affine { + const ERR_MSG: &str = + "'IntoSW' is expected to be implemented only for curves supporting the mapping"; + utils::ark_next::map_te_to_sw(&self).expect(ERR_MSG) } } @@ -207,12 +214,12 @@ fn make_piop_params(domain_size: usize) -> PiopParams where BaseField: ark_ff::PrimeField, CurveConfig: SWCurveConfig, - AffinePoint: SwMap>, + AffinePoint: IntoSW>, { let domain = ring_proof::Domain::new(domain_size, true); PiopParams::::setup( domain, - S::BLINDING_BASE.to_sw(), - S::COMPLEMENT_POINT.to_sw(), + S::BLINDING_BASE.into_sw(), + S::COMPLEMENT_POINT.into_sw(), ) } diff --git a/src/testing.rs b/src/testing.rs index ad980d6..b5cd58a 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -71,7 +71,7 @@ pub fn ring_prove_verify() where BaseField: ark_ff::PrimeField, CurveConfig: ark_ec::short_weierstrass::SWCurveConfig + Clone, - AffinePoint: ring::SwMap>, + AffinePoint: ring::IntoSW>, { use ring::{Prover, RingContext, Verifier}; From c4d99a5768fef46fd1c903e5fd1b680d6fc8ce8c Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 30 May 2024 19:14:04 +0200 Subject: [PATCH 6/6] More nits --- src/lib.rs | 1 + src/ring.rs | 4 ++-- src/testing.rs | 7 ++----- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7bf1bda..4309d98 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,6 +50,7 @@ pub type CurveConfig = as AffineRepr>::Config; pub type HashOutput = digest::Output<::Hasher>; /// Verification error(s) +#[derive(Debug)] pub enum Error { VerificationFailure, } diff --git a/src/ring.rs b/src/ring.rs index 7b8ee55..c5bdd2b 100644 --- a/src/ring.rs +++ b/src/ring.rs @@ -164,12 +164,12 @@ where self.piop_params.keyset_part_size } - pub fn prover_key(&self, pks: Vec>) -> ProverKey { + pub fn prover_key(&self, pks: &[AffinePoint]) -> ProverKey { let pks = pks.iter().map(|p| p.into_sw()).collect(); ring_proof::index(self.pcs_params.clone(), &self.piop_params, pks).0 } - pub fn verifier_key(&self, pks: Vec>) -> VerifierKey { + pub fn verifier_key(&self, pks: &[AffinePoint]) -> VerifierKey { let pks: Vec<_> = pks.iter().map(|p| p.into_sw()).collect(); ring_proof::index(self.pcs_params.clone(), &self.piop_params, pks).1 } diff --git a/src/testing.rs b/src/testing.rs index b5cd58a..756d588 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -90,14 +90,11 @@ where let mut pks = random_vec::>(keyset_size, Some(rng)); pks[prover_idx] = public.0; - let prover_key = ring_ctx.prover_key(pks.clone()); + let prover_key = ring_ctx.prover_key(&pks); let prover = ring_ctx.prover(prover_key, prover_idx); let proof = secret.prove(input, output, b"foo", &prover); - let mut buf = Vec::new(); - proof.serialize_compressed(&mut buf).unwrap(); - println!("RING PROOF LEN: {}", buf.len()); - let verifier_key = ring_ctx.verifier_key(pks); + let verifier_key = ring_ctx.verifier_key(&pks); let verifier = ring_ctx.verifier(verifier_key); let result = Public::verify(input, output, b"foo", &proof, &verifier); assert!(result.is_ok());