diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b91a06d2..824ebd91 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ env: jobs: build: - name: ${{ matrix.name }} + name: ${{ matrix.rust }} - ${{ matrix.target }} runs-on: ubuntu-latest # The build matrix does not yet support 'allow failures' at job level. @@ -22,9 +22,19 @@ jobs: - 1.36.0 - stable - nightly + target: + - x86_64-unknown-linux-gnu + - thumbv7m-none-eabi include: - rust: nightly + target: x86_64-unknown-linux-gnu args: --all-features + - target: thumbv7m-none-eabi + test-target: arm-unknown-linux-gnueabi + args: --no-default-features --features=alloc + exclude: + - rust: 1.36.0 + target: thumbv7m-none-eabi steps: - name: Checkout @@ -34,24 +44,28 @@ jobs: uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.rust || 'stable' }} + target: ${{ matrix.target }} profile: minimal override: true - name: Build uses: actions-rs/cargo@v1 with: + use-cross: true command: build - args: --verbose ${{ matrix.args }} + args: --target ${{ matrix.target }} --verbose ${{ matrix.args }} - name: Test uses: actions-rs/cargo@v1 with: + use-cross: true command: test - args: --verbose ${{ matrix.args }} + args: --target ${{ matrix.test-target || matrix.target }} --verbose ${{ matrix.args }} - name: Bench uses: actions-rs/cargo@v1 with: + use-cross: true command: bench - args: --verbose --no-run ${{ matrix.args }} + args: --target ${{ matrix.test-target || matrix.target }} --verbose --no-run ${{ matrix.args }} if: matrix.rust == 'nightly' \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 24e95dc7..bb9faa2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,19 +12,17 @@ categories = ["cryptography"] readme = "README.md" [dependencies] -num-bigint = { version = "0.6", features = ["rand", "i128", "u64_digit", "prime", "zeroize"], package = "num-bigint-dig" } -num-traits = "0.2.6" -num-integer = "0.1.39" -num-iter = "0.1.37" -lazy_static = "1.3.0" -rand = "0.7.0" -byteorder = "1.3.1" -thiserror = "1.0.11" -subtle = "2.0.0" -simple_asn1 = "0.4" +num-bigint = { version = "0.6", features = ["i128", "u64_digit", "prime", "zeroize"], default-features = false, package = "num-bigint-dig" } +num-traits = { version= "0.2.9", default-features = false, features = ["libm"] } +num-integer = { version = "0.1.39", default-features = false } +num-iter = { version = "0.1.37", default-features = false } +lazy_static = { version = "1.3.0", features = ["spin_no_std"] } +rand = { version = "0.7.0", default-features = false } +byteorder = { version = "1.3.1", default-features = false } +subtle = { version = "2.0.0", default-features = false } +simple_asn1 = { version = "0.4", optional = true } pem = { version = "0.8", optional = true } -digest = { version = "0.9.0", features = ["std"] } -sha2 = "0.9.0" +digest = { version = "0.9.0", default-features = false } [dependencies.zeroize] version = "1.1.0" @@ -35,7 +33,7 @@ package = "serde" optional = true version = "1.0.89" default-features = false -features = ["std", "derive"] +features = ["derive"] [dev-dependencies] base64 = "0.12.0" @@ -43,8 +41,9 @@ hex = "0.4.0" serde_test = "1.0.89" rand_xorshift = "0.2.0" pem = "0.8" -sha-1 = "0.9.0" -sha3 = "0.9.0" +sha-1 = { default-features = false, version = "0.9.0" } +sha2 = { default-features = false, version = "0.9.0" } +sha3 = { default-features = false, version = "0.9.0" } [[bench]] name = "key" @@ -56,8 +55,10 @@ name = "key" # debug = true [features] -default = ["pem"] +default = ["std", "pem"] nightly = ["subtle/nightly", "num-bigint/nightly"] serde = ["num-bigint/serde", "serde_crate"] serde1 = ["serde"] # deprecated expose-internals = [] +std = ["alloc", "simple_asn1", "digest/std", "rand/std"] +alloc = ["digest/alloc"] \ No newline at end of file diff --git a/src/algorithms.rs b/src/algorithms.rs index 76c8c128..66ac504f 100644 --- a/src/algorithms.rs +++ b/src/algorithms.rs @@ -2,7 +2,10 @@ use digest::DynDigest; use num_bigint::traits::ModInverse; use num_bigint::{BigUint, RandPrime}; use num_traits::{FromPrimitive, One, Zero}; +#[allow(unused_imports)] +use num_traits::Float; use rand::Rng; +use alloc::vec; use crate::errors::{Error, Result}; use crate::key::RSAPrivateKey; @@ -143,7 +146,7 @@ pub fn mgf1_xor(out: &mut [u8], digest: &mut dyn DynDigest, seed: &[u8]) { let mut counter = [0u8; 4]; let mut i = 0; - const MAX_LEN: u64 = std::u32::MAX as u64 + 1; + const MAX_LEN: u64 = core::u32::MAX as u64 + 1; assert!(out.len() as u64 <= MAX_LEN); while i < out.len() { diff --git a/src/encode.rs b/src/encode.rs index d2723e6a..b53cfd08 100644 --- a/src/encode.rs +++ b/src/encode.rs @@ -8,6 +8,8 @@ use num_bigint::{BigUint, ToBigInt}; use num_traits::Zero; use pem::{EncodeConfig, LineEnding}; use simple_asn1::{to_der, ASN1Block}; +use std::prelude::v1::*; +use std::{vec, format}; const DEFAULT_ENCODING_CONFIG: EncodeConfig = EncodeConfig { line_ending: LineEnding::LF, diff --git a/src/errors.rs b/src/errors.rs index 82445d39..b6e10cfc 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,42 +1,51 @@ -use thiserror::Error; +use alloc::string::String; -pub type Result = ::std::result::Result; +pub type Result = core::result::Result; /// Error types -#[derive(Debug, Error)] +#[derive(Debug)] pub enum Error { - #[error("invalid padding scheme")] InvalidPaddingScheme, - #[error("decryption error")] Decryption, - #[error("verification error")] Verification, - #[error("message too long")] MessageTooLong, - #[error("input must be hashed")] InputNotHashed, - #[error("nprimes must be >= 2")] NprimesTooSmall, - #[error("too few primes of given length to generate an RSA key")] TooFewPrimes, - #[error("invalid prime value")] InvalidPrime, - #[error("invalid modulus")] InvalidModulus, - #[error("invalid exponent")] InvalidExponent, - #[error("invalid coefficient")] InvalidCoefficient, - #[error("public exponent too small")] PublicExponentTooSmall, - #[error("public exponent too large")] PublicExponentTooLarge, - #[error("parse error: {}", reason)] ParseError { reason: String }, - #[error("encoding error: {}", reason)] EncodeError { reason: String }, - #[error("internal error")] Internal, - #[error("label too long")] LabelTooLong, } + +#[cfg(feature = "std")] +impl std::error::Error for Error {} +impl core::fmt::Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + match self { + Error::InvalidPaddingScheme => write!(f, "invalid padding scheme"), + Error::Decryption => write!(f, "decryption error"), + Error::Verification => write!(f, "verification error"), + Error::MessageTooLong => write!(f, "message too long"), + Error::InputNotHashed => write!(f, "input must be hashed"), + Error::NprimesTooSmall => write!(f, "nprimes must be >= 2"), + Error::TooFewPrimes => write!(f, "too few primes of given length to generate an RSA key"), + Error::InvalidPrime => write!(f, "invalid prime value"), + Error::InvalidModulus => write!(f, "invalid modulus"), + Error::InvalidExponent => write!(f, "invalid exponent"), + Error::InvalidCoefficient => write!(f, "invalid coefficient"), + Error::PublicExponentTooSmall => write!(f, "public exponent too small"), + Error::PublicExponentTooLarge => write!(f, "public exponent too large"), + Error::ParseError { reason } => write!(f, "parse error: {}", reason), + Error::EncodeError { reason } => write!(f, "encoding error: {}", reason), + Error::Internal => write!(f, "internal error"), + Error::LabelTooLong => write!(f, "label too long"), + } + } +} \ No newline at end of file diff --git a/src/internals.rs b/src/internals.rs index eb291288..427ba64a 100644 --- a/src/internals.rs +++ b/src/internals.rs @@ -1,8 +1,10 @@ use num_bigint::{BigInt, BigUint, IntoBigInt, IntoBigUint, ModInverse, RandBigInt, ToBigInt}; use num_traits::{One, Signed, Zero}; use rand::Rng; -use std::borrow::Cow; +use alloc::borrow::Cow; use zeroize::Zeroize; +use alloc::vec::Vec; +use alloc::vec; use crate::errors::{Error, Result}; use crate::key::{PublicKeyParts, RSAPrivateKey}; diff --git a/src/key.rs b/src/key.rs index 8d142ff6..e4df5b55 100644 --- a/src/key.rs +++ b/src/key.rs @@ -2,11 +2,12 @@ use num_bigint::traits::ModInverse; use num_bigint::Sign::Plus; use num_bigint::{BigInt, BigUint}; use num_traits::{FromPrimitive, One}; -use rand::{rngs::ThreadRng, Rng}; +use rand::{rngs::StdRng, Rng}; #[cfg(feature = "serde")] use serde_crate::{Deserialize, Serialize}; -use std::ops::Deref; +use core::ops::Deref; use zeroize::Zeroize; +use alloc::vec::Vec; use crate::algorithms::{generate_multi_prime_key, generate_multi_prime_key_with_exp}; use crate::errors::{Error, Result}; @@ -247,6 +248,7 @@ impl RSAPublicKey { /// let der_bytes = base64::decode(&der_encoded).expect("failed to decode base64 content"); /// let public_key = RSAPublicKey::from_pkcs1(&der_bytes).expect("failed to parse key"); /// ``` + #[cfg(feature = "std")] pub fn from_pkcs1(der: &[u8]) -> Result { crate::parse::parse_public_key_pkcs1(der) } @@ -281,6 +283,7 @@ impl RSAPublicKey { /// let der_bytes = base64::decode(&der_encoded).expect("failed to decode base64 content"); /// let public_key = RSAPublicKey::from_pkcs8(&der_bytes).expect("failed to parse key"); /// ``` + #[cfg(feature = "std")] pub fn from_pkcs8(der: &[u8]) -> Result { crate::parse::parse_public_key_pkcs8(der) } @@ -405,6 +408,7 @@ impl RSAPrivateKey { /// let der_bytes = base64::decode(&der_encoded).expect("failed to decode base64 content"); /// let private_key = RSAPrivateKey::from_pkcs1(&der_bytes).expect("failed to parse key"); /// ``` + #[cfg(feature = "std")] pub fn from_pkcs1(der: &[u8]) -> Result { crate::parse::parse_private_key_pkcs1(der) } @@ -445,6 +449,7 @@ impl RSAPrivateKey { /// let der_bytes = base64::decode(&der_encoded).expect("failed to decode base64 content"); /// let private_key = RSAPrivateKey::from_pkcs8(&der_bytes).expect("failed to parse key"); /// ``` + #[cfg(feature = "std")] pub fn from_pkcs8(der: &[u8]) -> Result { crate::parse::parse_private_key_pkcs8(der) } @@ -554,10 +559,10 @@ impl RSAPrivateKey { match padding { // need to pass any Rng as the type arg, so the type checker is happy, it is not actually used for anything PaddingScheme::PKCS1v15Encrypt => { - pkcs1v15::decrypt::(None, self, ciphertext) + pkcs1v15::decrypt::(None, self, ciphertext) } PaddingScheme::OAEP { mut digest, label } => { - oaep::decrypt::(None, self, ciphertext, &mut *digest, label) + oaep::decrypt::(None, self, ciphertext, &mut *digest, label) } _ => Err(Error::InvalidPaddingScheme), } @@ -584,14 +589,15 @@ impl RSAPrivateKey { /// Sign the given digest. pub fn sign(&self, padding: PaddingScheme, digest_in: &[u8]) -> Result> { match padding { + // need to pass any Rng as the type arg, so the type checker is happy, it is not actually used for anything PaddingScheme::PKCS1v15Sign { ref hash } => { - pkcs1v15::sign::(None, self, hash.as_ref(), digest_in) + pkcs1v15::sign::(None, self, hash.as_ref(), digest_in) } PaddingScheme::PSS { mut salt_rng, mut digest, salt_len, - } => pss::sign::<_, ThreadRng, _>( + } => pss::sign::<_, StdRng, _>( &mut *salt_rng, None, self, @@ -652,9 +658,10 @@ mod tests { use super::*; use crate::internals; + use std::time::SystemTime; use digest::{Digest, DynDigest}; use num_traits::{FromPrimitive, ToPrimitive}; - use rand::{distributions::Alphanumeric, rngs::ThreadRng, thread_rng}; + use rand::{distributions::Alphanumeric, rngs::StdRng, SeedableRng}; use sha1::Sha1; use sha2::{Sha224, Sha256, Sha384, Sha512}; use sha3::{Sha3_256, Sha3_384, Sha3_512}; @@ -687,10 +694,11 @@ mod tests { let pub_key: RSAPublicKey = private_key.clone().into(); let m = BigUint::from_u64(42).expect("invalid 42"); let c = internals::encrypt(&pub_key, &m); - let m2 = internals::decrypt::(None, &private_key, &c) + let m2 = internals::decrypt::(None, &private_key, &c) .expect("unable to decrypt without blinding"); assert_eq!(m, m2); - let mut rng = thread_rng(); + let seed = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); + let mut rng = StdRng::seed_from_u64(seed.as_secs()); let m3 = internals::decrypt(Some(&mut rng), &private_key, &c) .expect("unable to decrypt with blinding"); assert_eq!(m, m3); @@ -700,7 +708,8 @@ mod tests { ($name:ident, $multi:expr, $size:expr) => { #[test] fn $name() { - let mut rng = thread_rng(); + let seed = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); + let mut rng = StdRng::seed_from_u64(seed.as_secs()); for _ in 0..10 { let private_key = if $multi == 2 { @@ -730,7 +739,8 @@ mod tests { #[test] fn test_impossible_keys() { // make sure not infinite loops are hit here. - let mut rng = thread_rng(); + let seed = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); + let mut rng = StdRng::seed_from_u64(seed.as_secs()); for i in 0..32 { let _ = RSAPrivateKey::new(&mut rng, i).is_err(); let _ = generate_multi_prime_key(&mut rng, 3, i); @@ -902,7 +912,8 @@ mod tests { } fn do_test_encrypt_decrypt_oaep(prk: &RSAPrivateKey) { - let mut rng = thread_rng(); + let seed = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); + let mut rng = StdRng::seed_from_u64(seed.as_secs()); let k = prk.size(); @@ -913,7 +924,7 @@ mod tests { } let has_label: bool = rng.gen(); let label: Option = if has_label { - Some(rng.sample_iter(&Alphanumeric).take(30).collect()) + Some(rng.clone().sample_iter(&Alphanumeric).take(30).collect()) } else { None }; @@ -949,7 +960,8 @@ mod tests { #[test] fn test_decrypt_oaep_invalid_hash() { - let mut rng = thread_rng(); + let seed = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); + let mut rng = StdRng::seed_from_u64(seed.as_secs()); let priv_key = get_private_key(); let pub_key: RSAPublicKey = (&priv_key).into(); let ciphertext = pub_key diff --git a/src/lib.rs b/src/lib.rs index 5b6d9907..23255a09 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,9 +7,12 @@ //! Using PKCS1v15. //! ``` //! use rsa::{PublicKey, RSAPrivateKey, RSAPublicKey, PaddingScheme}; +//! # /* //! use rand::rngs::OsRng; -//! //! let mut rng = OsRng; +//! # */ +//! # use rand::{SeedableRng, rngs::StdRng}; +//! # let mut rng = rand::rngs::StdRng::seed_from_u64(0); //! let bits = 2048; //! let private_key = RSAPrivateKey::new(&mut rng, bits).expect("failed to generate a key"); //! let public_key = RSAPublicKey::from(&private_key); @@ -29,9 +32,13 @@ //! Using OAEP. //! ``` //! use rsa::{PublicKey, RSAPrivateKey, RSAPublicKey, PaddingScheme}; +//! # /* //! use rand::rngs::OsRng; -//! //! let mut rng = OsRng; +//! # */ +//! # use rand::{SeedableRng, rngs::StdRng}; +//! # let mut rng = rand::rngs::StdRng::seed_from_u64(0); +//! //! let bits = 2048; //! let private_key = RSAPrivateKey::new(&mut rng, bits).expect("failed to generate a key"); //! let public_key = RSAPublicKey::from(&private_key); @@ -47,6 +54,15 @@ //! let dec_data = private_key.decrypt(padding, &enc_data).expect("failed to decrypt"); //! assert_eq!(&data[..], &dec_data[..]); //! ``` +#![cfg_attr(not(test), no_std)] + +#[cfg(not(feature = "alloc"))] +compile_error!("This crate does not yet support environments without liballoc. See https://github.com/RustCrypto/RSA/issues/51."); + +#[cfg(feature = "alloc")] +extern crate alloc; +#[cfg(feature = "std")] +extern crate std; #[macro_use] extern crate lazy_static; @@ -61,43 +77,62 @@ extern crate hex; #[cfg(all(test, feature = "serde"))] extern crate serde_test; +#[cfg(feature = "alloc")] pub use num_bigint::BigUint; /// Useful algorithms. +#[cfg(feature = "alloc")] pub mod algorithms; /// Error types. +#[cfg(feature = "alloc")] pub mod errors; /// Supported hash functions. +#[cfg(feature = "alloc")] pub mod hash; /// Supported padding schemes. +#[cfg(feature = "alloc")] pub mod padding; #[cfg(feature = "pem")] pub use pem; +#[cfg(feature = "std")] mod encode; + +#[cfg(feature = "alloc")] mod key; +#[cfg(feature = "alloc")] mod oaep; +#[cfg(feature = "std")] mod parse; +#[cfg(feature = "alloc")] mod pkcs1v15; +#[cfg(feature = "alloc")] mod pss; +#[cfg(feature = "alloc")] mod raw; +#[cfg(feature = "std")] pub use self::encode::{ PrivateKeyEncoding, PrivateKeyPemEncoding, PublicKeyEncoding, PublicKeyPemEncoding, }; +#[cfg(feature = "alloc")] pub use self::hash::Hash; +#[cfg(feature = "alloc")] pub use self::key::{PublicKey, PublicKeyParts, RSAPrivateKey, RSAPublicKey}; +#[cfg(feature = "alloc")] pub use self::padding::PaddingScheme; // Optionally expose internals if requested via feature-flag. #[cfg(not(feature = "expose-internals"))] +#[cfg(feature = "alloc")] mod internals; /// Internal raw RSA functions. #[cfg(feature = "expose-internals")] +#[cfg(feature = "alloc")] pub mod internals; diff --git a/src/oaep.rs b/src/oaep.rs index 00fe6392..7f5f9f2e 100644 --- a/src/oaep.rs +++ b/src/oaep.rs @@ -1,4 +1,7 @@ use rand::Rng; +use alloc::vec; +use alloc::vec::Vec; +use alloc::string::String; use digest::DynDigest; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; diff --git a/src/padding.rs b/src/padding.rs index 6b5e2ccf..395c08a5 100644 --- a/src/padding.rs +++ b/src/padding.rs @@ -1,4 +1,6 @@ -use std::fmt; +use core::fmt; +use alloc::string::{String, ToString}; +use alloc::boxed::Box; use digest::{Digest, DynDigest}; use rand::RngCore; diff --git a/src/parse.rs b/src/parse.rs index d4784288..c085d23f 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -4,8 +4,12 @@ use crate::{ }; use simple_asn1::{ASN1Block, ASN1DecodeErr, BigUint, OID}; +use alloc::format; +use alloc::vec; +use alloc::string::ToString; +use alloc::vec::Vec; #[cfg(feature = "pem")] -use std::convert::TryFrom; +use core::convert::TryFrom; impl From for Error { fn from(e: ASN1DecodeErr) -> Error { diff --git a/src/pkcs1v15.rs b/src/pkcs1v15.rs index 5e4ad496..d56ccea7 100644 --- a/src/pkcs1v15.rs +++ b/src/pkcs1v15.rs @@ -1,5 +1,7 @@ use rand::Rng; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq}; +use alloc::vec; +use alloc::vec::Vec; use crate::errors::{Error, Result}; use crate::hash::Hash; @@ -215,15 +217,17 @@ mod tests { use num_bigint::BigUint; use num_traits::FromPrimitive; use num_traits::Num; - use rand::thread_rng; + use rand::{SeedableRng, rngs::StdRng}; use sha1::{Digest, Sha1}; + use std::time::SystemTime; use crate::{Hash, PaddingScheme, PublicKey, PublicKeyParts, RSAPrivateKey, RSAPublicKey}; #[test] fn test_non_zero_bytes() { for _ in 0..10 { - let mut rng = thread_rng(); + let seed = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); + let mut rng = StdRng::seed_from_u64(seed.as_secs()); let mut b = vec![0u8; 512]; non_zero_random_bytes(&mut rng, &mut b); for el in &b { @@ -286,7 +290,8 @@ mod tests { #[test] fn test_encrypt_decrypt_pkcs1v15() { - let mut rng = thread_rng(); + let seed = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); + let mut rng = StdRng::seed_from_u64(seed.as_secs()); let priv_key = get_private_key(); let k = priv_key.size(); @@ -324,7 +329,8 @@ mod tests { assert_ne!(out, digest); assert_eq!(out, expected); - let mut rng = thread_rng(); + let seed = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); + let mut rng = StdRng::seed_from_u64(seed.as_secs()); let out2 = priv_key .sign_blinded( &mut rng, diff --git a/src/pss.rs b/src/pss.rs index 76bbcc9d..500ca7b0 100644 --- a/src/pss.rs +++ b/src/pss.rs @@ -1,4 +1,5 @@ -use std::vec::Vec; +use alloc::vec; +use alloc::vec::Vec; use digest::DynDigest; use rand::{Rng, RngCore}; @@ -239,8 +240,9 @@ mod test { use num_bigint::BigUint; use num_traits::{FromPrimitive, Num}; - use rand::thread_rng; use sha1::{Digest, Sha1}; + use std::time::SystemTime; + use rand::{SeedableRng, rngs::StdRng}; fn get_private_key() -> RSAPrivateKey { // In order to generate new test vectors you'll need the PEM form of this key: @@ -278,9 +280,11 @@ mod test { let digest = Sha1::digest(test[0].as_bytes()).to_vec(); let sig = hex::decode(test[1]).unwrap(); + let seed = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); + let rng = StdRng::seed_from_u64(seed.as_secs()); pub_key .verify( - PaddingScheme::new_pss::(thread_rng()), + PaddingScheme::new_pss::(rng), &digest, &sig, ) @@ -294,19 +298,22 @@ mod test { let tests = ["test\n"]; + let seed = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); + let rng = StdRng::seed_from_u64(seed.as_secs()); + for test in &tests { let digest = Sha1::digest(test.as_bytes()).to_vec(); let sig = priv_key .sign_blinded( - &mut thread_rng(), - PaddingScheme::new_pss::(thread_rng()), + &mut rng.clone(), + PaddingScheme::new_pss::(rng.clone()), &digest, ) .expect("failed to sign"); priv_key .verify( - PaddingScheme::new_pss::(thread_rng()), + PaddingScheme::new_pss::(rng.clone()), &digest, &sig, ) diff --git a/src/raw.rs b/src/raw.rs index 9bf55e96..569ed5f4 100644 --- a/src/raw.rs +++ b/src/raw.rs @@ -1,6 +1,7 @@ use num_bigint::BigUint; use rand::Rng; use zeroize::Zeroize; +use alloc::vec::Vec; use crate::errors::{Error, Result}; use crate::internals;