From fcd399c2065e7f3cd8388be798b52e41da7f3314 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 12 Sep 2025 16:51:21 -0600 Subject: [PATCH] elliptic-curve: change `Curve::ORDER` to be `Odd` Previously it was `NonZero`. This associated constant is for the curve's prime order subgroup, which will always be odd. There are many modular algorithms which require the modulus is odd, and bounding the `ORDER` on `Odd` ensures those algorithms will be compatible with the scalar field. The `primefield` crate and the params we are computing for every field of every curve are also `Odd` (i.e. the `modulus` of `MontyParams`). --- elliptic-curve/src/dev.rs | 4 ++-- elliptic-curve/src/lib.rs | 9 +++------ elliptic-curve/src/scalar/primitive.rs | 12 ++++++------ 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index e8016cc01..f5c871a77 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -6,7 +6,7 @@ use crate::{ BatchNormalize, Curve, CurveArithmetic, CurveGroup, FieldBytesEncoding, PrimeCurve, array::typenum::U32, - bigint::{Limb, NonZero, U256}, + bigint::{Limb, Odd, U256}, error::{Error, Result}, ops::{Invert, LinearCombination, Reduce, ShrAssign}, point::{AffineCoordinates, NonIdentity}, @@ -70,7 +70,7 @@ impl Curve for MockCurve { type FieldBytesSize = U32; type Uint = U256; - const ORDER: NonZero = NonZero::::from_be_hex( + const ORDER: Odd = Odd::::from_be_hex( "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", ); } diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index a473e09ad..a5b2e1aa2 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -133,7 +133,7 @@ pub use { #[cfg(feature = "pkcs8")] pub use pkcs8; -use bigint::NonZero; +use bigint::Odd; use core::{ fmt::Debug, ops::{Add, ShrAssign}, @@ -174,11 +174,8 @@ pub trait Curve: 'static + Copy + Clone + Debug + Default + Eq + Ord + Send + Sy + FieldBytesEncoding + ShrAssign; - /// Order of this elliptic curve, i.e. number of elements in the scalar - /// field. - // TODO(tarcieri): make `Odd`? the prime order subgroup should always have an odd number of - // elements, even if there is a cofactor - const ORDER: NonZero; + /// Order of this curve's prime order subgroup, i.e. number of elements in the scalar field. + const ORDER: Odd; } /// Marker trait for elliptic curves with prime order. diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index adfcf1cec..92d00bd87 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -3,7 +3,7 @@ use crate::{ Curve, Error, FieldBytes, FieldBytesEncoding, Result, array::Array, - bigint::{Limb, NonZero, prelude::*}, + bigint::{Limb, Odd, prelude::*}, scalar::FromUintUnchecked, scalar::IsHigh, }; @@ -62,12 +62,12 @@ where }; /// Scalar modulus. - pub const MODULUS: NonZero = C::ORDER; + pub const MODULUS: Odd = C::ORDER; /// Generate a random [`ScalarPrimitive`]. pub fn random(rng: &mut R) -> Self { Self { - inner: C::Uint::random_mod(rng, &Self::MODULUS), + inner: C::Uint::random_mod(rng, Self::MODULUS.as_nz_ref()), } } @@ -254,7 +254,7 @@ where fn add(self, other: &Self) -> Self { Self { - inner: self.inner.add_mod(&other.inner, &Self::MODULUS), + inner: self.inner.add_mod(&other.inner, Self::MODULUS.as_nz_ref()), } } } @@ -296,7 +296,7 @@ where fn sub(self, other: &Self) -> Self { Self { - inner: self.inner.sub_mod(&other.inner, &Self::MODULUS), + inner: self.inner.sub_mod(&other.inner, Self::MODULUS.as_nz_ref()), } } } @@ -327,7 +327,7 @@ where fn neg(self) -> Self { Self { - inner: self.inner.neg_mod(&Self::MODULUS), + inner: self.inner.neg_mod(Self::MODULUS.as_nz_ref()), } } }