From 4456de88184251b95c98e089a74a5c107b494f14 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Sun, 2 Mar 2025 21:37:03 -0800 Subject: [PATCH] Provide a `Group::try_from_rng` --- CHANGELOG.md | 2 ++ src/lib.rs | 20 ++++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8c7b05..d7434ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ and this library adheres to Rust's notion of - `group::Group::random(rng: impl RngCore) -> Self` has been changed to `Group::random(rng: &mut R) -> Self`, to enable passing a trait object as the RNG. +- `group::Group::try_from_rng` is a new trait method that must be implemented by + downstreams. `Group::random` now has a default implementation that calls it. ## [0.13.0] - 2022-12-06 ### Changed diff --git a/src/lib.rs b/src/lib.rs index b59c590..3116649 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,11 +9,12 @@ extern crate alloc; // Re-export ff to make version-matching easier. pub use ff; +use core::convert::Infallible; use core::fmt; use core::iter::Sum; use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use ff::PrimeField; -use rand_core::RngCore; +use rand_core::{RngCore, TryRngCore}; use subtle::{Choice, CtOption}; pub mod cofactor; @@ -76,7 +77,22 @@ pub trait Group: /// this group. /// /// This function is non-deterministic, and samples from the user-provided RNG. - fn random(rng: &mut R) -> Self; + fn random(rng: &mut R) -> Self { + Self::try_from_rng(rng) + .map_err(|e: Infallible| e) + .expect("Infallible failed") + + // NOTE: once MSRV gets to 1.82 remove the map_err/expect and use + // let Ok(out) = Self::try_from_rng(rng); + // out + // See: https://blog.rust-lang.org/2024/10/17/Rust-1.82.0.html#omitting-empty-types-in-pattern-matching + } + + /// Returns an element chosen uniformly at random from the non-identity elements of + /// this group. + /// + /// This function is non-deterministic, and samples from the user-provided RNG. + fn try_from_rng(rng: &mut R) -> Result; /// Returns the additive identity, also known as the "neutral element". fn identity() -> Self;