bc_components/
keypair.rs

1use bc_rand::RandomNumberGenerator;
2
3use crate::{
4    EncapsulationScheme, PrivateKeys, PublicKeys, Result, SignatureScheme,
5};
6
7/// Generates a key pair using the default signature and encapsulation schemes.
8///
9/// This function creates a new key pair containing both signing and
10/// encapsulation (encryption) keys using the default cryptographic schemes:
11/// - Default signature scheme: Currently `SignatureScheme::Schnorr`
12/// - Default encapsulation scheme: Currently `EncapsulationScheme::X25519`
13///
14/// # Returns
15///
16/// A tuple containing:
17/// - `PrivateKeys`: The private keys for signing and encapsulation
18/// - `PublicKeys`: The corresponding public keys
19///
20/// # Example
21///
22/// ```
23/// use bc_components::keypair;
24///
25/// // Generate a key pair with default cryptographic schemes
26/// let (private_keys, public_keys) = keypair();
27///
28/// // The private_keys can be used for signing and decryption
29/// // The public_keys can be shared and used for verification and encryption
30/// ```
31#[cfg(any(feature = "secp256k1", feature = "ed25519"))]
32pub fn keypair() -> (PrivateKeys, PublicKeys) {
33    keypair_opt(SignatureScheme::default(), EncapsulationScheme::default())
34}
35
36/// Generates a key pair using the default schemes and a custom random number
37/// generator.
38///
39/// This function creates a deterministic key pair using the provided random
40/// number generator and the default cryptographic schemes.
41///
42/// # Parameters
43///
44/// * `rng` - A mutable reference to a random number generator
45///
46/// # Returns
47///
48/// A Result containing a tuple with `PrivateKeys` and `PublicKeys` if
49/// successful, or an error if key generation fails.
50///
51/// # Errors
52///
53/// Returns an error if either the signature or encapsulation key generation
54/// fails.
55///
56/// # Example
57///
58/// ```
59/// use bc_components::keypair_using;
60/// use bc_rand::SecureRandomNumberGenerator;
61///
62/// // Create a random number generator
63/// let mut rng = SecureRandomNumberGenerator;
64///
65/// // Generate a key pair with default schemes but custom RNG
66/// let result = keypair_using(&mut rng);
67/// assert!(result.is_ok());
68/// ```
69#[cfg(any(feature = "secp256k1", feature = "ed25519"))]
70pub fn keypair_using(
71    rng: &mut impl RandomNumberGenerator,
72) -> Result<(PrivateKeys, PublicKeys)> {
73    keypair_opt_using(
74        SignatureScheme::default(),
75        EncapsulationScheme::default(),
76        rng,
77    )
78}
79
80/// Generates a key pair with specified signature and encapsulation schemes.
81///
82/// This function creates a new key pair with custom cryptographic schemes for
83/// both signing and encryption operations.
84///
85/// # Parameters
86///
87/// * `signature_scheme` - The signature scheme to use (e.g., Schnorr, ECDSA,
88///   Ed25519)
89/// * `encapsulation_scheme` - The key encapsulation scheme to use (e.g.,
90///   X25519, ML-KEM)
91///
92/// # Returns
93///
94/// A tuple containing:
95/// - `PrivateKeys`: The private keys for signing and encapsulation
96/// - `PublicKeys`: The corresponding public keys
97///
98/// # Example
99///
100/// ```ignore
101/// use bc_components::{EncapsulationScheme, SignatureScheme, keypair_opt};
102///
103/// // Generate a key pair with Ed25519 for signing and ML-KEM768 for encryption
104/// let (private_keys, public_keys) =
105///     keypair_opt(SignatureScheme::Ed25519, EncapsulationScheme::MLKEM768);
106/// ```
107pub fn keypair_opt(
108    signature_scheme: SignatureScheme,
109    _encapsulation_scheme: EncapsulationScheme,
110) -> (PrivateKeys, PublicKeys) {
111    #[cfg(any(
112        feature = "secp256k1",
113        feature = "ed25519",
114        feature = "ssh",
115        feature = "pqcrypto"
116    ))]
117    {
118        let (_signing_private_key, _signing_public_key) =
119            signature_scheme.keypair();
120        let (_encapsulation_private_key, _encapsulation_public_key) =
121            _encapsulation_scheme.keypair();
122        let private_keys = PrivateKeys::with_keys(
123            _signing_private_key,
124            _encapsulation_private_key,
125        );
126        let public_keys =
127            PublicKeys::new(_signing_public_key, _encapsulation_public_key);
128        (private_keys, public_keys)
129    }
130    #[cfg(not(any(
131        feature = "secp256k1",
132        feature = "ed25519",
133        feature = "ssh",
134        feature = "pqcrypto"
135    )))]
136    {
137        match signature_scheme {}
138    }
139}
140
141/// Generates a key pair with specified schemes using a custom random number
142/// generator.
143///
144/// This function provides the most control over key pair generation by allowing
145/// custom specification of both cryptographic schemes and the random number
146/// generator.
147///
148/// # Parameters
149///
150/// * `signature_scheme` - The signature scheme to use
151/// * `encapsulation_scheme` - The key encapsulation scheme to use
152/// * `rng` - A mutable reference to a random number generator
153///
154/// # Returns
155///
156/// A Result containing a tuple with `PrivateKeys` and `PublicKeys` if
157/// successful, or an error if key generation fails.
158///
159/// # Errors
160///
161/// Returns an error if either the signature or encapsulation key generation
162/// fails.
163///
164/// # Example
165///
166/// ```ignore
167/// # // Requires secp256k1 feature (enabled by default)
168/// use bc_components::{
169///     EncapsulationScheme, SignatureScheme, keypair_opt_using,
170/// };
171/// use bc_rand::SecureRandomNumberGenerator;
172///
173/// // Create a random number generator
174/// let mut rng = SecureRandomNumberGenerator;
175///
176/// // Generate a specific key pair deterministically
177/// let result = keypair_opt_using(
178///     SignatureScheme::Ecdsa,
179///     EncapsulationScheme::X25519,
180///     &mut rng,
181/// );
182/// assert!(result.is_ok());
183/// ```
184pub fn keypair_opt_using(
185    signature_scheme: SignatureScheme,
186    encapsulation_scheme: EncapsulationScheme,
187    rng: &mut impl RandomNumberGenerator,
188) -> Result<(PrivateKeys, PublicKeys)> {
189    let (signing_private_key, signing_public_key) =
190        signature_scheme.keypair_using(rng, "")?;
191    let (encapsulation_private_key, encapsulation_public_key) =
192        encapsulation_scheme.keypair_using(rng)?;
193    let private_keys =
194        PrivateKeys::with_keys(signing_private_key, encapsulation_private_key);
195    let public_keys =
196        PublicKeys::new(signing_public_key, encapsulation_public_key);
197    Ok((private_keys, public_keys))
198}