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::{BigInteger, PrimeField};
11use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
12use digest::Digest;
13use digest::OutputSizeUser;
14use rand_core::CryptoRngCore;
15
16fn prune_buffer<F: PrimeField>(mut bytes: [u8; 32]) -> F {
17 bytes[0] &= 0b1111_1000;
18 bytes[31] &= 0b0111_1111;
19 bytes[31] |= 0b0100_0000;
20 F::from_le_bytes_mod_order(&bytes[..])
21}
22
23#[derive(Copy, Clone, Debug)]
24/// EdDSA secret key is 32 byte data
25pub struct SecretKey([u8; 32]);
26
27impl SecretKey {
28 fn expand<F: PrimeField, D: Digest>(&self) -> (F, [u8; 32]) {
29 let hash = D::new().chain_update(self.0).finalize();
30 let (buffer, hash_prefix) = hash.split_at(32);
31 let buffer: [u8; 32] = buffer.try_into().unwrap();
32 let hash_prefix: [u8; 32] = hash_prefix.try_into().unwrap();
33 let x = prune_buffer(buffer);
34 (x, hash_prefix)
35 }
36
37 pub fn to_bytes(&self) -> [u8; 32] {
38 self.0
39 }
40
41 pub fn from_bytes(bytes: &[u8; 32]) -> Self {
42 Self(bytes.clone())
43 }
44}
45
46/// `PublicKey` is EdDSA signature verification key
47#[derive(Copy, Clone, Debug, CanonicalSerialize, CanonicalDeserialize)]
48pub struct PublicKey<TE: TECurveConfig>(pub Affine<TE>);
49
50impl<TE: TECurveConfig> PublicKey<TE> {
51 pub fn xy(&self) -> (&TE::BaseField, &TE::BaseField) {
52 self.as_ref().xy().unwrap()
53 }
54
55 pub fn to_bytes(&self) -> Vec<u8> {
56 let mut bytes = Vec::new();
57 self.serialize_compressed(&mut bytes).unwrap();
58 bytes
59 }
60
61 pub fn from_bytes(bytes: &[u8]) -> Result<Self, Box<dyn ark_std::error::Error>> {
62 let point = Affine::<TE>::deserialize_compressed(bytes)?;
63 Ok(Self(point))
64 }
65}
66
67impl<TE: TECurveConfig> From<Affine<TE>> for PublicKey<TE> {
68 fn from(affine: Affine<TE>) -> Self {
69 Self(affine)
70 }
71}
72
73impl<TE: TECurveConfig> AsRef<Affine<TE>> for PublicKey<TE> {
74 fn as_ref(&self) -> &Affine<TE> {
75 &self.0
76 }
77}
78
79#[derive(Copy, Clone, Debug)]
80/// `SigningKey` produces EdDSA signatures for given message
81pub struct SigningKey<TE: TECurveConfig> {
82 secret_key: SecretKey,
83 public_key: PublicKey<TE>,
84}
85
86impl<TE: TECurveConfig + Clone> SigningKey<TE>
87where
88 TE::BaseField: PrimeField + Absorb,
89{
90 pub fn new<D: Digest>(secret_key: &SecretKey) -> Result<Self, Error> {
91 (<D as OutputSizeUser>::output_size() == 64)
92 .then_some(())
93 .ok_or(Error::BadDigestOutput)?;
94
95 let (x, _) = secret_key.expand::<TE::ScalarField, D>();
96 let public_key: Affine<TE> = (Affine::<TE>::generator() * x).into();
97 let signing_key = Self {
98 secret_key: *secret_key,
99 public_key: PublicKey(public_key),
100 };
101
102 Ok(signing_key)
103 }
104
105 pub fn from_bytes<D: Digest>(bytes: &[u8; 32]) -> Result<Self, Error> {
106 let secret_key = SecretKey::from_bytes(bytes);
107 Self::new::<D>(&secret_key)
108 }
109
110 pub fn to_bytes(&self) -> [u8; 32] {
111 self.secret_key.to_bytes()
112 }
113
114 pub fn generate<D: Digest>(rng: &mut impl CryptoRngCore) -> Result<Self, Error> {
115 let mut secret_key = SecretKey([0; 32]);
116 rng.fill_bytes(&mut secret_key.0);
117 Self::new::<D>(&secret_key)
118 }
119
120 pub fn public_key(&self) -> &PublicKey<TE> {
121 &self.public_key
122 }
123
124 pub fn sign<D: Digest>(
125 &self,
126 poseidon: &PoseidonConfig<TE::BaseField>,
127 message: &TE::BaseField,
128 ) -> Signature<TE> {
129 let (x, prefix) = self.secret_key.expand::<TE::ScalarField, D>();
130
131 let mut h = D::new();
132 h.update(prefix);
133 let msg_bytes = message.into_bigint().to_bytes_le();
134 let mut msg32: [u8; 32] = [0; 32];
135 msg32[..msg_bytes.len()].copy_from_slice(&msg_bytes[..]);
136 h.update(msg32);
137
138 let r: TE::ScalarField = crate::from_digest(h);
139 let sig_r: Affine<TE> = (Affine::<TE>::generator() * r).into();
140
141 let mut poseidon = PoseidonSponge::new(poseidon);
142
143 let (sig_r_x, sig_r_y) = sig_r.xy().unwrap();
144 poseidon.absorb(sig_r_x);
145 poseidon.absorb(sig_r_y);
146 let (pk_x, pk_y) = self.public_key.0.xy().unwrap();
147 poseidon.absorb(pk_x);
148 poseidon.absorb(pk_y);
149 poseidon.absorb(message);
150
151 // use poseidon over Fq, so that it can be done too in-circuit
152 let k = poseidon.squeeze_field_elements::<TE::BaseField>(1);
153 let k = k.first().unwrap();
154 let k = TE::ScalarField::from_le_bytes_mod_order(&k.into_bigint().to_bytes_le());
155
156 let sig_s = (x * k) + r;
157
158 Signature::new(sig_r, sig_s)
159 }
160}
161
162impl<TE: TECurveConfig> SigningKey<TE> {
163 pub fn shared_key<D: Digest>(&self, recipient: &PublicKey<TE>) -> [u8; 32] {
164 let (x, _) = self.secret_key.expand::<TE::ScalarField, D>();
165 let shared_key: Affine<TE> = (*recipient.as_ref() * x).into();
166 let mut data = Vec::new();
167 shared_key.serialize_compressed(&mut data).unwrap();
168 data[00..32].try_into().unwrap()
169 }
170}
171
172impl<TE: TECurveConfig + Clone> PublicKey<TE>
173where
174 TE::BaseField: PrimeField + Absorb,
175{
176 pub fn verify(
177 &self,
178 poseidon: &PoseidonConfig<TE::BaseField>,
179 message: &TE::BaseField,
180 signature: &Signature<TE>,
181 ) -> Result<(), Error> {
182 let mut poseidon = PoseidonSponge::new(poseidon);
183
184 let (sig_r_x, sig_r_y) = signature.r().xy().unwrap();
185 poseidon.absorb(sig_r_x);
186 poseidon.absorb(sig_r_y);
187 let (pk_x, pk_y) = self.0.xy().unwrap();
188 poseidon.absorb(pk_x);
189 poseidon.absorb(pk_y);
190 poseidon.absorb(message);
191
192 // use poseidon over Fq, so that it can be done too in-circuit
193 let k = poseidon.squeeze_field_elements::<TE::BaseField>(1);
194 let k = k.first().unwrap();
195
196 let kx_b = self.0.mul_bigint(k.into_bigint());
197 let s_b = Affine::<TE>::generator() * signature.s();
198 let r_rec: Affine<TE> = (s_b - kx_b).into();
199
200 (signature.r() == &r_rec).then_some(()).ok_or(Error::Verify)
201 }
202}