ant_quic/crypto/
raw_keys.rs1use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey};
8use rand::rngs::OsRng;
9use thiserror::Error;
10
11#[derive(Debug, Error)]
13pub enum RawKeyError {
14 #[error("Invalid key format: {0}")]
15 InvalidFormat(String),
16
17 #[error("Verification failed")]
18 VerificationFailed,
19
20 #[error("Encoding error: {0}")]
21 EncodingError(String),
22
23 #[error("Decoding error: {0}")]
24 DecodingError(String),
25}
26
27#[derive(Clone, Debug)]
29pub struct Ed25519KeyPair {
30 signing_key: SigningKey,
31 verifying_key: VerifyingKey,
32}
33
34impl Ed25519KeyPair {
35 pub fn generate() -> Self {
37 let signing_key = SigningKey::generate(&mut OsRng);
38 let verifying_key = VerifyingKey::from(&signing_key);
39
40 Self {
41 signing_key,
42 verifying_key,
43 }
44 }
45
46 pub fn from_signing_key(signing_key: SigningKey) -> Self {
48 let verifying_key = VerifyingKey::from(&signing_key);
49 Self {
50 signing_key,
51 verifying_key,
52 }
53 }
54
55 pub fn public_key_spki(&self) -> Vec<u8> {
57 create_ed25519_subject_public_key_info(&self.verifying_key)
58 }
59
60 pub fn public_key_bytes(&self) -> [u8; 32] {
62 *self.verifying_key.as_bytes()
63 }
64
65 pub fn verifying_key(&self) -> &VerifyingKey {
67 &self.verifying_key
68 }
69
70 pub fn sign(&self, data: &[u8]) -> Signature {
72 self.signing_key.sign(data)
73 }
74
75 pub fn verify(&self, data: &[u8], signature: &Signature) -> Result<(), RawKeyError> {
77 self.verifying_key
78 .verify(data, signature)
79 .map_err(|_| RawKeyError::VerificationFailed)
80 }
81}
82
83pub fn create_ed25519_subject_public_key_info(public_key: &VerifyingKey) -> Vec<u8> {
88 let mut spki = Vec::with_capacity(44);
98
99 spki.extend_from_slice(&[0x30, 0x2a]);
101
102 spki.extend_from_slice(&[0x30, 0x05]);
104
105 spki.extend_from_slice(&[0x06, 0x03, 0x2b, 0x65, 0x70]);
107
108 spki.extend_from_slice(&[0x03, 0x21, 0x00]); spki.extend_from_slice(public_key.as_bytes());
113
114 spki
115}
116
117pub fn extract_ed25519_key_from_spki(spki_der: &[u8]) -> Result<[u8; 32], RawKeyError> {
122 if spki_der.len() != 44 {
124 return Err(RawKeyError::InvalidFormat(format!(
125 "Invalid SPKI length: expected 44 bytes, got {}",
126 spki_der.len()
127 )));
128 }
129
130 let ed25519_oid = [0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70];
132
133 if !spki_der.starts_with(&ed25519_oid) {
134 return Err(RawKeyError::InvalidFormat(
135 "Invalid SPKI format: Ed25519 OID not found".to_string(),
136 ));
137 }
138
139 let mut public_key = [0u8; 32];
141 public_key.copy_from_slice(&spki_der[12..44]);
142
143 Ok(public_key)
144}
145
146pub fn verifying_key_from_spki(spki_der: &[u8]) -> Result<VerifyingKey, RawKeyError> {
148 let key_bytes = extract_ed25519_key_from_spki(spki_der)?;
149 VerifyingKey::from_bytes(&key_bytes)
150 .map_err(|e| RawKeyError::InvalidFormat(format!("Invalid Ed25519 public key: {e}")))
151}
152
153pub fn derive_peer_id_from_public_key(public_key: &VerifyingKey) -> [u8; 32] {
159 let key_bytes = public_key.as_bytes();
160
161 let mut input = Vec::with_capacity(20 + 32); input.extend_from_slice(b"AUTONOMI_PEER_ID_V1:");
164 input.extend_from_slice(key_bytes);
165
166 #[cfg(all(feature = "ring", not(feature = "aws-lc-rs")))]
167 {
168 use ring::digest::{SHA256, digest};
170
171 let hash = digest(&SHA256, &input);
173 let hash_bytes = hash.as_ref();
174
175 let mut peer_id_bytes = [0u8; 32];
176 peer_id_bytes.copy_from_slice(hash_bytes);
177 peer_id_bytes
178 }
179
180 #[cfg(feature = "aws-lc-rs")]
181 {
182 use aws_lc_rs::digest;
183
184 let hash = digest::digest(&digest::SHA256, &input);
186 let hash_bytes = hash.as_ref();
187
188 let mut peer_id_bytes = [0u8; 32];
189 peer_id_bytes.copy_from_slice(hash_bytes);
190 peer_id_bytes
191 }
192
193 #[cfg(not(any(feature = "ring", feature = "aws-lc-rs")))]
194 {
195 use sha2::{Digest, Sha256};
197
198 let mut hasher = Sha256::new();
199 hasher.update(&input);
200 let result = hasher.finalize();
201
202 let mut peer_id_bytes = [0u8; 32];
203 peer_id_bytes.copy_from_slice(&result);
204 peer_id_bytes
205 }
206}
207
208pub fn verify_peer_id(peer_id: &[u8; 32], public_key: &VerifyingKey) -> bool {
210 let derived_id = derive_peer_id_from_public_key(public_key);
211 peer_id == &derived_id
212}
213
214pub fn generate_ed25519_keypair() -> Ed25519KeyPair {
216 Ed25519KeyPair::generate()
217}
218
219#[cfg(test)]
220mod tests {
221 use super::*;
222
223 #[test]
224 fn test_keypair_generation() {
225 let keypair = Ed25519KeyPair::generate();
226 let signature = keypair.sign(b"test message");
227 assert!(keypair.verify(b"test message", &signature).is_ok());
228 assert!(keypair.verify(b"wrong message", &signature).is_err());
229 }
230
231 #[test]
232 fn test_spki_encoding_decoding() {
233 let keypair = Ed25519KeyPair::generate();
234 let spki = keypair.public_key_spki();
235
236 assert_eq!(spki.len(), 44);
238 assert_eq!(&spki[0..2], &[0x30, 0x2a]); let extracted_key = extract_ed25519_key_from_spki(&spki).unwrap();
242 assert_eq!(extracted_key, keypair.public_key_bytes());
243
244 let verifying_key = verifying_key_from_spki(&spki).unwrap();
246 assert_eq!(verifying_key.as_bytes(), keypair.verifying_key().as_bytes());
247 }
248
249 #[test]
250 fn test_peer_id_derivation() {
251 let keypair1 = Ed25519KeyPair::generate();
252 let keypair2 = Ed25519KeyPair::generate();
253
254 let peer_id1 = derive_peer_id_from_public_key(keypair1.verifying_key());
255 let peer_id2 = derive_peer_id_from_public_key(keypair1.verifying_key());
256 let peer_id3 = derive_peer_id_from_public_key(keypair2.verifying_key());
257
258 assert_eq!(peer_id1, peer_id2);
260
261 assert_ne!(peer_id1, peer_id3);
263
264 assert!(verify_peer_id(&peer_id1, keypair1.verifying_key()));
266 assert!(!verify_peer_id(&peer_id1, keypair2.verifying_key()));
267 }
268
269 #[test]
270 fn test_invalid_spki() {
271 let result = extract_ed25519_key_from_spki(&[0; 43]);
273 assert!(result.is_err());
274
275 let mut invalid_spki = vec![0; 44];
277 invalid_spki[7] = 0xFF; let result = extract_ed25519_key_from_spki(&invalid_spki);
279 assert!(result.is_err());
280 }
281}