diff --git a/Cargo.toml b/Cargo.toml index d9f1c8e..743e6b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ license = "MIT OR Apache-2.0" cfg-if = "1.0" hex = { version = "=0.4.3", default-features = false } subtle = { version = "2.5", default-features = false } +rand_core = { version = "0.6", default-features = false } zeroize = { version = "1.7", default-features = false } # no-std num-bigint = { version = "0.4.4", optional = true, default-features = false } @@ -38,7 +39,7 @@ once_cell = { version = "1.8", optional = true, default-features = false } # compile [features] default = ["arkworks"] -alloc = ["once_cell/alloc", "zeroize/alloc"] +alloc = ["once_cell/alloc", "zeroize/alloc", "rand_core/alloc"] std = [ "alloc", "zeroize/std", @@ -46,6 +47,7 @@ std = [ "num-bigint/std", "hex/std", "subtle/std", + "rand_core/std" ] parallel = [ "ark-ff/parallel", diff --git a/src/fields/fp.rs b/src/fields/fp.rs index 37661fd..e0d9bc0 100644 --- a/src/fields/fp.rs +++ b/src/fields/fp.rs @@ -1,7 +1,5 @@ -// Fiat-crypto generates some unused type aliases, but we don't want to edit the generated code at all. -#![allow(dead_code)] - use cfg_if::cfg_if; +use rand_core::CryptoRngCore; use crate::EncodingError; @@ -115,7 +113,6 @@ impl Fp { }) // let acc = } - /// /// Convert bytes into an Fp element, returning None if these bytes are not already reduced. /// /// This means that values that cannot be produced by encoding a field element will return @@ -132,6 +129,17 @@ impl Fp { pub fn to_bytes(&self) -> [u8; N_8] { self.to_bytes_le() } + + /// Sample a random field element uniformly. + pub fn rand(rng: &mut R) -> Self { + // Sample wide, reduce + let bytes = { + let mut out = [0u8; N_8 + 16]; + rng.fill_bytes(&mut out); + out + }; + Self::from_le_bytes_mod_order(&bytes) + } } #[cfg(test)] diff --git a/src/fields/fq.rs b/src/fields/fq.rs index c513e44..45d5a3c 100644 --- a/src/fields/fq.rs +++ b/src/fields/fq.rs @@ -1,7 +1,5 @@ -// Fiat-crypto generates some unused type aliases, but we don't want to edit the generated code at all. -#![allow(dead_code)] - use cfg_if::cfg_if; +use rand_core::CryptoRngCore; use crate::EncodingError; @@ -116,6 +114,17 @@ impl Fq { pub fn to_bytes(&self) -> [u8; N_8] { self.to_bytes_le() } + + /// Sample a random field element uniformly. + pub fn rand(rng: &mut R) -> Self { + // Sample wide, reduce + let bytes = { + let mut out = [0u8; N_8 + 16]; + rng.fill_bytes(&mut out); + out + }; + Self::from_le_bytes_mod_order(&bytes) + } } #[cfg(test)] diff --git a/src/fields/fr.rs b/src/fields/fr.rs index 388d411..7ff60c1 100644 --- a/src/fields/fr.rs +++ b/src/fields/fr.rs @@ -1,7 +1,5 @@ -// Fiat-crypto generates some unused type aliases, but we don't want to edit the generated code at all. -#![allow(dead_code)] - use cfg_if::cfg_if; +use rand_core::CryptoRngCore; use crate::EncodingError; @@ -108,6 +106,17 @@ impl Fr { pub fn to_bytes(&self) -> [u8; N_8] { self.to_bytes_le() } + + /// Sample a random field element uniformly. + pub fn rand(rng: &mut R) -> Self { + // Sample wide, reduce + let bytes = { + let mut out = [0u8; N_8 + 16]; + rng.fill_bytes(&mut out); + out + }; + Self::from_le_bytes_mod_order(&bytes) + } } #[cfg(test)]