Skip to main content

dcrypt_sign/
lib.rs

1//! Digital Signature Schemes
2//!
3//! This crate implements various digital signature schemes,
4//! both traditional and post-quantum.
5
6#![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// Re-export EdDSA types
41#[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}