arnaucube
arnaucube/arkeddsaPublic Self-hosted repository
better bounds

reuse ark-error
kilic onurkilic1004@gmail.com
Thu, 11 Jul 2024 16:51:00 +0300
commit

1e696264a920933e048b4aab72a2e9760787f6c9

parent

822bab04895135675f7a599af29bdcf923be758f

3 files changed, 89 insertions(+), 76 deletions(-)

jump to
M src/eddsa.rs → 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 @@ }

#[derive(Copy, Clone, Debug)] /// `PublicKey` is EdDSA signature verification key -pub struct PublicKey<A: AffineRepr>(A) -where - A::Config: TECurveConfig; +pub struct PublicKey<TE: TECurveConfig>(Affine<TE>); + +impl<TE: TECurveConfig> PublicKey<TE> { + pub fn point(&self) -> &Affine<TE> { + &self.0 + } + + pub fn xy(&self) -> (&TE::BaseField, &TE::BaseField) { + self.as_ref().xy().unwrap() + } +} + +impl<TE: TECurveConfig> From<Affine<TE>> for PublicKey<TE> { + fn from(affine: Affine<TE>) -> Self { + Self(affine) + } +} -impl<A: AffineRepr> PublicKey<A> -where - A::Config: TECurveConfig, -{ - pub fn xy(&self) -> (&A::BaseField, &A::BaseField) { - self.0.xy().unwrap() +impl<TE: TECurveConfig> AsRef<Affine<TE>> for PublicKey<TE> { + fn as_ref(&self) -> &Affine<TE> { + &self.0 } } #[derive(Copy, Clone, Debug)] /// `SigningKey` produces EdDSA signatures for given message -pub struct SigningKey<A: AffineRepr> -where - A::Config: TECurveConfig, -{ +pub struct SigningKey<TE: TECurveConfig> { secret_key: SecretKey, - public_key: PublicKey<A>, + public_key: PublicKey<TE>, } -impl<A: AffineRepr> SigningKey<A> +impl<TE: TECurveConfig> SigningKey<TE> where - A::Config: TECurveConfig, - A::BaseField: PrimeField + Absorb, + TE::BaseField: PrimeField + Absorb, { pub fn new<D: Digest>(secret_key: &SecretKey) -> Result<Self, Error> { (<D as OutputSizeUser>::output_size() == 64) .then_some(()) - .ok_or(Error::BadOutputSize)?; + .ok_or(Error::BadDigestOutput)?; - let (x, _) = secret_key.expand::<A::ScalarField, D>(); - let public_key: A = (A::generator() * x).into_affine(); + let (x, _) = secret_key.expand::<TE::ScalarField, D>(); + let public_key: Affine<TE> = (Affine::<TE>::generator() * x).into(); let signing_key = Self { secret_key: *secret_key, public_key: PublicKey(public_key),

@@ -90,35 +100,36 @@ rng.fill_bytes(&mut secret_key.0);

Self::new::<D>(&secret_key) } - pub fn public_key(&self) -> &PublicKey<A> { + pub fn public_key(&self) -> &PublicKey<TE> { &self.public_key } pub fn sign<D: Digest, E: Absorb>( &self, - poseidon: &PoseidonConfig<A::BaseField>, + poseidon: &PoseidonConfig<TE::BaseField>, message: &[E], - ) -> Signature<A> { - let (x, prefix) = self.secret_key.expand::<A::ScalarField, D>(); + ) -> Signature<TE> { + let (x, prefix) = self.secret_key.expand::<TE::ScalarField, D>(); 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<TE> = (Affine::<TE>::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::<A::ScalarField>(1); + let k = poseidon.squeeze_field_elements::<TE::ScalarField>(1); let k = k.first().unwrap(); let sig_s = (x * k) + r;

@@ -127,33 +138,32 @@ Signature::new(sig_r, sig_s)

} } -impl<A: AffineRepr> PublicKey<A> +impl<TE: TECurveConfig> PublicKey<TE> where - A::Config: TECurveConfig, - A::BaseField: PrimeField + Absorb, + TE::BaseField: PrimeField + Absorb, { pub fn verify<E: Absorb>( &self, - poseidon: &PoseidonConfig<A::BaseField>, + poseidon: &PoseidonConfig<TE::BaseField>, message: &[E], - signature: &Signature<A>, + signature: &Signature<TE>, ) -> 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::<A::ScalarField>(1); + let k = poseidon.squeeze_field_elements::<TE::ScalarField>(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::<TE>::generator() * signature.s(); + let r_rec: Affine<TE> = (s_b - kx_b).into(); (signature.r() == &r_rec).then_some(()).ok_or(Error::Verify) }
M src/lib.rs → src/lib.rs

@@ -14,9 +14,19 @@

#[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 {

@@ -24,7 +34,7 @@

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 @@ );

PoseidonConfig::new(full_rounds, partial_rounds, 5, mds, ark, rate, 1) } - fn run_test<A: AffineRepr, D: Digest>() + fn run_test<TE: TECurveConfig, D: Digest>() where - A::BaseField: Absorb + PrimeField, - A::Config: TECurveConfig, + TE::BaseField: Absorb + PrimeField, { let poseidon = poseidon_config(4, 8, 55); - let signing_key = SigningKey::<A>::generate::<D>(&mut OsRng).unwrap(); + let signing_key = SigningKey::<TE>::generate::<D>(&mut OsRng).unwrap(); let message = b"xxx yyy <<< zzz >>> bunny"; let signature = signing_key.sign::<D, _>(&poseidon, &message[..]); let public_key = signing_key.public_key();

@@ -63,10 +72,10 @@ }

#[test] fn test_eddsa() { - run_test::<ark_ed_on_bn254::EdwardsAffine, sha2::Sha512>(); - run_test::<ark_ed_on_bn254::EdwardsAffine, blake2::Blake2b512>(); - run_test::<crate::ed_on_bn254_twist::EdwardsAffine, sha2::Sha512>(); - run_test::<ark_ed_on_bls12_381::EdwardsAffine, sha2::Sha512>(); - run_test::<ark_ed_on_bls12_381_bandersnatch::EdwardsAffine, sha2::Sha512>(); + run_test::<ark_ed_on_bn254::EdwardsConfig, sha2::Sha512>(); + run_test::<ark_ed_on_bn254::EdwardsConfig, blake2::Blake2b512>(); + run_test::<crate::ed_on_bn254_twist::EdwardsConfig, sha2::Sha512>(); + run_test::<ark_ed_on_bls12_381::EdwardsConfig, sha2::Sha512>(); + run_test::<ark_ed_on_bls12_381_bandersnatch::EdwardsConfig, sha2::Sha512>(); } }
M src/signature.rs → 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<A: AffineRepr> { - r: A, - s: A::ScalarField, +pub struct Signature<TE: TECurveConfig> { + r: Affine<TE>, + s: TE::ScalarField, } -impl<A: AffineRepr> Signature<A> -where - A::Config: TECurveConfig, -{ +impl<TE: TECurveConfig> Signature<TE> { /// 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<u8> { let mut bytes = Vec::new(); self.r.serialize_uncompressed(&mut bytes).unwrap();

@@ -25,32 +21,30 @@ bytes

} /// 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<Signature<A>, 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<Self, Box<dyn ark_std::error::Error>> { + 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::<TE>::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<TE>, s: TE::ScalarField) -> Self { Self { r, s } } - pub(crate) fn r(&self) -> &A { + pub fn r(&self) -> &Affine<TE> { &self.r } - pub(crate) fn s(&self) -> &A::ScalarField { + pub fn s(&self) -> &TE::ScalarField { &self.s } }