From 141e331355068c5bef3d8bcc40fbe27d8b14e27a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 2 Jun 2026 14:43:24 -0600 Subject: [PATCH] elliptic-curve: upgrade to `ff`/`group` v0.14.0 API This uses new versions of `rustcrypto-ff`/`rustcrypto-group` which are based on the `ff`/`group` v0.14.0 releases. The main notable change was the introduction of the `CurveAffine` trait in zkcrypto/group#48. There aren't releases of these crates yet as I'd like to get the entire stack upgraded first in git repos so I can release everything at once. --- Cargo.lock | 5 ++- Cargo.toml | 1 + elliptic-curve/src/arithmetic.rs | 6 ++-- elliptic-curve/src/dev/mock_curve.rs | 38 ++++++++++++++++++--- elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/point/basepoint_table.rs | 2 +- elliptic-curve/src/point/non_identity.rs | 14 ++++---- 7 files changed, 50 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d5112ed9b..6d1b71ded 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -487,8 +487,7 @@ checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" [[package]] name = "rustcrypto-ff" version = "0.14.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd2a8adb347447693cd2ba0d218c4b66c62da9b0a5672b17b981e4291ec65ff6" +source = "git+https://github.com/RustCrypto/ff#064c5a7418576641bd58ae244a8eea1c9592f577" dependencies = [ "rand_core", "subtle", @@ -497,7 +496,7 @@ dependencies = [ [[package]] name = "rustcrypto-group" version = "0.14.0-rc.1" -source = "git+https://github.com/RustCrypto/group#d5ef2775cb66a10085c9ec48432c51cad4e7b3ee" +source = "git+https://github.com/RustCrypto/group#2f1ea2e4f65d8a117d2445190357f841f9381db9" dependencies = [ "rand_core", "rustcrypto-ff", diff --git a/Cargo.toml b/Cargo.toml index ec248c5ba..d2c9c5a76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,4 +58,5 @@ crypto-common = { path = "crypto-common" } digest = { path = "digest" } signature = { path = "signature" } +rustcrypto-ff = { git = "https://github.com/RustCrypto/ff" } rustcrypto-group = { git = "https://github.com/RustCrypto/group" } diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 57c550b96..5e24b09cc 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,7 +1,8 @@ //! Elliptic curve arithmetic traits. use crate::{ - Curve, CurveGroup, Error, FieldBytes, Group, NonZeroScalar, PrimeCurve, ScalarValue, + Curve, CurveAffine, CurveGroup, Error, FieldBytes, Group, NonZeroScalar, PrimeCurve, + ScalarValue, ctutils::{CtEq, CtSelect}, ops::{Invert, LinearCombination, Mul, MulByGeneratorVartime, MulVartime, Reduce}, point::{AffineCoordinates, NonIdentity}, @@ -23,6 +24,7 @@ pub trait CurveArithmetic: Curve { + ConstantTimeEq + CtEq + CtSelect + + CurveAffine + Debug + Default + DefaultIsZeroes @@ -64,7 +66,7 @@ pub trait CurveArithmetic: Curve { + MulVartime + for<'a> MulVartime<&'a Self::Scalar> + TryInto, Error = Error> - + CurveGroup + + CurveGroup + Group; /// Scalar field modulo this curve's order. diff --git a/elliptic-curve/src/dev/mock_curve.rs b/elliptic-curve/src/dev/mock_curve.rs index 5919bcbca..1057517e3 100644 --- a/elliptic-curve/src/dev/mock_curve.rs +++ b/elliptic-curve/src/dev/mock_curve.rs @@ -5,7 +5,8 @@ //! generically over curves without having to pull in a complete curve implementation. use crate::{ - BatchNormalize, Curve, CurveArithmetic, CurveGroup, FieldBytesEncoding, Generate, PrimeCurve, + BatchNormalize, Curve, CurveAffine, CurveArithmetic, CurveGroup, FieldBytesEncoding, Generate, + PrimeCurve, array::typenum::U32, bigint::{Limb, Odd, U256, modular::Retrieve}, ctutils, @@ -92,7 +93,7 @@ impl Field for Scalar { const ZERO: Self = Self(ScalarValue::ZERO); const ONE: Self = Self(ScalarValue::ONE); - fn try_from_rng(rng: &mut R) -> core::result::Result { + fn try_random(rng: &mut R) -> core::result::Result { let mut bytes = FieldBytes::default(); loop { @@ -464,6 +465,27 @@ impl AffineCoordinates for AffinePoint { } } +impl CurveAffine for AffinePoint { + type Curve = ProjectivePoint; + type Scalar = Scalar; + + fn identity() -> Self { + Self::Identity + } + + fn generator() -> Self { + Self::Generator + } + + fn is_identity(&self) -> Choice { + unimplemented!(); + } + + fn to_curve(&self) -> ProjectivePoint { + unimplemented!(); + } +} + impl ConstantTimeEq for AffinePoint { fn ct_eq(&self, other: &Self) -> Choice { match (self, other) { @@ -580,6 +602,14 @@ impl Mul for AffinePoint { } } +impl Neg for AffinePoint { + type Output = Self; + + fn neg(self) -> Self { + unimplemented!(); + } +} + impl TryFrom for NonIdentity { type Error = Error; @@ -709,7 +739,7 @@ impl TryFrom for NonIdentity { impl group::Group for ProjectivePoint { type Scalar = Scalar; - fn try_from_rng(_rng: &mut R) -> core::result::Result { + fn try_random(_rng: &mut R) -> core::result::Result { unimplemented!(); } @@ -775,7 +805,7 @@ impl group::GroupEncoding for ProjectivePoint { } impl CurveGroup for ProjectivePoint { - type AffineRepr = AffinePoint; + type Affine = AffinePoint; fn to_affine(&self) -> AffinePoint { match self { diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 0ee691ebb..7f9ca1ee7 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -111,7 +111,7 @@ pub use { scalar::{NonZeroScalar, Scalar}, }, ff::{self, Field, PrimeField}, - group::{self, Curve as CurveGroup, Group}, + group::{self, Curve as CurveGroup, CurveAffine, Group}, }; #[cfg(any(feature = "pkcs8", feature = "sec1"))] diff --git a/elliptic-curve/src/point/basepoint_table.rs b/elliptic-curve/src/point/basepoint_table.rs index 125dd20ef..5a6ac453d 100644 --- a/elliptic-curve/src/point/basepoint_table.rs +++ b/elliptic-curve/src/point/basepoint_table.rs @@ -180,7 +180,7 @@ pub(super) mod vartime { .map(|(_, scalar)| WnafScalar::new(scalar)), ); - WnafBase::multiscalar_mul(scalars.iter(), bases.iter()) + WnafBase::multiscalar_mul(scalars, bases) } } diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index f6fee940d..8af1bf501 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -111,7 +111,7 @@ where } /// Converts this element into its affine representation. - pub fn to_affine(self) -> NonIdentity { + pub fn to_affine(self) -> NonIdentity { NonIdentity { point: self.point.to_affine(), } @@ -148,11 +148,11 @@ impl

AsRef

for NonIdentity

{ impl BatchNormalize<[Self; N]> for NonIdentity

where - P: CurveGroup + BatchNormalize<[P; N], Output = [P::AffineRepr; N]>, + P: CurveGroup + BatchNormalize<[P; N], Output = [P::Affine; N]>, { - type Output = [NonIdentity; N]; + type Output = [NonIdentity; N]; - fn batch_normalize(points: &[Self; N]) -> [NonIdentity; N] { + fn batch_normalize(points: &[Self; N]) -> [NonIdentity; N] { let points = Self::array_as_inner::(points); let affine_points =

>::batch_normalize(points); affine_points.map(|point| NonIdentity { point }) @@ -162,11 +162,11 @@ where #[cfg(feature = "alloc")] impl

BatchNormalize<[Self]> for NonIdentity

where - P: CurveGroup + BatchNormalize<[P], Output = Vec>, + P: CurveGroup + BatchNormalize<[P], Output = Vec>, { - type Output = Vec>; + type Output = Vec>; - fn batch_normalize(points: &[Self]) -> Vec> { + fn batch_normalize(points: &[Self]) -> Vec> { let points = Self::slice_as_inner(points); let affine_points =

>::batch_normalize(points); affine_points