crypto/signatures/
ed25519.rs1use core::{
5 cmp::Ordering,
6 convert::TryFrom,
7 hash::{Hash, Hasher},
8};
9
10use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing};
11
12#[deprecated = "Use associated const SecretKey::LENGTH"]
13pub const SECRET_KEY_LENGTH: usize = 32;
14#[deprecated = "Use associated const PublicKey::LENGTH"]
15pub const PUBLIC_KEY_LENGTH: usize = 32;
16#[deprecated = "Use associated const Signature::LENGTH"]
17pub const SIGNATURE_LENGTH: usize = 64;
18
19#[derive(Zeroize, ZeroizeOnDrop, Clone)]
20pub struct SecretKey(ed25519_zebra::SigningKey);
21
22impl SecretKey {
23 pub const LENGTH: usize = 32;
24
25 #[cfg(feature = "random")]
26 #[cfg_attr(docsrs, doc(cfg(feature = "random")))]
27 pub fn generate() -> crate::Result<Self> {
28 let mut bs = [0u8; SecretKey::LENGTH];
29 crate::utils::rand::fill(&mut bs)?;
30 let sk = Self::from_bytes(&bs);
31 bs.zeroize();
32 Ok(sk)
33 }
34
35 #[cfg(feature = "rand")]
36 pub fn generate_with<R: rand::CryptoRng + rand::RngCore>(rng: &mut R) -> Self {
37 let mut bs = [0_u8; SecretKey::LENGTH];
38 rng.fill_bytes(&mut bs);
39 let sk = Self::from_bytes(&bs);
40 bs.zeroize();
41 sk
42 }
43
44 pub fn public_key(&self) -> PublicKey {
45 PublicKey(ed25519_zebra::VerificationKey::from(&self.0))
46 }
47
48 pub fn to_bytes(&self) -> Zeroizing<[u8; SecretKey::LENGTH]> {
49 Zeroizing::new(self.0.into())
50 }
51
52 pub fn as_slice(&self) -> &[u8] {
53 self.0.as_ref()
54 }
55
56 pub fn from_bytes(bytes: &[u8; SecretKey::LENGTH]) -> Self {
57 Self((*bytes).into())
58 }
59
60 pub fn sign(&self, msg: &[u8]) -> Signature {
61 Signature(self.0.sign(msg))
62 }
63}
64
65#[derive(Copy, Clone, Debug)]
66#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
67pub struct PublicKey(ed25519_zebra::VerificationKey);
68
69impl PublicKey {
70 pub const LENGTH: usize = 32;
71
72 pub fn verify(&self, sig: &Signature, msg: &[u8]) -> bool {
73 self.0.verify(&sig.0, msg).is_ok()
74 }
75
76 pub fn as_slice(&self) -> &[u8] {
77 self.0.as_ref()
78 }
79
80 pub fn to_bytes(self) -> [u8; PublicKey::LENGTH] {
81 self.0.into()
82 }
83
84 pub fn try_from_bytes(bytes: [u8; PublicKey::LENGTH]) -> crate::Result<Self> {
85 ed25519_zebra::VerificationKey::try_from(bytes)
86 .map(Self)
87 .map_err(|_| crate::Error::ConvertError {
88 from: "compressed bytes",
89 to: "Ed25519 public key",
90 })
91 }
92}
93
94impl AsRef<[u8]> for PublicKey {
95 fn as_ref(&self) -> &[u8] {
96 self.0.as_ref()
97 }
98}
99
100impl TryFrom<[u8; PublicKey::LENGTH]> for PublicKey {
101 type Error = crate::Error;
102 fn try_from(bytes: [u8; PublicKey::LENGTH]) -> crate::Result<Self> {
103 Self::try_from_bytes(bytes)
104 }
105}
106
107impl From<PublicKey> for [u8; PublicKey::LENGTH] {
108 fn from(pk: PublicKey) -> Self {
109 pk.to_bytes()
110 }
111}
112
113impl PartialEq for PublicKey {
114 fn eq(&self, other: &Self) -> bool {
115 self.as_slice() == other.as_slice()
116 }
117}
118
119impl Eq for PublicKey {}
120
121impl PartialOrd for PublicKey {
122 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
123 Some(self.cmp(other))
124 }
125}
126
127impl Ord for PublicKey {
128 fn cmp(&self, other: &Self) -> Ordering {
129 self.as_slice().cmp(other.as_slice())
130 }
131}
132
133impl Hash for PublicKey {
134 fn hash<H: Hasher>(&self, state: &mut H) {
135 (self.as_slice()).hash(state);
136 }
137}
138
139#[derive(Copy, Clone, Debug)]
140#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
141pub struct PublicKeyBytes(ed25519_zebra::VerificationKeyBytes);
142
143impl PublicKeyBytes {
144 pub const LENGTH: usize = PublicKey::LENGTH;
145
146 pub fn verify(&self, sig: &Signature, msg: &[u8]) -> crate::Result<bool> {
147 Ok(self.into_public_key()?.verify(sig, msg))
148 }
149
150 pub fn into_public_key(self) -> crate::Result<PublicKey> {
151 self.0
152 .try_into()
153 .map_err(|_| crate::Error::ConvertError {
154 from: "Ed25519 public key bytes",
155 to: "Ed25519 public key",
156 })
157 .map(PublicKey)
158 }
159
160 pub fn as_slice(&self) -> &[u8] {
161 self.0.as_ref()
162 }
163
164 pub fn to_bytes(self) -> [u8; PublicKey::LENGTH] {
165 self.0.into()
166 }
167
168 pub fn from_bytes(bytes: [u8; PublicKey::LENGTH]) -> Self {
169 Self(ed25519_zebra::VerificationKeyBytes::from(bytes))
170 }
171}
172
173impl TryFrom<PublicKeyBytes> for PublicKey {
174 type Error = crate::Error;
175
176 fn try_from(value: PublicKeyBytes) -> Result<Self, Self::Error> {
177 value.into_public_key()
178 }
179}
180
181impl AsRef<[u8]> for PublicKeyBytes {
182 fn as_ref(&self) -> &[u8] {
183 self.0.as_ref()
184 }
185}
186
187impl From<[u8; PublicKey::LENGTH]> for PublicKeyBytes {
188 fn from(bytes: [u8; PublicKey::LENGTH]) -> Self {
189 Self::from_bytes(bytes)
190 }
191}
192
193impl From<PublicKeyBytes> for [u8; PublicKey::LENGTH] {
194 fn from(pk: PublicKeyBytes) -> Self {
195 pk.to_bytes()
196 }
197}
198
199impl PartialEq for PublicKeyBytes {
200 fn eq(&self, other: &Self) -> bool {
201 self.as_slice() == other.as_slice()
202 }
203}
204
205impl Eq for PublicKeyBytes {}
206
207impl PartialOrd for PublicKeyBytes {
208 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
209 Some(self.cmp(other))
210 }
211}
212
213impl Ord for PublicKeyBytes {
214 fn cmp(&self, other: &Self) -> Ordering {
215 self.as_slice().cmp(other.as_slice())
216 }
217}
218
219impl Hash for PublicKeyBytes {
220 fn hash<H: Hasher>(&self, state: &mut H) {
221 (self.as_slice()).hash(state);
222 }
223}
224
225#[derive(Copy, Clone, Debug, Eq, PartialEq)]
226#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
227pub struct Signature(ed25519_zebra::Signature);
228
229impl Signature {
230 pub const LENGTH: usize = 64;
231
232 pub fn to_bytes(&self) -> [u8; Signature::LENGTH] {
233 self.0.into()
234 }
235
236 pub fn from_bytes(bs: [u8; Signature::LENGTH]) -> Self {
237 Self(ed25519_zebra::Signature::from(bs))
238 }
239}
240
241impl PartialOrd for Signature {
242 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
243 Some(self.cmp(other))
244 }
245}
246
247impl Ord for Signature {
248 fn cmp(&self, other: &Self) -> Ordering {
249 let r_cmp = self.0.r_bytes().cmp(other.0.r_bytes());
250 let s_cmp = self.0.s_bytes().cmp(other.0.s_bytes());
251 r_cmp.then(s_cmp)
252 }
253}
254
255impl Hash for Signature {
256 fn hash<H: Hasher>(&self, state: &mut H) {
257 <[u8; 64]>::from(self.0).hash(state);
258 }
259}