Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ exclude = ["checkct/", "marvin_toolkit/", "thirdparty/"]

[dependencies]
const-oid = { version = "0.10", default-features = false }
crypto-bigint = { version = "0.7.6", default-features = false, features = ["zeroize", "alloc"] }
crypto-bigint = { version = "0.7.7", default-features = false, features = ["zeroize", "alloc"] }
crypto-primes = { version = "0.7", default-features = false }
digest = { version = "0.11", default-features = false, features = ["alloc", "oid"] }
rand_core = { version = "0.10", default-features = false }
Expand Down
4 changes: 2 additions & 2 deletions checkct/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions checkct/driver/src/raw_rsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use checkct_macros::checkct;
use core::hint::black_box;
use crypto_bigint::{
modular::{BoxedMontyForm, BoxedMontyParams, MontyParams},
BoxedUint, NonZero,
BoxedUint, NonZero, Odd,
};
use rsa::{
hazmat::rsa_decrypt,
Expand Down Expand Up @@ -69,7 +69,7 @@ impl PrivateKeyParts for NonCrtKey {
&self.d
}

fn primes(&self) -> &[BoxedUint] {
fn primes(&self) -> &[Odd<BoxedUint>] {
&[]
}

Expand Down
6 changes: 3 additions & 3 deletions src/algorithms/rsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ pub fn rsa_decrypt<R: TryCryptoRng + ?Sized>(
// (m1 - m2) mod p = (m1 mod p) - (m2 mod p) mod p
let m2_mod_p = match p_params.bits_precision().cmp(&q_params.bits_precision()) {
Ordering::Less => {
let p_wide = NonZero::new(priv_key.primes()[0].clone())
.expect("`p` is non-zero")
let p_wide = priv_key.primes()[0]
.as_nz_ref()
.resize_unchecked(q_params.bits_precision());
(&m2 % p_wide).resize_unchecked(p_params.bits_precision())
}
Expand All @@ -138,7 +138,7 @@ pub fn rsa_decrypt<R: TryCryptoRng + ?Sized>(
// m = m2 + h.q
let m2 = m2.try_resize(n.bits_precision()).ok_or(Error::Internal)?;
let hq = h
.concatenating_mul(&priv_key.primes()[1])
.concatenating_mul(priv_key.primes()[1].as_ref())
.try_resize(n.bits_precision())
.ok_or(Error::Internal)?;
m2.wrapping_add(&hq)
Expand Down
4 changes: 2 additions & 2 deletions src/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,13 @@ impl pkcs1::EncodeRsaPrivateKey for RsaPrivateKey {

let exponent1 = Zeroizing::new(
(self.d()
% NonZero::new((&self.primes[0]).resize_unchecked(bits) - &BoxedUint::one())
% NonZero::new(self.primes[0].as_ref().resize_unchecked(bits) - &BoxedUint::one())
.unwrap())
.to_be_bytes(),
);
let exponent2 = Zeroizing::new(
(self.d()
% NonZero::new((&self.primes[1]).resize_unchecked(bits) - &BoxedUint::one())
% NonZero::new(self.primes[1].as_ref().resize_unchecked(bits) - &BoxedUint::one())
.unwrap())
.to_be_bytes(),
);
Expand Down
53 changes: 24 additions & 29 deletions src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub struct RsaPublicKey {
/// Public exponent: power to which a plaintext message is raised in
/// order to encrypt it.
///
/// Typically `0x10001` (`65537`)
/// The recommended value is `0x10001` (`65537`).
e: BoxedUint,

n_params: BoxedMontyParams,
Expand Down Expand Up @@ -71,7 +71,7 @@ pub struct RsaPrivateKey {
/// Private exponent
pub(crate) d: BoxedUint,
/// Prime factors of N, contains >= 2 elements.
pub(crate) primes: Vec<BoxedUint>,
pub(crate) primes: Vec<Odd<BoxedUint>>,
/// Precomputed values to speed up private operations
pub(crate) precomputed: Option<PrecomputedValues>,
}
Expand Down Expand Up @@ -424,9 +424,11 @@ impl RsaPrivateKey {
.into_iter()
.map(|p| {
let p_bits = p.bits();
p.resize_unchecked(p_bits)
Odd::new(p.resize_unchecked(p_bits))
.into_option()
.ok_or(Error::InvalidPrime)
})
.collect();
.collect::<Result<Vec<_>>>()?;

let k = RsaPrivateKey {
pubkey_components: RsaPublicKey {
Expand Down Expand Up @@ -589,14 +591,8 @@ impl RsaPrivateKey {
let p = self.primes[0].clone();
let q = self.primes[1].clone();

let p_odd = Odd::new(p.clone())
.into_option()
.ok_or(Error::InvalidPrime)?;
let p_params = BoxedMontyParams::new(p_odd);
let q_odd = Odd::new(q.clone())
.into_option()
.ok_or(Error::InvalidPrime)?;
let q_params = BoxedMontyParams::new(q_odd);
let p_params = BoxedMontyParams::new(p.clone());
let q_params = BoxedMontyParams::new(q.clone());

let x = NonZero::new(p.wrapping_sub(BoxedUint::one()))
.into_option()
Expand All @@ -611,16 +607,10 @@ impl RsaPrivateKey {
// Note that since `p` and `q` may have different `bits_precision`,
// so we have to equalize them to calculate the remainder.
let q_mod_p = match p.bits_precision().cmp(&q.bits_precision()) {
Ordering::Less => (&q
% NonZero::new(p.clone())
.expect("`p` is non-zero")
.resize_unchecked(q.bits_precision()))
.resize_unchecked(p.bits_precision()),
Ordering::Greater => {
(&q).resize_unchecked(p.bits_precision())
% &NonZero::new(p.clone()).expect("`p` is non-zero")
}
Ordering::Equal => &q % NonZero::new(p.clone()).expect("`p` is non-zero"),
Ordering::Less => (q.as_ref() % p.as_nz_ref().resize_unchecked(q.bits_precision()))
.resize_unchecked(p.bits_precision()),
Ordering::Greater => q.as_ref().resize_unchecked(p.bits_precision()) % p.as_nz_ref(),
Ordering::Equal => q.as_ref() % p.as_nz_ref(),
};

let q_mod_p = BoxedMontyForm::new(q_mod_p, &p_params);
Expand Down Expand Up @@ -649,8 +639,7 @@ impl RsaPrivateKey {
pub fn crt_coefficient(&self) -> Option<BoxedUint> {
let p = &self.primes[0];
let q = &self.primes[1];
// TODO: maybe store primes as `NonZero`?
Option::from(q.invert_mod(&NonZero::new(p.clone()).expect("prime")))
Option::from(q.invert_odd_mod(p))
}

/// Performs basic sanity checks on the key.
Expand Down Expand Up @@ -713,7 +702,7 @@ impl PrivateKeyParts for RsaPrivateKey {
&self.d
}

fn primes(&self) -> &[BoxedUint] {
fn primes(&self) -> &[Odd<BoxedUint>] {
&self.primes
}

Expand Down Expand Up @@ -797,10 +786,10 @@ fn validate_private_key_parts(key: &RsaPrivateKey) -> Result<()> {
let one = BoxedUint::one();
for prime in &key.primes {
// Any primes ≤ 1 will cause divide-by-zero panics later.
if prime <= &one {
if prime.as_ref() <= &one {
return Err(Error::InvalidPrime);
}
m = m.wrapping_mul(prime);
m = m.wrapping_mul(prime.as_ref());
}
if m != *key.pubkey_components.n {
return Err(Error::InvalidModulus);
Expand Down Expand Up @@ -1212,7 +1201,10 @@ mod tests {
let ref_key = RsaPrivateKey::from_pkcs8_der(RSA_2048_PRIV_DER).unwrap();
assert_eq!(ref_key.validate(), Ok(()));

let primes = PrivateKeyParts::primes(&ref_key).to_vec();
let primes: Vec<_> = PrivateKeyParts::primes(&ref_key)
.iter()
.map(|p| p.as_ref().clone())
.collect();

let exp = PublicKeyParts::e(&ref_key);
let key = RsaPrivateKey::from_primes(primes, exp.clone())
Expand All @@ -1235,7 +1227,10 @@ mod tests {
let ref_key = RsaPrivateKey::from_pkcs8_der(RSA_2048_SP800_PRIV_DER).unwrap();
assert_eq!(ref_key.validate(), Ok(()));

let primes = PrivateKeyParts::primes(&ref_key).to_vec();
let primes: Vec<_> = PrivateKeyParts::primes(&ref_key)
.iter()
.map(|p| p.as_ref().clone())
.collect();
let exp = PublicKeyParts::e(&ref_key);

let key = RsaPrivateKey::from_p_q(primes[0].clone(), primes[1].clone(), exp.clone())
Expand Down
6 changes: 3 additions & 3 deletions src/traits/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::key::SecretPrime;
use alloc::boxed::Box;
use crypto_bigint::{
modular::{BoxedMontyForm, BoxedMontyParams},
BoxedUint, NonZero,
BoxedUint, NonZero, Odd,
};
use zeroize::Zeroize;

Expand Down Expand Up @@ -51,8 +51,8 @@ pub trait PrivateKeyParts: PublicKeyParts {
/// Returns the private exponent of the key.
fn d(&self) -> &BoxedUint;

/// Returns the prime factors.
fn primes(&self) -> &[BoxedUint];
/// Returns the odd prime factors.
fn primes(&self) -> &[Odd<BoxedUint>];

/// Returns prime `p` if precomputed.
fn p(&self) -> Option<&SecretPrime>;
Expand Down
16 changes: 8 additions & 8 deletions tests/pkcs1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ fn decode_rsa2048_priv_der() {
1024,
)
.unwrap();
assert!(bool::from(key.primes()[0].ct_eq(&expected_prime)));
assert!(bool::from(key.primes()[0].as_ref().ct_eq(&expected_prime)));

let expected_prime = BoxedUint::from_be_slice(
&hex!(
Expand All @@ -103,7 +103,7 @@ fn decode_rsa2048_priv_der() {
1024,
)
.unwrap();
assert!(bool::from(key.primes()[1].ct_eq(&expected_prime)));
assert!(bool::from(key.primes()[1].as_ref().ct_eq(&expected_prime)));
}

#[test]
Expand Down Expand Up @@ -170,7 +170,7 @@ fn decode_rsa4096_priv_der() {
2048,
)
.unwrap();
assert!(bool::from(key.primes()[0].ct_eq(&expected_prime)));
assert!(bool::from(key.primes()[0].as_ref().ct_eq(&expected_prime)));

let expected_prime = BoxedUint::from_be_slice(
&hex!(
Expand All @@ -186,7 +186,7 @@ fn decode_rsa4096_priv_der() {
2048,
)
.unwrap();
assert!(bool::from(key.primes()[1].ct_eq(&expected_prime)));
assert!(bool::from(key.primes()[1].as_ref().ct_eq(&expected_prime)));
}

#[test]
Expand Down Expand Up @@ -317,7 +317,7 @@ fn decode_rsa2048_priv_pem() {
1024,
)
.unwrap();
assert!(bool::from(key.primes()[0].ct_eq(&expected_prime)));
assert!(bool::from(key.primes()[0].as_ref().ct_eq(&expected_prime)));

let expected_prime = BoxedUint::from_be_slice(
&hex!(
Expand All @@ -329,7 +329,7 @@ fn decode_rsa2048_priv_pem() {
1024,
)
.unwrap();
assert!(bool::from(key.primes()[1].ct_eq(&expected_prime)));
assert!(bool::from(key.primes()[1].as_ref().ct_eq(&expected_prime)));
}

#[test]
Expand Down Expand Up @@ -398,7 +398,7 @@ fn decode_rsa4096_priv_pem() {
2048,
)
.unwrap();
assert!(bool::from(key.primes()[0].ct_eq(&expected_prime)));
assert!(bool::from(key.primes()[0].as_ref().ct_eq(&expected_prime)));

let expected_prime = BoxedUint::from_be_slice(
&hex!(
Expand All @@ -414,7 +414,7 @@ fn decode_rsa4096_priv_pem() {
2048,
)
.unwrap();
assert!(bool::from(key.primes()[1].ct_eq(&expected_prime)));
assert!(bool::from(key.primes()[1].as_ref().ct_eq(&expected_prime)));
}

#[test]
Expand Down
12 changes: 6 additions & 6 deletions tests/pkcs8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ fn decode_rsa2048_priv_der() {
1024,
)
.unwrap();
assert!(bool::from(key.primes()[0].ct_eq(&expected_prime)));
assert!(bool::from(key.primes()[0].as_ref().ct_eq(&expected_prime)));

let expected_prime = BoxedUint::from_be_slice(
&hex!(
Expand All @@ -91,7 +91,7 @@ fn decode_rsa2048_priv_der() {
1024,
)
.unwrap();
assert!(bool::from(key.primes()[1].ct_eq(&expected_prime)));
assert!(bool::from(key.primes()[1].as_ref().ct_eq(&expected_prime)));

let _ = pkcs1v15::SigningKey::<Sha256>::from_pkcs8_der(RSA_2048_PRIV_DER).unwrap();
}
Expand Down Expand Up @@ -163,7 +163,7 @@ fn decode_rsa2048_pss_priv_der() {
1024,
)
.unwrap();
assert!(bool::from(key.primes()[0].ct_eq(&expected_prime)));
assert!(bool::from(key.primes()[0].as_ref().ct_eq(&expected_prime)));

let expected_prime = BoxedUint::from_be_slice(
&hex!(
Expand All @@ -175,7 +175,7 @@ fn decode_rsa2048_pss_priv_der() {
1024,
)
.unwrap();
assert!(bool::from(key.primes()[1].ct_eq(&expected_prime)));
assert!(bool::from(key.primes()[1].as_ref().ct_eq(&expected_prime)));

let _ = pss::SigningKey::<Sha256>::from_pkcs8_der(RSA_2048_PSS_PRIV_DER).unwrap();
}
Expand Down Expand Up @@ -270,7 +270,7 @@ fn decode_rsa2048_priv_pem() {
1024,
)
.unwrap();
assert!(bool::from(key.primes()[0].ct_eq(&expected_prime)));
assert!(bool::from(key.primes()[0].as_ref().ct_eq(&expected_prime)));

let expected_prime = BoxedUint::from_be_slice(
&hex!(
Expand All @@ -282,7 +282,7 @@ fn decode_rsa2048_priv_pem() {
1024,
)
.unwrap();
assert!(bool::from(key.primes()[1].ct_eq(&expected_prime)));
assert!(bool::from(key.primes()[1].as_ref().ct_eq(&expected_prime)));

let _ = pkcs1v15::SigningKey::<Sha256>::from_pkcs8_pem(RSA_2048_PRIV_PEM).unwrap();
}
Expand Down
Loading