mirror of
https://github.com/RustCrypto/signatures
synced 2026-06-21 13:45:42 +00:00
dsa: add TryCryptoRng support (#1367)
This renames the previous `generate` methods to `try_generate_from_rng_with_key_size` and changes them to accept a `TryCryptoRng`, returning a `Result` with potential RNG errors. This helps clear the way for implementing the `Generate` trait from `crypto-common`, which defines its own `generate` method which takes no parameters, using the system RNG and default key size.
This commit is contained in:
@@ -7,7 +7,8 @@ use std::{fs::File, io::Write};
|
||||
|
||||
fn main() {
|
||||
let mut rng = rand_core::UnwrapErr(SysRng);
|
||||
let components = Components::generate(&mut rng, KeySize::DSA_2048_256);
|
||||
let components =
|
||||
Components::try_generate_from_rng_with_key_size(&mut rng, KeySize::DSA_2048_256).unwrap();
|
||||
let signing_key = SigningKey::generate(&mut rng, components);
|
||||
let verifying_key = signing_key.verifying_key();
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ use getrandom::{SysRng, rand_core::UnwrapErr};
|
||||
|
||||
fn main() {
|
||||
let mut rng = UnwrapErr(SysRng);
|
||||
let components = Components::generate(&mut rng, KeySize::DSA_2048_256);
|
||||
let components =
|
||||
Components::try_generate_from_rng_with_key_size(&mut rng, KeySize::DSA_2048_256).unwrap();
|
||||
let signing_key = SigningKey::generate(&mut rng, components);
|
||||
let _verifying_key = signing_key.verifying_key();
|
||||
}
|
||||
|
||||
@@ -7,8 +7,11 @@ use signature::{RandomizedDigestSigner, SignatureEncoding};
|
||||
use std::{fs::File, io::Write};
|
||||
|
||||
fn main() {
|
||||
let components =
|
||||
Components::try_generate_from_rng_with_key_size(&mut SysRng, KeySize::DSA_2048_256)
|
||||
.unwrap();
|
||||
|
||||
let mut rng = UnwrapErr(SysRng);
|
||||
let components = Components::generate(&mut rng, KeySize::DSA_2048_256);
|
||||
let signing_key = SigningKey::generate(&mut rng, components);
|
||||
let verifying_key = signing_key.verifying_key();
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
//! Module containing the definition of the common components container
|
||||
//!
|
||||
|
||||
use crate::{size::KeySize, two};
|
||||
use crate::{generate, size::KeySize, two};
|
||||
use crypto_bigint::{BoxedUint, NonZero, Odd};
|
||||
use der::{
|
||||
self, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence, Tag, Writer,
|
||||
asn1::UintRef,
|
||||
};
|
||||
use signature::rand_core::CryptoRng;
|
||||
use signature::rand_core::TryCryptoRng;
|
||||
|
||||
/// The common components of an DSA keypair
|
||||
///
|
||||
@@ -87,10 +87,13 @@ impl Components {
|
||||
}
|
||||
|
||||
/// Generate a new pair of common components
|
||||
pub fn generate<R: CryptoRng + ?Sized>(rng: &mut R, key_size: KeySize) -> Self {
|
||||
let (p, q, g) = crate::generate::common_components(rng, key_size);
|
||||
Self::from_components(p.get(), q.get(), g.get())
|
||||
.expect("[Bug] Newly generated components considered invalid")
|
||||
pub fn try_generate_from_rng_with_key_size<R: TryCryptoRng + ?Sized>(
|
||||
rng: &mut R,
|
||||
key_size: KeySize,
|
||||
) -> Result<Self, R::Error> {
|
||||
let (p, q, g) = generate::common_components(rng, key_size)?;
|
||||
Ok(Self::from_components(p.get(), q.get(), g.get())
|
||||
.expect("[Bug] Newly generated components considered invalid"))
|
||||
}
|
||||
|
||||
/// DSA prime p
|
||||
|
||||
+4
-3
@@ -1,6 +1,6 @@
|
||||
use crypto_bigint::{BoxedUint, NonZero, Resize};
|
||||
use crypto_primes::{Flavor, random_prime};
|
||||
use signature::rand_core::CryptoRng;
|
||||
use signature::rand_core::{TryCryptoRng, UnwrapErr};
|
||||
|
||||
mod components;
|
||||
mod keypair;
|
||||
@@ -33,6 +33,7 @@ fn calculate_bounds(size: u32) -> (NonZero<BoxedUint>, NonZero<BoxedUint>) {
|
||||
///
|
||||
/// This wrapper function mainly exists to enforce the [`CryptoRng`](rand::CryptoRng) requirement (I might otherwise forget it)
|
||||
#[inline]
|
||||
fn generate_prime<R: CryptoRng + ?Sized>(bit_length: u32, rng: &mut R) -> BoxedUint {
|
||||
random_prime(rng, Flavor::Any, bit_length)
|
||||
fn generate_prime<R: TryCryptoRng + ?Sized>(bit_length: u32, rng: &mut R) -> BoxedUint {
|
||||
let mut rng = UnwrapErr(rng);
|
||||
random_prime(&mut rng, Flavor::Any, bit_length)
|
||||
}
|
||||
|
||||
@@ -8,11 +8,11 @@ use crate::{
|
||||
two,
|
||||
};
|
||||
use crypto_bigint::{
|
||||
BoxedUint, ConcatenatingMul, NonZero, Odd, RandomBits, Resize,
|
||||
BoxedUint, ConcatenatingMul, NonZero, Odd, RandomBits, RandomBitsError, Resize,
|
||||
modular::{BoxedMontyForm, BoxedMontyParams},
|
||||
};
|
||||
use crypto_primes::{Flavor, is_prime};
|
||||
use signature::rand_core::CryptoRng;
|
||||
use signature::rand_core::TryCryptoRng;
|
||||
|
||||
#[cfg(feature = "hazmat")]
|
||||
use {crate::Components, crypto_bigint::CtOption};
|
||||
@@ -22,10 +22,11 @@ use {crate::Components, crypto_bigint::CtOption};
|
||||
/// # Returns
|
||||
///
|
||||
/// Tuple of three `BoxedUint`s. Ordered like this `(p, q, g)`
|
||||
pub(crate) fn common<R: CryptoRng + ?Sized>(
|
||||
#[allow(clippy::type_complexity, reason = "internal helper")]
|
||||
pub(crate) fn common<R: TryCryptoRng + ?Sized>(
|
||||
rng: &mut R,
|
||||
KeySize { l, n }: KeySize,
|
||||
) -> (Odd<BoxedUint>, NonZero<BoxedUint>, NonZero<BoxedUint>) {
|
||||
) -> Result<(Odd<BoxedUint>, NonZero<BoxedUint>, NonZero<BoxedUint>), R::Error> {
|
||||
// Calculate the lower and upper bounds of p and q
|
||||
let (p_min, p_max) = calculate_bounds(l);
|
||||
let (q_min, q_max): (NonZero<_>, _) = calculate_bounds(n);
|
||||
@@ -41,7 +42,11 @@ pub(crate) fn common<R: CryptoRng + ?Sized>(
|
||||
// Attempt to find a prime p which has a subgroup of the order q
|
||||
for _ in 0..4096 {
|
||||
let m = 'gen_m: loop {
|
||||
let m = BoxedUint::random_bits(rng, l);
|
||||
let m = match BoxedUint::try_random_bits(rng, l) {
|
||||
Ok(m) => m,
|
||||
Err(RandomBitsError::RandCore(err)) => return Err(err),
|
||||
Err(other) => unreachable!("[bug] RNG error: {other}"),
|
||||
};
|
||||
|
||||
if m > *p_min && m < *p_max {
|
||||
break 'gen_m m;
|
||||
@@ -82,7 +87,7 @@ pub(crate) fn common<R: CryptoRng + ?Sized>(
|
||||
|
||||
let q = q.resize(n);
|
||||
|
||||
(p, q, g)
|
||||
Ok((p, q, g))
|
||||
}
|
||||
|
||||
/// Calculate the public component from the common components and the private component
|
||||
|
||||
+8
-4
@@ -14,13 +14,17 @@
|
||||
//!
|
||||
#![cfg_attr(feature = "hazmat", doc = "```")]
|
||||
#![cfg_attr(not(feature = "hazmat"), doc = "```ignore")]
|
||||
//! # use dsa::{KeySize, Components, SigningKey};
|
||||
//! use getrandom::{SysRng, rand_core::UnwrapErr};
|
||||
//! # fn main() -> Result<(), core::convert::Infallible> {
|
||||
//! use dsa::{KeySize, Components, SigningKey};
|
||||
//!
|
||||
//! let mut csprng = UnwrapErr(SysRng);
|
||||
//! let components = Components::generate(&mut csprng, KeySize::DSA_2048_256);
|
||||
//! # use getrandom::{SysRng, rand_core::UnwrapErr};
|
||||
//! # let mut csprng = UnwrapErr(SysRng);
|
||||
//!
|
||||
//! let components = Components::try_generate_from_rng_with_key_size(&mut csprng, KeySize::DSA_2048_256)?;
|
||||
//! let signing_key = SigningKey::generate(&mut csprng, components);
|
||||
//! let verifying_key = signing_key.verifying_key();
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! Create keypair from existing components
|
||||
|
||||
@@ -20,7 +20,7 @@ prop_compose! {
|
||||
fn private_key()(seed in any::<[u8; 32]>()) -> SigningKey {
|
||||
let mut rng = ChaCha8Rng::from_seed(seed);
|
||||
#[allow(deprecated)]
|
||||
let components = Components::generate(&mut rng, KeySize::DSA_1024_160);
|
||||
let components = Components::try_generate_from_rng_with_key_size(&mut rng, KeySize::DSA_1024_160).unwrap();
|
||||
SigningKey::generate(&mut rng, components)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@ const MESSAGE_SIGNATURE_OPENSSL_ASN1: &[u8] = &hex!(
|
||||
/// Generate a random DSA keypair
|
||||
fn generate_random_keypair() -> SigningKey {
|
||||
let mut rng = UnwrapErr(SysRng);
|
||||
let components = Components::generate(&mut rng, KeySize::DSA_1024_160);
|
||||
let components =
|
||||
Components::try_generate_from_rng_with_key_size(&mut rng, KeySize::DSA_1024_160).unwrap();
|
||||
SigningKey::generate(&mut rng, components)
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@ const OPENSSL_PEM_PRIVATE_KEY: &str = include_str!("pems/private.pem");
|
||||
|
||||
fn generate_keypair() -> SigningKey {
|
||||
let mut rng = UnwrapErr(SysRng);
|
||||
let components = Components::generate(&mut rng, KeySize::DSA_1024_160);
|
||||
let components =
|
||||
Components::try_generate_from_rng_with_key_size(&mut rng, KeySize::DSA_1024_160).unwrap();
|
||||
SigningKey::generate(&mut rng, components)
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@ const OPENSSL_PEM_PUBLIC_KEY: &str = include_str!("pems/public.pem");
|
||||
#[cfg(feature = "hazmat")]
|
||||
fn generate_verifying_key() -> VerifyingKey {
|
||||
let mut rng = rand_core::UnwrapErr(SysRng);
|
||||
let components = Components::generate(&mut rng, KeySize::DSA_1024_160);
|
||||
let components =
|
||||
Components::try_generate_from_rng_with_key_size(&mut rng, KeySize::DSA_1024_160).unwrap();
|
||||
let signing_key = SigningKey::generate(&mut rng, components);
|
||||
|
||||
signing_key.verifying_key().clone()
|
||||
|
||||
Reference in New Issue
Block a user