From b4e87492d7db6477c05b6e8a53b95c6d87406736 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 30 Dec 2022 10:05:11 -0700 Subject: [PATCH 1/8] Add `Group::mul_by_generator` Adds a provided method to the `Group` trait for performing multiplication by the generator. The use case is overriding this method in the event that precomputed scalar multiplication tables are available, which may be conditional depending on crate features like `alloc` or feature-gated static precomputed tables. --- src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 27ed5c9..b738244 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -90,6 +90,12 @@ pub trait Group: /// Doubles this element. #[must_use] fn double(&self) -> Self; + + /// Multiply by the generator of the prime-order subgroup. + #[must_use] + fn mul_by_generator(scalar: &Self::Scalar) -> Self { + Self::generator() * scalar + } } /// Efficient representation of an elliptic curve point guaranteed. From 6ab641f6ac8bb0bfd1e72faa0a94a3b13166840a Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 16 Apr 2025 11:45:26 +0000 Subject: [PATCH 2/8] Raise MSRV to 1.63 --- CHANGELOG.md | 2 ++ Cargo.toml | 2 +- README.md | 2 +- rust-toolchain.toml | 2 +- src/wnaf.rs | 6 ++++++ 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aec3f6d..591a72e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this library adheres to Rust's notion of [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- MSRV is now 1.63.0. ## [0.13.0] - 2022-12-06 ### Changed diff --git a/Cargo.toml b/Cargo.toml index bff1cf0..49fe2ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ authors = [ "Jack Grigg ", ] edition = "2021" -rust-version = "1.56" +rust-version = "1.63" readme = "README.md" license = "MIT/Apache-2.0" diff --git a/README.md b/README.md index c3c0640..efff81c 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ wider discussion. ## Minimum Supported Rust Version -Requires Rust **1.56** or higher. +Requires Rust **1.63** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. diff --git a/rust-toolchain.toml b/rust-toolchain.toml index de43b23..3eebdfe 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.56.0" +channel = "1.63.0" components = [ "clippy", "rustfmt" ] diff --git a/src/wnaf.rs b/src/wnaf.rs index 175d676..fdcf432 100644 --- a/src/wnaf.rs +++ b/src/wnaf.rs @@ -255,6 +255,12 @@ pub struct Wnaf { window_size: W, } +impl Default for Wnaf<(), Vec, Vec> { + fn default() -> Self { + Self::new() + } +} + impl Wnaf<(), Vec, Vec> { /// Construct a new wNAF context without allocating. pub fn new() -> Self { From 8240c176e346c20b6fa8bec87c4b88cd4bcc2faa Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 16 Apr 2025 11:49:01 +0000 Subject: [PATCH 3/8] Update lockfile to latest MSRV-compatible dependencies --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 46af6c4..775e6a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ff" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ "rand_core", "subtle", @@ -26,9 +26,9 @@ dependencies = [ [[package]] name = "memuse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2145869435ace5ea6ea3d35f59be559317ec9a0d04e1812d5f185a87b6d36f1a" +checksum = "3d97bbf43eb4f088f8ca469930cde17fa036207c9a5e02ccc5107c4e8b17c964" [[package]] name = "rand" @@ -56,6 +56,6 @@ dependencies = [ [[package]] name = "subtle" -version = "2.4.1" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" From 055cc14b002b22bde892c07602561ca026f884e1 Mon Sep 17 00:00:00 2001 From: pinkforest <36498018+pinkforest@users.noreply.github.com> Date: Sun, 26 Jan 2025 08:59:10 +0000 Subject: [PATCH 4/8] Bump to rust-random 0.9 Co-authored-by: Jack Grigg --- CHANGELOG.md | 1 + Cargo.lock | 71 ++++++++++++++++++++++++++++++++++++++++++------ Cargo.toml | 9 ++++-- src/tests/mod.rs | 4 +-- 4 files changed, 72 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 591a72e..3276d5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this library adheres to Rust's notion of ## [Unreleased] ### Changed - MSRV is now 1.63.0. +- Migrated to `ff 0.14`, `rand_core 0.9`. ## [0.13.0] - 2022-12-06 ### Changed diff --git a/Cargo.lock b/Cargo.lock index 775e6a1..c0263ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,8 +5,7 @@ version = 3 [[package]] name = "ff" version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +source = "git+https://github.com/zkcrypto/ff.git?rev=241caff9bcedafbe279b5a4d875461f66b3f9701#241caff9bcedafbe279b5a4d875461f66b3f9701" dependencies = [ "rand_core", "subtle", @@ -30,26 +29,45 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d97bbf43eb4f088f8ca469930cde17fa036207c9a5e02ccc5107c4e8b17c964" +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + [[package]] name = "rand" -version = "0.8.5" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ "rand_core", + "zerocopy", ] [[package]] name = "rand_core" -version = "0.6.4" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" [[package]] name = "rand_xorshift" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" dependencies = [ "rand_core", ] @@ -59,3 +77,40 @@ name = "subtle" version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "zerocopy" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index 49fe2ba..b666707 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,9 +17,9 @@ repository = "https://github.com/zkcrypto/group" [dependencies] ff = { version = "0.13", default-features = false } -rand = { version = "0.8", optional = true, default-features = false } -rand_core = { version = "0.6", default-features = false } -rand_xorshift = { version = "0.3", optional = true } +rand = { version = "0.9", optional = true, default-features = false } +rand_core = { version = "0.9", default-features = false } +rand_xorshift = { version = "0.4", optional = true } subtle = { version = "2.2.1", default-features = false } # Crate for exposing the dynamic memory usage of the w-NAF structs. @@ -33,3 +33,6 @@ wnaf-memuse = ["alloc", "memuse"] [badges] maintenance = { status = "actively-developed" } + +[patch.crates-io] +ff = { git = "https://github.com/zkcrypto/ff.git", rev = "241caff9bcedafbe279b5a4d875461f66b3f9701" } diff --git a/src/tests/mod.rs b/src/tests/mod.rs index ff79a9b..c81a926 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -378,8 +378,8 @@ fn random_transformation_tests() { for _ in 0..10 { let mut v = (0..1000).map(|_| G::random(&mut rng)).collect::>(); - use rand::distributions::{Distribution, Uniform}; - let between = Uniform::new(0, 1000); + use rand::distr::{Distribution, Uniform}; + let between = Uniform::new(0, 1000).unwrap(); // Sprinkle in some normalized points for _ in 0..5 { v[between.sample(&mut rng)] = G::identity(); From f3537bcd1c16a5ce48022e3eb948578fae4204c6 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Sun, 2 Mar 2025 21:37:03 -0800 Subject: [PATCH 5/8] Relax `Sized` requirements on the rng --- CHANGELOG.md | 3 +++ src/lib.rs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3276d5c..f8c7b05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this library adheres to Rust's notion of ### Changed - MSRV is now 1.63.0. - Migrated to `ff 0.14`, `rand_core 0.9`. +- `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. ## [0.13.0] - 2022-12-06 ### Changed diff --git a/src/lib.rs b/src/lib.rs index 27ed5c9..b59c590 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,7 +76,7 @@ pub trait Group: /// this group. /// /// This function is non-deterministic, and samples from the user-provided RNG. - fn random(rng: impl RngCore) -> Self; + fn random(rng: &mut R) -> Self; /// Returns the additive identity, also known as the "neutral element". fn identity() -> Self; From 4456de88184251b95c98e089a74a5c107b494f14 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Sun, 2 Mar 2025 21:37:03 -0800 Subject: [PATCH 6/8] 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; From a2604792918e9a60c4ddf28d4572a0ac3378e968 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 17 Apr 2025 17:41:39 +0000 Subject: [PATCH 7/8] Preview 0.14.0-pre.0 --- Cargo.lock | 7 ++++--- Cargo.toml | 7 ++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c0263ce..cffd341 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,8 +4,9 @@ version = 3 [[package]] name = "ff" -version = "0.13.1" -source = "git+https://github.com/zkcrypto/ff.git?rev=241caff9bcedafbe279b5a4d875461f66b3f9701#241caff9bcedafbe279b5a4d875461f66b3f9701" +version = "0.14.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d42dd26f5790eda47c1a2158ea4120e32c35ddc9a7743c98a292accc01b54ef3" dependencies = [ "rand_core", "subtle", @@ -13,7 +14,7 @@ dependencies = [ [[package]] name = "group" -version = "0.13.0" +version = "0.14.0-pre.0" dependencies = [ "ff", "memuse", diff --git a/Cargo.toml b/Cargo.toml index b666707..a153e74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "group" -version = "0.13.0" +version = "0.14.0-pre.0" authors = [ "Sean Bowe ", "Jack Grigg ", @@ -16,7 +16,7 @@ homepage = "https://github.com/zkcrypto/group" repository = "https://github.com/zkcrypto/group" [dependencies] -ff = { version = "0.13", default-features = false } +ff = { version = "=0.14.0-pre.0", default-features = false } rand = { version = "0.9", optional = true, default-features = false } rand_core = { version = "0.9", default-features = false } rand_xorshift = { version = "0.4", optional = true } @@ -33,6 +33,3 @@ wnaf-memuse = ["alloc", "memuse"] [badges] maintenance = { status = "actively-developed" } - -[patch.crates-io] -ff = { git = "https://github.com/zkcrypto/ff.git", rev = "241caff9bcedafbe279b5a4d875461f66b3f9701" } From 21104854da7f316c470213ab4a2ace239d24dd28 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sat, 29 Jul 2023 17:32:01 +0000 Subject: [PATCH 8/8] Introduce `CurveAffine` trait This unifies the methods previously exposed by the `PrimeCurveAffine` and `CofactorCurveAffine` traits. The prime-order and cofactor traits are now all marker traits, and their affine-specific traits are automatically derived. --- CHANGELOG.md | 17 +++++++++++++++++ src/cofactor.rs | 48 ++++------------------------------------------- src/lib.rs | 49 +++++++++++++++++++++++++++++++++++++++++------- src/prime.rs | 44 ++++--------------------------------------- src/tests/mod.rs | 8 ++------ 5 files changed, 69 insertions(+), 97 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7434ec..44138f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ and this library adheres to Rust's notion of [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- `group::CurveAffine` + ### Changed - MSRV is now 1.63.0. - Migrated to `ff 0.14`, `rand_core 0.9`. @@ -14,6 +17,20 @@ and this library adheres to Rust's notion of 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. +- The curve-related traits have been refactored around the new `CurveAffine` + trait: + - `group::Curve::AffineRepr` has been renamed to `Curve::Affine`. + - All of the trait methods and associated types on the following traits have + been removed (use `group::Curve::Affine` or the `group::CurveAffine` trait + instead; trait implementors must implement `group::CurveAffine` instead + using the same logic): + - `group::cofactor::CofactorCurve` + - `group::cofactor::CofactorCurveAffine` + - `group::prime::PrimeCurve` + - `group::prime::PrimeCurveAffine` + - `group::cofactor::CofactorCurveAffine` and `group::prime::PrimeCurveAffine` + now have blanket implementations for all types `C: group::CurveAffine` where + `C::Curve` implements `CofactorCurve` or `PrimeCurve` respectively. ## [0.13.0] - 2022-12-06 ### Changed diff --git a/src/cofactor.rs b/src/cofactor.rs index 84bfe0a..fae0a89 100644 --- a/src/cofactor.rs +++ b/src/cofactor.rs @@ -1,9 +1,6 @@ -use core::fmt; -use core::ops::{Mul, Neg}; -use ff::PrimeField; use subtle::{Choice, CtOption}; -use crate::{prime::PrimeGroup, Curve, Group, GroupEncoding, GroupOps, GroupOpsOwned}; +use crate::{prime::PrimeGroup, Curve, CurveAffine, Group, GroupEncoding, GroupOps, GroupOpsOwned}; /// This trait represents an element of a cryptographic group with a large prime-order /// subgroup and a comparatively-small cofactor. @@ -54,47 +51,10 @@ pub trait CofactorGroup: /// Efficient representation of an elliptic curve point guaranteed to be /// in the correct prime order subgroup. -pub trait CofactorCurve: - Curve::Affine> + CofactorGroup -{ - type Affine: CofactorCurveAffine - + Mul - + for<'r> Mul<&'r Self::Scalar, Output = Self>; -} +pub trait CofactorCurve: Curve + CofactorGroup {} /// Affine representation of an elliptic curve point guaranteed to be /// in the correct prime order subgroup. -pub trait CofactorCurveAffine: - GroupEncoding - + Copy - + Clone - + Sized - + Send - + Sync - + fmt::Debug - + PartialEq - + Eq - + 'static - + Neg - + Mul<::Scalar, Output = ::Curve> - + for<'r> Mul< - &'r ::Scalar, - Output = ::Curve, - > -{ - type Scalar: PrimeField; - type Curve: CofactorCurve; - - /// Returns the additive identity. - fn identity() -> Self; +pub trait CofactorCurveAffine: CurveAffine {} - /// Returns a fixed generator of unknown exponent. - fn generator() -> Self; - - /// Determines if this point represents the point at infinity; the - /// additive identity. - fn is_identity(&self) -> Choice; - - /// Converts this element to its curve representation. - fn to_curve(&self) -> Self::Curve; -} +impl CofactorCurveAffine for C where C::Curve: CofactorCurve {} diff --git a/src/lib.rs b/src/lib.rs index cd3cf5e..4395525 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -114,16 +114,16 @@ pub trait Group: } } -/// Efficient representation of an elliptic curve point guaranteed. -pub trait Curve: - Group + GroupOps<::AffineRepr> + GroupOpsOwned<::AffineRepr> -{ +/// Efficient representation of an elliptic curve point. +pub trait Curve: Group + GroupOps + GroupOpsOwned { /// The affine representation for this elliptic curve. - type AffineRepr; + type Affine: CurveAffine + + Mul + + for<'r> Mul<&'r Self::Scalar, Output = Self>; /// Converts a batch of projective elements into affine elements. This function will /// panic if `p.len() != q.len()`. - fn batch_normalize(p: &[Self], q: &mut [Self::AffineRepr]) { + fn batch_normalize(p: &[Self], q: &mut [Self::Affine]) { assert_eq!(p.len(), q.len()); for (p, q) in p.iter().zip(q.iter_mut()) { @@ -132,7 +132,42 @@ pub trait Curve: } /// Converts this element into its affine representation. - fn to_affine(&self) -> Self::AffineRepr; + fn to_affine(&self) -> Self::Affine; +} + +/// Affine representation of an elliptic curve point. +pub trait CurveAffine: + GroupEncoding + + Copy + + fmt::Debug + + Eq + + Send + + Sync + + 'static + + Neg + + Mul<::Scalar, Output = Self::Curve> + + for<'r> Mul<&'r ::Scalar, Output = Self::Curve> +{ + /// The efficient representation for this elliptic curve. + type Curve: Curve; + + /// Scalars modulo the order of this group's scalar field. + /// + /// This associated type is temporary, and will be removed once downstream users have + /// migrated to using `Curve` as the primary generic bound. + type Scalar: PrimeField; + + /// Returns the additive identity. + fn identity() -> Self; + + /// Returns a fixed generator of unknown exponent. + fn generator() -> Self; + + /// Determines if this point represents the additive identity. + fn is_identity(&self) -> Choice; + + /// Converts this affine point to its efficient representation. + fn to_curve(&self) -> Self::Curve; } pub trait GroupEncoding: Sized { diff --git a/src/prime.rs b/src/prime.rs index 174888e..0964782 100644 --- a/src/prime.rs +++ b/src/prime.rs @@ -1,50 +1,14 @@ -use core::fmt; -use core::ops::{Mul, Neg}; -use ff::PrimeField; -use subtle::Choice; - -use crate::{Curve, Group, GroupEncoding}; +use crate::{Curve, CurveAffine, Group, GroupEncoding}; /// This trait represents an element of a prime-order cryptographic group. pub trait PrimeGroup: Group + GroupEncoding {} /// Efficient representation of an elliptic curve point guaranteed to be /// in the correct prime order subgroup. -pub trait PrimeCurve: Curve::Affine> + PrimeGroup { - type Affine: PrimeCurveAffine - + Mul - + for<'r> Mul<&'r Self::Scalar, Output = Self>; -} +pub trait PrimeCurve: Curve + PrimeGroup {} /// Affine representation of an elliptic curve point guaranteed to be /// in the correct prime order subgroup. -pub trait PrimeCurveAffine: GroupEncoding - + Copy - + Clone - + Sized - + Send - + Sync - + fmt::Debug - + PartialEq - + Eq - + 'static - + Neg - + Mul<::Scalar, Output = ::Curve> - + for<'r> Mul<&'r ::Scalar, Output = ::Curve> -{ - type Scalar: PrimeField; - type Curve: PrimeCurve; - - /// Returns the additive identity. - fn identity() -> Self; - - /// Returns a fixed generator of unknown exponent. - fn generator() -> Self; - - /// Determines if this point represents the point at infinity; the - /// additive identity. - fn is_identity(&self) -> Choice; +pub trait PrimeCurveAffine: CurveAffine {} - /// Converts this element to its curve representation. - fn to_curve(&self) -> Self::Curve; -} +impl PrimeCurveAffine for C where C::Curve: PrimeCurve {} diff --git a/src/tests/mod.rs b/src/tests/mod.rs index c81a926..a598e50 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -4,11 +4,7 @@ use ff::{Field, PrimeField}; use rand::SeedableRng; use rand_xorshift::XorShiftRng; -use crate::{ - prime::{PrimeCurve, PrimeCurveAffine}, - wnaf::WnafGroup, - GroupEncoding, UncompressedEncoding, -}; +use crate::{prime::PrimeCurve, wnaf::WnafGroup, CurveAffine, GroupEncoding, UncompressedEncoding}; pub fn curve_tests() { let mut rng = XorShiftRng::from_seed([ @@ -426,7 +422,7 @@ fn random_compressed_encoding_tests() { pub fn random_uncompressed_encoding_tests() where - ::Affine: UncompressedEncoding, + G::Affine: UncompressedEncoding, { let mut rng = XorShiftRng::from_seed([ 0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,