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_elements_with_padding,
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 {
126 <Self as SequentialCommit>::to_commitment(self)
127 }
128
129 pub fn verify(&self, message: Word, signature: &Signature) -> bool {
131 let message_bytes: [u8; 32] = message.into();
132 self.inner.verify(&message_bytes, &signature.inner).is_ok()
133 }
134
135 pub(crate) fn to_x25519(&self) -> x25519_dalek::PublicKey {
145 let mont_point = self.inner.to_montgomery();
146 x25519_dalek::PublicKey::from(mont_point.to_bytes())
147 }
148}
149
150impl SequentialCommit for PublicKey {
151 type Commitment = Word;
152
153 fn to_elements(&self) -> Vec<Felt> {
154 bytes_to_elements_with_padding(&self.to_bytes())
155 }
156}
157
158#[derive(Debug, Error)]
159pub enum PublicKeyError {
160 #[error("Could not verify with given public key and signature")]
161 VerificationFailed,
162}
163
164#[derive(Debug, Clone, PartialEq, Eq)]
169pub struct Signature {
170 inner: ed25519_dalek::Signature,
171}
172
173impl Signature {
174 pub fn verify(&self, message: Word, pub_key: &PublicKey) -> bool {
176 pub_key.verify(message, self)
177 }
178}
179
180impl Serializable for SecretKey {
184 fn write_into<W: ByteWriter>(&self, target: &mut W) {
185 target.write_bytes(&self.inner.to_bytes());
186 }
187}
188
189impl Deserializable for SecretKey {
190 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
191 let mut bytes: [u8; SECRET_KEY_BYTES] = source.read_array()?;
192 let inner = ed25519_dalek::SigningKey::from_bytes(&bytes);
193 bytes.zeroize();
194
195 Ok(Self { inner })
196 }
197}
198
199impl Serializable for PublicKey {
200 fn write_into<W: ByteWriter>(&self, target: &mut W) {
201 target.write_bytes(&self.inner.to_bytes());
202 }
203}
204
205impl Deserializable for PublicKey {
206 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
207 let bytes: [u8; PUBLIC_KEY_BYTES] = source.read_array()?;
208 let inner = ed25519_dalek::VerifyingKey::from_bytes(&bytes).map_err(|_| {
209 DeserializationError::InvalidValue("Invalid Ed25519 public key".to_string())
210 })?;
211 Ok(Self { inner })
212 }
213}
214
215impl Serializable for Signature {
216 fn write_into<W: ByteWriter>(&self, target: &mut W) {
217 target.write_bytes(&self.inner.to_bytes())
218 }
219}
220
221impl Deserializable for Signature {
222 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
223 let bytes: [u8; SIGNATURE_BYTES] = source.read_array()?;
224 let inner = ed25519_dalek::Signature::from_bytes(&bytes);
225 Ok(Self { inner })
226 }
227}