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