From 1e696264a920933e048b4aab72a2e9760787f6c9 Mon Sep 17 00:00:00 2001 From: kilic Date: Thu, 11 Jul 2024 16:51:00 +0300 Subject: [PATCH] better bounds reuse ark-error --- src/eddsa.rs | 94 ++++++++++++++++++++++++++---------------------- src/lib.rs | 33 ++++++++++------- src/signature.rs | 38 +++++++++----------- 3 files changed, 89 insertions(+), 76 deletions(-) diff --git a/src/eddsa.rs b/src/eddsa.rs index 2898348..06a5e8d 100644 --- a/src/eddsa.rs +++ b/src/eddsa.rs @@ -3,7 +3,10 @@ use ark_crypto_primitives::sponge::{ poseidon::{PoseidonConfig, PoseidonSponge}, Absorb, CryptographicSponge, }; -use ark_ec::{twisted_edwards::TECurveConfig, AffineRepr, CurveGroup}; +use ark_ec::{ + twisted_edwards::{Affine, TECurveConfig}, + AffineRepr, +}; use ark_ff::PrimeField; use digest::Digest; use digest::OutputSizeUser; @@ -41,41 +44,48 @@ impl SecretKey { #[derive(Copy, Clone, Debug)] /// `PublicKey` is EdDSA signature verification key -pub struct PublicKey(A) -where - A::Config: TECurveConfig; +pub struct PublicKey(Affine); -impl PublicKey -where - A::Config: TECurveConfig, -{ - pub fn xy(&self) -> (&A::BaseField, &A::BaseField) { - self.0.xy().unwrap() +impl PublicKey { + pub fn point(&self) -> &Affine { + &self.0 + } + + pub fn xy(&self) -> (&TE::BaseField, &TE::BaseField) { + self.as_ref().xy().unwrap() + } +} + +impl From> for PublicKey { + fn from(affine: Affine) -> Self { + Self(affine) + } +} + +impl AsRef> for PublicKey { + fn as_ref(&self) -> &Affine { + &self.0 } } #[derive(Copy, Clone, Debug)] /// `SigningKey` produces EdDSA signatures for given message -pub struct SigningKey -where - A::Config: TECurveConfig, -{ +pub struct SigningKey { secret_key: SecretKey, - public_key: PublicKey, + public_key: PublicKey, } -impl SigningKey +impl SigningKey where - A::Config: TECurveConfig, - A::BaseField: PrimeField + Absorb, + TE::BaseField: PrimeField + Absorb, { pub fn new(secret_key: &SecretKey) -> Result { (::output_size() == 64) .then_some(()) - .ok_or(Error::BadOutputSize)?; + .ok_or(Error::BadDigestOutput)?; - let (x, _) = secret_key.expand::(); - let public_key: A = (A::generator() * x).into_affine(); + let (x, _) = secret_key.expand::(); + let public_key: Affine = (Affine::::generator() * x).into(); let signing_key = Self { secret_key: *secret_key, public_key: PublicKey(public_key), @@ -90,35 +100,36 @@ where Self::new::(&secret_key) } - pub fn public_key(&self) -> &PublicKey { + pub fn public_key(&self) -> &PublicKey { &self.public_key } pub fn sign( &self, - poseidon: &PoseidonConfig, + poseidon: &PoseidonConfig, message: &[E], - ) -> Signature { - let (x, prefix) = self.secret_key.expand::(); + ) -> Signature { + let (x, prefix) = self.secret_key.expand::(); let mut h = D::new(); h.update(prefix); message .iter() .for_each(|m| h.update(m.to_sponge_bytes_as_vec())); - let r: A::ScalarField = crate::from_digest(h); - let sig_r = (A::generator() * r).into_affine(); + let r: TE::ScalarField = crate::from_digest(h); + let sig_r: Affine = (Affine::::generator() * r).into(); let mut poseidon = PoseidonSponge::new(poseidon); + let (sig_r_x, sig_r_y) = sig_r.xy().unwrap(); poseidon.absorb(sig_r_x); poseidon.absorb(sig_r_y); - let (vk_x, vk_y) = self.public_key.0.xy().unwrap(); - poseidon.absorb(vk_x); - poseidon.absorb(vk_y); + let (pk_x, pk_y) = self.public_key.0.xy().unwrap(); + poseidon.absorb(pk_x); + poseidon.absorb(pk_y); message.iter().for_each(|m| poseidon.absorb(m)); - let k = poseidon.squeeze_field_elements::(1); + let k = poseidon.squeeze_field_elements::(1); let k = k.first().unwrap(); let sig_s = (x * k) + r; @@ -127,33 +138,32 @@ where } } -impl PublicKey +impl PublicKey where - A::Config: TECurveConfig, - A::BaseField: PrimeField + Absorb, + TE::BaseField: PrimeField + Absorb, { pub fn verify( &self, - poseidon: &PoseidonConfig, + poseidon: &PoseidonConfig, message: &[E], - signature: &Signature, + signature: &Signature, ) -> Result<(), Error> { let mut poseidon = PoseidonSponge::new(poseidon); let (sig_r_x, sig_r_y) = signature.r().xy().unwrap(); poseidon.absorb(sig_r_x); poseidon.absorb(sig_r_y); - let (vk_x, vk_y) = self.0.xy().unwrap(); - poseidon.absorb(vk_x); - poseidon.absorb(vk_y); + let (pk_x, pk_y) = self.0.xy().unwrap(); + poseidon.absorb(pk_x); + poseidon.absorb(pk_y); message.iter().for_each(|m| poseidon.absorb(m)); - let k = poseidon.squeeze_field_elements::(1); + let k = poseidon.squeeze_field_elements::(1); let k = k.first().unwrap(); let kx_b = self.0 * k; - let s_b = A::generator() * signature.s(); - let r_rec: A = (s_b - kx_b).into(); + let s_b = Affine::::generator() * signature.s(); + let r_rec: Affine = (s_b - kx_b).into(); (signature.r() == &r_rec).then_some(()).ok_or(Error::Verify) } diff --git a/src/lib.rs b/src/lib.rs index a3d668b..21abb04 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,17 +14,27 @@ pub(crate) fn from_digest(digest: D) -> F { #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Error { Verify, - BadOutputSize, - InvalidData, + BadDigestOutput, } +impl core::fmt::Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + match *self { + Error::Verify => write!(f, "Signature verification failed"), + Error::BadDigestOutput => write!(f, "Bad digest output size"), + } + } +} + +impl ark_std::error::Error for Error {} + #[cfg(test)] mod test { use crate::SigningKey; use ark_crypto_primitives::sponge::poseidon::{find_poseidon_ark_and_mds, PoseidonConfig}; use ark_crypto_primitives::sponge::Absorb; - use ark_ec::{twisted_edwards::TECurveConfig, AffineRepr}; + use ark_ec::twisted_edwards::TECurveConfig; use ark_ff::PrimeField; use digest::Digest; use rand_core::OsRng; @@ -46,13 +56,12 @@ mod test { PoseidonConfig::new(full_rounds, partial_rounds, 5, mds, ark, rate, 1) } - fn run_test() + fn run_test() where - A::BaseField: Absorb + PrimeField, - A::Config: TECurveConfig, + TE::BaseField: Absorb + PrimeField, { let poseidon = poseidon_config(4, 8, 55); - let signing_key = SigningKey::::generate::(&mut OsRng).unwrap(); + let signing_key = SigningKey::::generate::(&mut OsRng).unwrap(); let message = b"xxx yyy <<< zzz >>> bunny"; let signature = signing_key.sign::(&poseidon, &message[..]); let public_key = signing_key.public_key(); @@ -63,10 +72,10 @@ mod test { #[test] fn test_eddsa() { - run_test::(); - run_test::(); - run_test::(); - run_test::(); - run_test::(); + run_test::(); + run_test::(); + run_test::(); + run_test::(); + run_test::(); } } diff --git a/src/signature.rs b/src/signature.rs index 505340b..d3ac897 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -1,22 +1,18 @@ -use crate::Error; +use ark_ec::twisted_edwards::Affine; use ark_ec::twisted_edwards::TECurveConfig; -use ark_ec::AffineRepr; use ark_serialize::CanonicalDeserialize; use ark_serialize::CanonicalSerialize; #[derive(Clone, Copy, Debug)] /// `SignatureComponents` contains the realized parts of a signature -pub struct Signature { - r: A, - s: A::ScalarField, +pub struct Signature { + r: Affine, + s: TE::ScalarField, } -impl Signature -where - A::Config: TECurveConfig, -{ +impl Signature { /// Serializes the signature components to bytes as uncompressed. - /// Expect output size to be `size_of(A::BaseField) * 2 + size_of(A::ScalarField)` + /// Expect output size to be `size_of(TE::BaseField) * 2 + size_of(TE::ScalarField)` pub fn to_bytes(&self) -> Vec { let mut bytes = Vec::new(); self.r.serialize_uncompressed(&mut bytes).unwrap(); @@ -25,32 +21,30 @@ where } /// Checked deserialization of the signature components from bytes. - /// Expects input size to be `size_of(A::BaseField) * 2 + size_of(A::ScalarField)` - pub fn from_bytes(bytes: &[u8]) -> Result, Error> { - let point_size = A::Config::serialized_size(ark_serialize::Compress::No); - (bytes.len() == 32 + A::Config::serialized_size(ark_serialize::Compress::No)) + /// Expects input size to be `size_of(TE::BaseField) * 2 + size_of(TE::ScalarField)` + pub fn from_bytes(bytes: &[u8]) -> Result> { + let point_size = TE::serialized_size(ark_serialize::Compress::No); + (bytes.len() == 32 + TE::serialized_size(ark_serialize::Compress::No)) .then_some(true) - .ok_or(Error::InvalidData)?; + .ok_or(ark_serialize::SerializationError::InvalidData)?; let off1 = point_size; let off2 = off1 + 32; - let r = - A::deserialize_uncompressed(&bytes[00..off1]).map_err(|_| crate::Error::InvalidData)?; - let s = A::ScalarField::deserialize_uncompressed(&bytes[off1..off2]) - .map_err(|_| crate::Error::InvalidData)?; + let r = Affine::::deserialize_uncompressed(&bytes[00..off1])?; + let s = TE::ScalarField::deserialize_uncompressed(&bytes[off1..off2])?; Ok(Signature { r, s }) } - pub fn new(r: A, s: A::ScalarField) -> Self { + pub fn new(r: Affine, s: TE::ScalarField) -> Self { Self { r, s } } - pub(crate) fn r(&self) -> &A { + pub fn r(&self) -> &Affine { &self.r } - pub(crate) fn s(&self) -> &A::ScalarField { + pub fn s(&self) -> &TE::ScalarField { &self.s } }