Skip to content

Commit 08b8cf2

Browse files
daxpeddatarcieri
andcommitted
Use rejection sampling for random point generation
Co-Authored-By: Tony Arcieri <[email protected]>
1 parent 912d939 commit 08b8cf2

File tree

4 files changed

+46
-15
lines changed

4 files changed

+46
-15
lines changed

ed448-goldilocks/src/decaf/points.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,14 @@ impl Group for DecafPoint {
174174
where
175175
R: TryRngCore + ?Sized,
176176
{
177-
let mut uniform_bytes = [0u8; 112];
178-
rng.try_fill_bytes(&mut uniform_bytes)?;
179-
Ok(Self::from_uniform_bytes(&uniform_bytes))
177+
let mut bytes = DecafPointRepr::default();
178+
179+
loop {
180+
rng.try_fill_bytes(bytes.as_mut())?;
181+
if let Some(point) = Self::from_bytes(&bytes).into() {
182+
return Ok(point);
183+
}
184+
}
180185
}
181186

182187
fn identity() -> Self {

ed448-goldilocks/src/edwards/extended.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,9 +341,14 @@ impl Group for EdwardsPoint {
341341
where
342342
R: TryRngCore + ?Sized,
343343
{
344-
let mut bytes = [0u8; 32];
345-
rng.try_fill_bytes(&mut bytes)?;
346-
Ok(Self::hash_with_defaults(&bytes))
344+
let mut bytes = Array::default();
345+
346+
loop {
347+
rng.try_fill_bytes(bytes.as_mut())?;
348+
if let Some(point) = Self::from_bytes(&bytes).into() {
349+
return Ok(point);
350+
}
351+
}
347352
}
348353

349354
fn identity() -> Self {

k256/src/arithmetic/projective.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use elliptic_curve::{
1212
BatchNormalize, CurveGroup, Error, Result,
1313
group::{
1414
Group, GroupEncoding,
15-
ff::Field,
1615
prime::{PrimeCurve, PrimeCurveAffine, PrimeGroup},
1716
},
1817
rand_core::TryRngCore,
@@ -411,7 +410,18 @@ impl Group for ProjectivePoint {
411410
type Scalar = Scalar;
412411

413412
fn try_from_rng<R: TryRngCore + ?Sized>(rng: &mut R) -> core::result::Result<Self, R::Error> {
414-
Ok(Self::GENERATOR * Scalar::try_from_rng(rng)?)
413+
let mut bytes = CompressedPoint::default();
414+
415+
loop {
416+
rng.try_fill_bytes(&mut bytes)?;
417+
418+
// Ensure SEC1 tag is 0x02 or 0x03 (compressed w\ even vs odd y-coordinate respectively)
419+
bytes[0] = (bytes[0] & 1) | 2;
420+
421+
if let Some(point) = Self::from_bytes(&bytes).into() {
422+
return Ok(point);
423+
}
424+
}
415425
}
416426

417427
fn identity() -> Self {

primeorder/src/projective.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -258,13 +258,24 @@ where
258258

259259
impl<C> Group for ProjectivePoint<C>
260260
where
261-
Self: Double,
261+
Self: GroupEncoding,
262262
C: PrimeCurveParams,
263263
{
264264
type Scalar = Scalar<C>;
265265

266266
fn try_from_rng<R: TryRngCore + ?Sized>(rng: &mut R) -> core::result::Result<Self, R::Error> {
267-
Ok(Self::GENERATOR * <Scalar<C> as Field>::try_from_rng(rng)?)
267+
let mut bytes = <Self as GroupEncoding>::Repr::default();
268+
269+
loop {
270+
rng.try_fill_bytes(bytes.as_mut())?;
271+
272+
// Ensure SEC1 tag is 0x02 or 0x03 (compressed w\ even vs odd y-coordinate respectively)
273+
bytes.as_mut()[0] = (bytes.as_mut()[0] & 1) | 2;
274+
275+
if let Some(point) = Self::from_bytes(&bytes).into() {
276+
return Ok(point);
277+
}
278+
}
268279
}
269280

270281
fn identity() -> Self {
@@ -311,7 +322,7 @@ where
311322

312323
impl<C> CurveGroup for ProjectivePoint<C>
313324
where
314-
Self: Double,
325+
Self: GroupEncoding,
315326
C: PrimeCurveParams,
316327
{
317328
type AffineRepr = AffinePoint<C>;
@@ -331,7 +342,7 @@ where
331342

332343
impl<const N: usize, C> BatchNormalize<[ProjectivePoint<C>; N]> for ProjectivePoint<C>
333344
where
334-
Self: Double,
345+
Self: GroupEncoding,
335346
C: PrimeCurveParams,
336347
{
337348
type Output = [<Self as CurveGroup>::AffineRepr; N];
@@ -348,7 +359,7 @@ where
348359
#[cfg(feature = "alloc")]
349360
impl<C> BatchNormalize<[ProjectivePoint<C>]> for ProjectivePoint<C>
350361
where
351-
Self: Double,
362+
Self: GroupEncoding,
352363
C: PrimeCurveParams,
353364
{
354365
type Output = Vec<<Self as CurveGroup>::AffineRepr>;
@@ -400,15 +411,15 @@ where
400411

401412
impl<C> LinearCombination<[(Self, Scalar<C>)]> for ProjectivePoint<C>
402413
where
403-
Self: Double,
414+
Self: GroupEncoding,
404415
C: PrimeCurveParams,
405416
{
406417
// TODO(tarcieri): optimized implementation
407418
}
408419

409420
impl<C, const N: usize> LinearCombination<[(Self, Scalar<C>); N]> for ProjectivePoint<C>
410421
where
411-
Self: Double,
422+
Self: GroupEncoding,
412423
C: PrimeCurveParams,
413424
{
414425
// TODO(tarcieri): optimized implementation

0 commit comments

Comments
 (0)