1use alloc::vec::Vec;
2
3use constant_time_eq::constant_time_eq;
4use crypto::{
5 Hasher,
6 blake3::Blake3,
7 curve25519::ed25519,
8 hmac::Hmac,
9 p256, rsa,
10 sha2::{Sha256, Sha384, Sha512},
11};
12use smallvec::SmallVec;
13
14use crate::{Algorithm, Error};
15
16pub(crate) const SIGNATURE_MAX_SIZE: usize = 3309; pub trait Signer {
19 fn sign(&self, message: &[u8]) -> Result<Signature, Error>;
20 fn algorithm(&self) -> Algorithm;
21}
22
23pub trait Verifier {
24 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error>;
25 fn algorithm(&self) -> Algorithm;
26}
27
28#[derive(Clone, Copy)]
33pub struct Signature {
34 value: [u8; SIGNATURE_MAX_SIZE],
35 length: usize,
36}
37
38impl core::ops::Deref for Signature {
39 type Target = [u8];
40
41 #[inline]
42 fn deref(&self) -> &[u8] {
43 &self.value[..self.length as usize]
44 }
45}
46
47impl AsRef<[u8]> for Signature {
48 #[inline]
49 fn as_ref(&self) -> &[u8] {
50 &self.value[..self.length]
51 }
52}
53
54impl TryFrom<&[u8]> for Signature {
55 type Error = Error;
56
57 #[inline]
58 fn try_from(signature: &[u8]) -> Result<Self, Self::Error> {
59 let length = signature.len();
60 if length > SIGNATURE_MAX_SIZE {
61 return Err(Error::InvalidSignature);
62 }
63
64 let mut value = [0u8; SIGNATURE_MAX_SIZE];
65 value[..length].copy_from_slice(signature);
66
67 return Ok(Signature {
68 value,
69 length,
70 });
71 }
72}
73
74impl<const N: usize> TryFrom<[u8; N]> for Signature {
75 type Error = Error;
76
77 #[inline]
78 fn try_from(signature: [u8; N]) -> Result<Self, Self::Error> {
79 signature.as_slice().try_into()
80 }
81}
82
83impl<const N: usize> TryFrom<&[u8; N]> for Signature {
84 type Error = Error;
85
86 #[inline]
87 fn try_from(signature: &[u8; N]) -> Result<Self, Self::Error> {
88 signature.as_slice().try_into()
89 }
90}
91
92impl TryFrom<Vec<u8>> for Signature {
93 type Error = Error;
94
95 #[inline]
96 fn try_from(signature: Vec<u8>) -> Result<Self, Self::Error> {
97 signature.as_slice().try_into()
98 }
99}
100
101#[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize, zeroize::ZeroizeOnDrop))]
107pub struct Blake3Key {
108 key: [u8; 32],
109}
110
111impl Blake3Key {
112 pub fn generate() -> Blake3Key {
114 let key = crypto::random_bytes();
115 return Blake3Key {
116 key,
117 };
118 }
119
120 #[inline(always)]
121 pub fn from_bytes(key: &[u8; 32]) -> Blake3Key {
122 return Blake3Key {
123 key: *key,
124 };
125 }
126
127 #[inline(always)]
128 pub fn as_bytes(&self) -> &[u8; 32] {
129 return &self.key;
130 }
131}
132
133impl Signer for Blake3Key {
134 fn sign(&self, message: &[u8]) -> Result<Signature, Error> {
135 let signature = Blake3::keyed_hash(&self.key, message);
136 return signature.as_ref().try_into();
137 }
138
139 #[inline(always)]
140 fn algorithm(&self) -> Algorithm {
141 Algorithm::BLAKE3
142 }
143}
144
145impl Verifier for Blake3Key {
146 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error> {
147 let expected_signature = Blake3::keyed_hash(&self.key, message);
148 return match constant_time_eq(signature.as_ref(), &expected_signature) {
149 true => Ok(()),
150 false => Err(Error::InvalidSignature),
151 };
152 }
153
154 #[inline(always)]
155 fn algorithm(&self) -> Algorithm {
156 Algorithm::BLAKE3
157 }
158}
159
160#[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize, zeroize::ZeroizeOnDrop))]
166pub struct HmacSha256Key {
167 key: SmallVec<u8, 32>,
168}
169
170impl HmacSha256Key {
171 pub fn generate() -> HmacSha256Key {
173 let key: [u8; 32] = crypto::random_bytes();
174 return HmacSha256Key {
175 key: key.into(),
176 };
177 }
178
179 pub fn from_bytes(key: &[u8]) -> Result<HmacSha256Key, Error> {
182 if key.len() < 16 {
184 return Err(Error::InvalidKey);
185 }
186
187 return Ok(HmacSha256Key {
188 key: SmallVec::from_slice_copy(key),
189 });
190 }
191
192 #[inline(always)]
193 pub fn as_bytes(&self) -> &[u8] {
194 return &self.key;
195 }
196}
197
198impl Signer for HmacSha256Key {
199 fn sign(&self, message: &[u8]) -> Result<Signature, Error> {
200 let signature = Hmac::<Sha256>::mac(&self.key, message);
201 return signature.as_ref().try_into();
202 }
203
204 #[inline(always)]
205 fn algorithm(&self) -> Algorithm {
206 Algorithm::HS256
207 }
208}
209
210impl Verifier for HmacSha256Key {
211 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error> {
212 let message_mac = Hmac::<Sha256>::mac(&self.key, message);
213 return match constant_time_eq(&message_mac, signature) {
214 true => Ok(()),
215 false => Err(Error::InvalidSignature),
216 };
217 }
218
219 #[inline(always)]
220 fn algorithm(&self) -> Algorithm {
221 Algorithm::HS256
222 }
223}
224
225#[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize, zeroize::ZeroizeOnDrop))]
231pub struct HmacSha512Key {
232 key: SmallVec<u8, 32>,
233}
234
235impl HmacSha512Key {
236 pub fn generate() -> HmacSha256Key {
238 let key: [u8; 32] = crypto::random_bytes();
239 return HmacSha256Key {
240 key: key.into(),
241 };
242 }
243
244 pub fn from_bytes(key: &[u8]) -> Result<HmacSha512Key, Error> {
247 if key.len() < 16 {
249 return Err(Error::InvalidKey);
250 }
251
252 return Ok(HmacSha512Key {
253 key: SmallVec::from_slice_copy(key),
254 });
255 }
256
257 #[inline(always)]
258 pub fn as_bytes(&self) -> &[u8] {
259 return &self.key;
260 }
261}
262
263impl Signer for HmacSha512Key {
264 fn sign(&self, message: &[u8]) -> Result<Signature, Error> {
265 let signature = Hmac::<Sha512>::mac(&self.key, message);
266 return signature.as_ref().try_into();
267 }
268
269 #[inline(always)]
270 fn algorithm(&self) -> Algorithm {
271 Algorithm::HS512
272 }
273}
274
275impl Verifier for HmacSha512Key {
276 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error> {
277 let message_mac = Hmac::<Sha512>::mac(&self.key, message);
278 return match constant_time_eq(&message_mac, signature) {
279 true => Ok(()),
280 false => Err(Error::InvalidSignature),
281 };
282 }
283
284 #[inline(always)]
285 fn algorithm(&self) -> Algorithm {
286 Algorithm::HS512
287 }
288}
289
290pub struct Ed25519SecretKey {
296 pub(crate) key: ed25519::SecretKey,
297}
298
299impl Ed25519SecretKey {
300 pub fn generate() -> Ed25519SecretKey {
302 let key = ed25519::SecretKey::generate();
303 return Ed25519SecretKey {
304 key,
305 };
306 }
307
308 pub fn from_bytes(seed: &[u8; 32]) -> Result<Ed25519SecretKey, Error> {
310 let key = ed25519::SecretKey::from_bytes(seed);
311 return Ok(Ed25519SecretKey {
312 key,
313 });
314 }
315
316 #[inline(always)]
318 pub(crate) fn to_bytes(&self) -> [u8; 32] {
319 return self.key.to_bytes();
320 }
321
322 #[inline(always)]
323 pub fn public_key(&self) -> Ed25519PublicKey {
324 return Ed25519PublicKey {
325 key: self.key.public_key(),
326 };
327 }
328}
329
330impl From<ed25519::SecretKey> for Ed25519SecretKey {
331 fn from(key: ed25519::SecretKey) -> Self {
332 Self {
333 key,
334 }
335 }
336}
337
338impl Signer for Ed25519SecretKey {
339 fn sign(&self, message: &[u8]) -> Result<Signature, Error> {
340 return self.key.sign(message).as_ref().try_into();
341 }
342
343 #[inline(always)]
344 fn algorithm(&self) -> Algorithm {
345 Algorithm::EdDSA
346 }
347}
348
349pub struct Ed25519PublicKey {
350 key: ed25519::PublicKey,
351}
352
353impl Ed25519PublicKey {
354 pub fn from_bytes(public_key: &[u8; 32]) -> Result<Ed25519PublicKey, Error> {
355 let key = ed25519::PublicKey::from_bytes(public_key).map_err(|_| Error::InvalidKey)?;
356 Ok(Ed25519PublicKey {
357 key,
358 })
359 }
360
361 #[inline(always)]
363 pub fn to_bytes(&self) -> [u8; 32] {
364 self.key.to_bytes()
365 }
366}
367
368impl From<ed25519::PublicKey> for Ed25519PublicKey {
369 fn from(key: ed25519::PublicKey) -> Self {
370 Self {
371 key,
372 }
373 }
374}
375
376impl Verifier for Ed25519PublicKey {
377 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error> {
378 let signature = signature.try_into().map_err(|_| Error::InvalidSignature)?;
379 return self
380 .key
381 .verify(message, &signature)
382 .map_err(|_| Error::InvalidSignature);
383 }
384
385 #[inline(always)]
386 fn algorithm(&self) -> Algorithm {
387 Algorithm::EdDSA
388 }
389}
390
391pub struct P256SecretKey {
397 key: p256::SecretKey,
398}
399
400impl P256SecretKey {
401 pub fn generate() -> Result<P256SecretKey, Error> {
403 let key = p256::SecretKey::generate().map_err(|_| Error::InvalidKey)?;
404 return Ok(P256SecretKey {
405 key,
406 });
407 }
408
409 #[inline(always)]
410 pub fn from_bytes(bytes: &[u8; 32]) -> Result<P256SecretKey, Error> {
411 let key = p256::SecretKey::from_bytes(bytes).map_err(|_| Error::InvalidKey)?;
412 return Ok(P256SecretKey {
413 key,
414 });
415 }
416
417 #[inline(always)]
419 pub(crate) fn to_bytes(&self) -> [u8; 32] {
420 return self.key.to_bytes();
421 }
422
423 #[inline(always)]
424 pub fn public_key(&self) -> P256PublicKey {
425 return P256PublicKey {
426 key: self.key.public_key(),
427 };
428 }
429}
430
431impl From<p256::SecretKey> for P256SecretKey {
432 fn from(key: p256::SecretKey) -> Self {
433 Self {
434 key,
435 }
436 }
437}
438
439impl Signer for P256SecretKey {
440 fn sign(&self, message: &[u8]) -> Result<Signature, Error> {
441 return self
442 .key
443 .sign(message)
444 .map_err(|err| Error::Unspecified(alloc::format!("error signing message: {err:?}")))?
445 .as_ref()
446 .try_into();
447 }
448
449 #[inline(always)]
450 fn algorithm(&self) -> Algorithm {
451 Algorithm::ES256
452 }
453}
454
455pub struct P256PublicKey {
456 pub(crate) key: p256::PublicKey,
457}
458
459impl P256PublicKey {
460 pub fn from_x_y(x: &[u8; 32], y: &[u8; 32]) -> Result<P256PublicKey, Error> {
461 let key = p256::PublicKey::from_x_y(x, y).map_err(|_| Error::InvalidKey)?;
462 Ok(P256PublicKey {
463 key,
464 })
465 }
466
467 pub fn from_bytes(public_key: &[u8]) -> Result<P256PublicKey, Error> {
468 let key = p256::PublicKey::from_bytes(public_key).map_err(|_| Error::InvalidKey)?;
469 Ok(P256PublicKey {
470 key,
471 })
472 }
473
474 }
480
481impl From<p256::PublicKey> for P256PublicKey {
482 fn from(key: p256::PublicKey) -> Self {
483 Self {
484 key,
485 }
486 }
487}
488
489impl Verifier for P256PublicKey {
490 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error> {
491 let signature = signature.try_into().map_err(|_| Error::InvalidSignature)?;
492 return self
493 .key
494 .verify(message, &signature)
495 .map_err(|_| Error::InvalidSignature);
496 }
497
498 #[inline(always)]
499 fn algorithm(&self) -> Algorithm {
500 Algorithm::ES256
501 }
502}
503
504pub struct RsaPublicKey {
534 pub(crate) key: rsa::PublicKey,
535 pub(crate) alg: Algorithm,
536}
537
538impl RsaPublicKey {
539 pub(crate) fn from_n_e(alg: Algorithm, n: &[u8], e: &[u8]) -> Result<Self, Error> {
550 if !matches!(
551 alg,
552 Algorithm::RS256
553 | Algorithm::RS384
554 | Algorithm::RS512
555 | Algorithm::PS256
556 | Algorithm::PS384
557 | Algorithm::PS512
558 ) {
559 return Err(Error::InvalidKey);
560 }
561 let key = rsa::PublicKey::from_n_e(n, e).map_err(|_| Error::InvalidKey)?;
562 Ok(RsaPublicKey {
563 key,
564 alg,
565 })
566 }
567
568 pub fn from_pkcs1_der(pkcs1_der: &[u8], alg: Algorithm) -> Result<Self, Error> {
578 if !matches!(
579 alg,
580 Algorithm::RS256
581 | Algorithm::RS384
582 | Algorithm::RS512
583 | Algorithm::PS256
584 | Algorithm::PS384
585 | Algorithm::PS512
586 ) {
587 return Err(Error::InvalidKey);
588 }
589 let key = rsa::PublicKey::from_pkcs1_der(pkcs1_der).map_err(|_| Error::InvalidKey)?;
590 Ok(RsaPublicKey {
591 key,
592 alg,
593 })
594 }
595}
596
597impl Verifier for RsaPublicKey {
598 fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), Error> {
599 match self.alg {
600 Algorithm::RS256 => {
601 let digest = Sha256::hash(message);
602 self.key
603 .verify_pkcs1_v1_5(signature, digest.as_ref(), rsa::DIGEST_INFO_SHA256_PREFIX)
604 }
605 Algorithm::RS384 => {
606 let digest = Sha384::hash(message);
607 self.key
608 .verify_pkcs1_v1_5(signature, digest.as_ref(), rsa::DIGEST_INFO_SHA384_PREFIX)
609 }
610 Algorithm::RS512 => {
611 let digest = Sha512::hash(message);
612 self.key
613 .verify_pkcs1_v1_5(signature, digest.as_ref(), rsa::DIGEST_INFO_SHA512_PREFIX)
614 }
615 Algorithm::PS256 => self.key.verify_pss::<Sha256>(signature, message, Sha256::OUTPUT_SIZE),
616 Algorithm::PS384 => self.key.verify_pss::<Sha384>(signature, message, Sha384::OUTPUT_SIZE),
617 Algorithm::PS512 => self.key.verify_pss::<Sha512>(signature, message, Sha512::OUTPUT_SIZE),
618 _ => return Err(Error::InvalidKey),
619 }
620 .map_err(|_| Error::InvalidSignature)
621 }
622
623 #[inline(always)]
624 fn algorithm(&self) -> Algorithm {
625 self.alg
626 }
627}