1#![cfg_attr(not(feature = "std"), no_std)]
7#![forbid(unsafe_code)]
8
9extern crate alloc;
10
11pub mod error;
12#[cfg(feature = "post-quantum")]
13#[path = "dilithium/mod.rs"]
14pub mod mldsa;
15
16#[cfg(feature = "post-quantum")]
17pub use mldsa::{MlDsa44, MlDsa65, MlDsa87};
18
19#[cfg(feature = "traditional")]
20pub mod bls;
21#[cfg(feature = "traditional")]
22pub mod ecdsa;
23#[cfg(feature = "traditional")]
24pub mod eddsa;
25
26#[cfg(feature = "traditional")]
27pub use bls::{
28 Bls12381G2Basic, Bls12381G2MessageAugmentation, Bls12381G2ProofOfPossession,
29 Bls12381ProofOfPossession, Bls12381PublicKey, Bls12381SecretKey, Bls12381Signature,
30 Eth2Bls12381G2PopV4,
31};
32#[cfg(feature = "traditional")]
33pub use ecdsa::{
34 EcdsaP224, EcdsaP224PublicKey, EcdsaP224SecretKey, EcdsaP224Signature, EcdsaP256,
35 EcdsaP256PublicKey, EcdsaP256SecretKey, EcdsaP256Signature, EcdsaP384, EcdsaP384PublicKey,
36 EcdsaP384SecretKey, EcdsaP384Signature, EcdsaP521, EcdsaP521PublicKey, EcdsaP521SecretKey,
37 EcdsaP521Signature,
38};
39
40#[cfg(feature = "traditional")]
42pub use eddsa::Ed25519;
43
44#[cfg(test)]
45mod rng_failure_tests {
46 use super::*;
47 use dcrypt_api::Signature;
48 use dcrypt_internal::{CryptoRng, Error as RngError, RngCore};
49
50 struct FailingRng;
51
52 impl RngCore for FailingRng {
53 fn try_fill_bytes(&mut self, destination: &mut [u8]) -> Result<(), RngError> {
54 destination.fill(0xa5);
55 Err(RngError)
56 }
57 }
58
59 impl CryptoRng for FailingRng {}
60
61 macro_rules! keypair_propagates_rng_failure {
62 ($name:ident, $scheme:ty) => {
63 #[test]
64 fn $name() {
65 assert!(<$scheme>::keypair(&mut FailingRng).is_err());
66 }
67 };
68 }
69
70 #[cfg(feature = "traditional")]
71 keypair_propagates_rng_failure!(p224_keypair_rng_failure, EcdsaP224);
72 #[cfg(feature = "traditional")]
73 keypair_propagates_rng_failure!(p256_keypair_rng_failure, EcdsaP256);
74 #[cfg(feature = "traditional")]
75 keypair_propagates_rng_failure!(p384_keypair_rng_failure, EcdsaP384);
76 #[cfg(feature = "traditional")]
77 keypair_propagates_rng_failure!(p521_keypair_rng_failure, EcdsaP521);
78 #[cfg(feature = "traditional")]
79 #[test]
80 fn ed25519_keypair_rng_failure() {
81 assert!(matches!(
82 Ed25519::keypair(&mut FailingRng),
83 Err(dcrypt_api::Error::RandomGenerationError { .. })
84 ));
85 }
86
87 #[cfg(feature = "traditional")]
88 #[test]
89 fn bls_keygen_rng_failure() {
90 assert!(matches!(
91 Bls12381SecretKey::generate(&mut FailingRng, b"caller salt"),
92 Err(dcrypt_api::Error::RandomGenerationError { .. })
93 ));
94 assert!(matches!(
95 Eth2Bls12381G2PopV4::generate(&mut FailingRng),
96 Err(dcrypt_api::Error::RandomGenerationError { .. })
97 ));
98 }
99
100 #[cfg(feature = "post-quantum")]
101 #[test]
102 fn mldsa44_keypair_rng_failure() {
103 assert!(matches!(
104 MlDsa44::keypair(&mut FailingRng),
105 Err(dcrypt_api::Error::RandomGenerationError { .. })
106 ));
107 }
108
109 #[cfg(feature = "post-quantum")]
110 #[test]
111 fn mldsa_randomized_signing_propagates_rng_failure() {
112 let mut keygen_rng = dcrypt_internal::ChaCha20Rng::from_seed([0x42; 32]);
113 let (_, secret) = MlDsa44::keypair(&mut keygen_rng).unwrap();
114 assert!(matches!(
115 MlDsa44::sign_with_rng(b"message", &secret, &mut FailingRng),
116 Err(dcrypt_api::Error::RandomGenerationError { .. })
117 ));
118 }
119}