1use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey};
4use thiserror::Error;
5use zeroize::ZeroizeOnDrop;
6
7pub type SecretKey = [u8; 32];
9
10pub type PublicKey = [u8; 32];
12
13pub type SignatureBytes = [u8; 64];
15
16#[derive(Debug, Error)]
17pub enum SigningError {
18 #[error("Invalid secret key")]
19 InvalidSecretKey,
20
21 #[error("Invalid public key")]
22 InvalidPublicKey,
23
24 #[error("Invalid signature")]
25 InvalidSignature,
26
27 #[error("Signature verification failed")]
28 VerificationFailed,
29}
30
31#[derive(ZeroizeOnDrop)]
35pub struct KeyPair {
36 signing_key: SigningKey,
37}
38
39impl Clone for KeyPair {
40 fn clone(&self) -> Self {
41 let secret = self.signing_key.to_bytes();
43 Self {
44 signing_key: SigningKey::from_bytes(&secret),
45 }
46 }
47}
48
49impl KeyPair {
50 pub fn generate() -> Self {
52 let mut secret = [0u8; 32];
53 getrandom::fill(&mut secret).expect("Failed to generate random bytes");
54 let signing_key = SigningKey::from_bytes(&secret);
55 Self { signing_key }
56 }
57
58 pub fn from_secret_key(secret: &SecretKey) -> Result<Self, SigningError> {
60 let signing_key = SigningKey::from_bytes(secret);
61 Ok(Self { signing_key })
62 }
63
64 pub fn secret_key(&self) -> SecretKey {
66 self.signing_key.to_bytes()
67 }
68
69 pub fn public_key(&self) -> PublicKey {
71 self.signing_key.verifying_key().to_bytes()
72 }
73
74 pub fn sign(&self, message: &[u8]) -> SignatureBytes {
76 let signature = self.signing_key.sign(message);
77 signature.to_bytes()
78 }
79
80 pub fn verify(&self, message: &[u8], signature: &[u8]) -> bool {
82 if signature.len() != 64 {
83 return false;
84 }
85 let mut sig_bytes = [0u8; 64];
86 sig_bytes.copy_from_slice(signature);
87 verify(&self.public_key(), message, &sig_bytes).is_ok()
88 }
89}
90
91pub fn verify(
93 public_key: &PublicKey,
94 message: &[u8],
95 signature: &SignatureBytes,
96) -> Result<(), SigningError> {
97 let verifying_key =
98 VerifyingKey::from_bytes(public_key).map_err(|_| SigningError::InvalidPublicKey)?;
99
100 let signature = Signature::from_bytes(signature);
101
102 verifying_key
103 .verify(message, &signature)
104 .map_err(|_| SigningError::VerificationFailed)
105}
106
107#[derive(Debug, Clone)]
109pub struct BatchVerifyItem {
110 pub public_key: PublicKey,
112 pub message: Vec<u8>,
114 pub signature: SignatureBytes,
116}
117
118impl BatchVerifyItem {
119 pub fn new(public_key: PublicKey, message: Vec<u8>, signature: SignatureBytes) -> Self {
121 Self {
122 public_key,
123 message,
124 signature,
125 }
126 }
127}
128
129#[derive(Debug, Clone)]
131pub struct BatchVerifyResult {
132 pub total: usize,
134 pub valid_count: usize,
136 pub invalid_count: usize,
138 pub invalid_indices: Vec<usize>,
140 pub all_valid: bool,
142}
143
144pub fn verify_batch(items: &[BatchVerifyItem]) -> Result<BatchVerifyResult, SigningError> {
150 if items.is_empty() {
151 return Ok(BatchVerifyResult {
152 total: 0,
153 valid_count: 0,
154 invalid_count: 0,
155 invalid_indices: vec![],
156 all_valid: true,
157 });
158 }
159
160 let mut verifying_keys = Vec::with_capacity(items.len());
162 let mut signatures = Vec::with_capacity(items.len());
163 let messages: Vec<&[u8]> = items.iter().map(|item| item.message.as_slice()).collect();
164
165 for item in items {
166 let vk = VerifyingKey::from_bytes(&item.public_key)
167 .map_err(|_| SigningError::InvalidPublicKey)?;
168 let sig = Signature::from_bytes(&item.signature);
169 verifying_keys.push(vk);
170 signatures.push(sig);
171 }
172
173 let batch_result = ed25519_dalek::verify_batch(&messages, &signatures, &verifying_keys);
175
176 if batch_result.is_ok() {
177 return Ok(BatchVerifyResult {
179 total: items.len(),
180 valid_count: items.len(),
181 invalid_count: 0,
182 invalid_indices: vec![],
183 all_valid: true,
184 });
185 }
186
187 let mut invalid_indices = Vec::new();
189 let mut valid_count = 0;
190
191 for (i, item) in items.iter().enumerate() {
192 match verify(&item.public_key, &item.message, &item.signature) {
193 Ok(()) => valid_count += 1,
194 Err(_) => invalid_indices.push(i),
195 }
196 }
197
198 Ok(BatchVerifyResult {
199 total: items.len(),
200 valid_count,
201 invalid_count: invalid_indices.len(),
202 invalid_indices,
203 all_valid: false,
204 })
205}
206
207pub fn verify_batch_fast(items: &[BatchVerifyItem]) -> bool {
211 if items.is_empty() {
212 return true;
213 }
214
215 let mut verifying_keys = Vec::with_capacity(items.len());
217 let mut signatures = Vec::with_capacity(items.len());
218 let messages: Vec<&[u8]> = items.iter().map(|item| item.message.as_slice()).collect();
219
220 for item in items {
221 match VerifyingKey::from_bytes(&item.public_key) {
222 Ok(vk) => verifying_keys.push(vk),
223 Err(_) => return false,
224 }
225 signatures.push(Signature::from_bytes(&item.signature));
226 }
227
228 ed25519_dalek::verify_batch(&messages, &signatures, &verifying_keys).is_ok()
229}
230
231pub fn verify_dual_signatures(
233 provider_pubkey: &PublicKey,
234 requester_pubkey: &PublicKey,
235 provider_message: &[u8],
236 requester_message: &[u8],
237 provider_signature: &SignatureBytes,
238 requester_signature: &SignatureBytes,
239) -> Result<(), SigningError> {
240 let items = vec![
241 BatchVerifyItem::new(
242 *provider_pubkey,
243 provider_message.to_vec(),
244 *provider_signature,
245 ),
246 BatchVerifyItem::new(
247 *requester_pubkey,
248 requester_message.to_vec(),
249 *requester_signature,
250 ),
251 ];
252
253 let result = verify_batch(&items)?;
254 if result.all_valid {
255 Ok(())
256 } else {
257 Err(SigningError::VerificationFailed)
258 }
259}
260
261#[cfg(test)]
262mod tests {
263 use super::*;
264
265 #[test]
266 fn test_sign_verify() {
267 let keypair = KeyPair::generate();
268 let message = b"Hello, CHIE Protocol!";
269
270 let signature = keypair.sign(message);
271 let public_key = keypair.public_key();
272
273 assert!(verify(&public_key, message, &signature).is_ok());
274 assert!(verify(&public_key, b"Wrong message", &signature).is_err());
275 }
276
277 #[test]
278 fn test_keypair_from_secret() {
279 let keypair1 = KeyPair::generate();
280 let secret = keypair1.secret_key();
281 let keypair2 = KeyPair::from_secret_key(&secret).unwrap();
282
283 assert_eq!(keypair1.public_key(), keypair2.public_key());
284 }
285
286 #[test]
287 fn test_verify_with_wrong_public_key() {
288 let keypair1 = KeyPair::generate();
289 let keypair2 = KeyPair::generate();
290 let message = b"Test message";
291
292 let signature = keypair1.sign(message);
293 let wrong_pubkey = keypair2.public_key();
294
295 let result = verify(&wrong_pubkey, message, &signature);
296 assert!(result.is_err());
297 assert!(matches!(result, Err(SigningError::VerificationFailed)));
298 }
299
300 #[test]
301 fn test_invalid_signature_format() {
302 let keypair = KeyPair::generate();
303 let message = b"Test message";
304
305 let mut signature = keypair.sign(message);
306 signature[0] ^= 0xFF;
308
309 let result = verify(&keypair.public_key(), message, &signature);
310 assert!(result.is_err());
311 assert!(matches!(result, Err(SigningError::VerificationFailed)));
312 }
313
314 #[test]
315 fn test_keypair_verify_method() {
316 let keypair = KeyPair::generate();
317 let message = b"Test message";
318
319 let signature = keypair.sign(message);
320 assert!(keypair.verify(message, &signature));
321 assert!(!keypair.verify(b"Wrong message", &signature));
322 }
323
324 #[test]
325 fn test_keypair_verify_invalid_signature_length() {
326 let keypair = KeyPair::generate();
327 let message = b"Test message";
328
329 let short_sig = [0u8; 32];
331 assert!(!keypair.verify(message, &short_sig));
332
333 let long_sig = [0u8; 96];
335 assert!(!keypair.verify(message, &long_sig));
336 }
337
338 #[test]
339 fn test_batch_verify_all_valid() {
340 let mut items = Vec::new();
341 for _ in 0..10 {
342 let keypair = KeyPair::generate();
343 let message = b"Test message";
344 let signature = keypair.sign(message);
345 items.push(BatchVerifyItem::new(
346 keypair.public_key(),
347 message.to_vec(),
348 signature,
349 ));
350 }
351
352 let result = verify_batch(&items).unwrap();
353 assert_eq!(result.total, 10);
354 assert_eq!(result.valid_count, 10);
355 assert_eq!(result.invalid_count, 0);
356 assert!(result.all_valid);
357 assert!(result.invalid_indices.is_empty());
358 }
359
360 #[test]
361 fn test_batch_verify_some_invalid() {
362 let mut items = Vec::new();
363
364 for _ in 0..5 {
366 let keypair = KeyPair::generate();
367 let message = b"Valid message";
368 let signature = keypair.sign(message);
369 items.push(BatchVerifyItem::new(
370 keypair.public_key(),
371 message.to_vec(),
372 signature,
373 ));
374 }
375
376 for _ in 0..3 {
378 let keypair = KeyPair::generate();
379 let message = b"Original message";
380 let signature = keypair.sign(message);
381 items.push(BatchVerifyItem::new(
382 keypair.public_key(),
383 b"Different message".to_vec(), signature,
385 ));
386 }
387
388 let result = verify_batch(&items).unwrap();
389 assert_eq!(result.total, 8);
390 assert_eq!(result.valid_count, 5);
391 assert_eq!(result.invalid_count, 3);
392 assert!(!result.all_valid);
393 assert_eq!(result.invalid_indices, vec![5, 6, 7]);
394 }
395
396 #[test]
397 fn test_batch_verify_empty() {
398 let items = vec![];
399 let result = verify_batch(&items).unwrap();
400 assert_eq!(result.total, 0);
401 assert_eq!(result.valid_count, 0);
402 assert_eq!(result.invalid_count, 0);
403 assert!(result.all_valid);
404 }
405
406 #[test]
407 fn test_batch_verify_fast_all_valid() {
408 let mut items = Vec::new();
409 for _ in 0..10 {
410 let keypair = KeyPair::generate();
411 let message = b"Test message";
412 let signature = keypair.sign(message);
413 items.push(BatchVerifyItem::new(
414 keypair.public_key(),
415 message.to_vec(),
416 signature,
417 ));
418 }
419
420 assert!(verify_batch_fast(&items));
421 }
422
423 #[test]
424 fn test_batch_verify_fast_one_invalid() {
425 let mut items = Vec::new();
426
427 for _ in 0..5 {
429 let keypair = KeyPair::generate();
430 let message = b"Valid message";
431 let signature = keypair.sign(message);
432 items.push(BatchVerifyItem::new(
433 keypair.public_key(),
434 message.to_vec(),
435 signature,
436 ));
437 }
438
439 let keypair = KeyPair::generate();
441 let signature = keypair.sign(b"Original");
442 items.push(BatchVerifyItem::new(
443 keypair.public_key(),
444 b"Modified".to_vec(),
445 signature,
446 ));
447
448 assert!(!verify_batch_fast(&items));
449 }
450
451 #[test]
452 fn test_batch_verify_fast_empty() {
453 let items = vec![];
454 assert!(verify_batch_fast(&items));
455 }
456
457 #[test]
458 fn test_dual_signatures_valid() {
459 let provider = KeyPair::generate();
460 let requester = KeyPair::generate();
461
462 let provider_msg = b"Provider proof";
463 let requester_msg = b"Requester proof";
464
465 let provider_sig = provider.sign(provider_msg);
466 let requester_sig = requester.sign(requester_msg);
467
468 let result = verify_dual_signatures(
469 &provider.public_key(),
470 &requester.public_key(),
471 provider_msg,
472 requester_msg,
473 &provider_sig,
474 &requester_sig,
475 );
476
477 assert!(result.is_ok());
478 }
479
480 #[test]
481 fn test_dual_signatures_invalid_provider() {
482 let provider = KeyPair::generate();
483 let requester = KeyPair::generate();
484
485 let provider_msg = b"Provider proof";
486 let requester_msg = b"Requester proof";
487
488 let provider_sig = provider.sign(b"Wrong message");
489 let requester_sig = requester.sign(requester_msg);
490
491 let result = verify_dual_signatures(
492 &provider.public_key(),
493 &requester.public_key(),
494 provider_msg,
495 requester_msg,
496 &provider_sig,
497 &requester_sig,
498 );
499
500 assert!(result.is_err());
501 assert!(matches!(result, Err(SigningError::VerificationFailed)));
502 }
503
504 #[test]
505 fn test_dual_signatures_invalid_requester() {
506 let provider = KeyPair::generate();
507 let requester = KeyPair::generate();
508
509 let provider_msg = b"Provider proof";
510 let requester_msg = b"Requester proof";
511
512 let provider_sig = provider.sign(provider_msg);
513 let requester_sig = requester.sign(b"Wrong message");
514
515 let result = verify_dual_signatures(
516 &provider.public_key(),
517 &requester.public_key(),
518 provider_msg,
519 requester_msg,
520 &provider_sig,
521 &requester_sig,
522 );
523
524 assert!(result.is_err());
525 assert!(matches!(result, Err(SigningError::VerificationFailed)));
526 }
527
528 #[test]
529 fn test_keypair_clone() {
530 let keypair1 = KeyPair::generate();
531 let keypair2 = keypair1.clone();
532
533 let message = b"Test message";
534 let sig1 = keypair1.sign(message);
535 let sig2 = keypair2.sign(message);
536
537 assert!(verify(&keypair1.public_key(), message, &sig1).is_ok());
539 assert!(verify(&keypair2.public_key(), message, &sig2).is_ok());
540 assert!(verify(&keypair1.public_key(), message, &sig2).is_ok());
541 assert!(verify(&keypair2.public_key(), message, &sig1).is_ok());
542
543 assert_eq!(keypair1.public_key(), keypair2.public_key());
545 }
546
547 #[test]
548 fn test_signature_determinism() {
549 let keypair = KeyPair::generate();
550 let message = b"Deterministic test";
551
552 let sig1 = keypair.sign(message);
553 let sig2 = keypair.sign(message);
554
555 assert_eq!(sig1, sig2);
557 }
558
559 #[test]
560 fn test_different_messages_different_signatures() {
561 let keypair = KeyPair::generate();
562 let message1 = b"First message";
563 let message2 = b"Second message";
564
565 let sig1 = keypair.sign(message1);
566 let sig2 = keypair.sign(message2);
567
568 assert_ne!(sig1, sig2);
569 }
570
571 #[test]
572 fn test_keypair_generation_randomness() {
573 let keypair1 = KeyPair::generate();
574 let keypair2 = KeyPair::generate();
575 let keypair3 = KeyPair::generate();
576
577 assert_ne!(keypair1.public_key(), keypair2.public_key());
579 assert_ne!(keypair2.public_key(), keypair3.public_key());
580 assert_ne!(keypair1.public_key(), keypair3.public_key());
581 }
582}