diff --git a/ed448-goldilocks/src/decaf/points.rs b/ed448-goldilocks/src/decaf/points.rs index d4e1dd5c2..5f8b7c010 100644 --- a/ed448-goldilocks/src/decaf/points.rs +++ b/ed448-goldilocks/src/decaf/points.rs @@ -174,9 +174,14 @@ impl Group for DecafPoint { where R: TryRngCore + ?Sized, { - let mut uniform_bytes = [0u8; 112]; - rng.try_fill_bytes(&mut uniform_bytes)?; - Ok(Self::from_uniform_bytes(&uniform_bytes)) + let mut bytes = DecafPointRepr::default(); + + loop { + rng.try_fill_bytes(bytes.as_mut())?; + if let Some(point) = Self::from_bytes(&bytes).into() { + return Ok(point); + } + } } fn identity() -> Self { diff --git a/ed448-goldilocks/src/edwards/extended.rs b/ed448-goldilocks/src/edwards/extended.rs index 9b0da4adb..2b63e56ea 100644 --- a/ed448-goldilocks/src/edwards/extended.rs +++ b/ed448-goldilocks/src/edwards/extended.rs @@ -341,9 +341,14 @@ impl Group for EdwardsPoint { where R: TryRngCore + ?Sized, { - let mut bytes = [0u8; 32]; - rng.try_fill_bytes(&mut bytes)?; - Ok(Self::hash_with_defaults(&bytes)) + let mut bytes = Array::default(); + + loop { + rng.try_fill_bytes(bytes.as_mut())?; + if let Some(point) = Self::from_bytes(&bytes).into() { + return Ok(point); + } + } } fn identity() -> Self { diff --git a/k256/src/arithmetic/affine.rs b/k256/src/arithmetic/affine.rs index 883a4f2ab..bb25b46a9 100644 --- a/k256/src/arithmetic/affine.rs +++ b/k256/src/arithmetic/affine.rs @@ -9,6 +9,7 @@ use elliptic_curve::{ Error, Result, group::{GroupEncoding, prime::PrimeCurveAffine}, point::{AffineCoordinates, DecompactPoint, DecompressPoint, NonIdentity}, + rand_core::TryRngCore, sec1::{self, FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, zeroize::DefaultIsZeroes, @@ -73,6 +74,22 @@ impl AffinePoint { ]), infinity: 0, }; + + /// Generate a random [`AffinePoint`]. + pub fn try_from_rng( + rng: &mut R, + ) -> core::result::Result { + let mut bytes = FieldBytes::default(); + let mut sign = 0; + + loop { + rng.try_fill_bytes(&mut bytes)?; + rng.try_fill_bytes(core::array::from_mut(&mut sign))?; + if let Some(point) = Self::decompress(&bytes, Choice::from(sign & 1)).into_option() { + return Ok(point); + } + } + } } impl AffinePoint { diff --git a/k256/src/arithmetic/projective.rs b/k256/src/arithmetic/projective.rs index 8d3de16dc..901e98397 100644 --- a/k256/src/arithmetic/projective.rs +++ b/k256/src/arithmetic/projective.rs @@ -12,7 +12,6 @@ use elliptic_curve::{ BatchNormalize, CurveGroup, Error, Result, group::{ Group, GroupEncoding, - ff::Field, prime::{PrimeCurve, PrimeCurveAffine, PrimeGroup}, }, rand_core::TryRngCore, @@ -411,7 +410,7 @@ impl Group for ProjectivePoint { type Scalar = Scalar; fn try_from_rng(rng: &mut R) -> core::result::Result { - Ok(Self::GENERATOR * Scalar::try_from_rng(rng)?) + AffinePoint::try_from_rng(rng).map(Self::from) } fn identity() -> Self { diff --git a/primeorder/src/affine.rs b/primeorder/src/affine.rs index a93970d3e..54a498ee9 100644 --- a/primeorder/src/affine.rs +++ b/primeorder/src/affine.rs @@ -13,6 +13,7 @@ use elliptic_curve::{ ff::{Field, PrimeField}, group::{GroupEncoding, prime::PrimeCurveAffine}, point::{AffineCoordinates, DecompactPoint, DecompressPoint, Double, NonIdentity}, + rand_core::TryRngCore, sec1::{ self, CompressedPoint, EncodedPoint, FromEncodedPoint, ModulusSize, ToCompactEncodedPoint, ToEncodedPoint, UncompressedPointSize, @@ -77,6 +78,28 @@ where } } +impl AffinePoint +where + C: PrimeCurveParams, + FieldBytes: Copy, +{ + /// Generate a cryptographically random [`AffinePoint`]. + pub fn try_from_rng( + rng: &mut R, + ) -> core::result::Result { + let mut bytes = FieldBytes::::default(); + let mut sign = 0; + + loop { + rng.try_fill_bytes(&mut bytes)?; + rng.try_fill_bytes(core::array::from_mut(&mut sign))?; + if let Some(point) = Self::decompress(&bytes, Choice::from(sign & 1)).into_option() { + return Ok(point); + } + } + } +} + impl AffineCoordinates for AffinePoint where C: PrimeCurveParams, diff --git a/primeorder/src/projective.rs b/primeorder/src/projective.rs index 6389a6ae2..30dd1c3c5 100644 --- a/primeorder/src/projective.rs +++ b/primeorder/src/projective.rs @@ -258,13 +258,13 @@ where impl Group for ProjectivePoint where - Self: Double, C: PrimeCurveParams, + FieldBytes: Copy, { type Scalar = Scalar; fn try_from_rng(rng: &mut R) -> core::result::Result { - Ok(Self::GENERATOR * as Field>::try_from_rng(rng)?) + AffinePoint::try_from_rng(rng).map(Self::from) } fn identity() -> Self { @@ -311,8 +311,8 @@ where impl CurveGroup for ProjectivePoint where - Self: Double, C: PrimeCurveParams, + FieldBytes: Copy, { type AffineRepr = AffinePoint; @@ -331,8 +331,8 @@ where impl BatchNormalize<[ProjectivePoint; N]> for ProjectivePoint where - Self: Double, C: PrimeCurveParams, + FieldBytes: Copy, { type Output = [::AffineRepr; N]; @@ -348,8 +348,8 @@ where #[cfg(feature = "alloc")] impl BatchNormalize<[ProjectivePoint]> for ProjectivePoint where - Self: Double, C: PrimeCurveParams, + FieldBytes: Copy, { type Output = Vec<::AffineRepr>; @@ -400,16 +400,16 @@ where impl LinearCombination<[(Self, Scalar)]> for ProjectivePoint where - Self: Double, C: PrimeCurveParams, + FieldBytes: Copy, { // TODO(tarcieri): optimized implementation } impl LinearCombination<[(Self, Scalar); N]> for ProjectivePoint where - Self: Double, C: PrimeCurveParams, + FieldBytes: Copy, { // TODO(tarcieri): optimized implementation }