From b000cf735ab5c70d9889b1c1bddb91a6c1e8f4fd Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Wed, 26 Feb 2025 11:50:16 -0800 Subject: [PATCH 1/2] elliptic-curve: ff now borrows the rng --- Cargo.lock | 2 +- Cargo.toml | 3 ++- elliptic-curve/src/dev.rs | 2 +- elliptic-curve/src/scalar/nonzero.rs | 5 ++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 631bb060..cde29925 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -237,7 +237,7 @@ dependencies = [ [[package]] name = "ff" version = "0.13.0" -source = "git+https://github.com/pinkforest/ff.git?branch=bump-rand-core#c734f7f21d6639bc6494dde538209d0770207c49" +source = "git+https://github.com/baloo/ff.git?branch=baloo%2Frelax-sized-rng#4ae604c5af58d047de06ea42197ef44f3f7d7834" dependencies = [ "bitvec", "rand_core", diff --git a/Cargo.toml b/Cargo.toml index 8c3861fb..9adb2a1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,8 @@ hmac = { git = "https://github.com/RustCrypto/MACs.git" } crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint.git" } # https://github.com/zkcrypto/ff/pull/122 -ff = { git = "https://github.com/pinkforest/ff.git", branch = "bump-rand-core" } +# https://github.com/zkcrypto/ff/pull/126 +ff = { git = "https://github.com/baloo/ff.git", branch = "baloo/relax-sized-rng" } # https://github.com/zkcrypto/group/pull/56 group = { git = "https://github.com/pinkforest/group.git", branch = "bump-rand-0.9" } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 567c97f4..01f4e209 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -99,7 +99,7 @@ impl Field for Scalar { const ZERO: Self = Self(ScalarPrimitive::ZERO); const ONE: Self = Self(ScalarPrimitive::ONE); - fn random(mut rng: impl RngCore) -> Self { + fn random(rng: &mut R) -> Self { let mut bytes = FieldBytes::default(); loop { diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 88f82a8a..43009868 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -47,14 +47,13 @@ where C: CurveArithmetic, { /// Generate a random `NonZeroScalar`. - pub fn random(mut rng: &mut R) -> Self { + pub fn random(rng: &mut R) -> Self { // Use rejection sampling to eliminate zero values. // While this method isn't constant-time, the attacker shouldn't learn // anything about unrelated outputs so long as `rng` is a secure `CryptoRng`. loop { // TODO: remove after `Field::random` switches to `&mut impl RngCore` - #[allow(clippy::needless_borrows_for_generic_args)] - if let Some(result) = Self::new(Field::random(&mut rng)).into() { + if let Some(result) = Self::new(Field::random(rng)).into() { break result; } } From d4ee8d28491f112071f1ef9647cfb64ea8643508 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Wed, 26 Feb 2025 11:54:24 -0800 Subject: [PATCH 2/2] elliptic-curve: adds `Scalar::try_from_rng` method --- Cargo.lock | 1 - Cargo.toml | 3 ++- elliptic-curve/src/dev.rs | 13 ++++++++++++- elliptic-curve/src/scalar/nonzero.rs | 15 ++++++++++++++- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cde29925..1a2f3ae2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -237,7 +237,6 @@ dependencies = [ [[package]] name = "ff" version = "0.13.0" -source = "git+https://github.com/baloo/ff.git?branch=baloo%2Frelax-sized-rng#4ae604c5af58d047de06ea42197ef44f3f7d7834" dependencies = [ "bitvec", "rand_core", diff --git a/Cargo.toml b/Cargo.toml index 9adb2a1f..04a65869 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,8 @@ crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint.git" } # https://github.com/zkcrypto/ff/pull/122 # https://github.com/zkcrypto/ff/pull/126 -ff = { git = "https://github.com/baloo/ff.git", branch = "baloo/relax-sized-rng" } +# https://github.com/zkcrypto/ff/pull/127 +ff = { git = "https://github.com/baloo/ff.git", branch = "baloo/try_from_rng" } # https://github.com/zkcrypto/group/pull/56 group = { git = "https://github.com/pinkforest/group.git", branch = "bump-rand-0.9" } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 01f4e209..26b14d90 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -10,7 +10,7 @@ use crate::{ error::{Error, Result}, ops::{Invert, LinearCombination, MulByGenerator, Reduce, ShrAssign}, point::AffineCoordinates, - rand_core::RngCore, + rand_core::{RngCore, TryRngCore}, scalar::{FromUintUnchecked, IsHigh}, sec1::{CompressedPoint, FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, @@ -110,6 +110,17 @@ impl Field for Scalar { } } + fn try_from_rng(rng: &mut R) -> core::result::Result { + let mut bytes = FieldBytes::default(); + + loop { + rng.try_fill_bytes(&mut bytes)?; + if let Some(scalar) = Self::from_repr(bytes).into() { + return Ok(scalar); + } + } + } + fn is_zero(&self) -> Choice { self.0.is_zero() } diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 43009868..06e39b4d 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -13,7 +13,7 @@ use core::{ }; use crypto_bigint::{ArrayEncoding, Integer}; use ff::{Field, PrimeField}; -use rand_core::CryptoRng; +use rand_core::{CryptoRng, TryCryptoRng}; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; use zeroize::Zeroize; @@ -59,6 +59,19 @@ where } } + /// Generate a random `NonZeroScalar`. + pub fn try_from_rng(rng: &mut R) -> Result { + // Use rejection sampling to eliminate zero values. + // While this method isn't constant-time, the attacker shouldn't learn + // anything about unrelated outputs so long as `rng` is a secure `CryptoRng`. + loop { + // TODO: remove after `Field::random` switches to `&mut impl RngCore` + if let Some(result) = Self::new(Scalar::::try_from_rng(rng)?).into() { + break Ok(result); + } + } + } + /// Create a [`NonZeroScalar`] from a scalar. pub fn new(scalar: Scalar) -> CtOption { CtOption::new(Self { scalar }, !scalar.is_zero())