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 feb6946..4309d98 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,13 +41,16 @@ 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 CurveConfig = as AffineRepr>::Config; + pub type HashOutput = digest::Output<::Hasher>; /// Verification error(s) +#[derive(Debug)] pub enum Error { VerificationFailure, } 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 e0081d4..c5bdd2b 100644 --- a/src/ring.rs +++ b/src/ring.rs @@ -1,22 +1,13 @@ use crate::*; -use ark_ec::{short_weierstrass::SWCurveConfig, CurveConfig}; -use ark_serialize::{Compress, Read, SerializationError, Valid, Validate, Write}; +use ark_ec::short_weierstrass::SWCurveConfig; 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; - /// KZG Polynomial Commitment Scheme. type Pcs = fflonk::pcs::kzg::KZG<::Pairing>; @@ -27,34 +18,37 @@ 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 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 where - ::BaseField: ark_ff::PrimeField, + BaseField: ark_ff::PrimeField, { pub pedersen_proof: PedersenProof, pub ring_proof: RingProof, } -pub trait RingProver +pub trait Prover where - Curve: SWCurveConfig, - as CurveConfig>::BaseField: ark_ff::PrimeField, + BaseField: ark_ff::PrimeField, + CurveConfig: SWCurveConfig, { /// Generate a proof for the given input/output and user additional data. fn prove( @@ -62,38 +56,23 @@ where input: Input, output: Output, ad: impl AsRef<[u8]>, - prover: &Prover, + prover: &RingProver, ) -> Proof; } -pub trait RingVerifier +impl Prover for Secret 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, + BaseField: ark_ff::PrimeField, + 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); @@ -104,21 +83,37 @@ 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 - Curve: SWCurveConfig, - as CurveConfig>::BaseField: ark_ff::PrimeField, + BaseField: ark_ff::PrimeField, + CurveConfig: SWCurveConfig, + AffinePoint: IntoSW>, { 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(); + 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); } @@ -129,8 +124,8 @@ where #[derive(Clone)] pub struct RingContext where - Curve: SWCurveConfig + Clone, - as CurveConfig>::BaseField: ark_ff::PrimeField, + BaseField: ark_ff::PrimeField, + CurveConfig: SWCurveConfig + Clone, { pub pcs_params: PcsParams, pub piop_params: PiopParams, @@ -139,8 +134,9 @@ where impl RingContext where - Curve: SWCurveConfig + Clone, - as CurveConfig>::BaseField: ark_ff::PrimeField, + BaseField: ark_ff::PrimeField, + CurveConfig: SWCurveConfig + Clone, + AffinePoint: IntoSW>, { pub fn from_seed(domain_size: usize, seed: [u8; 32]) -> Self { use ark_std::rand::SeedableRng; @@ -168,16 +164,18 @@ 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 } - 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, @@ -185,8 +183,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"), @@ -194,82 +192,34 @@ 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 IntoSW { + fn into_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 IntoSW for ark_ec::short_weierstrass::Affine { + fn into_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 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) } } fn make_piop_params(domain_size: usize) -> PiopParams where - Curve: SWCurveConfig, - as CurveConfig>::BaseField: ark_ff::PrimeField, + BaseField: ark_ff::PrimeField, + CurveConfig: SWCurveConfig, + AffinePoint: IntoSW>, { 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.into_sw(), + S::COMPLEMENT_POINT.into_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/suites/bandersnatch.rs b/src/suites/bandersnatch.rs index a070049..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,17 @@ pub mod weierstrass { } #[cfg(feature = "ring")] - pub mod ring { + mod ring_defs { 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 RingProver = ring_suite::RingProver; + pub type RingVerifier = ring_suite::RingVerifier; + 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,13 +107,12 @@ 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; } + #[cfg(feature = "ring")] + pub use ring_defs::*; + + #[cfg(test)] + suite_tests!(BandersnatchSha512, true); } pub mod edwards { @@ -124,9 +123,6 @@ pub mod edwards { suite_types!(BandersnatchSha512Edwards); - #[cfg(test)] - suite_tests!(BandersnatchSha512Edwards); - impl Suite for BandersnatchSha512Edwards { const SUITE_ID: u8 = CUSTOM_SUITE_ID_FLAG | 0x04; const CHALLENGE_LEN: usize = 32; @@ -136,6 +132,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 +143,40 @@ pub mod edwards { AffinePoint::new_unchecked(X, Y) }; } + + #[cfg(feature = "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 RingProver = ring_suite::RingProver; + pub type RingVerifier = ring_suite::RingVerifier; + 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. + /// + /// 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(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 9e5ab82..756d588 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,12 +67,13 @@ pub fn pedersen_prove_verify() { } #[cfg(feature = "ring")] -pub fn ring_prove_verify() +pub fn ring_prove_verify() where - S::Config: ark_ec::short_weierstrass::SWCurveConfig + Clone, - ::BaseField: ark_ff::PrimeField, + BaseField: ark_ff::PrimeField, + CurveConfig: ark_ec::short_weierstrass::SWCurveConfig + Clone, + AffinePoint: ring::IntoSW>, { - use crate::ring::{RingContext, RingProver, RingVerifier}; + use ring::{Prover, RingContext, Verifier}; let rng = &mut ark_std::test_rng(); let domain_size = 1024; @@ -89,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()); @@ -106,7 +104,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 +121,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) => {}; }