Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Random Number Generators #18

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@ default = ["rustc-serialize"]
name = "api"

[dependencies]
rand = { version = "0.5", features = ["i128_support"], default-features = false }
rand_core = {version = "0.5", default-features = false, features = ["alloc"]}
rustc-serialize = { version = "0.3", optional = true }
byteorder = { version = "1.0", features = ["i128"], default-features = false }
crunchy = "0.2.1"
lazy_static = { version = "1.4.0", features = ["spin_no_std"] }
rustc-hex = { version = "2", default-features = false }

[dev-dependencies]
rand = { version = "0.5", features = ["i128_support"] }
rand = "0.7"
rand_chacha = "0.2"

[dev-dependencies.bincode]
version = "0.6"
Expand Down
26 changes: 15 additions & 11 deletions src/arith.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::cmp::Ordering;
use rand::Rng;
use rand_core::{CryptoRng, RngCore};

#[cfg(feature = "rustc-serialize")]
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
Expand Down Expand Up @@ -83,7 +83,7 @@ impl U512 {
pub fn from_slice(s: &[u8]) -> Result<U512, Error> {
if s.len() != 64 {
return Err(Error::InvalidLength {
expected: 32,
expected: 64,
actual: s.len(),
});
}
Expand All @@ -97,8 +97,12 @@ impl U512 {
}

/// Get a random U512
pub fn random<R: Rng>(rng: &mut R) -> U512 {
U512(rng.gen())
pub fn random<R: CryptoRng + RngCore>(rng: &mut R) -> U512 {
let mut u512_bytes = [0u8; 64];
rng.fill_bytes(&mut u512_bytes);

U512::from_slice(&u512_bytes)
.expect("I believe 64 != 64 should always be false")
}

pub fn get_bit(&self, n: usize) -> Option<bool> {
Expand Down Expand Up @@ -158,7 +162,7 @@ impl Encodable for U512 {
}

for i in 0..(4 * 16) {
try!(s.emit_u8(buf[i]));
s.emit_u8(buf[i])?;
}

Ok(())
Expand All @@ -171,7 +175,7 @@ impl Decodable for U512 {
let mut buf = [0; (4 * 16)];

for i in 0..(4 * 16) {
buf[i] = try!(s.read_u8());
buf[i] = s.read_u8()?;
}

Ok(U512::interpret(&buf))
Expand All @@ -188,7 +192,7 @@ impl Encodable for U256 {
}

for i in 0..(2 * 16) {
try!(s.emit_u8(buf[i]));
s.emit_u8(buf[i])?;
}

Ok(())
Expand All @@ -201,7 +205,7 @@ impl Decodable for U256 {
let mut buf = [0; (2 * 16)];

for i in 0..(2 * 16) {
buf[i] = try!(s.read_u8());
buf[i] = s.read_u8()?;
}

U256::from_slice(&buf).map_err(|_| s.error("Invalid input length; Also unreachable;"))
Expand Down Expand Up @@ -302,7 +306,7 @@ impl U256 {
}

/// Produce a random number (mod `modulo`)
pub fn random<R: Rng>(rng: &mut R, modulo: &U256) -> U256 {
pub fn random<R: CryptoRng + RngCore>(rng: &mut R, modulo: &U256) -> U256 {
U512::random(rng).divrem(modulo).1
}

Expand Down Expand Up @@ -607,7 +611,7 @@ fn mul_reduce(this: &mut [u128; 2], by: &[u128; 2], modulus: &[u128; 2], inv: u1

#[test]
fn setting_bits() {
let rng = &mut ::rand::thread_rng();
let rng = &mut rand::thread_rng();
let modulo = U256::from([0xffffffffffffffff; 4]);

let a = U256::random(rng, &modulo);
Expand Down Expand Up @@ -648,7 +652,7 @@ fn to_big_endian() {

#[test]
fn testing_divrem() {
let rng = &mut ::rand::thread_rng();
let rng = &mut rand::thread_rng();

let modulo = U256::from([
0x3c208c16d87cfd47,
Expand Down
8 changes: 4 additions & 4 deletions src/fields/fp.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use alloc::vec::Vec;
use core::ops::{Add, Mul, Neg, Sub};
use rand::Rng;
use rand_core::{CryptoRng, RngCore};
use fields::FieldElement;
use arith::{U256, U512};

Expand Down Expand Up @@ -34,7 +34,7 @@ macro_rules! field_impl {
#[cfg(feature = "rustc-serialize")]
impl Decodable for $name {
fn decode<S: Decoder>(s: &mut S) -> Result<$name, S::Error> {
$name::new(try!(U256::decode(s))).ok_or_else(|| s.error("integer is not less than modulus"))
$name::new(U256::decode(s)?).ok_or_else(|| s.error("integer is not less than modulus"))
}
}

Expand Down Expand Up @@ -115,7 +115,7 @@ macro_rules! field_impl {
$name(U256::from($one))
}

fn random<R: Rng>(rng: &mut R) -> Self {
fn random<R: CryptoRng + RngCore>(rng: &mut R) -> Self {
$name(U256::random(rng, &U256::from($modulus)))
}

Expand Down Expand Up @@ -285,7 +285,7 @@ pub fn const_fq(i: [u64; 4]) -> Fq {

#[test]
fn test_rsquared() {
let rng = &mut ::rand::thread_rng();
let rng = &mut rand::thread_rng();

for _ in 0..1000 {
let a = Fr::random(rng);
Expand Down
4 changes: 2 additions & 2 deletions src/fields/fq12.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::ops::{Add, Mul, Neg, Sub};
use rand::Rng;
use rand_core::{CryptoRng, RngCore};
use fields::{const_fq, FieldElement, Fq, Fq2, Fq6};
use arith::U256;

Expand Down Expand Up @@ -281,7 +281,7 @@ impl FieldElement for Fq12 {
}
}

fn random<R: Rng>(rng: &mut R) -> Self {
fn random<R: CryptoRng + RngCore>(rng: &mut R) -> Self {
Fq12 {
c0: Fq6::random(rng),
c1: Fq6::random(rng),
Expand Down
6 changes: 3 additions & 3 deletions src/fields/fq2.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::ops::{Add, Mul, Neg, Sub};
use rand::Rng;
use rand_core::{CryptoRng, RngCore};
use fields::{const_fq, FieldElement, Fq};
use arith::{U256, U512};

Expand Down Expand Up @@ -56,7 +56,7 @@ impl Encodable for Fq2 {
#[cfg(feature = "rustc-serialize")]
impl Decodable for Fq2 {
fn decode<S: Decoder>(s: &mut S) -> Result<Fq2, S::Error> {
let combined = try!(U512::decode(s));
let combined = U512::decode(s)?;

match combined.divrem(&Fq::modulus()) {
(Some(c1), c0) => Ok(Fq2::new(Fq::new(c0).unwrap(), Fq::new(c1).unwrap())),
Expand Down Expand Up @@ -116,7 +116,7 @@ impl FieldElement for Fq2 {
}
}

fn random<R: Rng>(rng: &mut R) -> Self {
fn random<R: CryptoRng + RngCore>(rng: &mut R) -> Self {
Fq2 {
c0: Fq::random(rng),
c1: Fq::random(rng),
Expand Down
4 changes: 2 additions & 2 deletions src/fields/fq6.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use fields::{const_fq, FieldElement, Fq, Fq2};
use core::ops::{Add, Mul, Neg, Sub};
use rand::Rng;
use rand_core::{CryptoRng, RngCore};

fn frobenius_coeffs_c1(n: usize) -> Fq2 {
match n % 6 {
Expand Down Expand Up @@ -148,7 +148,7 @@ impl FieldElement for Fq6 {
}
}

fn random<R: Rng>(rng: &mut R) -> Self {
fn random<R: CryptoRng + RngCore>(rng: &mut R) -> Self {
Fq6 {
c0: Fq2::random(rng),
c1: Fq2::random(rng),
Expand Down
4 changes: 2 additions & 2 deletions src/fields/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ mod fq6;
mod fq12;

use arith::U256;
use rand::Rng;
use rand_core::{CryptoRng, RngCore};
use core::ops::{Add, Mul, Neg, Sub};
use alloc::fmt::Debug;

Expand All @@ -26,7 +26,7 @@ pub trait FieldElement
+ Debug {
fn zero() -> Self;
fn one() -> Self;
fn random<R: Rng>(&mut R) -> Self;
fn random<R: CryptoRng + RngCore>(&mut R) -> Self;
fn is_zero(&self) -> bool;
fn squared(&self) -> Self {
(*self) * (*self)
Expand Down
27 changes: 15 additions & 12 deletions src/fields/tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use rand::{Rng, SeedableRng, StdRng};
extern crate rand_chacha;
use rand_core::{CryptoRng, RngCore, SeedableRng};
use self::rand_chacha::ChaChaRng;

use super::FieldElement;

fn can_invert<F: FieldElement>() {
Expand All @@ -20,7 +23,7 @@ fn can_invert<F: FieldElement>() {
assert_eq!(F::zero().inverse(), None);
}

fn rand_element_eval<F: FieldElement, R: Rng>(rng: &mut R) {
fn rand_element_eval<F: FieldElement, R: CryptoRng + RngCore>(rng: &mut R) {
for _ in 0..100 {
let a = F::random(rng);
let b = F::random(rng);
Expand All @@ -31,7 +34,7 @@ fn rand_element_eval<F: FieldElement, R: Rng>(rng: &mut R) {
}
}

fn rand_element_squaring<F: FieldElement, R: Rng>(rng: &mut R) {
fn rand_element_squaring<F: FieldElement, R: CryptoRng + RngCore>(rng: &mut R) {
for _ in 0..100 {
let a = F::random(rng);

Expand All @@ -46,7 +49,7 @@ fn rand_element_squaring<F: FieldElement, R: Rng>(rng: &mut R) {
}
}

fn rand_element_addition_and_negation<F: FieldElement, R: Rng>(rng: &mut R) {
fn rand_element_addition_and_negation<F: FieldElement, R: CryptoRng + RngCore>(rng: &mut R) {
for _ in 0..100 {
let a = F::random(rng);

Expand Down Expand Up @@ -85,7 +88,7 @@ fn rand_element_addition_and_negation<F: FieldElement, R: Rng>(rng: &mut R) {
}
}

fn rand_element_inverse<F: FieldElement, R: Rng>(rng: &mut R) {
fn rand_element_inverse<F: FieldElement, R: CryptoRng + RngCore>(rng: &mut R) {
for _ in 0..10000 {
let a = F::random(rng);
assert!(a.inverse().unwrap() * a == F::one());
Expand All @@ -94,7 +97,7 @@ fn rand_element_inverse<F: FieldElement, R: Rng>(rng: &mut R) {
}
}

fn rand_element_multiplication<F: FieldElement, R: Rng>(rng: &mut R) {
fn rand_element_multiplication<F: FieldElement, R: CryptoRng + RngCore>(rng: &mut R) {
// If field is not associative under multiplication, 1/8 of all triplets a, b, c
// will fail the test (a*b)*c = a*(b*c).

Expand All @@ -120,11 +123,11 @@ pub fn field_trials<F: FieldElement>() {
0, 0, 0, 0, 0, 0, 0, 13, // 1293
0, 0, 0, 0, 0, 0, 96, 7u8, // 192103
];
let mut rng = StdRng::from_seed(seed);
let mut rng = ChaChaRng::from_seed(seed);

rand_element_squaring::<F, StdRng>(&mut rng);
rand_element_addition_and_negation::<F, StdRng>(&mut rng);
rand_element_multiplication::<F, StdRng>(&mut rng);
rand_element_inverse::<F, StdRng>(&mut rng);
rand_element_eval::<F, StdRng>(&mut rng);
rand_element_squaring::<F, ChaChaRng>(&mut rng);
rand_element_addition_and_negation::<F, ChaChaRng>(&mut rng);
rand_element_multiplication::<F, ChaChaRng>(&mut rng);
rand_element_inverse::<F, ChaChaRng>(&mut rng);
rand_element_eval::<F, ChaChaRng>(&mut rng);
}
Loading