Replaces Rng256 with new Rng API (#612)

* Replaces the Rng256 with RngCore from rand_core

The old trait was designed with our software crypto in mind. We should
use a more standard API going forward.

- Removes libraries/rng256/
- Ports libraries/crypto/ to rand_core
- Moves the used RNG trait to api/

* Use StdRng directy in TestEnv
This commit is contained in:
kaczmarczyck
2023-04-11 10:23:38 +02:00
committed by GitHub
parent 4cc1b4fddf
commit be42b47caf
34 changed files with 219 additions and 536 deletions

View File

@@ -10,7 +10,6 @@ license = "Apache-2.0"
edition = "2018"
[dependencies]
rng256 = { path = "../rng256" }
arrayref = "0.3.6"
subtle = { version = "2.2.3", default-features = false, features = ["nightly"] }
byteorder = { version = "1", default-features = false }
@@ -20,7 +19,8 @@ untrusted = { version = "0.7.0", optional = true }
serde = { version = "1.0", optional = true, features = ["derive"] }
serde_json = { version = "=1.0.69", optional = true }
regex = { version = "1", optional = true }
rand_core = "0.6.4"
[features]
std = ["hex", "ring", "rng256/std", "untrusted", "serde", "serde_json", "regex"]
std = ["hex", "ring", "untrusted", "serde", "serde_json", "regex", "rand_core/getrandom"]
with_ctap1 = []

View File

@@ -14,7 +14,7 @@
use super::int256::{Digit, Int256};
use core::ops::Mul;
use rng256::Rng256;
use rand_core::RngCore;
use subtle::{self, Choice, ConditionallySelectable, CtOption};
// An exponent on the elliptic curve, that is an element modulo the curve order N.
@@ -112,7 +112,7 @@ impl NonZeroExponentP256 {
// Generates a uniformly distributed element 0 < k < N
pub fn gen_uniform<R>(r: &mut R) -> NonZeroExponentP256
where
R: Rng256,
R: RngCore,
{
loop {
let x = Int256::gen_uniform_256(r);
@@ -293,52 +293,4 @@ pub mod test {
assert_eq!(ONE.inv(), ONE);
assert_eq!(N_MIN_1.inv(), N_MIN_1);
}
/** RNG **/
// Mock rng that samples through a list of values, then panics.
struct StressTestingRng {
values: Vec<Int256>,
index: usize,
}
impl StressTestingRng {
pub fn new(values: Vec<Int256>) -> StressTestingRng {
StressTestingRng { values, index: 0 }
}
}
impl Rng256 for StressTestingRng {
// This function is unused, as we redefine gen_uniform_u32x8.
fn gen_uniform_u8x32(&mut self) -> [u8; 32] {
unreachable!()
}
fn gen_uniform_u32x8(&mut self) -> [u32; 8] {
let result = self.values[self.index].digits();
self.index += 1;
result
}
}
#[test]
fn test_uniform_non_zero_is_below_n() {
let mut rng = StressTestingRng::new(vec![
Int256::new([
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff,
]),
Int256::N,
N_MIN_1.to_int(),
Int256::N_MIN_2,
]);
assert_eq!(NonZeroExponentP256::gen_uniform(&mut rng), N_MIN_1);
}
#[test]
fn test_uniform_n_is_above_zero() {
let mut rng = StressTestingRng::new(vec![Int256::ZERO]);
assert_eq!(NonZeroExponentP256::gen_uniform(&mut rng), ONE);
}
}

View File

@@ -17,7 +17,7 @@ use alloc::vec::Vec;
use arrayref::{array_mut_ref, array_ref};
use byteorder::{BigEndian, ByteOrder};
use core::ops::{Add, AddAssign, Sub, SubAssign};
use rng256::Rng256;
use rand_core::RngCore;
use subtle::{self, Choice, ConditionallySelectable, ConstantTimeEq};
const BITS_PER_DIGIT: usize = 32;
@@ -119,11 +119,13 @@ impl Int256 {
// Generates a uniformly distributed integer 0 <= x < 2^256
pub fn gen_uniform_256<R>(r: &mut R) -> Int256
where
R: Rng256,
R: RngCore,
{
Int256 {
digits: r.gen_uniform_u32x8(),
let mut digits = [0; NDIGITS];
for i in 0..NDIGITS {
digits[i] = r.next_u32();
}
Int256 { digits }
}
/** Serialization **/

View File

@@ -16,7 +16,7 @@ use super::ec::exponent256::NonZeroExponentP256;
use super::ec::int256;
use super::ec::int256::Int256;
use super::ec::point::PointP256;
use rng256::Rng256;
use rand_core::RngCore;
pub const NBYTES: usize = int256::NBYTES;
@@ -32,7 +32,7 @@ pub struct PubKey {
impl SecKey {
pub fn gensk<R>(rng: &mut R) -> SecKey
where
R: Rng256,
R: RngCore,
{
SecKey {
a: NonZeroExponentP256::gen_uniform(rng),
@@ -99,7 +99,7 @@ impl PubKey {
#[cfg(test)]
mod test {
use super::*;
use rng256::ThreadRng256;
use rand_core::OsRng;
// Run more test iterations in release mode, as the code should be faster.
#[cfg(not(debug_assertions))]
@@ -110,7 +110,7 @@ mod test {
/** Test that key generation creates valid keys **/
#[test]
fn test_gen_pub_is_valid_random() {
let mut rng = ThreadRng256 {};
let mut rng = OsRng::default();
for _ in 0..ITERATIONS {
let sk = SecKey::gensk(&mut rng);
@@ -122,7 +122,7 @@ mod test {
/** Test that the exchanged key is the same on both sides **/
#[test]
fn test_exchange_x_is_symmetric() {
let mut rng = ThreadRng256 {};
let mut rng = OsRng::default();
for _ in 0..ITERATIONS {
let sk_a = SecKey::gensk(&mut rng);
@@ -135,7 +135,7 @@ mod test {
#[test]
fn test_exchange_x_bytes_is_symmetric() {
let mut rng = ThreadRng256 {};
let mut rng = OsRng::default();
for _ in 0..ITERATIONS {
let sk_a = SecKey::gensk(&mut rng);

View File

@@ -24,7 +24,7 @@ use alloc::vec::Vec;
use arrayref::array_mut_ref;
use arrayref::{array_ref, mut_array_refs};
use core::marker::PhantomData;
use rng256::Rng256;
use rand_core::RngCore;
pub const NBYTES: usize = int256::NBYTES;
@@ -46,7 +46,7 @@ pub struct PubKey {
impl SecKey {
pub fn gensk<R>(rng: &mut R) -> SecKey
where
R: Rng256,
R: RngCore,
{
SecKey {
k: NonZeroExponentP256::gen_uniform(rng),
@@ -67,7 +67,7 @@ impl SecKey {
pub fn sign_rng<H, R>(&self, msg: &[u8], rng: &mut R) -> Signature
where
H: Hash256,
R: Rng256,
R: RngCore,
{
let m = ExponentP256::modn(Int256::from_bin(&H::hash(msg)));
@@ -347,7 +347,7 @@ where
mod test {
use super::super::sha256::Sha256;
use super::*;
use rng256::ThreadRng256;
use rand_core::OsRng;
// Run more test iterations in release mode, as the code should be faster.
#[cfg(not(debug_assertions))]
@@ -355,10 +355,16 @@ mod test {
#[cfg(debug_assertions)]
const ITERATIONS: u32 = 500;
fn gen_random_message(rng: &mut impl RngCore) -> [u8; 32] {
let mut bytes = [0; 32];
rng.fill_bytes(&mut bytes);
bytes
}
/** Test that key generation creates valid keys **/
#[test]
fn test_genpk_is_valid_random() {
let mut rng = ThreadRng256 {};
let mut rng = OsRng::default();
for _ in 0..ITERATIONS {
let sk = SecKey::gensk(&mut rng);
@@ -370,7 +376,7 @@ mod test {
/** Serialization **/
#[test]
fn test_seckey_to_bytes_from_bytes() {
let mut rng = ThreadRng256 {};
let mut rng = OsRng::default();
for _ in 0..ITERATIONS {
let sk = SecKey::gensk(&mut rng);
@@ -461,10 +467,10 @@ mod test {
// Test that signed message hashes are correctly verified.
#[test]
fn test_sign_rfc6979_verify_hash_random() {
let mut rng = ThreadRng256 {};
let mut rng = OsRng::default();
for _ in 0..ITERATIONS {
let msg = rng.gen_uniform_u8x32();
let msg = gen_random_message(&mut rng);
let sk = SecKey::gensk(&mut rng);
let pk = sk.genpk();
let sign = sk.sign_rfc6979::<Sha256>(&msg);
@@ -476,10 +482,10 @@ mod test {
// Test that signed messages are correctly verified.
#[test]
fn test_sign_rfc6979_verify_random() {
let mut rng = ThreadRng256 {};
let mut rng = OsRng::default();
for _ in 0..ITERATIONS {
let msg = rng.gen_uniform_u8x32();
let msg = gen_random_message(&mut rng);
let sk = SecKey::gensk(&mut rng);
let pk = sk.genpk();
let sign = sk.sign_rfc6979::<Sha256>(&msg);
@@ -490,10 +496,10 @@ mod test {
// Test that signed messages are correctly verified.
#[test]
fn test_sign_verify_random() {
let mut rng = ThreadRng256 {};
let mut rng = OsRng::default();
for _ in 0..ITERATIONS {
let msg = rng.gen_uniform_u8x32();
let msg = gen_random_message(&mut rng);
let sk = SecKey::gensk(&mut rng);
let pk = sk.genpk();
let sign = sk.sign_rng::<Sha256, _>(&msg, &mut rng);
@@ -578,10 +584,10 @@ mod test {
fn test_self_sign_ring_verify() {
use ring::signature::VerificationAlgorithm;
let mut rng = ThreadRng256 {};
let mut rng = OsRng::default();
for _ in 0..ITERATIONS {
let msg_bytes = rng.gen_uniform_u8x32();
let msg_bytes = gen_random_message(&mut rng);
let sk = SecKey::gensk(&mut rng);
let pk = sk.genpk();
let sign = sk.sign_rng::<Sha256, _>(&msg_bytes, &mut rng);