Skip to content

Commit 71639a3

Browse files
committed
cleanup unwraps
1 parent 36f50bb commit 71639a3

11 files changed

+129
-104
lines changed

Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dsa/src/components.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//!
44
55
use crate::{size::KeySize, two};
6-
use crypto_bigint::{BoxedUint, NonZero};
6+
use crypto_bigint::{BoxedUint, NonZero, Odd};
77
use pkcs8::der::{
88
self, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence, Tag, Writer,
99
asn1::UintRef,
@@ -17,7 +17,7 @@ use signature::rand_core::CryptoRng;
1717
#[must_use]
1818
pub struct Components {
1919
/// Prime p
20-
p: NonZero<BoxedUint>,
20+
p: Odd<BoxedUint>,
2121

2222
/// Quotient q
2323
q: NonZero<BoxedUint>,
@@ -31,11 +31,11 @@ pub struct Components {
3131
impl Components {
3232
/// Construct the common components container from its inner values (p, q and g)
3333
pub fn from_components(
34-
p: NonZero<BoxedUint>,
34+
p: Odd<BoxedUint>,
3535
q: NonZero<BoxedUint>,
3636
g: NonZero<BoxedUint>,
3737
) -> signature::Result<Self> {
38-
if *p < two() || *q < two() || g > p {
38+
if *p < two() || *q < two() || *g > *p {
3939
return Err(signature::Error::new());
4040
}
4141

@@ -59,7 +59,7 @@ impl Components {
5959

6060
/// DSA prime p
6161
#[must_use]
62-
pub const fn p(&self) -> &NonZero<BoxedUint> {
62+
pub const fn p(&self) -> &Odd<BoxedUint> {
6363
&self.p
6464
}
6565

@@ -88,7 +88,7 @@ impl<'a> DecodeValue<'a> for Components {
8888
let q = BoxedUint::from_be_slice(q.as_bytes(), (q.as_bytes().len() * 8) as u32).unwrap();
8989
let g = BoxedUint::from_be_slice(g.as_bytes(), (g.as_bytes().len() * 8) as u32).unwrap();
9090

91-
let p = NonZero::new(p).unwrap();
91+
let p = Odd::new(p).unwrap();
9292
let q = NonZero::new(q).unwrap();
9393
let g = NonZero::new(g).unwrap();
9494

dsa/src/generate.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crypto_bigint::BoxedUint;
1+
use crypto_bigint::{BoxedUint, NonZero};
22
use signature::rand_core::CryptoRng;
33

44
mod components;
@@ -13,10 +13,13 @@ pub use self::keypair::keypair;
1313

1414
/// Calculate the upper and lower bounds for generating values like p or q
1515
#[inline]
16-
fn calculate_bounds(size: u32) -> (BoxedUint, BoxedUint) {
16+
fn calculate_bounds(size: u32) -> (NonZero<BoxedUint>, NonZero<BoxedUint>) {
1717
let lower = BoxedUint::one().widen(size + 1).shl(size - 1);
1818
let upper = BoxedUint::one().widen(size + 1).shl(size);
1919

20+
let lower = NonZero::new(lower).expect("[bug] shl can't go backward");
21+
let upper = NonZero::new(upper).expect("[bug] shl can't go backward");
22+
2023
(lower, upper)
2124
}
2225

dsa/src/generate/components.rs

+22-20
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::{
1111
use crypto_bigint::{
1212
BoxedUint, NonZero, Odd, RandomBits,
1313
modular::{BoxedMontyForm, BoxedMontyParams},
14+
subtle::CtOption,
1415
};
1516
use signature::rand_core::CryptoRng;
1617

@@ -22,73 +23,74 @@ use signature::rand_core::CryptoRng;
2223
pub fn common<R: CryptoRng + ?Sized>(
2324
rng: &mut R,
2425
KeySize { l, n }: KeySize,
25-
) -> (NonZero<BoxedUint>, NonZero<BoxedUint>, NonZero<BoxedUint>) {
26+
) -> (Odd<BoxedUint>, NonZero<BoxedUint>, NonZero<BoxedUint>) {
2627
// Calculate the lower and upper bounds of p and q
2728
let (p_min, p_max) = calculate_bounds(l);
28-
let (q_min, q_max) = calculate_bounds(n);
29+
let (q_min, q_max): (NonZero<_>, _) = calculate_bounds(n);
2930

30-
let (p, q) = 'gen_pq: loop {
31+
let (p, q): (Odd<_>, _) = 'gen_pq: loop {
3132
let q = generate_prime(n, rng);
32-
if q < q_min || q > q_max {
33+
if q < *q_min || q > *q_max {
3334
continue;
3435
}
35-
let q = NonZero::new(q).unwrap();
36+
let q = NonZero::new(q)
37+
.expect("[bug] invariant violation, q is above q_min which itself is NonZero");
3638

3739
// Attempt to find a prime p which has a subgroup of the order q
3840
for _ in 0..4096 {
3941
let m = 'gen_m: loop {
4042
let m = BoxedUint::random_bits(rng, l);
4143

42-
if m > p_min && m < p_max {
44+
if m > *p_min && m < *p_max {
4345
break 'gen_m m;
4446
}
4547
};
46-
let rem = NonZero::new((two() * &*q).widen(m.bits_precision())).unwrap();
48+
let rem = NonZero::new((two() * &*q).widen(m.bits_precision()))
49+
.expect("[bug] 2 * NonZero can't be zero");
4750

4851
let mr = &m % &rem;
4952
let p = m - mr + BoxedUint::one();
50-
let p = NonZero::new(p).unwrap();
5153

52-
if crypto_primes::is_prime_with_rng(rng, &*p) {
54+
if crypto_primes::is_prime_with_rng(rng, &p) {
55+
let p = Odd::new(p).expect("[bug] Any even number would be prime. P is at least 2^L and L is at least 1024.");
5356
break 'gen_pq (p, q);
5457
}
5558
}
5659
};
5760

61+
// Q needs to be the same precision as P for the operations below.
5862
let q = q.widen(l);
5963

6064
// Generate g using the unverifiable method as defined by Appendix A.2.1
6165
let e = (&*p - &BoxedUint::one()) / &q;
62-
let mut h = BoxedUint::one().widen(q.bits_precision());
66+
let mut h = BoxedUint::one().widen(l);
6367
let g = loop {
64-
let params = BoxedMontyParams::new_vartime(Odd::new((*p).clone()).unwrap());
68+
let params = BoxedMontyParams::new_vartime(p.clone());
6569
let form = BoxedMontyForm::new(h.clone(), params);
6670
let g = form.pow(&e).retrieve();
6771

6872
if !bool::from(g.is_one()) {
73+
// TODO(baloo): shouldn't we check e can't be 1 here?
74+
// and g could still be zero right? In which case just loop around?
6975
break NonZero::new(g).unwrap();
7076
}
7177

72-
// https://github.com/RustCrypto/crypto-bigint/issues/784
73-
#[allow(clippy::assign_op_pattern)]
74-
{
75-
h = h + BoxedUint::one();
76-
}
78+
h += BoxedUint::one();
7779
};
7880

79-
let q = NonZero::new(q.shorten(n)).unwrap();
81+
let q = NonZero::new(q.shorten(n)).expect("[bug] q_min(2^N-1) < q < q_max(2^N), Q is non zero");
8082

8183
(p, q, g)
8284
}
8385

8486
/// Calculate the public component from the common components and the private component
8587
#[inline]
86-
pub fn public(components: &Components, x: &NonZero<BoxedUint>) -> NonZero<BoxedUint> {
88+
pub fn public(components: &Components, x: &NonZero<BoxedUint>) -> CtOption<NonZero<BoxedUint>> {
8789
let p = components.p();
8890
let g = components.g();
8991

90-
let params = BoxedMontyParams::new_vartime(Odd::new((**p).clone()).unwrap());
92+
let params = BoxedMontyParams::new_vartime(p.clone());
9193
let form = BoxedMontyForm::new((**g).clone(), params);
9294

93-
NonZero::new(form.pow(x).retrieve()).unwrap()
95+
NonZero::new(form.pow(x).retrieve())
9496
}

dsa/src/generate/keypair.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,19 @@ use signature::rand_core::CryptoRng;
1010
/// Generate a new keypair
1111
#[inline]
1212
pub fn keypair<R: CryptoRng + ?Sized>(rng: &mut R, components: Components) -> SigningKey {
13-
let x = loop {
14-
let x = BoxedUint::random_mod(rng, components.q());
15-
if let Some(x) = NonZero::new(x).into() {
16-
break x;
13+
let (x, y) = loop {
14+
let x = 'gen_x: loop {
15+
let x = BoxedUint::random_mod(rng, components.q());
16+
if let Some(x) = NonZero::new(x).into() {
17+
break 'gen_x x;
18+
}
19+
};
20+
21+
if let Some(y) = components::public(&components, &x).into_option() {
22+
break (x, y);
1723
}
1824
};
1925

20-
let y = components::public(&components, &x);
21-
2226
VerifyingKey::from_components(components, y)
2327
.and_then(|verifying_key| SigningKey::from_components(verifying_key, x))
2428
.expect("[Bug] Newly generated keypair considered invalid")

dsa/src/generate/secret_number.rs

+15-11
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,19 @@ fn strip_leading_zeros(buffer: &[u8], desired_size: usize) -> &[u8] {
2020
///
2121
/// Secret number k and its modular multiplicative inverse with q
2222
#[inline]
23-
pub fn secret_number_rfc6979<D>(signing_key: &SigningKey, hash: &[u8]) -> (BoxedUint, BoxedUint)
23+
pub fn secret_number_rfc6979<D>(
24+
signing_key: &SigningKey,
25+
hash: &[u8],
26+
) -> Result<(BoxedUint, BoxedUint), signature::Error>
2427
where
2528
D: Digest + BlockSizeUser + FixedOutputReset,
2629
{
2730
let q = signing_key.verifying_key().components().q();
2831
let size = (q.bits() / 8) as usize;
32+
let hash = BoxedUint::from_be_slice(&hash[..min(size, hash.len())], q.bits_precision())
33+
.map_err(|_| signature::Error::new())?;
2934

3035
// Reduce hash mod q
31-
let hash =
32-
BoxedUint::from_be_slice(&hash[..min(size, hash.len())], q.bits_precision()).unwrap();
3336
let hash = (hash % q).to_be_bytes();
3437
let hash = strip_leading_zeros(&hash, size);
3538

@@ -43,11 +46,11 @@ where
4346
loop {
4447
rfc6979::generate_k_mut::<D>(x_bytes, q_bytes, hash, &[], &mut buffer);
4548

46-
let k = BoxedUint::from_be_slice(&buffer, q.bits_precision()).unwrap();
49+
let k = BoxedUint::from_be_slice(&buffer, q.bits_precision())
50+
.map_err(|_| signature::Error::new())?;
4751
if let Some(inv_k) = k.inv_mod(q).into() {
4852
if (bool::from(k.is_nonzero())) & (k < **q) {
49-
//debug_assert!(bool::from(k.is_odd()));
50-
return (k, inv_k);
53+
return Ok((k, inv_k));
5154
}
5255
}
5356
}
@@ -62,7 +65,7 @@ where
6265
pub fn secret_number<R: TryCryptoRng + ?Sized>(
6366
rng: &mut R,
6467
components: &Components,
65-
) -> Option<(BoxedUint, BoxedUint)> {
68+
) -> Result<Option<(BoxedUint, BoxedUint)>, signature::Error> {
6669
let q = components.q();
6770
let n = q.bits();
6871
let q = q.widen(n + 64);
@@ -71,17 +74,18 @@ pub fn secret_number<R: TryCryptoRng + ?Sized>(
7174
// Attempt to try a fitting secret number
7275
// Give up after 4096 tries
7376
for _ in 0..4096 {
74-
let c = BoxedUint::try_random_bits(rng, n + 64).unwrap();
75-
let rem = NonZero::new((&**q - &BoxedUint::one()).widen(c.bits_precision())).unwrap();
77+
let c = BoxedUint::try_random_bits(rng, n + 64).map_err(|_| signature::Error::new())?;
78+
let rem = NonZero::new((&**q - &BoxedUint::one()).widen(c.bits_precision()))
79+
.expect("[bug] minimum size for q is to 2^(160 - 1)");
7680
let k = (c % rem) + BoxedUint::one();
7781

7882
if let Some(inv_k) = k.inv_mod(q).into() {
7983
// `k` and `k^-1` both have to be in the range `[1, q-1]`
8084
if (inv_k > BoxedUint::zero() && inv_k < **q) && (k > BoxedUint::zero() && k < **q) {
81-
return Some((k, inv_k));
85+
return Ok(Some((k, inv_k)));
8286
}
8387
}
8488
}
8589

86-
None
90+
Ok(None)
8791
}

dsa/src/lib.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@
2626
#![cfg_attr(feature = "hazmat", doc = "```")]
2727
#![cfg_attr(not(feature = "hazmat"), doc = "```ignore")]
2828
//! # use dsa::{Components, SigningKey, VerifyingKey};
29-
//! # use crypto_bigint::{BoxedUint, NonZero};
29+
//! # use crypto_bigint::{BoxedUint, NonZero, Odd};
3030
//! # let read_common_parameters = ||
3131
//! # (
32-
//! # NonZero::new(BoxedUint::one()).unwrap(),
32+
//! # Odd::new(BoxedUint::one()).unwrap(),
3333
//! # NonZero::new(BoxedUint::one()).unwrap(),
3434
//! # NonZero::new(BoxedUint::one()).unwrap(),
3535
//! # );
@@ -77,8 +77,8 @@ pub const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10040.4.
7777

7878
use alloc::{boxed::Box, vec::Vec};
7979
use pkcs8::der::{
80-
self, Decode, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence, Writer,
81-
asn1::UintRef,
80+
self, Decode, DecodeValue, Encode, EncodeValue, FixedTag, Header, Length, Reader, Sequence,
81+
Writer, asn1::UintRef,
8282
};
8383
use signature::SignatureEncoding;
8484

@@ -120,11 +120,17 @@ impl<'a> DecodeValue<'a> for Signature {
120120
let r = UintRef::decode(reader)?;
121121
let s = UintRef::decode(reader)?;
122122

123-
let r = BoxedUint::from_be_slice(r.as_bytes(), r.as_bytes().len() as u32 * 8).unwrap();
124-
let s = BoxedUint::from_be_slice(s.as_bytes(), s.as_bytes().len() as u32 * 8).unwrap();
125-
126-
let r = NonZero::new(r).unwrap();
127-
let s = NonZero::new(s).unwrap();
123+
let r = BoxedUint::from_be_slice(r.as_bytes(), r.as_bytes().len() as u32 * 8)
124+
.map_err(|_| UintRef::TAG.value_error())?;
125+
let s = BoxedUint::from_be_slice(s.as_bytes(), s.as_bytes().len() as u32 * 8)
126+
.map_err(|_| UintRef::TAG.value_error())?;
127+
128+
let r = NonZero::new(r)
129+
.into_option()
130+
.ok_or(UintRef::TAG.value_error())?;
131+
let s = NonZero::new(s)
132+
.into_option()
133+
.ok_or(UintRef::TAG.value_error())?;
128134

129135
Ok(Self::from_components(r, s))
130136
})

0 commit comments

Comments
 (0)