miden_crypto/dsa/eddsa_25519/
mod.rs1use alloc::{string::ToString, vec::Vec};
5
6use ed25519_dalek::{Signer, Verifier};
7use miden_crypto_derive::{SilentDebug, SilentDisplay};
8use rand::{CryptoRng, RngCore};
9use thiserror::Error;
10
11use crate::{
12 Felt, SequentialCommit, Word,
13 ecdh::x25519::{EphemeralPublicKey, SharedSecret},
14 utils::{
15 ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable,
16 bytes_to_packed_u32_elements,
17 },
18 zeroize::{Zeroize, ZeroizeOnDrop},
19};
20
21#[cfg(test)]
22mod tests;
23
24const SECRET_KEY_BYTES: usize = 32;
29pub(crate) const PUBLIC_KEY_BYTES: usize = 32;
31const SIGNATURE_BYTES: usize = 64;
33
34#[derive(Clone, SilentDebug, SilentDisplay)]
39pub struct SecretKey {
40 inner: ed25519_dalek::SigningKey,
41}
42
43impl SecretKey {
44 #[cfg(feature = "std")]
46 #[allow(clippy::new_without_default)]
47 pub fn new() -> Self {
48 let mut rng = rand::rng();
49
50 Self::with_rng(&mut rng)
51 }
52
53 pub fn with_rng<R: CryptoRng + RngCore>(rng: &mut R) -> Self {
55 let mut seed = [0u8; SECRET_KEY_BYTES];
56 rand::RngCore::fill_bytes(rng, &mut seed);
57
58 let inner = ed25519_dalek::SigningKey::from_bytes(&seed);
59
60 seed.zeroize();
62
63 Self { inner }
64 }
65
66 pub fn public_key(&self) -> PublicKey {
68 PublicKey { inner: self.inner.verifying_key() }
69 }
70
71 pub fn sign(&self, message: Word) -> Signature {
73 let message_bytes: [u8; 32] = message.into();
74 let sig = self.inner.sign(&message_bytes);
75 Signature { inner: sig }
76 }
77
78 pub fn get_shared_secret(&self, pk_e: EphemeralPublicKey) -> SharedSecret {
81 let shared = self.to_x25519().diffie_hellman(&pk_e.inner);
82 SharedSecret::new(shared)
83 }
84
85 fn to_x25519(&self) -> x25519_dalek::StaticSecret {
92 let mut scalar_bytes = self.inner.to_scalar_bytes();
93 let static_secret = x25519_dalek::StaticSecret::from(scalar_bytes);
94
95 scalar_bytes.zeroize();
97
98 static_secret
99 }
100}
101
102impl ZeroizeOnDrop for SecretKey {}
105
106impl PartialEq for SecretKey {
107 fn eq(&self, other: &Self) -> bool {
108 use subtle::ConstantTimeEq;
109 self.inner.to_bytes().ct_eq(&other.inner.to_bytes()).into()
110 }
111}
112
113impl Eq for SecretKey {}
114
115#[derive(Debug, Clone, PartialEq, Eq)]
119pub struct PublicKey {
120 pub(crate) inner: ed25519_dalek::VerifyingKey,
121}
122
123impl PublicKey {
124 pub fn to_commitment(&self) -> Word {
129 <Self as SequentialCommit>::to_commitment(self)
130 }
131
132 pub fn verify(&self, message: Word, signature: &Signature) -> bool {
134 let message_bytes: [u8; 32] = message.into();
135 self.inner.verify(&message_bytes, &signature.inner).is_ok()
136 }
137
138 pub(crate) fn to_x25519(&self) -> x25519_dalek::PublicKey {
148 let mont_point = self.inner.to_montgomery();
149 x25519_dalek::PublicKey::from(mont_point.to_bytes())
150 }
151}
152
153impl SequentialCommit for PublicKey {
154 type Commitment = Word;
155
156 fn to_elements(&self) -> Vec<Felt> {
157 bytes_to_packed_u32_elements(&self.to_bytes())
158 }
159}
160
161#[derive(Debug, Error)]
162pub enum PublicKeyError {
163 #[error("Could not verify with given public key and signature")]
164 VerificationFailed,
165}
166
167#[derive(Debug, Clone, PartialEq, Eq)]
172pub struct Signature {
173 inner: ed25519_dalek::Signature,
174}
175
176impl Signature {
177 pub fn verify(&self, message: Word, pub_key: &PublicKey) -> bool {
179 pub_key.verify(message, self)
180 }
181}
182
183impl Serializable for SecretKey {
187 fn write_into<W: ByteWriter>(&self, target: &mut W) {
188 target.write_bytes(&self.inner.to_bytes());
189 }
190}
191
192impl Deserializable for SecretKey {
193 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
194 let mut bytes: [u8; SECRET_KEY_BYTES] = source.read_array()?;
195 let inner = ed25519_dalek::SigningKey::from_bytes(&bytes);
196 bytes.zeroize();
197
198 Ok(Self { inner })
199 }
200}
201
202impl Serializable for PublicKey {
203 fn write_into<W: ByteWriter>(&self, target: &mut W) {
204 target.write_bytes(&self.inner.to_bytes());
205 }
206}
207
208impl Deserializable for PublicKey {
209 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
210 let bytes: [u8; PUBLIC_KEY_BYTES] = source.read_array()?;
211 let inner = ed25519_dalek::VerifyingKey::from_bytes(&bytes).map_err(|_| {
212 DeserializationError::InvalidValue("Invalid Ed25519 public key".to_string())
213 })?;
214 Ok(Self { inner })
215 }
216}
217
218impl Serializable for Signature {
219 fn write_into<W: ByteWriter>(&self, target: &mut W) {
220 target.write_bytes(&self.inner.to_bytes())
221 }
222}
223
224impl Deserializable for Signature {
225 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
226 let bytes: [u8; SIGNATURE_BYTES] = source.read_array()?;
227 let inner = ed25519_dalek::Signature::from_bytes(&bytes);
228 Ok(Self { inner })
229 }
230}