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}