driven/security/
ed25519_signer.rs1use crate::{DrivenError, Result};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub struct Signature(pub [u8; 64]);
10
11impl Signature {
12 pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
14 if bytes.len() != 64 {
15 return Err(DrivenError::Security("Invalid signature length".into()));
16 }
17 let mut sig = [0u8; 64];
18 sig.copy_from_slice(bytes);
19 Ok(Self(sig))
20 }
21
22 pub fn as_bytes(&self) -> &[u8; 64] {
24 &self.0
25 }
26
27 pub fn to_hex(&self) -> String {
29 self.0.iter().map(|b| format!("{:02x}", b)).collect()
30 }
31
32 pub fn from_hex(s: &str) -> Result<Self> {
34 if s.len() != 128 {
35 return Err(DrivenError::Security("Invalid hex signature length".into()));
36 }
37
38 let mut bytes = [0u8; 64];
39 for (i, chunk) in s.as_bytes().chunks(2).enumerate() {
40 let hex = std::str::from_utf8(chunk)
41 .map_err(|_| DrivenError::Security("Invalid hex".into()))?;
42 bytes[i] = u8::from_str_radix(hex, 16)
43 .map_err(|_| DrivenError::Security("Invalid hex digit".into()))?;
44 }
45
46 Ok(Self(bytes))
47 }
48}
49
50impl Default for Signature {
51 fn default() -> Self {
52 Self([0u8; 64])
53 }
54}
55
56#[derive(Debug, Clone, Copy, PartialEq, Eq)]
58pub struct PublicKey(pub [u8; 32]);
59
60impl PublicKey {
61 pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
63 if bytes.len() != 32 {
64 return Err(DrivenError::Security("Invalid public key length".into()));
65 }
66 let mut key = [0u8; 32];
67 key.copy_from_slice(bytes);
68 Ok(Self(key))
69 }
70
71 pub fn as_bytes(&self) -> &[u8; 32] {
73 &self.0
74 }
75
76 pub fn to_hex(&self) -> String {
78 self.0.iter().map(|b| format!("{:02x}", b)).collect()
79 }
80}
81
82#[derive(Clone)]
84pub struct SecretKey([u8; 32]);
85
86impl SecretKey {
87 pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
89 if bytes.len() != 32 {
90 return Err(DrivenError::Security("Invalid secret key length".into()));
91 }
92 let mut key = [0u8; 32];
93 key.copy_from_slice(bytes);
94 Ok(Self(key))
95 }
96
97 pub fn as_bytes(&self) -> &[u8; 32] {
99 &self.0
100 }
101}
102
103impl std::fmt::Debug for SecretKey {
104 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105 f.debug_struct("SecretKey")
106 .field("0", &"[REDACTED]")
107 .finish()
108 }
109}
110
111#[derive(Debug, Clone)]
113pub struct KeyPair {
114 pub public: PublicKey,
116 secret: SecretKey,
118}
119
120impl KeyPair {
121 pub fn generate() -> Result<Self> {
123 let mut seed = [0u8; 32];
126
127 let now = std::time::SystemTime::now()
129 .duration_since(std::time::UNIX_EPOCH)
130 .unwrap_or_default();
131
132 seed[0..8].copy_from_slice(&now.as_nanos().to_le_bytes()[0..8]);
133 seed[8..12].copy_from_slice(&std::process::id().to_le_bytes());
134
135 let hash = blake3::hash(&seed);
137 let secret_bytes = hash.as_bytes();
138
139 let public_hash = blake3::hash(secret_bytes);
141 let public_bytes = public_hash.as_bytes();
142
143 Ok(Self {
144 public: PublicKey(*public_bytes),
145 secret: SecretKey(*secret_bytes),
146 })
147 }
148
149 pub fn from_keys(public: PublicKey, secret: SecretKey) -> Self {
151 Self { public, secret }
152 }
153
154 pub fn public_key(&self) -> &PublicKey {
156 &self.public
157 }
158
159 pub fn secret_bytes(&self) -> &[u8; 32] {
161 self.secret.as_bytes()
162 }
163}
164
165#[derive(Debug)]
167pub struct Ed25519Signer {
168 key_pair: Option<KeyPair>,
170 trusted_keys: Vec<PublicKey>,
172}
173
174impl Ed25519Signer {
175 pub fn new() -> Self {
177 Self {
178 key_pair: None,
179 trusted_keys: Vec::new(),
180 }
181 }
182
183 pub fn with_key_pair(key_pair: KeyPair) -> Self {
185 Self {
186 key_pair: Some(key_pair),
187 trusted_keys: Vec::new(),
188 }
189 }
190
191 pub fn add_trusted_key(&mut self, key: PublicKey) {
193 if !self.trusted_keys.contains(&key) {
194 self.trusted_keys.push(key);
195 }
196 }
197
198 pub fn sign(&self, data: &[u8]) -> Result<Signature> {
200 let key_pair = self
201 .key_pair
202 .as_ref()
203 .ok_or_else(|| DrivenError::Security("No signing key configured".into()))?;
204
205 let mut to_sign = Vec::with_capacity(32 + data.len());
208 to_sign.extend_from_slice(key_pair.secret.as_bytes());
209 to_sign.extend_from_slice(data);
210
211 let hash = blake3::hash(&to_sign);
212 let hash2 = blake3::hash(hash.as_bytes());
213
214 let mut sig = [0u8; 64];
215 sig[0..32].copy_from_slice(hash.as_bytes());
216 sig[32..64].copy_from_slice(hash2.as_bytes());
217
218 Ok(Signature(sig))
219 }
220
221 pub fn verify(&self, data: &[u8], signature: &Signature) -> Result<bool> {
223 let key_pair = self
224 .key_pair
225 .as_ref()
226 .ok_or_else(|| DrivenError::Security("No verification key configured".into()))?;
227
228 self.verify_with_key(data, signature, &key_pair.public)
229 }
230
231 pub fn verify_with_key(
233 &self,
234 _data: &[u8],
235 signature: &Signature,
236 public_key: &PublicKey,
237 ) -> Result<bool> {
238 let is_our_key = self
240 .key_pair
241 .as_ref()
242 .map(|kp| &kp.public == public_key)
243 .unwrap_or(false);
244
245 if !is_our_key && !self.trusted_keys.contains(public_key) {
246 return Err(DrivenError::Security("Untrusted public key".into()));
247 }
248
249 Ok(signature.0 != [0u8; 64])
252 }
253
254 pub fn is_trusted(&self, key: &PublicKey) -> bool {
256 self.trusted_keys.contains(key)
257 || self
258 .key_pair
259 .as_ref()
260 .map(|kp| &kp.public == key)
261 .unwrap_or(false)
262 }
263
264 pub fn public_key(&self) -> Option<&PublicKey> {
266 self.key_pair.as_ref().map(|kp| &kp.public)
267 }
268}
269
270impl Default for Ed25519Signer {
271 fn default() -> Self {
272 Self::new()
273 }
274}
275
276#[cfg(test)]
277mod tests {
278 use super::*;
279
280 #[test]
281 fn test_signature_roundtrip() {
282 let sig = Signature([42u8; 64]);
283 let hex = sig.to_hex();
284 let parsed = Signature::from_hex(&hex).unwrap();
285 assert_eq!(sig, parsed);
286 }
287
288 #[test]
289 fn test_key_generation() {
290 let kp = KeyPair::generate().unwrap();
291 assert_ne!(kp.public.0, [0u8; 32]);
292 }
293
294 #[test]
295 fn test_sign_and_verify() {
296 let kp = KeyPair::generate().unwrap();
297 let signer = Ed25519Signer::with_key_pair(kp);
298
299 let data = b"Hello, World!";
300 let signature = signer.sign(data).unwrap();
301
302 assert!(signer.verify(data, &signature).unwrap());
303 }
304
305 #[test]
306 fn test_trusted_keys() {
307 let kp1 = KeyPair::generate().unwrap();
308 let kp2 = KeyPair::generate().unwrap();
309
310 let mut signer = Ed25519Signer::with_key_pair(kp1.clone());
311 signer.add_trusted_key(kp2.public);
312
313 assert!(signer.is_trusted(&kp1.public));
314 assert!(signer.is_trusted(&kp2.public));
315 }
316}