diff --git a/Cargo.toml b/Cargo.toml index 9edfe8c..91ec335 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ p384 = { version = "0.13.0", default-features = false, features = [ "hash2curve", "voprf", ] } -blind-rsa-signatures = "0.15.0" +blind-rsa-signatures = "0.17" http = "1" typenum = "1" nom = "8" diff --git a/benches/public.rs b/benches/public.rs index b464277..0abf9c2 100644 --- a/benches/public.rs +++ b/benches/public.rs @@ -9,14 +9,14 @@ use privacypass::{ }, }; +use blind_rsa_signatures::reexports::rand::CryptoRng; use criterion::{Criterion, async_executor::FuturesExecutor}; use generic_array::ArrayLength; -use rand::{CryptoRng, RngCore}; use tokio::runtime::Runtime; use privacypass::{TokenType, auth::authenticate::TokenChallenge}; -async fn create_public_keypair( +async fn create_public_keypair( rng: &mut R, key_store: public_memory_store::IssuerMemoryKeyStore, server: privacypass::public_tokens::server::IssuerServer, @@ -52,7 +52,7 @@ pub fn criterion_public_benchmark(c: &mut Criterion) { c.bench_function("PUBLIC SERVER: Generate key pair", move |b| { b.to_async(FuturesExecutor).iter_with_setup( || { - let rng = rand::thread_rng(); + let rng = blind_rsa_signatures::reexports::rand::rng(); let key_store = IssuerMemoryKeyStore::default(); let server = IssuerServer::new(); (rng, key_store, server) @@ -67,7 +67,7 @@ pub fn criterion_public_benchmark(c: &mut Criterion) { c.bench_function("PUBLIC CLIENT: Issue token request", move |b| { b.iter_with_setup( || { - let mut rng = rand::thread_rng(); + let mut rng = blind_rsa_signatures::reexports::rand::rng(); let key_store = IssuerMemoryKeyStore::default(); let server = IssuerServer::new(); @@ -92,7 +92,7 @@ pub fn criterion_public_benchmark(c: &mut Criterion) { c.bench_function("PUBLIC SERVER: Issue token response", move |b| { b.to_async(FuturesExecutor).iter_with_setup( || { - let rng = &mut rand::thread_rng(); + let rng = &mut blind_rsa_signatures::reexports::rand::rng(); let key_store = IssuerMemoryKeyStore::default(); let server = IssuerServer::new(); @@ -119,7 +119,7 @@ pub fn criterion_public_benchmark(c: &mut Criterion) { c.bench_function("PUBLIC CLIENT: Issue token", move |b| { b.iter_with_setup( || { - let rng = &mut rand::thread_rng(); + let rng = &mut blind_rsa_signatures::reexports::rand::rng(); let key_store = IssuerMemoryKeyStore::default(); let server = IssuerServer::new(); @@ -152,7 +152,7 @@ pub fn criterion_public_benchmark(c: &mut Criterion) { c.bench_function("PUBLIC SERVER: Redeem token", move |b| { b.to_async(FuturesExecutor).iter_with_setup( || { - let rng = &mut rand::thread_rng(); + let rng = &mut blind_rsa_signatures::reexports::rand::rng(); let issuer_key_store = IssuerMemoryKeyStore::default(); let origin_key_store = OriginMemoryKeyStore::default(); diff --git a/src/amortized_tokens/response.rs b/src/amortized_tokens/response.rs index f2d383e..55250a9 100644 --- a/src/amortized_tokens/response.rs +++ b/src/amortized_tokens/response.rs @@ -117,8 +117,7 @@ impl AmortizedBatchTokenResponse { .iter() .zip(token_state.token_inputs.iter()) { - let authenticator = - GenericArray::from_slice(authenticator.as_ref()).clone(); + let authenticator = GenericArray::from_slice(authenticator.as_ref()).clone(); let token = Token::new( token_input.token_type, token_input.nonce, diff --git a/src/public_tokens/det_rng.rs b/src/public_tokens/det_rng.rs index a2e3117..73df8ef 100644 --- a/src/public_tokens/det_rng.rs +++ b/src/public_tokens/det_rng.rs @@ -1,6 +1,8 @@ //! Helper RNG that returns the same set of values for each call to (try_)fill_bytes. -use rand::{CryptoRng, Error, RngCore, rngs::OsRng}; +use blind_rsa_signatures::DefaultRng; +use blind_rsa_signatures::reexports::rand::{TryCryptoRng, TryRng}; +use std::convert::Infallible; /// This RNG step is used to generate deterministic values for the nonce, salt, /// and blind. @@ -44,7 +46,7 @@ impl DeterministicRng { self.additional_blind.as_deref() } - fn fill_with_data(&mut self, dest: &mut [u8]) { + fn fill_with_data(&mut self, dest: &mut [u8]) -> Result<(), Infallible> { match self.step { RngStep::Nonce => { dest.copy_from_slice(&self.nonce); @@ -60,32 +62,30 @@ impl DeterministicRng { } RngStep::AdditionalBlind => { let mut ab = [0u8; 256]; - OsRng.fill_bytes(&mut ab); + DefaultRng.try_fill_bytes(&mut ab)?; dest.copy_from_slice(&ab); self.additional_blind = Some(ab.to_vec()); self.step = RngStep::AdditionalBlind; } } + Ok(()) } } -impl RngCore for DeterministicRng { - fn next_u32(&mut self) -> u32 { - unimplemented!() - } +impl TryRng for DeterministicRng { + type Error = Infallible; - fn next_u64(&mut self) -> u64 { + fn try_next_u32(&mut self) -> Result { unimplemented!() } - fn fill_bytes(&mut self, dest: &mut [u8]) { - self.fill_with_data(dest); + fn try_next_u64(&mut self) -> Result { + unimplemented!() } - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - self.fill_with_data(dest); - Ok(()) + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Infallible> { + self.fill_with_data(dest) } } -impl CryptoRng for DeterministicRng {} +impl TryCryptoRng for DeterministicRng {} diff --git a/src/public_tokens/mod.rs b/src/public_tokens/mod.rs index fe16e09..692f8f2 100644 --- a/src/public_tokens/mod.rs +++ b/src/public_tokens/mod.rs @@ -1,5 +1,6 @@ //! # Publicly Verifiable Tokens +use blind_rsa_signatures::{Deterministic, PSS, Sha384}; use sha2::{Digest, Sha256}; use typenum::U256; @@ -17,7 +18,8 @@ pub use response::*; /// Publicly Verifiable Token alias pub type PublicToken = Token; -pub use blind_rsa_signatures::PublicKey; +/// Publicly Verifiable Token public key type alias (SHA-384, PSS, Deterministic). +pub type PublicKey = blind_rsa_signatures::PublicKey; use self::server::serialize_public_key; diff --git a/src/public_tokens/request.rs b/src/public_tokens/request.rs index 003a370..b2f5383 100644 --- a/src/public_tokens/request.rs +++ b/src/public_tokens/request.rs @@ -1,7 +1,9 @@ //! Request implementation of the Publicly Verifiable Token protocol. -use blind_rsa_signatures::{BlindingResult, Options, PublicKey}; -use rand::{CryptoRng, RngCore}; +use blind_rsa_signatures::BlindingResult; +use blind_rsa_signatures::reexports::rand::CryptoRng; + +use super::PublicKey; use tls_codec_derive::{TlsDeserialize, TlsSerialize, TlsSize}; use crate::{ @@ -41,7 +43,7 @@ impl TokenRequest { /// /// # Errors /// Returns an error if the challenge is invalid. - pub fn new( + pub fn new( rng: &mut R, public_key: PublicKey, challenge: &TokenChallenge, @@ -62,16 +64,15 @@ impl TokenRequest { let token_input = TokenInput::new(TokenType::Public, nonce, challenge_digest, token_key_id); - let options = Options::default(); let blinding_result = public_key - .blind(rng, token_input.serialize(), false, &options) + .blind(rng, token_input.serialize()) .map_err(|source| IssueTokenRequestError::BlindingError { source: source.into(), })?; - debug_assert!(blinding_result.blind_msg.len() == NK); + debug_assert!(blinding_result.blind_message.len() == NK); let mut blinded_msg = [0u8; NK]; - blinded_msg.copy_from_slice(blinding_result.blind_msg.as_slice()); + blinded_msg.copy_from_slice(blinding_result.blind_message.as_slice()); let token_request = TokenRequest { token_type: TokenType::Public, diff --git a/src/public_tokens/response.rs b/src/public_tokens/response.rs index c1e22b1..80b6016 100644 --- a/src/public_tokens/response.rs +++ b/src/public_tokens/response.rs @@ -1,6 +1,6 @@ //! Response implementation of the Publicly Verifiable Token protocol. -use blind_rsa_signatures::{BlindSignature, Options}; +use blind_rsa_signatures::BlindSignature; use generic_array::{GenericArray, typenum::U256}; use tls_codec_derive::{TlsDeserialize, TlsSerialize, TlsSize}; @@ -28,18 +28,11 @@ impl TokenResponse { pub fn issue_token(self, token_state: &TokenState) -> Result { // authenticator = rsabssa_finalize(pkI, nonce, blind_sig, blind_inv) let token_input = token_state.token_input.serialize(); - let options = Options::default(); let token_type = TokenType::Public; let blind_sig = BlindSignature(self.blind_sig.to_vec()); let signature = token_state .public_key - .finalize( - &blind_sig, - &token_state.blinding_result.secret, - None, - token_input, - &options, - ) + .finalize(&blind_sig, &token_state.blinding_result, token_input) .map_err(|source| IssueTokenError::SignatureFinalizationFailed { token_type, source, diff --git a/src/public_tokens/server.rs b/src/public_tokens/server.rs index 6ea83ba..8652c31 100644 --- a/src/public_tokens/server.rs +++ b/src/public_tokens/server.rs @@ -1,9 +1,14 @@ //! Server-side implementation of Publicly Verifiable Token protocol. use async_trait::async_trait; -use blind_rsa_signatures::{KeyPair, Options, PublicKey, Signature}; +use blind_rsa_signatures::reexports::rand::CryptoRng; +use blind_rsa_signatures::{ + Deterministic, KeyPair as GenericKeyPair, PSS, PublicKey as GenericPublicKey, Sha384, Signature, +}; use generic_array::ArrayLength; -use rand::{CryptoRng, RngCore, rngs::OsRng}; + +type KeyPair = GenericKeyPair; +type PublicKey = GenericPublicKey; use crate::{ COLLISION_AVOIDANCE_ATTEMPTS, NonceStore, TokenInput, TokenType, TruncatedTokenKeyId, @@ -41,7 +46,7 @@ pub trait OriginKeyStore { /// Serializes a keypair into a DER-encoded PKCS#8 document. #[must_use] pub fn serialize_public_key(public_key: &PublicKey) -> Vec { - public_key.to_spki(Some(&Options::default())).unwrap() + public_key.to_spki().unwrap() } const KEYSIZE_IN_BITS: usize = 2048; @@ -63,7 +68,7 @@ impl IssuerServer { /// /// # Errors /// Returns an error if creating the keypair fails. - pub async fn create_keypair( + pub async fn create_keypair( &self, rng: &mut R, key_store: &IKS, @@ -96,7 +101,6 @@ impl IssuerServer { key_store: &IKS, token_request: TokenRequest, ) -> Result { - let rng = &mut OsRng; if token_request.token_type != TokenType::Public { return Err(IssueTokenResponseError::InvalidTokenType { expected: TokenType::Public, @@ -109,10 +113,9 @@ impl IssuerServer { .ok_or(IssueTokenResponseError::KeyIdNotFound)?; // blind_sig = rsabssa_blind_sign(skI, TokenRequest.blinded_msg) - let options = Options::default(); let blind_signature = key_pair .sk - .blind_sign(rng, token_request.blinded_msg, &options) + .blind_sign(token_request.blinded_msg) .map_err(|source| IssueTokenResponseError::BlindSignatureFailed { source })?; debug_assert!(blind_signature.len() == NK); @@ -182,13 +185,12 @@ impl OriginServer { return Err(RedeemTokenError::KeyIdNotFound); } - let options = Options::default(); let signature = Signature(token.authenticator().to_vec()); let token_input_bytes = token_input.serialize(); let verified = public_keys.iter().any(|public_key| { - signature - .verify(public_key, None, &token_input_bytes, &options) + public_key + .verify(&signature, None, &token_input_bytes) .is_ok() }); diff --git a/src/test_utils/public_memory_store.rs b/src/test_utils/public_memory_store.rs index 2e9fab2..4067c0e 100644 --- a/src/test_utils/public_memory_store.rs +++ b/src/test_utils/public_memory_store.rs @@ -2,7 +2,10 @@ //! `OriginKeyStore` traits. use crate::{TruncatedTokenKeyId, public_tokens::server::*}; use async_trait::async_trait; -use blind_rsa_signatures::{KeyPair, PublicKey}; +use blind_rsa_signatures::{Deterministic, PSS, Sha384}; + +type KeyPair = blind_rsa_signatures::KeyPair; +type PublicKey = blind_rsa_signatures::PublicKey; use std::collections::{HashMap, hash_map::Entry}; use tokio::sync::Mutex; diff --git a/tests/generic_tokens.rs b/tests/generic_tokens.rs index dba2737..e724b02 100644 --- a/tests/generic_tokens.rs +++ b/tests/generic_tokens.rs @@ -1,3 +1,4 @@ +use blind_rsa_signatures::reexports::rand::rng; use p384::NistP384; use privacypass::{ TokenType, @@ -14,7 +15,6 @@ use privacypass::{ public_memory_store::{IssuerMemoryKeyStore, OriginMemoryKeyStore}, }, }; -use rand::thread_rng; use voprf::Ristretto255; #[tokio::test] @@ -45,7 +45,7 @@ async fn generic_tokens_cycle() { // === Set up the public token server === - let rng = &mut thread_rng(); + let rng = &mut rng(); // Server: Instantiate in-memory keystore and nonce store. let issuer_key_store = IssuerMemoryKeyStore::default(); diff --git a/tests/kat_private.rs b/tests/kat_private.rs index 63d964c..4d28318 100644 --- a/tests/kat_private.rs +++ b/tests/kat_private.rs @@ -87,7 +87,7 @@ pub(crate) async fn evaluate_vector(vector: PrivateToken // Convert parameters let token_challenge = TokenChallenge::deserialize(vector.token_challenge.as_slice()).unwrap(); let challenge_digest: [u8; 32] = token_challenge.digest().unwrap(); - let nonce: [u8; 32] = <[u8; 32]>::try_from(vector.nonce.as_ref()).unwrap(); + let nonce: [u8; 32] = <[u8; 32]>::try_from(vector.nonce.as_slice()).unwrap(); let blind = ::deserialize_scalar(&vector.blind).unwrap(); // Client: Prepare a TokenRequest after having received a challenge diff --git a/tests/kat_public.rs b/tests/kat_public.rs index e894570..40b0860 100644 --- a/tests/kat_public.rs +++ b/tests/kat_public.rs @@ -2,9 +2,9 @@ use std::{fs::File, io::Write}; use serde::{Deserialize, Serialize}; -use blind_rsa_signatures::{KeyPair, Options, PublicKey, SecretKey}; +use blind_rsa_signatures::{DefaultRng, Deterministic, KeyPair, PSS, PublicKey, SecretKey, Sha384}; -use rand::{RngCore, rngs::OsRng}; +use blind_rsa_signatures::reexports::rand::Rng; use tls_codec::Serialize as TlsSerializeTrait; use privacypass::{ @@ -73,14 +73,17 @@ pub(crate) async fn evaluate_vector(vector: PublicTokenTestVector) { let origin_server = OriginServer::new(); // Keys - let options = Options::default(); - - let sec_key = SecretKey::from_pem(&String::from_utf8_lossy(&vector.sk_s)).unwrap(); - let pub_key = PublicKey::from_spki(&vector.pk_s, Some(&options)).unwrap(); + let sec_key = + SecretKey::::from_pem(&String::from_utf8_lossy(&vector.sk_s)) + .unwrap(); + let pub_key = PublicKey::::from_spki(&vector.pk_s).unwrap(); // KAT: Check public key // Derive the public key from the private and compare it - assert_eq!(sec_key.to_public_key(), pub_key.0); + assert_eq!( + sec_key.public_key().unwrap().to_spki().unwrap(), + pub_key.to_spki().unwrap() + ); // Serialize the public key and compare it assert_eq!(serialize_public_key(&pub_key), vector.pk_s); @@ -182,7 +185,7 @@ pub(crate) async fn generate_kat_public_token() -> PublicTokenTestVector { let origin_server = OriginServer::new(); // Keys - let keypair = KeyPair::generate(&mut OsRng, 2048).unwrap(); + let keypair = KeyPair::::generate(&mut DefaultRng, 2048).unwrap(); let sk_s = keypair.sk.to_pem().unwrap().into_bytes(); let pk_s = serialize_public_key(&keypair.pk); @@ -202,13 +205,13 @@ pub(crate) async fn generate_kat_public_token() -> PublicTokenTestVector { // Prepare the deterministic number generator let mut nonce: Nonce = [0u8; 32]; - OsRng.fill_bytes(&mut nonce); + DefaultRng.fill_bytes(&mut nonce); let mut blind = [0u8; 256]; - OsRng.fill_bytes(&mut blind); + DefaultRng.fill_bytes(&mut blind); let mut salt = [0u8; 48]; - OsRng.fill_bytes(&mut salt); + DefaultRng.fill_bytes(&mut salt); let det_rng = &mut DeterministicRng::new( nonce.clone().to_vec(), @@ -216,9 +219,9 @@ pub(crate) async fn generate_kat_public_token() -> PublicTokenTestVector { blind.clone().to_vec(), ); - let redemption_context = if OsRng.next_u32().is_multiple_of(2) { + let redemption_context = if DefaultRng.next_u32().is_multiple_of(2) { let mut bytes = [0u8; 32]; - OsRng.fill_bytes(&mut bytes); + DefaultRng.fill_bytes(&mut bytes); Some(bytes) } else { None diff --git a/tests/public_tokens.rs b/tests/public_tokens.rs index e02111b..c43aa98 100644 --- a/tests/public_tokens.rs +++ b/tests/public_tokens.rs @@ -1,4 +1,5 @@ -use blind_rsa_signatures::{KeyPair, Options, PublicKey, SecretKey}; +use blind_rsa_signatures::reexports::rand::rng; +use blind_rsa_signatures::{Deterministic, KeyPair, PSS, PublicKey, SecretKey, Sha384}; use privacypass::{ TokenType, auth::authenticate::TokenChallenge, @@ -12,11 +13,10 @@ use privacypass::{ public_memory_store::{IssuerMemoryKeyStore, OriginMemoryKeyStore}, }, }; -use rand::thread_rng; #[tokio::test] async fn public_tokens_cycle() { - let rng = &mut thread_rng(); + let rng = &mut rng(); // Server: Instantiate in-memory keystore and nonce store. let issuer_key_store = IssuerMemoryKeyStore::default(); @@ -84,7 +84,7 @@ async fn public_tokens_cycle() { #[tokio::test] async fn redeem_token_supports_multiple_public_keys_per_truncated_id() { - let rng = &mut thread_rng(); + let rng = &mut rng(); let issuer_key_store = IssuerMemoryKeyStore::default(); let origin_key_store = OriginMemoryKeyStore::default(); @@ -103,13 +103,14 @@ async fn redeem_token_supports_multiple_public_keys_per_truncated_id() { let truncated_token_key_id = u8::from_str_radix(TRUNCATED_TOKEN_KEY_ID_HEX, 16).expect("valid truncated id"); - let options = Options::default(); - - let initial_public_key = - PublicKey::from_spki(&decode_hex(INITIAL_PUBLIC_KEY_SPKI_DER_HEX), Some(&options)) - .expect("initial public key should decode"); - let initial_secret_key = SecretKey::from_der(&decode_hex(INITIAL_SECRET_KEY_PKCS8_DER_HEX)) - .expect("initial secret key should decode"); + let initial_public_key = PublicKey::::from_spki(&decode_hex( + INITIAL_PUBLIC_KEY_SPKI_DER_HEX, + )) + .expect("initial public key should decode"); + let initial_secret_key = SecretKey::::from_der(&decode_hex( + INITIAL_SECRET_KEY_PKCS8_DER_HEX, + )) + .expect("initial secret key should decode"); let initial_keypair = KeyPair { pk: initial_public_key.clone(), sk: initial_secret_key, @@ -140,11 +141,14 @@ async fn redeem_token_supports_multiple_public_keys_per_truncated_id() { .unwrap(); let token = token_response.issue_token(&token_state).unwrap(); - let rotated_public_key = - PublicKey::from_spki(&decode_hex(ROTATED_PUBLIC_KEY_SPKI_DER_HEX), Some(&options)) - .expect("rotated public key should decode"); - let rotated_secret_key = SecretKey::from_der(&decode_hex(ROTATED_SECRET_KEY_PKCS8_DER_HEX)) - .expect("rotated secret key should decode"); + let rotated_public_key = PublicKey::::from_spki(&decode_hex( + ROTATED_PUBLIC_KEY_SPKI_DER_HEX, + )) + .expect("rotated public key should decode"); + let rotated_secret_key = SecretKey::::from_der(&decode_hex( + ROTATED_SECRET_KEY_PKCS8_DER_HEX, + )) + .expect("rotated secret key should decode"); let rotated_keypair = KeyPair { pk: rotated_public_key.clone(), sk: rotated_secret_key,