zlicenser_protocol/crypto/
signature.rs1use ed25519_dalek::{Signer, Verifier};
2use rand::rngs::OsRng;
3use rand::RngCore;
4use subtle::ConstantTimeEq;
5use zeroize::{Zeroize, ZeroizeOnDrop};
6
7use crate::error::Error;
8
9#[derive(Zeroize, ZeroizeOnDrop)]
11pub struct SigningKey([u8; 32]);
12
13impl SigningKey {
14 pub fn generate() -> Self {
15 let mut b = [0u8; 32];
16 OsRng.fill_bytes(&mut b);
17 Self(b)
18 }
19
20 pub fn from_bytes(b: &[u8; 32]) -> Self {
21 Self(*b)
22 }
23
24 pub fn to_bytes(&self) -> [u8; 32] {
25 self.0
26 }
27
28 pub fn verifying_key(&self) -> VerifyingKey {
29 VerifyingKey(ed25519_dalek::SigningKey::from_bytes(&self.0).verifying_key())
30 }
31
32 pub fn sign(&self, msg: &[u8]) -> Signature {
33 Signature(ed25519_dalek::SigningKey::from_bytes(&self.0).sign(msg))
34 }
35}
36
37impl PartialEq for SigningKey {
38 fn eq(&self, other: &Self) -> bool {
39 self.0.ct_eq(&other.0).into()
40 }
41}
42
43#[derive(Debug, Clone)]
44pub struct VerifyingKey(ed25519_dalek::VerifyingKey);
45
46impl VerifyingKey {
47 pub fn from_bytes(b: &[u8; 32]) -> Result<Self, Error> {
48 ed25519_dalek::VerifyingKey::from_bytes(b)
49 .map(Self)
50 .map_err(|_| Error::Malformed("invalid Ed25519 verifying key"))
51 }
52
53 pub fn to_bytes(&self) -> [u8; 32] {
54 self.0.to_bytes()
55 }
56
57 pub fn verify(&self, msg: &[u8], sig: &Signature) -> Result<(), Error> {
58 self.0
59 .verify(msg, &sig.0)
60 .map_err(|_| Error::SignatureInvalid)
61 }
62}
63
64impl PartialEq for VerifyingKey {
65 fn eq(&self, other: &Self) -> bool {
66 self.0.as_bytes().ct_eq(other.0.as_bytes()).into()
67 }
68}
69
70impl Eq for VerifyingKey {}
71
72#[derive(Debug, Clone)]
73pub struct Signature(ed25519_dalek::Signature);
74
75impl Signature {
76 pub fn from_bytes(b: &[u8; 64]) -> Self {
77 Self(ed25519_dalek::Signature::from_bytes(b))
78 }
79
80 pub fn to_bytes(&self) -> [u8; 64] {
81 self.0.to_bytes()
82 }
83}
84
85impl PartialEq for Signature {
86 fn eq(&self, other: &Self) -> bool {
87 self.0.to_bytes().ct_eq(&other.0.to_bytes()).into()
88 }
89}
90
91impl Eq for Signature {}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
99 fn rfc8032_test_vector_1() {
100 let private_bytes: [u8; 32] = [
101 0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60, 0xba, 0x84, 0x4a, 0xf4, 0x92, 0xec,
102 0x2c, 0xc4, 0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32, 0x69, 0x19, 0x70, 0x3b, 0xac, 0x03,
103 0x1c, 0xae, 0x7f, 0x60,
104 ];
105 let expected_pub: [u8; 32] = [
106 0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b, 0xfe, 0xd3, 0xc9, 0x64,
107 0x07, 0x3a, 0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23, 0x25, 0xaf, 0x02, 0x1a, 0x68,
108 0xf7, 0x07, 0x51, 0x1a,
109 ];
110 let expected_sig: [u8; 64] = [
111 0xe5, 0x56, 0x43, 0x00, 0xc3, 0x60, 0xac, 0x72, 0x90, 0x86, 0xe2, 0xcc, 0x80, 0x6e,
112 0x82, 0x8a, 0x84, 0x87, 0x7f, 0x1e, 0xb8, 0xe5, 0xd9, 0x74, 0xd8, 0x73, 0xe0, 0x65,
113 0x22, 0x49, 0x01, 0x55, 0x5f, 0xb8, 0x82, 0x15, 0x90, 0xa3, 0x3b, 0xac, 0xc6, 0x1e,
114 0x39, 0x70, 0x1c, 0xf9, 0xb4, 0x6b, 0xd2, 0x5b, 0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24,
115 0x65, 0x51, 0x41, 0x43, 0x8e, 0x7a, 0x10, 0x0b,
116 ];
117
118 let sk = SigningKey::from_bytes(&private_bytes);
119 assert_eq!(sk.verifying_key().to_bytes(), expected_pub);
120 let sig = sk.sign(b"");
121 assert_eq!(sig.to_bytes(), expected_sig);
122 sk.verifying_key().verify(b"", &sig).unwrap();
123 }
124
125 #[test]
126 fn bit_flipped_signature_fails() {
127 let sk = SigningKey::generate();
128 let vk = sk.verifying_key();
129 let mut sig_bytes = sk.sign(b"message").to_bytes();
130 sig_bytes[0] ^= 0x01;
131 let bad_sig = Signature::from_bytes(&sig_bytes);
132 assert!(matches!(
133 vk.verify(b"message", &bad_sig),
134 Err(Error::SignatureInvalid)
135 ));
136 }
137
138 #[test]
139 fn sign_verify_roundtrip() {
140 let sk = SigningKey::generate();
141 let msg = b"roundtrip test";
142 let sig = sk.sign(msg);
143 sk.verifying_key().verify(msg, &sig).unwrap();
144 }
145}