1#![forbid(unsafe_code)]
2
3pub mod ecdsa_p256;
20pub mod ecdsa_p384;
21pub mod ecdsa_p521;
22pub mod ed448;
23pub mod ed448_ext;
24pub mod frost;
25pub mod rsa_sig;
26pub mod schnorr;
27
28pub use ecdsa_p256::{EcdsaP256Signer, EcdsaP256Verifier};
29pub use ecdsa_p384::{EcdsaP384Signer, EcdsaP384Verifier};
30pub use ecdsa_p521::{EcdsaP521Signer, EcdsaP521Verifier};
31pub use ed448::{Ed448SigningKey, Ed448VerifyingKey};
32pub use ed448_ext::{ed448ctx_sign, ed448ctx_verify, ed448ph_sign, ed448ph_verify};
33pub use rsa_sig::{
34 rsa_generate_keypair, rsa_oaep_sha256_decrypt, rsa_oaep_sha256_encrypt,
35 RsaPkcs1v15Sha256Signer, RsaPkcs1v15Sha256Verifier, RsaPkcs1v15Sha384Signer,
36 RsaPkcs1v15Sha384Verifier, RsaPkcs1v15Sha512Signer, RsaPkcs1v15Sha512Verifier,
37 RsaPssSha256Signer, RsaPssSha256Verifier, RsaPssSha384Signer, RsaPssSha384Verifier,
38 RsaPssSha512Signer, RsaPssSha512Verifier,
39};
40pub use schnorr::{schnorr_bip340_sign_with_aux, SchnorrBip340};
41
42use ed25519_dalek::{Signature, SigningKey, VerifyingKey};
46use oxicrypto_core::{CryptoError, SecretKey, SecretVec, Signer, Verifier};
47use p256::elliptic_curve::Generate;
48
49#[must_use = "key pair result must be used"]
59pub fn ed25519_generate_keypair<R: rand_core::TryCryptoRng + ?Sized>(
60 rng: &mut R,
61) -> Result<(SecretKey<32>, [u8; 32]), CryptoError> {
62 let mut seed = [0u8; 32];
63 rng.try_fill_bytes(&mut seed)
64 .map_err(|_| CryptoError::Rng)?;
65 let signing_key = SigningKey::from_bytes(&seed);
66 let verifying_key = signing_key.verifying_key();
67 Ok((SecretKey::new(seed), *verifying_key.as_bytes()))
68}
69
70#[must_use = "key pair result must be used"]
75pub fn ecdsa_p256_generate_keypair<R: rand_core::TryCryptoRng + ?Sized>(
76 rng: &mut R,
77) -> Result<(SecretVec, Vec<u8>), CryptoError> {
78 let secret_key = p256::SecretKey::try_generate_from_rng(rng).map_err(|_| CryptoError::Rng)?;
79 let public_key = secret_key.public_key();
80 let sk_bytes = SecretVec::from_slice(secret_key.to_bytes().as_slice());
81 let pk_bytes = public_key.to_sec1_bytes().to_vec();
82 Ok((sk_bytes, pk_bytes))
83}
84
85#[must_use = "key pair result must be used"]
90pub fn ecdsa_p384_generate_keypair<R: rand_core::TryCryptoRng + ?Sized>(
91 rng: &mut R,
92) -> Result<(SecretVec, Vec<u8>), CryptoError> {
93 let secret_key = p384::SecretKey::try_generate_from_rng(rng).map_err(|_| CryptoError::Rng)?;
94 let public_key = secret_key.public_key();
95 let sk_bytes = SecretVec::from_slice(secret_key.to_bytes().as_slice());
96 let pk_bytes = public_key.to_sec1_bytes().to_vec();
97 Ok((sk_bytes, pk_bytes))
98}
99
100#[must_use = "key pair result must be used"]
105pub fn ecdsa_p521_generate_keypair<R: rand_core::TryCryptoRng + ?Sized>(
106 rng: &mut R,
107) -> Result<(SecretVec, Vec<u8>), CryptoError> {
108 let secret_key = p521::SecretKey::try_generate_from_rng(rng).map_err(|_| CryptoError::Rng)?;
109 let public_key = secret_key.public_key();
110 let sk_bytes = SecretVec::from_slice(secret_key.to_bytes().as_slice());
111 let pk_bytes = public_key.to_sec1_bytes().to_vec();
112 Ok((sk_bytes, pk_bytes))
113}
114
115#[must_use = "batch verification result must be checked"]
124pub fn ed25519_verify_batch(
125 messages: &[&[u8]],
126 signatures: &[Signature],
127 verifying_keys: &[VerifyingKey],
128) -> Result<(), CryptoError> {
129 use ed25519_dalek::Verifier as DalekVerifier;
130 if messages.len() != signatures.len() || messages.len() != verifying_keys.len() {
131 return Err(CryptoError::BadInput);
132 }
133 for ((msg, sig), vk) in messages
134 .iter()
135 .zip(signatures.iter())
136 .zip(verifying_keys.iter())
137 {
138 vk.verify(msg, sig).map_err(|_| CryptoError::Sign)?;
139 }
140 Ok(())
141}
142
143#[derive(Debug, Default, Clone, Copy)]
161pub struct EcdsaP256;
162
163impl Signer for EcdsaP256 {
164 fn name(&self) -> &'static str {
165 "ECDSA-P256"
166 }
167 fn signature_len(&self) -> usize {
168 72
169 } fn sign(&self, sk: &[u8], msg: &[u8], sig_out: &mut [u8]) -> Result<usize, CryptoError> {
171 let signer = EcdsaP256Signer::from_bytes(sk)?;
172 let sig_bytes = signer.sign(msg)?;
173 if sig_out.len() < sig_bytes.len() {
174 return Err(CryptoError::BufferTooSmall);
175 }
176 sig_out[..sig_bytes.len()].copy_from_slice(&sig_bytes);
177 Ok(sig_bytes.len())
178 }
179}
180
181#[derive(Debug, Default, Clone, Copy)]
185pub struct EcdsaP256Verify;
186
187impl Verifier for EcdsaP256Verify {
188 fn name(&self) -> &'static str {
189 "ECDSA-P256"
190 }
191 fn verify(&self, pk: &[u8], msg: &[u8], sig: &[u8]) -> Result<(), CryptoError> {
192 let verifier = EcdsaP256Verifier::from_sec1_bytes(pk)?;
193 verifier.verify(msg, sig)
194 }
195}
196
197#[derive(Debug, Default, Clone, Copy)]
201pub struct EcdsaP384;
202
203impl Signer for EcdsaP384 {
204 fn name(&self) -> &'static str {
205 "ECDSA-P384"
206 }
207 fn signature_len(&self) -> usize {
208 104
209 } fn sign(&self, sk: &[u8], msg: &[u8], sig_out: &mut [u8]) -> Result<usize, CryptoError> {
211 let signer = EcdsaP384Signer::from_bytes(sk)?;
212 let sig_bytes = signer.sign(msg)?;
213 if sig_out.len() < sig_bytes.len() {
214 return Err(CryptoError::BufferTooSmall);
215 }
216 sig_out[..sig_bytes.len()].copy_from_slice(&sig_bytes);
217 Ok(sig_bytes.len())
218 }
219}
220
221#[derive(Debug, Default, Clone, Copy)]
223pub struct EcdsaP384Verify;
224
225impl Verifier for EcdsaP384Verify {
226 fn name(&self) -> &'static str {
227 "ECDSA-P384"
228 }
229 fn verify(&self, pk: &[u8], msg: &[u8], sig: &[u8]) -> Result<(), CryptoError> {
230 let verifier = EcdsaP384Verifier::from_sec1_bytes(pk)?;
231 verifier.verify(msg, sig)
232 }
233}
234
235#[derive(Debug, Default, Clone, Copy)]
239pub struct EcdsaP521;
240
241impl Signer for EcdsaP521 {
242 fn name(&self) -> &'static str {
243 "ECDSA-P521"
244 }
245 fn signature_len(&self) -> usize {
246 139
247 } fn sign(&self, sk: &[u8], msg: &[u8], sig_out: &mut [u8]) -> Result<usize, CryptoError> {
249 let signer = EcdsaP521Signer::from_bytes(sk)?;
250 let sig_bytes = signer.sign(msg)?;
251 if sig_out.len() < sig_bytes.len() {
252 return Err(CryptoError::BufferTooSmall);
253 }
254 sig_out[..sig_bytes.len()].copy_from_slice(&sig_bytes);
255 Ok(sig_bytes.len())
256 }
257}
258
259#[derive(Debug, Default, Clone, Copy)]
261pub struct EcdsaP521Verify;
262
263impl Verifier for EcdsaP521Verify {
264 fn name(&self) -> &'static str {
265 "ECDSA-P521"
266 }
267 fn verify(&self, pk: &[u8], msg: &[u8], sig: &[u8]) -> Result<(), CryptoError> {
268 let verifier = EcdsaP521Verifier::from_sec1_bytes(pk)?;
269 verifier.verify(msg, sig)
270 }
271}
272
273#[derive(Debug, Default, Clone, Copy)]
279pub struct Ed448;
280
281impl Signer for Ed448 {
282 fn name(&self) -> &'static str {
283 "Ed448"
284 }
285 fn signature_len(&self) -> usize {
286 114
287 }
288 fn sign(&self, sk: &[u8], msg: &[u8], sig_out: &mut [u8]) -> Result<usize, CryptoError> {
289 if sig_out.len() < 114 {
290 return Err(CryptoError::BufferTooSmall);
291 }
292 let signer = Ed448SigningKey::from_bytes(sk)?;
293 let sig_bytes = signer.sign(msg)?;
294 sig_out[..114].copy_from_slice(&sig_bytes);
295 Ok(114)
296 }
297}
298
299#[derive(Debug, Default, Clone, Copy)]
301pub struct Ed448Verify;
302
303impl Verifier for Ed448Verify {
304 fn name(&self) -> &'static str {
305 "Ed448"
306 }
307 fn verify(&self, pk: &[u8], msg: &[u8], sig: &[u8]) -> Result<(), CryptoError> {
308 let verifier = Ed448VerifyingKey::from_bytes(pk)?;
309 verifier.verify(msg, sig)
310 }
311}
312
313#[derive(Debug, Default, Clone, Copy)]
319pub struct RsaPkcs1v15Sha256;
320
321impl Signer for RsaPkcs1v15Sha256 {
322 fn name(&self) -> &'static str {
323 "RSA-PKCS1v15-SHA256"
324 }
325 fn signature_len(&self) -> usize {
326 512
327 } fn sign(&self, sk: &[u8], msg: &[u8], sig_out: &mut [u8]) -> Result<usize, CryptoError> {
329 let signer = RsaPkcs1v15Sha256Signer::from_pkcs8_der(sk)?;
330 let sig_bytes = signer.sign(msg)?;
331 if sig_out.len() < sig_bytes.len() {
332 return Err(CryptoError::BufferTooSmall);
333 }
334 sig_out[..sig_bytes.len()].copy_from_slice(&sig_bytes);
335 Ok(sig_bytes.len())
336 }
337}
338
339#[derive(Debug, Default, Clone, Copy)]
343pub struct RsaPkcs1v15Sha256Verify;
344
345impl Verifier for RsaPkcs1v15Sha256Verify {
346 fn name(&self) -> &'static str {
347 "RSA-PKCS1v15-SHA256"
348 }
349 fn verify(&self, pk: &[u8], msg: &[u8], sig: &[u8]) -> Result<(), CryptoError> {
350 let verifier = RsaPkcs1v15Sha256Verifier::from_spki_der(pk)?;
351 verifier.verify(msg, sig)
352 }
353}
354
355#[derive(Debug, Default, Clone, Copy)]
359pub struct RsaPkcs1v15Sha384;
360
361impl Signer for RsaPkcs1v15Sha384 {
362 fn name(&self) -> &'static str {
363 "RSA-PKCS1v15-SHA384"
364 }
365 fn signature_len(&self) -> usize {
366 512
367 }
368 fn sign(&self, sk: &[u8], msg: &[u8], sig_out: &mut [u8]) -> Result<usize, CryptoError> {
369 let signer = RsaPkcs1v15Sha384Signer::from_pkcs8_der(sk)?;
370 let sig_bytes = signer.sign(msg)?;
371 if sig_out.len() < sig_bytes.len() {
372 return Err(CryptoError::BufferTooSmall);
373 }
374 sig_out[..sig_bytes.len()].copy_from_slice(&sig_bytes);
375 Ok(sig_bytes.len())
376 }
377}
378
379#[derive(Debug, Default, Clone, Copy)]
381pub struct RsaPkcs1v15Sha384Verify;
382
383impl Verifier for RsaPkcs1v15Sha384Verify {
384 fn name(&self) -> &'static str {
385 "RSA-PKCS1v15-SHA384"
386 }
387 fn verify(&self, pk: &[u8], msg: &[u8], sig: &[u8]) -> Result<(), CryptoError> {
388 let verifier = RsaPkcs1v15Sha384Verifier::from_spki_der(pk)?;
389 verifier.verify(msg, sig)
390 }
391}
392
393#[derive(Debug, Default, Clone, Copy)]
397pub struct RsaPkcs1v15Sha512;
398
399impl Signer for RsaPkcs1v15Sha512 {
400 fn name(&self) -> &'static str {
401 "RSA-PKCS1v15-SHA512"
402 }
403 fn signature_len(&self) -> usize {
404 512
405 }
406 fn sign(&self, sk: &[u8], msg: &[u8], sig_out: &mut [u8]) -> Result<usize, CryptoError> {
407 let signer = RsaPkcs1v15Sha512Signer::from_pkcs8_der(sk)?;
408 let sig_bytes = signer.sign(msg)?;
409 if sig_out.len() < sig_bytes.len() {
410 return Err(CryptoError::BufferTooSmall);
411 }
412 sig_out[..sig_bytes.len()].copy_from_slice(&sig_bytes);
413 Ok(sig_bytes.len())
414 }
415}
416
417#[derive(Debug, Default, Clone, Copy)]
419pub struct RsaPkcs1v15Sha512Verify;
420
421impl Verifier for RsaPkcs1v15Sha512Verify {
422 fn name(&self) -> &'static str {
423 "RSA-PKCS1v15-SHA512"
424 }
425 fn verify(&self, pk: &[u8], msg: &[u8], sig: &[u8]) -> Result<(), CryptoError> {
426 let verifier = RsaPkcs1v15Sha512Verifier::from_spki_der(pk)?;
427 verifier.verify(msg, sig)
428 }
429}
430
431#[derive(Debug, Default, Clone, Copy)]
435pub struct RsaPssSha256;
436
437impl Signer for RsaPssSha256 {
438 fn name(&self) -> &'static str {
439 "RSA-PSS-SHA256"
440 }
441 fn signature_len(&self) -> usize {
442 512
443 }
444 fn sign(&self, sk: &[u8], msg: &[u8], sig_out: &mut [u8]) -> Result<usize, CryptoError> {
445 let signer = RsaPssSha256Signer::from_pkcs8_der(sk)?;
446 let sig_bytes = signer.sign(msg)?;
447 if sig_out.len() < sig_bytes.len() {
448 return Err(CryptoError::BufferTooSmall);
449 }
450 sig_out[..sig_bytes.len()].copy_from_slice(&sig_bytes);
451 Ok(sig_bytes.len())
452 }
453}
454
455#[derive(Debug, Default, Clone, Copy)]
457pub struct RsaPssSha256Verify;
458
459impl Verifier for RsaPssSha256Verify {
460 fn name(&self) -> &'static str {
461 "RSA-PSS-SHA256"
462 }
463 fn verify(&self, pk: &[u8], msg: &[u8], sig: &[u8]) -> Result<(), CryptoError> {
464 let verifier = RsaPssSha256Verifier::from_spki_der(pk)?;
465 verifier.verify(msg, sig)
466 }
467}
468
469#[derive(Debug, Default, Clone, Copy)]
473pub struct RsaPssSha384;
474
475impl Signer for RsaPssSha384 {
476 fn name(&self) -> &'static str {
477 "RSA-PSS-SHA384"
478 }
479 fn signature_len(&self) -> usize {
480 512
481 }
482 fn sign(&self, sk: &[u8], msg: &[u8], sig_out: &mut [u8]) -> Result<usize, CryptoError> {
483 let signer = RsaPssSha384Signer::from_pkcs8_der(sk)?;
484 let sig_bytes = signer.sign(msg)?;
485 if sig_out.len() < sig_bytes.len() {
486 return Err(CryptoError::BufferTooSmall);
487 }
488 sig_out[..sig_bytes.len()].copy_from_slice(&sig_bytes);
489 Ok(sig_bytes.len())
490 }
491}
492
493#[derive(Debug, Default, Clone, Copy)]
495pub struct RsaPssSha384Verify;
496
497impl Verifier for RsaPssSha384Verify {
498 fn name(&self) -> &'static str {
499 "RSA-PSS-SHA384"
500 }
501 fn verify(&self, pk: &[u8], msg: &[u8], sig: &[u8]) -> Result<(), CryptoError> {
502 let verifier = RsaPssSha384Verifier::from_spki_der(pk)?;
503 verifier.verify(msg, sig)
504 }
505}
506
507#[derive(Debug, Default, Clone, Copy)]
511pub struct RsaPssSha512;
512
513impl Signer for RsaPssSha512 {
514 fn name(&self) -> &'static str {
515 "RSA-PSS-SHA512"
516 }
517 fn signature_len(&self) -> usize {
518 512
519 }
520 fn sign(&self, sk: &[u8], msg: &[u8], sig_out: &mut [u8]) -> Result<usize, CryptoError> {
521 let signer = RsaPssSha512Signer::from_pkcs8_der(sk)?;
522 let sig_bytes = signer.sign(msg)?;
523 if sig_out.len() < sig_bytes.len() {
524 return Err(CryptoError::BufferTooSmall);
525 }
526 sig_out[..sig_bytes.len()].copy_from_slice(&sig_bytes);
527 Ok(sig_bytes.len())
528 }
529}
530
531#[derive(Debug, Default, Clone, Copy)]
533pub struct RsaPssSha512Verify;
534
535impl Verifier for RsaPssSha512Verify {
536 fn name(&self) -> &'static str {
537 "RSA-PSS-SHA512"
538 }
539 fn verify(&self, pk: &[u8], msg: &[u8], sig: &[u8]) -> Result<(), CryptoError> {
540 let verifier = RsaPssSha512Verifier::from_spki_der(pk)?;
541 verifier.verify(msg, sig)
542 }
543}
544
545#[derive(Debug, Default, Clone, Copy)]
550pub struct Ed25519;
551
552impl Signer for Ed25519 {
553 fn name(&self) -> &'static str {
554 "Ed25519"
555 }
556 fn signature_len(&self) -> usize {
557 64
558 }
559 fn sign(&self, sk: &[u8], msg: &[u8], sig_out: &mut [u8]) -> Result<usize, CryptoError> {
560 if sig_out.len() < 64 {
561 return Err(CryptoError::BufferTooSmall);
562 }
563 let sk_bytes: &[u8; 32] = sk.try_into().map_err(|_| CryptoError::InvalidKey)?;
564 let signing_key = SigningKey::from_bytes(sk_bytes);
565
566 use ed25519_dalek::Signer as DalekSigner;
567 let signature: Signature = signing_key.sign(msg);
568 sig_out[..64].copy_from_slice(&signature.to_bytes());
569 Ok(64)
570 }
571}
572
573#[derive(Debug, Default, Clone, Copy)]
578pub struct Ed25519Verifier;
579
580impl Verifier for Ed25519Verifier {
581 fn name(&self) -> &'static str {
582 "Ed25519"
583 }
584 fn verify(&self, pk: &[u8], msg: &[u8], sig: &[u8]) -> Result<(), CryptoError> {
585 let pk_bytes: &[u8; 32] = pk.try_into().map_err(|_| CryptoError::InvalidKey)?;
586 let sig_bytes: &[u8; 64] = sig.try_into().map_err(|_| CryptoError::InvalidTag)?;
587
588 let verifying_key =
589 VerifyingKey::from_bytes(pk_bytes).map_err(|_| CryptoError::InvalidKey)?;
590 let signature = Signature::from_bytes(sig_bytes);
591
592 use ed25519_dalek::Verifier as DalekVerifier;
593 verifying_key
594 .verify(msg, &signature)
595 .map_err(|_| CryptoError::InvalidTag)
596 }
597}
598
599#[cfg(test)]
600mod tests {
601 use super::*;
602 use rand_chacha::ChaCha20Rng;
603 use rand_core::SeedableRng;
604
605 fn keypair_seed() -> ([u8; 32], [u8; 32]) {
606 let seed = [0x5au8; 32];
608 let signing_key = SigningKey::from_bytes(&seed);
609 let pk = signing_key.verifying_key().to_bytes();
610 (seed, pk)
611 }
612
613 fn test_rng() -> ChaCha20Rng {
614 ChaCha20Rng::from_seed([42u8; 32])
615 }
616
617 #[test]
618 fn ed25519_sign_verify_round_trip() {
619 let signer = Ed25519;
620 let verifier = Ed25519Verifier;
621 let (sk, pk) = keypair_seed();
622 let msg = b"test message for oxicrypto";
623
624 let mut sig = [0u8; 64];
625 let len = signer.sign(&sk, msg, &mut sig).expect("sign failed");
626 assert_eq!(len, 64);
627 verifier
628 .verify(&pk, msg, &sig)
629 .expect("verify should succeed");
630 }
631
632 #[test]
633 fn ed25519_corrupted_sig_fails() {
634 let signer = Ed25519;
635 let verifier = Ed25519Verifier;
636 let (sk, pk) = keypair_seed();
637 let msg = b"another test message";
638
639 let mut sig = [0u8; 64];
640 signer.sign(&sk, msg, &mut sig).expect("sign failed");
641 sig[0] ^= 0xff;
643
644 let result = verifier.verify(&pk, msg, &sig);
645 assert_eq!(result, Err(CryptoError::InvalidTag));
646 }
647
648 #[test]
649 fn ed25519_wrong_key_fails() {
650 let signer = Ed25519;
651 let verifier = Ed25519Verifier;
652 let (sk, _pk) = keypair_seed();
653 let other_seed = [0xabu8; 32];
655 let other_sk = SigningKey::from_bytes(&other_seed);
656 let other_pk = other_sk.verifying_key().to_bytes();
657
658 let msg = b"message signed with sk";
659 let mut sig = [0u8; 64];
660 signer.sign(&sk, msg, &mut sig).expect("sign failed");
661
662 let result = verifier.verify(&other_pk, msg, &sig);
663 assert_eq!(result, Err(CryptoError::InvalidTag));
664 }
665
666 #[test]
667 fn ed25519_invalid_sk_length_errors() {
668 let signer = Ed25519;
669 let msg = b"msg";
670 let mut sig = [0u8; 64];
671 let result = signer.sign(&[0u8; 16], msg, &mut sig);
672 assert_eq!(result, Err(CryptoError::InvalidKey));
673 }
674
675 #[test]
678 fn ed25519_keygen_sign_verify() {
679 let mut rng = test_rng();
680 let (sk_secret, pk_bytes) =
681 ed25519_generate_keypair(&mut rng).expect("ed25519 keygen failed");
682
683 let msg = b"hello from ed25519 keygen test";
684 let signer = Ed25519;
685 let verifier = Ed25519Verifier;
686
687 let mut sig_buf = [0u8; 64];
688 let len = signer
689 .sign(sk_secret.as_bytes(), msg, &mut sig_buf)
690 .expect("sign failed");
691 assert_eq!(len, 64);
692 verifier
693 .verify(&pk_bytes, msg, &sig_buf)
694 .expect("verify failed");
695 }
696
697 #[test]
700 fn ecdsa_p256_keygen_sign_verify() {
701 let mut rng = test_rng();
702 let (sk_secret, pk_bytes) =
703 ecdsa_p256_generate_keypair(&mut rng).expect("p256 keygen failed");
704
705 let msg = b"hello from p256 keygen test";
706 let signer_struct =
707 EcdsaP256Signer::from_bytes(sk_secret.as_bytes()).expect("p256 signer from bytes");
708 let sig_bytes = signer_struct.sign(msg).expect("p256 sign failed");
709
710 let verifier_struct =
711 EcdsaP256Verifier::from_sec1_bytes(&pk_bytes).expect("p256 verifier from sec1");
712 verifier_struct
713 .verify(msg, &sig_bytes)
714 .expect("p256 verify failed");
715 }
716
717 #[test]
718 fn ecdsa_p384_keygen_sign_verify() {
719 let mut rng = test_rng();
720 let (sk_secret, pk_bytes) =
721 ecdsa_p384_generate_keypair(&mut rng).expect("p384 keygen failed");
722
723 let msg = b"hello from p384 keygen test";
724 let signer_struct =
725 EcdsaP384Signer::from_bytes(sk_secret.as_bytes()).expect("p384 signer from bytes");
726 let sig_bytes = signer_struct.sign(msg).expect("p384 sign failed");
727
728 let verifier_struct =
729 EcdsaP384Verifier::from_sec1_bytes(&pk_bytes).expect("p384 verifier from sec1");
730 verifier_struct
731 .verify(msg, &sig_bytes)
732 .expect("p384 verify failed");
733 }
734
735 #[test]
736 fn ecdsa_p521_keygen_sign_verify() {
737 let mut rng = test_rng();
738 let (sk_secret, pk_bytes) =
739 ecdsa_p521_generate_keypair(&mut rng).expect("p521 keygen failed");
740
741 let msg = b"hello from p521 keygen test";
742 let signer_struct =
743 EcdsaP521Signer::from_bytes(sk_secret.as_bytes()).expect("p521 signer from bytes");
744 let sig_bytes = signer_struct.sign(msg).expect("p521 sign failed");
745
746 let verifier_struct =
747 EcdsaP521Verifier::from_sec1_bytes(&pk_bytes).expect("p521 verifier from sec1");
748 verifier_struct
749 .verify(msg, &sig_bytes)
750 .expect("p521 verify failed");
751 }
752
753 #[test]
756 fn ed25519_batch_verify_all_valid() {
757 use ed25519_dalek::Signer as DalekSigner;
758 let seeds: [[u8; 32]; 5] = [[0x01; 32], [0x02; 32], [0x03; 32], [0x04; 32], [0x05; 32]];
759 let signing_keys: Vec<SigningKey> = seeds.iter().map(SigningKey::from_bytes).collect();
760 let verifying_keys: Vec<VerifyingKey> =
761 signing_keys.iter().map(|sk| sk.verifying_key()).collect();
762
763 let messages: [&[u8]; 5] = [b"msg1", b"msg2", b"msg3", b"msg4", b"msg5"];
764 let signatures: Vec<Signature> = signing_keys
765 .iter()
766 .zip(messages.iter())
767 .map(|(sk, msg)| sk.sign(msg))
768 .collect();
769
770 let msg_refs: Vec<&[u8]> = messages.to_vec();
771 ed25519_verify_batch(&msg_refs, &signatures, &verifying_keys)
772 .expect("batch verify of 5 valid sigs should succeed");
773 }
774
775 #[test]
776 fn ed25519_batch_verify_one_tampered() {
777 use ed25519_dalek::Signer as DalekSigner;
778 let seeds: [[u8; 32]; 3] = [[0x11; 32], [0x22; 32], [0x33; 32]];
779 let signing_keys: Vec<SigningKey> = seeds.iter().map(SigningKey::from_bytes).collect();
780 let verifying_keys: Vec<VerifyingKey> =
781 signing_keys.iter().map(|sk| sk.verifying_key()).collect();
782
783 let messages: [&[u8]; 3] = [b"alpha", b"beta", b"gamma"];
784 let mut signatures: Vec<Signature> = signing_keys
785 .iter()
786 .zip(messages.iter())
787 .map(|(sk, msg)| sk.sign(msg))
788 .collect();
789
790 let mut tampered_bytes = signatures[1].to_bytes();
792 tampered_bytes[0] ^= 0xff;
793 signatures[1] = Signature::from_bytes(&tampered_bytes);
794
795 let msg_refs: Vec<&[u8]> = messages.to_vec();
796 let result = ed25519_verify_batch(&msg_refs, &signatures, &verifying_keys);
797 assert!(
798 result.is_err(),
799 "batch verify with tampered sig should fail"
800 );
801 }
802
803 #[test]
804 fn ed25519_batch_verify_empty() {
805 let result = ed25519_verify_batch(&[], &[], &[]);
806 assert!(result.is_ok(), "empty batch should succeed");
807 }
808
809 #[test]
810 fn ed25519_batch_verify_mismatched_lengths() {
811 let seed = [0x99u8; 32];
812 let sk = SigningKey::from_bytes(&seed);
813 use ed25519_dalek::Signer as DalekSigner;
814 let sig = sk.sign(b"test");
815 let vk = sk.verifying_key();
816
817 let result = ed25519_verify_batch(&[b"test", b"extra"], &[sig], &[vk]);
819 assert_eq!(result, Err(CryptoError::BadInput));
820 }
821}