arnaucube
arnaucube/arkeddsaPublic Self-hosted repository
arkeddsa/src/eddsa.rs
src/eddsa.rsRaw
  1use crate::{signature::Signature, Error};
  2use ark_crypto_primitives::sponge::{
  3    poseidon::{PoseidonConfig, PoseidonSponge},
  4    Absorb, CryptographicSponge,
  5};
  6use ark_ec::{twisted_edwards::TECurveConfig, AffineRepr, CurveGroup};
  7use ark_ff::PrimeField;
  8use digest::Digest;
  9use digest::OutputSizeUser;
 10use rand_core::CryptoRngCore;
 11
 12fn prune_buffer<F: PrimeField>(mut bytes: [u8; 32]) -> F {
 13    bytes[0] &= 0b1111_1000;
 14    bytes[31] &= 0b0111_1111;
 15    bytes[31] |= 0b0100_0000;
 16    F::from_le_bytes_mod_order(&bytes[..])
 17}
 18
 19#[derive(Copy, Clone, Debug)]
 20/// EdDSA secret key is 32 byte data
 21pub struct SecretKey([u8; 32]);
 22
 23impl SecretKey {
 24    fn expand<F: PrimeField, D: Digest>(&self) -> (F, [u8; 32]) {
 25        let hash = D::new().chain_update(self.0).finalize();
 26        let (buffer, hash_prefix) = hash.split_at(32);
 27        let buffer: [u8; 32] = buffer.try_into().unwrap();
 28        let hash_prefix: [u8; 32] = hash_prefix.try_into().unwrap();
 29        let x = prune_buffer(buffer);
 30        (x, hash_prefix)
 31    }
 32
 33    pub fn to_bytes(&self) -> [u8; 32] {
 34        self.0
 35    }
 36
 37    pub fn from_bytes(bytes: [u8; 32]) -> Self {
 38        Self(bytes)
 39    }
 40}
 41
 42#[derive(Copy, Clone, Debug)]
 43/// `PublicKey` is EdDSA signature verification key
 44pub struct PublicKey<A: AffineRepr>(A)
 45where
 46    A::Config: TECurveConfig;
 47
 48impl<A: AffineRepr> PublicKey<A>
 49where
 50    A::Config: TECurveConfig,
 51{
 52    pub fn xy(&self) -> (&A::BaseField, &A::BaseField) {
 53        self.0.xy().unwrap()
 54    }
 55}
 56
 57#[derive(Copy, Clone, Debug)]
 58/// `SigningKey` produces EdDSA signatures for given message
 59pub struct SigningKey<A: AffineRepr>
 60where
 61    A::Config: TECurveConfig,
 62{
 63    secret_key: SecretKey,
 64    public_key: PublicKey<A>,
 65}
 66
 67impl<A: AffineRepr> SigningKey<A>
 68where
 69    A::Config: TECurveConfig,
 70    A::BaseField: PrimeField + Absorb,
 71{
 72    pub fn new<D: Digest>(secret_key: &SecretKey) -> Result<Self, Error> {
 73        (<D as OutputSizeUser>::output_size() == 64)
 74            .then_some(())
 75            .ok_or(Error::BadOutputSize)?;
 76
 77        let (x, _) = secret_key.expand::<A::ScalarField, D>();
 78        let public_key: A = (A::generator() * x).into_affine();
 79        let signing_key = Self {
 80            secret_key: *secret_key,
 81            public_key: PublicKey(public_key),
 82        };
 83
 84        Ok(signing_key)
 85    }
 86
 87    pub fn generate<D: Digest>(rng: &mut impl CryptoRngCore) -> Result<Self, Error> {
 88        let mut secret_key = SecretKey([0; 32]);
 89        rng.fill_bytes(&mut secret_key.0);
 90        Self::new::<D>(&secret_key)
 91    }
 92
 93    pub fn public_key(&self) -> &PublicKey<A> {
 94        &self.public_key
 95    }
 96
 97    pub fn sign<D: Digest, E: Absorb>(
 98        &self,
 99        poseidon: &PoseidonConfig<A::BaseField>,
100        message: &[E],
101    ) -> Signature<A> {
102        let (x, prefix) = self.secret_key.expand::<A::ScalarField, D>();
103
104        let mut h = D::new();
105        h.update(prefix);
106        message
107            .iter()
108            .for_each(|m| h.update(m.to_sponge_bytes_as_vec()));
109        let r: A::ScalarField = crate::from_digest(h);
110        let sig_r = (A::generator() * r).into_affine();
111
112        let mut poseidon = PoseidonSponge::new(poseidon);
113        let (sig_r_x, sig_r_y) = sig_r.xy().unwrap();
114        poseidon.absorb(sig_r_x);
115        poseidon.absorb(sig_r_y);
116        let (vk_x, vk_y) = self.public_key.0.xy().unwrap();
117        poseidon.absorb(vk_x);
118        poseidon.absorb(vk_y);
119        message.iter().for_each(|m| poseidon.absorb(m));
120
121        let k = poseidon.squeeze_field_elements::<A::ScalarField>(1);
122        let k = k.first().unwrap();
123
124        let sig_s = (x * k) + r;
125
126        Signature::new(sig_r, sig_s)
127    }
128}
129
130impl<A: AffineRepr> PublicKey<A>
131where
132    A::Config: TECurveConfig,
133    A::BaseField: PrimeField + Absorb,
134{
135    pub fn verify<E: Absorb>(
136        &self,
137        poseidon: &PoseidonConfig<A::BaseField>,
138        message: &[E],
139        signature: &Signature<A>,
140    ) -> Result<(), Error> {
141        let mut poseidon = PoseidonSponge::new(poseidon);
142
143        let (sig_r_x, sig_r_y) = signature.r().xy().unwrap();
144        poseidon.absorb(sig_r_x);
145        poseidon.absorb(sig_r_y);
146        let (vk_x, vk_y) = self.0.xy().unwrap();
147        poseidon.absorb(vk_x);
148        poseidon.absorb(vk_y);
149        message.iter().for_each(|m| poseidon.absorb(m));
150
151        let k = poseidon.squeeze_field_elements::<A::ScalarField>(1);
152        let k = k.first().unwrap();
153
154        let kx_b = self.0 * k;
155        let s_b = A::generator() * signature.s();
156        let r_rec: A = (s_b - kx_b).into();
157
158        (signature.r() == &r_rec).then_some(()).ok_or(Error::Verify)
159    }
160}