Skip to content

Commit 30de2b6

Browse files
authored
Merge pull request #8 from risc0/victor/0-9-x
ZKVM-1458: Update RSA patch to v0.9.9
2 parents 388d54e + 93de4c5 commit 30de2b6

12 files changed

Lines changed: 99 additions & 45 deletions

File tree

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## 0.9.9 (2025-11-13)
8+
### Fixed
9+
- Support for cryptographic operations with larger keys ([#594])
10+
11+
[#594]: https://github.com/RustCrypto/RSA/pull/594
12+
13+
## 0.9.8 (2025-03-12)
14+
### Added
15+
- Doc comments to specify the `rand` version ([#473])
16+
17+
[#473]: https://github.com/RustCrypto/RSA/pull/473
18+
19+
## 0.9.7 (2024-11-26)
20+
### Fixed
21+
- always validate keys in from_components
22+
- do not crash when handling tiny keys in PKCS1v15
23+
724
## 0.9.6 (2023-12-01)
825
### Added
926
- expose a `pss::get_default_pss_signature_algo_id` helper ([#393])

Cargo.lock

Lines changed: 18 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rsa"
3-
version = "0.9.6"
3+
version = "0.9.9"
44
authors = ["RustCrypto Developers", "dignifiedquire <dignifiedquire@gmail.com>"]
55
edition = "2021"
66
description = "Pure Rust RSA implementation"
@@ -32,12 +32,12 @@ sha2 = { version = "0.10.6", optional = true, default-features = false, features
3232
serde = { version = "1.0.184", optional = true, default-features = false, features = ["derive"] }
3333

3434
[target.'cfg(target_os = "zkvm")'.dependencies]
35-
risc0-bigint2 = { git = "https://github.com/risc0/risc0", rev = "8fc8437633f08a66e0fbacce947f41d01b074774", default-features = false, features = ["num-bigint-dig"] }
35+
getrandom = { version = "0.2", default-features = false, features = ["custom"] }
36+
risc0-bigint2 = { version = "1.4.11", features = ["num-bigint-dig"] }
3637

3738
[dev-dependencies]
3839
base64ct = { version = "1", features = ["alloc"] }
3940
hex-literal = "0.4.1"
40-
proptest = "1"
4141
serde_test = "1.0.89"
4242
rand_xorshift = "0.3"
4343
rand_chacha = "0.3"
@@ -47,6 +47,12 @@ sha1 = { version = "0.10.5", default-features = false, features = ["oid"] }
4747
sha2 = { version = "0.10.6", default-features = false, features = ["oid"] }
4848
sha3 = { version = "0.10.7", default-features = false, features = ["oid"] }
4949

50+
[target.'cfg(not(target_os = "zkvm"))'.dev-dependencies]
51+
proptest = "1"
52+
53+
[target.'cfg(target_os = "zkvm")'.dev-dependencies]
54+
proptest = { version = "1", default-features = false, features = ["alloc"] }
55+
5056
[[bench]]
5157
name = "key"
5258

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ A portable RSA implementation in pure Rust.
1414
```rust
1515
use rsa::{Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey};
1616

17-
let mut rng = rand::thread_rng();
17+
let mut rng = rand::thread_rng(); // rand@0.8
1818
let bits = 2048;
1919
let priv_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
2020
let pub_key = RsaPublicKey::from(&priv_key);

src/algorithms/pkcs1v15.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub(crate) fn pkcs1v15_encrypt_pad<R>(
4141
where
4242
R: CryptoRngCore + ?Sized,
4343
{
44-
if msg.len() > k - 11 {
44+
if msg.len() + 11 > k {
4545
return Err(Error::MessageTooLong);
4646
}
4747

@@ -195,4 +195,13 @@ mod tests {
195195
}
196196
}
197197
}
198+
199+
#[test]
200+
fn test_encrypt_tiny_no_crash() {
201+
let mut rng = ChaCha8Rng::from_seed([42; 32]);
202+
let k = 8;
203+
let message = vec![1u8; 4];
204+
let res = pkcs1v15_encrypt_pad(&mut rng, &message, k);
205+
assert_eq!(res, Err(Error::MessageTooLong));
206+
}
198207
}

src/algorithms/rsa.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use num_bigint::{BigInt, BigUint, IntoBigInt, IntoBigUint, ModInverse, RandBigIn
66
use num_integer::{sqrt, Integer};
77
use num_traits::{FromPrimitive, One, Pow, Signed, Zero};
88
use rand_core::CryptoRngCore;
9+
#[cfg(target_os = "zkvm")]
10+
use risc0_bigint2::ToBigInt2Buffer;
911
use zeroize::{Zeroize, Zeroizing};
1012

1113
use crate::errors::{Error, Result};
@@ -22,8 +24,14 @@ pub fn rsa_encrypt<K: PublicKeyParts>(key: &K, m: &BigUint) -> Result<BigUint> {
2224
#[cfg(target_os = "zkvm")]
2325
{
2426
// If we're in the RISC Zero zkVM, try to use an accelerated version.
25-
if *key.e() == BigUint::new(vec![65537]) {
26-
return Ok(risc0_bigint2::rsa::modpow_65537(m, key.n()));
27+
if m.bits() <= 4096 && key.n().bits() <= 4096 && *key.e() == BigUint::new(vec![65537]) {
28+
let mut result = [0u32; risc0_bigint2::field::FIELD_4096_WIDTH_WORDS];
29+
risc0_bigint2::rsa::modpow_65537(
30+
&m.to_u32_array(),
31+
&key.n().to_u32_array(),
32+
&mut result,
33+
);
34+
return Ok(BigUint::from_slice(&result));
2735
}
2836
// Fall through when the exponent does not match the accelerator
2937
}

src/key.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ impl RsaPublicKey {
184184
/// Create a new public key from its components.
185185
pub fn new_with_max_size(n: BigUint, e: BigUint, max_size: usize) -> Result<Self> {
186186
let k = Self { n, e };
187-
check_public_with_max_size(&k, max_size)?;
187+
check_public_with_max_size(&k, Some(max_size))?;
188188
Ok(k)
189189
}
190190

@@ -251,7 +251,6 @@ impl RsaPrivateKey {
251251
d: BigUint,
252252
mut primes: Vec<BigUint>,
253253
) -> Result<RsaPrivateKey> {
254-
let mut should_validate = false;
255254
if primes.len() < 2 {
256255
if !primes.is_empty() {
257256
return Err(Error::NprimesTooSmall);
@@ -261,7 +260,6 @@ impl RsaPrivateKey {
261260
let (p, q) = recover_primes(&n, &e, &d)?;
262261
primes.push(p);
263262
primes.push(q);
264-
should_validate = true;
265263
}
266264

267265
let mut k = RsaPrivateKey {
@@ -271,10 +269,8 @@ impl RsaPrivateKey {
271269
precomputed: None,
272270
};
273271

274-
// Validate the key if we had to recover the primes.
275-
if should_validate {
276-
k.validate()?;
277-
}
272+
// Always validate the key, to ensure precompute can't fail
273+
k.validate()?;
278274

279275
// precompute when possible, ignore error otherwise.
280276
let _ = k.precompute();
@@ -497,14 +493,19 @@ impl PrivateKeyParts for RsaPrivateKey {
497493
/// Check that the public key is well formed and has an exponent within acceptable bounds.
498494
#[inline]
499495
pub fn check_public(public_key: &impl PublicKeyParts) -> Result<()> {
500-
check_public_with_max_size(public_key, RsaPublicKey::MAX_SIZE)
496+
check_public_with_max_size(public_key, None)
501497
}
502498

503499
/// Check that the public key is well formed and has an exponent within acceptable bounds.
504500
#[inline]
505-
fn check_public_with_max_size(public_key: &impl PublicKeyParts, max_size: usize) -> Result<()> {
506-
if public_key.n().bits() > max_size {
507-
return Err(Error::ModulusTooLarge);
501+
fn check_public_with_max_size(
502+
public_key: &impl PublicKeyParts,
503+
max_size: Option<usize>,
504+
) -> Result<()> {
505+
if let Some(max_size) = max_size {
506+
if public_key.n().bits() > max_size {
507+
return Err(Error::ModulusTooLarge);
508+
}
508509
}
509510

510511
let e = public_key
@@ -717,13 +718,13 @@ mod tests {
717718
Base64::decode_vec("CUWC+hRWOT421kwRllgVjy6FYv6jQUcgDNHeAiYZnf5HjS9iK2ki7v8G5dL/0f+Yf+NhE/4q8w4m8go51hACrVpP1p8GJDjiT09+RsOzITsHwl+ceEKoe56ZW6iDHBLlrNw5/MtcYhKpjNU9KJ2udm5J/c9iislcjgckrZG2IB8ADgXHMEByZ5DgaMl4AKZ1Gx8/q6KftTvmOT5rNTMLi76VN5KWQcDWK/DqXiOiZHM7Nr4dX4me3XeRgABJyNR8Fqxj3N1+HrYLe/zs7LOaK0++F9Ul3tLelhrhsvLxei3oCZkF9A/foD3on3luYA+1cRcxWpSY3h2J4/22+yo4+Q==").unwrap(),
718719
];
719720

720-
RsaPrivateKey::from_components(
721+
let res = RsaPrivateKey::from_components(
721722
BigUint::from_bytes_be(&n),
722723
BigUint::from_bytes_be(&e),
723724
BigUint::from_bytes_be(&d),
724725
primes.iter().map(|p| BigUint::from_bytes_be(p)).collect(),
725-
)
726-
.unwrap();
726+
);
727+
assert_eq!(res, Err(Error::InvalidModulus));
727728
}
728729

729730
#[test]

src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#![cfg_attr(not(feature = "sha2"), doc = "```ignore")]
2626
//! use rsa::{RsaPrivateKey, RsaPublicKey, Oaep, sha2::Sha256};
2727
//!
28-
//! let mut rng = rand::thread_rng();
28+
//! let mut rng = rand::thread_rng(); // rand@0.8
2929
//!
3030
//! let bits = 2048;
3131
//! let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
@@ -47,7 +47,7 @@
4747
//! ```
4848
//! use rsa::{RsaPrivateKey, RsaPublicKey, Pkcs1v15Encrypt};
4949
//!
50-
//! let mut rng = rand::thread_rng();
50+
//! let mut rng = rand::thread_rng(); // rand@0.8
5151
//!
5252
//! let bits = 2048;
5353
//! let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
@@ -74,7 +74,7 @@
7474
//! use rsa::signature::{Keypair, RandomizedSigner, SignatureEncoding, Verifier};
7575
//! use rsa::sha2::{Digest, Sha256};
7676
//!
77-
//! let mut rng = rand::thread_rng();
77+
//! let mut rng = rand::thread_rng(); // rand@0.8
7878
//!
7979
//! let bits = 2048;
8080
//! let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
@@ -101,7 +101,7 @@
101101
//! use rsa::signature::{Keypair,RandomizedSigner, SignatureEncoding, Verifier};
102102
//! use rsa::sha2::{Digest, Sha256};
103103
//!
104-
//! let mut rng = rand::thread_rng();
104+
//! let mut rng = rand::thread_rng(); // rand@0.8
105105
//!
106106
//! let bits = 2048;
107107
//! let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");

src/oaep.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl Oaep {
6161
/// let n = Base64::decode_vec("ALHgDoZmBQIx+jTmgeeHW6KsPOrj11f6CvWsiRleJlQpW77AwSZhd21ZDmlTKfaIHBSUxRUsuYNh7E2SHx8rkFVCQA2/gXkZ5GK2IUbzSTio9qXA25MWHvVxjMfKSL8ZAxZyKbrG94FLLszFAFOaiLLY8ECs7g+dXOriYtBwLUJK+lppbd+El+8ZA/zH0bk7vbqph5pIoiWggxwdq3mEz4LnrUln7r6dagSQzYErKewY8GADVpXcq5mfHC1xF2DFBub7bFjMVM5fHq7RK+pG5xjNDiYITbhLYrbVv3X0z75OvN0dY49ITWjM7xyvMWJXVJS7sJlgmCCL6RwWgP8PhcE=").unwrap();
6262
/// let e = Base64::decode_vec("AQAB").unwrap();
6363
///
64-
/// let mut rng = rand::thread_rng();
64+
/// let mut rng = rand::thread_rng(); // rand@0.8
6565
/// let key = RsaPublicKey::new(BigUint::from_bytes_be(&n), BigUint::from_bytes_be(&e)).unwrap();
6666
/// let padding = Oaep::new::<Sha256>();
6767
/// let encrypted_data = key.encrypt(&mut rng, padding, b"secret").unwrap();
@@ -98,7 +98,7 @@ impl Oaep {
9898
/// let n = Base64::decode_vec("ALHgDoZmBQIx+jTmgeeHW6KsPOrj11f6CvWsiRleJlQpW77AwSZhd21ZDmlTKfaIHBSUxRUsuYNh7E2SHx8rkFVCQA2/gXkZ5GK2IUbzSTio9qXA25MWHvVxjMfKSL8ZAxZyKbrG94FLLszFAFOaiLLY8ECs7g+dXOriYtBwLUJK+lppbd+El+8ZA/zH0bk7vbqph5pIoiWggxwdq3mEz4LnrUln7r6dagSQzYErKewY8GADVpXcq5mfHC1xF2DFBub7bFjMVM5fHq7RK+pG5xjNDiYITbhLYrbVv3X0z75OvN0dY49ITWjM7xyvMWJXVJS7sJlgmCCL6RwWgP8PhcE=").unwrap();
9999
/// let e = Base64::decode_vec("AQAB").unwrap();
100100
///
101-
/// let mut rng = rand::thread_rng();
101+
/// let mut rng = rand::thread_rng(); // rand@0.8
102102
/// let key = RsaPublicKey::new(BigUint::from_bytes_be(&n), BigUint::from_bytes_be(&e)).unwrap();
103103
/// let padding = Oaep::new_with_mgf_hash::<Sha256, Sha1>();
104104
/// let encrypted_data = key.encrypt(&mut rng, padding, b"secret").unwrap();

src/pkcs1v15/signature.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
#[allow(unused_imports)]
2-
pub use ::signature::{
3-
hazmat::{PrehashSigner, PrehashVerifier},
4-
DigestSigner, DigestVerifier, Error, Keypair, RandomizedDigestSigner, RandomizedSigner, Result,
5-
SignatureEncoding, Signer, Verifier,
6-
};
1+
pub use ::signature::SignatureEncoding;
72
use spki::{
83
der::{asn1::BitString, Result as DerResult},
94
SignatureBitStringEncoding,

0 commit comments

Comments
 (0)