diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b4d22f0d..0ea011d4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Breaking changes +- [\#577](https://github.com/arkworks-rs/algebra/pull/577) (`ark-ff`, `ark-ec`) Add `AdditiveGroup`, a trait for additive groups (equipped with scalar field). - [\#593](https://github.com/arkworks-rs/algebra/pull/593) (`ark-ec`) Change `AffineRepr::xy()` to return owned values. ### Features diff --git a/bench-templates/src/macros/ec.rs b/bench-templates/src/macros/ec.rs index 5cb7380c6..d8abde7f2 100644 --- a/bench-templates/src/macros/ec.rs +++ b/bench-templates/src/macros/ec.rs @@ -3,10 +3,10 @@ macro_rules! ec_bench { ($curve_name:expr, $Group:ident) => { $crate::paste! { mod [<$Group:lower>] { - use ark_ec::Group; + use ark_ec::PrimeGroup; use super::*; - type Scalar = <$Group as Group>::ScalarField; + type Scalar = <$Group as PrimeGroup>::ScalarField; fn rand(c: &mut $crate::criterion::Criterion) { let name = format!("{}::{}", $curve_name, stringify!($Group)); use ark_std::UniformRand; @@ -18,11 +18,12 @@ macro_rules! ec_bench { } fn arithmetic(c: &mut $crate::criterion::Criterion) { - use ark_ec::{CurveGroup, Group}; + use ark_ff::AdditiveGroup; + use ark_ec::{CurveGroup, PrimeGroup}; use ark_std::UniformRand; let name = format!("{}::{}", $curve_name, stringify!($Group)); - type Scalar = <$Group as Group>::ScalarField; + type Scalar = <$Group as PrimeGroup>::ScalarField; const SAMPLES: usize = 1000; let mut rng = ark_std::test_rng(); let mut arithmetic = diff --git a/bench-templates/src/macros/field.rs b/bench-templates/src/macros/field.rs index 585b5000a..03391f51b 100644 --- a/bench-templates/src/macros/field.rs +++ b/bench-templates/src/macros/field.rs @@ -63,6 +63,8 @@ macro_rules! f_bench { macro_rules! field_common { ($bench_group_name:expr, $F:ident) => { fn arithmetic(c: &mut $crate::criterion::Criterion) { + use ark_ff::AdditiveGroup; + let name = format!("{}::{}", $bench_group_name, stringify!($F)); const SAMPLES: usize = 1000; let mut rng = ark_std::test_rng(); diff --git a/ec/README.md b/ec/README.md index f80871a95..abbdab761 100644 --- a/ec/README.md +++ b/ec/README.md @@ -13,10 +13,10 @@ Implementations of particular curves using these curve models can be found in [` ### The `Group` trait -Many cryptographic protocols use as core building-blocks prime-order groups. The [`Group`](https://github.com/arkworks-rs/algebra/blob/master/ec/src/lib.rs) trait is an abstraction that represents elements of such abelian prime-order groups. It provides methods for performing common operations on group elements: +Many cryptographic protocols use as core building-blocks prime-order groups. The [`PrimeGroup`](https://github.com/arkworks-rs/algebra/blob/master/ec/src/lib.rs) trait is an abstraction that represents elements of such abelian prime-order groups. It provides methods for performing common operations on group elements: ```rust -use ark_ec::Group; +use ark_ec::{AdditiveGroup, PrimeGroup}; use ark_ff::{PrimeField, Field}; // We'll use the BLS12-381 G1 curve for this example. // This group has a prime order `r`, and is associated with a prime field `Fr`. @@ -49,12 +49,12 @@ assert_eq!(f, c); ## Scalar multiplication -While the `Group` trait already produces scalar multiplication routines, in many cases one can take advantage of +While the `PrimeGroup` trait already produces scalar multiplication routines, in many cases one can take advantage of the group structure to perform scalar multiplication more efficiently. To allow such specialization, `ark-ec` provides the `ScalarMul` and `VariableBaseMSM` traits. The latter trait computes an "inner product" between a vector of scalars `s` and a vector of group elements `g`. That is, it computes `s.iter().zip(g).map(|(s, g)| g * s).sum()`. ```rust -use ark_ec::{Group, VariableBaseMSM}; +use ark_ec::{PrimeGroup, VariableBaseMSM}; use ark_ff::{PrimeField, Field}; // We'll use the BLS12-381 G1 curve for this example. // This group has a prime order `r`, and is associated with a prime field `Fr`. @@ -72,7 +72,7 @@ let s2 = ScalarField::rand(&mut rng); // Note that we're using the `GAffine` type here, as opposed to `G`. // This is because MSMs are more efficient when the group elements are in affine form. (See below for why.) // -// The `VariableBaseMSM` trait allows specializing the input group element representation to allow +// The `VariableBaseMSM` trait allows specializing the input group element representation to allow // for more efficient implementations. let r = G::msm(&[a, b], &[s1, s2]).unwrap(); assert_eq!(r, a * s1 + b * s2); @@ -90,7 +90,7 @@ but is slower for most arithmetic operations. Let's explore how and when to use these: ```rust -use ark_ec::{AffineRepr, Group, CurveGroup, VariableBaseMSM}; +use ark_ec::{AdditiveGroup, AffineRepr, PrimeGroup, CurveGroup, VariableBaseMSM}; use ark_ff::{PrimeField, Field}; use ark_test_curves::bls12_381::{G1Projective as G, G1Affine as GAffine, Fr as ScalarField}; use ark_std::{Zero, UniformRand}; @@ -105,9 +105,9 @@ assert_eq!(a_aff, a); // We can also convert back to the `CurveGroup` representation: assert_eq!(a, a_aff.into_group()); -// As a general rule, most group operations are slower when elements -// are represented as `AffineRepr`. However, adding an `AffineRepr` -// point to a `CurveGroup` one is usually slightly more efficient than +// As a general rule, most group operations are slower when elements +// are represented as `AffineRepr`. However, adding an `AffineRepr` +// point to a `CurveGroup` one is usually slightly more efficient than // adding two `CurveGroup` points. let d = a + a_aff; assert_eq!(d, a.double()); diff --git a/ec/src/lib.rs b/ec/src/lib.rs index af5a0eb68..423680e0b 100644 --- a/ec/src/lib.rs +++ b/ec/src/lib.rs @@ -28,13 +28,14 @@ use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_std::{ fmt::{Debug, Display}, hash::Hash, - ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, + ops::{Add, AddAssign, Mul, MulAssign}, vec::Vec, }; -use num_traits::Zero; pub use scalar_mul::{variable_base::VariableBaseMSM, ScalarMul}; use zeroize::Zeroize; +pub use ark_ff::AdditiveGroup; + pub mod models; pub use self::models::*; @@ -47,39 +48,7 @@ pub mod hashing; pub mod pairing; /// Represents (elements of) a group of prime order `r`. -pub trait Group: - Eq - + 'static - + Sized - + CanonicalSerialize - + CanonicalDeserialize - + Copy - + Clone - + Default - + Send - + Sync - + Hash - + Debug - + Display - + UniformRand - + Zeroize - + Zero - + Neg - + Add - + Sub - + Mul<::ScalarField, Output = Self> - + AddAssign - + SubAssign - + MulAssign<::ScalarField> - + for<'a> Add<&'a Self, Output = Self> - + for<'a> Sub<&'a Self, Output = Self> - + for<'a> Mul<&'a ::ScalarField, Output = Self> - + for<'a> AddAssign<&'a Self> - + for<'a> SubAssign<&'a Self> - + for<'a> MulAssign<&'a ::ScalarField> - + core::iter::Sum - + for<'a> core::iter::Sum<&'a Self> -{ +pub trait PrimeGroup: AdditiveGroup { /// The scalar field `F_r`, where `r` is the order of this group. type ScalarField: PrimeField; @@ -87,17 +56,6 @@ pub trait Group: #[must_use] fn generator() -> Self; - /// Doubles `self`. - #[must_use] - fn double(&self) -> Self { - let mut copy = *self; - copy.double_in_place(); - copy - } - - /// Double `self` in place. - fn double_in_place(&mut self) -> &mut Self; - /// Performs scalar multiplication of this element. fn mul_bigint(&self, other: impl AsRef<[u64]>) -> Self; @@ -121,7 +79,7 @@ pub trait Group: /// /// The point is guaranteed to be in the correct prime order subgroup. pub trait CurveGroup: - Group + PrimeGroup + Add + AddAssign // + for<'a> Add<&'a Self::Affine, Output = Self> @@ -278,7 +236,7 @@ where Self::E2: MulAssign<::BaseField>, { type E1: CurveGroup< - BaseField = ::ScalarField, + BaseField = ::ScalarField, ScalarField = ::BaseField, >; type E2: CurveGroup; @@ -289,12 +247,12 @@ pub trait PairingFriendlyCycle: CurveCycle { type Engine1: pairing::Pairing< G1 = Self::E1, G1Affine = ::Affine, - ScalarField = ::ScalarField, + ScalarField = ::ScalarField, >; type Engine2: pairing::Pairing< G1 = Self::E2, G1Affine = ::Affine, - ScalarField = ::ScalarField, + ScalarField = ::ScalarField, >; } diff --git a/ec/src/models/bls12/g2.rs b/ec/src/models/bls12/g2.rs index f8068cecb..629ddcda4 100644 --- a/ec/src/models/bls12/g2.rs +++ b/ec/src/models/bls12/g2.rs @@ -1,4 +1,4 @@ -use ark_ff::{BitIteratorBE, Field, Fp2}; +use ark_ff::{AdditiveGroup, BitIteratorBE, Field, Fp2}; use ark_serialize::*; use ark_std::{vec::Vec, One}; diff --git a/ec/src/models/bn/g2.rs b/ec/src/models/bn/g2.rs index 434624520..281064496 100644 --- a/ec/src/models/bn/g2.rs +++ b/ec/src/models/bn/g2.rs @@ -1,4 +1,7 @@ -use ark_ff::fields::{Field, Fp2}; +use ark_ff::{ + fields::{Field, Fp2}, + AdditiveGroup, +}; use ark_serialize::*; use ark_std::vec::Vec; use num_traits::One; diff --git a/ec/src/models/bw6/g2.rs b/ec/src/models/bw6/g2.rs index 8c826efcd..7614e2c5b 100644 --- a/ec/src/models/bw6/g2.rs +++ b/ec/src/models/bw6/g2.rs @@ -1,4 +1,4 @@ -use ark_ff::{BitIteratorBE, Field}; +use ark_ff::{AdditiveGroup, BitIteratorBE, Field}; use ark_serialize::*; use ark_std::vec::Vec; use num_traits::One; diff --git a/ec/src/models/mnt4/mod.rs b/ec/src/models/mnt4/mod.rs index cd9490e7c..c9a618c9c 100644 --- a/ec/src/models/mnt4/mod.rs +++ b/ec/src/models/mnt4/mod.rs @@ -5,7 +5,7 @@ use crate::{ use ark_ff::{ fp2::{Fp2, Fp2Config}, fp4::{Fp4, Fp4Config}, - CyclotomicMultSubgroup, Field, PrimeField, + AdditiveGroup, CyclotomicMultSubgroup, Field, PrimeField, }; use itertools::Itertools; use num_traits::{One, Zero}; diff --git a/ec/src/models/mnt6/g2.rs b/ec/src/models/mnt6/g2.rs index 0a79a270a..cf2639c90 100644 --- a/ec/src/models/mnt6/g2.rs +++ b/ec/src/models/mnt6/g2.rs @@ -1,5 +1,3 @@ -use core::ops::Neg; - use crate::{ mnt6::MNT6Config, models::mnt6::MNT6, @@ -8,7 +6,7 @@ use crate::{ }; use ark_ff::fields::{Field, Fp3}; use ark_serialize::*; -use ark_std::vec::Vec; +use ark_std::{ops::Neg, vec::Vec}; use num_traits::One; pub type G2Affine

= Affine<

::G2Config>; diff --git a/ec/src/models/mnt6/mod.rs b/ec/src/models/mnt6/mod.rs index d01dadac7..47b0f70c5 100644 --- a/ec/src/models/mnt6/mod.rs +++ b/ec/src/models/mnt6/mod.rs @@ -5,7 +5,7 @@ use crate::{ use ark_ff::{ fp3::{Fp3, Fp3Config}, fp6_2over3::{Fp6, Fp6Config}, - CyclotomicMultSubgroup, Field, PrimeField, + AdditiveGroup, CyclotomicMultSubgroup, Field, PrimeField, }; use itertools::Itertools; use num_traits::{One, Zero}; diff --git a/ec/src/models/short_weierstrass/affine.rs b/ec/src/models/short_weierstrass/affine.rs index 7633d321a..1d1d9a04d 100644 --- a/ec/src/models/short_weierstrass/affine.rs +++ b/ec/src/models/short_weierstrass/affine.rs @@ -14,7 +14,7 @@ use ark_std::{ One, Zero, }; -use ark_ff::{fields::Field, PrimeField, ToConstraintField, UniformRand}; +use ark_ff::{fields::Field, AdditiveGroup, PrimeField, ToConstraintField, UniformRand}; use zeroize::Zeroize; diff --git a/ec/src/models/short_weierstrass/group.rs b/ec/src/models/short_weierstrass/group.rs index d94e20cba..58e5026f7 100644 --- a/ec/src/models/short_weierstrass/group.rs +++ b/ec/src/models/short_weierstrass/group.rs @@ -15,7 +15,7 @@ use ark_std::{ One, Zero, }; -use ark_ff::{fields::Field, PrimeField, ToConstraintField, UniformRand}; +use ark_ff::{fields::Field, AdditiveGroup, PrimeField, ToConstraintField, UniformRand}; use zeroize::Zeroize; @@ -25,7 +25,7 @@ use rayon::prelude::*; use super::{Affine, SWCurveConfig}; use crate::{ scalar_mul::{variable_base::VariableBaseMSM, ScalarMul}, - AffineRepr, CurveGroup, Group, + AffineRepr, CurveGroup, PrimeGroup, }; /// Jacobian coordinates for a point on an elliptic curve in short Weierstrass @@ -160,13 +160,11 @@ impl Zero for Projective

{ } } -impl Group for Projective

{ - type ScalarField = P::ScalarField; +impl AdditiveGroup for Projective

{ + type Scalar = P::ScalarField; - #[inline] - fn generator() -> Self { - Affine::generator().into() - } + const ZERO: Self = + Self::new_unchecked(P::BaseField::ONE, P::BaseField::ONE, P::BaseField::ZERO); /// Sets `self = 2 * self`. Note that Jacobian formulae are incomplete, and /// so doubling cannot be computed as `self + self`. Instead, this @@ -273,6 +271,15 @@ impl Group for Projective

{ self } } +} + +impl PrimeGroup for Projective

{ + type ScalarField = P::ScalarField; + + #[inline] + fn generator() -> Self { + Affine::generator().into() + } #[inline] fn mul_bigint(&self, other: impl AsRef<[u64]>) -> Self { diff --git a/ec/src/models/short_weierstrass/mod.rs b/ec/src/models/short_weierstrass/mod.rs index 1e7890dea..03183a8ee 100644 --- a/ec/src/models/short_weierstrass/mod.rs +++ b/ec/src/models/short_weierstrass/mod.rs @@ -4,7 +4,7 @@ use ark_serialize::{ }; use ark_std::io::{Read, Write}; -use ark_ff::fields::Field; +use ark_ff::{fields::Field, AdditiveGroup}; use crate::{ scalar_mul::{ diff --git a/ec/src/models/twisted_edwards/affine.rs b/ec/src/models/twisted_edwards/affine.rs index 4bf186721..2b168a809 100644 --- a/ec/src/models/twisted_edwards/affine.rs +++ b/ec/src/models/twisted_edwards/affine.rs @@ -15,7 +15,7 @@ use ark_std::{ use num_traits::{One, Zero}; use zeroize::Zeroize; -use ark_ff::{fields::Field, PrimeField, ToConstraintField, UniformRand}; +use ark_ff::{fields::Field, AdditiveGroup, PrimeField, ToConstraintField, UniformRand}; use super::{Projective, TECurveConfig, TEFlags}; use crate::AffineRepr; diff --git a/ec/src/models/twisted_edwards/group.rs b/ec/src/models/twisted_edwards/group.rs index d82d70a2e..88bf8128c 100644 --- a/ec/src/models/twisted_edwards/group.rs +++ b/ec/src/models/twisted_edwards/group.rs @@ -15,7 +15,7 @@ use ark_std::{ One, Zero, }; -use ark_ff::{fields::Field, PrimeField, ToConstraintField, UniformRand}; +use ark_ff::{fields::Field, AdditiveGroup, PrimeField, ToConstraintField, UniformRand}; use zeroize::Zeroize; @@ -25,7 +25,7 @@ use rayon::prelude::*; use super::{Affine, MontCurveConfig, TECurveConfig}; use crate::{ scalar_mul::{variable_base::VariableBaseMSM, ScalarMul}, - AffineRepr, CurveGroup, Group, + AffineRepr, CurveGroup, PrimeGroup, }; /// `Projective` implements Extended Twisted Edwards Coordinates @@ -150,12 +150,15 @@ impl Zero for Projective

{ } } -impl Group for Projective

{ - type ScalarField = P::ScalarField; +impl AdditiveGroup for Projective

{ + type Scalar = P::ScalarField; - fn generator() -> Self { - Affine::generator().into() - } + const ZERO: Self = Self::new_unchecked( + P::BaseField::ZERO, + P::BaseField::ONE, + P::BaseField::ZERO, + P::BaseField::ONE, + ); fn double_in_place(&mut self) -> &mut Self { // See "Twisted Edwards Curves Revisited" @@ -190,6 +193,14 @@ impl Group for Projective

{ self } +} + +impl PrimeGroup for Projective

{ + type ScalarField = P::ScalarField; + + fn generator() -> Self { + Affine::generator().into() + } #[inline] fn mul_bigint(&self, other: impl AsRef<[u64]>) -> Self { diff --git a/ec/src/models/twisted_edwards/mod.rs b/ec/src/models/twisted_edwards/mod.rs index 67402ed69..6d326b3a2 100644 --- a/ec/src/models/twisted_edwards/mod.rs +++ b/ec/src/models/twisted_edwards/mod.rs @@ -4,10 +4,10 @@ use ark_serialize::{ }; use ark_std::io::{Read, Write}; -use crate::{scalar_mul::variable_base::VariableBaseMSM, AffineRepr, Group}; +use crate::{scalar_mul::variable_base::VariableBaseMSM, AffineRepr}; use num_traits::Zero; -use ark_ff::fields::Field; +use ark_ff::{fields::Field, AdditiveGroup}; mod affine; pub use affine::*; diff --git a/ec/src/pairing.rs b/ec/src/pairing.rs index 05071a593..90012301e 100644 --- a/ec/src/pairing.rs +++ b/ec/src/pairing.rs @@ -1,4 +1,4 @@ -use ark_ff::{CyclotomicMultSubgroup, Field, One, PrimeField}; +use ark_ff::{AdditiveGroup, CyclotomicMultSubgroup, Field, One, PrimeField}; use ark_serialize::{ CanonicalDeserialize, CanonicalSerialize, Compress, SerializationError, Valid, Validate, }; @@ -16,7 +16,7 @@ use ark_std::{ }; use zeroize::Zeroize; -use crate::{AffineRepr, CurveGroup, Group, VariableBaseMSM}; +use crate::{AffineRepr, CurveGroup, PrimeGroup, VariableBaseMSM}; /// Collection of types (mainly fields and curves) that together describe /// how to compute a pairing over a pairing-friendly curve. @@ -265,7 +265,18 @@ impl Distribution> for Standard { } } -impl Group for PairingOutput

{ +impl AdditiveGroup for PairingOutput

{ + type Scalar = P::ScalarField; + + const ZERO: Self = Self(P::TargetField::ONE); + + fn double_in_place(&mut self) -> &mut Self { + self.0.cyclotomic_square_in_place(); + self + } +} + +impl PrimeGroup for PairingOutput

{ type ScalarField = P::ScalarField; fn generator() -> Self { @@ -277,11 +288,6 @@ impl Group for PairingOutput

{ P::pairing(g1.into(), g2.into()) } - fn double_in_place(&mut self) -> &mut Self { - self.0.cyclotomic_square_in_place(); - self - } - fn mul_bigint(&self, other: impl AsRef<[u64]>) -> Self { Self(self.0.cyclotomic_exp(other.as_ref())) } diff --git a/ec/src/scalar_mul/glv.rs b/ec/src/scalar_mul/glv.rs index ecb482e18..21ef70077 100644 --- a/ec/src/scalar_mul/glv.rs +++ b/ec/src/scalar_mul/glv.rs @@ -1,4 +1,4 @@ -use crate::Group; +use crate::AdditiveGroup; use crate::{ short_weierstrass::{Affine, Projective, SWCurveConfig}, CurveGroup, diff --git a/ec/src/scalar_mul/mod.rs b/ec/src/scalar_mul/mod.rs index a586b3118..1ae3a1e99 100644 --- a/ec/src/scalar_mul/mod.rs +++ b/ec/src/scalar_mul/mod.rs @@ -4,11 +4,9 @@ pub mod wnaf; pub mod fixed_base; pub mod variable_base; -use crate::{ - short_weierstrass::{Affine, Projective, SWCurveConfig}, - Group, -}; -use ark_ff::Zero; +use crate::PrimeGroup; +use crate::short_weierstrass::{Affine, Projective, SWCurveConfig}; +use ark_ff::{AdditiveGroup, Zero}; use ark_std::{ ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign}, vec::Vec, @@ -58,7 +56,7 @@ pub fn sw_double_and_add_projective( } pub trait ScalarMul: - Group + PrimeGroup + Add + AddAssign + for<'a> Add<&'a Self::MulBase, Output = Self> diff --git a/ec/src/scalar_mul/wnaf.rs b/ec/src/scalar_mul/wnaf.rs index d3e0b5437..0003538c5 100644 --- a/ec/src/scalar_mul/wnaf.rs +++ b/ec/src/scalar_mul/wnaf.rs @@ -1,4 +1,4 @@ -use crate::Group; +use crate::PrimeGroup; use ark_ff::{BigInteger, PrimeField}; use ark_std::vec::Vec; @@ -20,7 +20,7 @@ impl WnafContext { Self { window_size } } - pub fn table(&self, mut base: G) -> Vec { + pub fn table(&self, mut base: G) -> Vec { let mut table = Vec::with_capacity(1 << (self.window_size - 1)); let dbl = base.double(); @@ -37,7 +37,7 @@ impl WnafContext { /// multiplication; first, it uses `Self::table` to calculate an /// appropriate table of multiples of `g`, and then uses the wNAF /// algorithm to compute the scalar multiple. - pub fn mul(&self, g: G, scalar: &G::ScalarField) -> G { + pub fn mul(&self, g: G, scalar: &G::ScalarField) -> G { let table = self.table(g); self.mul_with_table(&table, scalar).unwrap() } @@ -48,7 +48,11 @@ impl WnafContext { /// `G::ScalarField`. /// /// Returns `None` if the table is too small. - pub fn mul_with_table(&self, base_table: &[G], scalar: &G::ScalarField) -> Option { + pub fn mul_with_table( + &self, + base_table: &[G], + scalar: &G::ScalarField, + ) -> Option { if 1 << (self.window_size - 1) > base_table.len() { return None; } diff --git a/ff/README.md b/ff/README.md index 389a1cc83..4d50a2af2 100644 --- a/ff/README.md +++ b/ff/README.md @@ -16,6 +16,7 @@ This crate contains two types of traits: The available field traits are: +- [`AdditiveGroup`](/ff/src/lib.rs) - Interface for additive groups that have a "scalar multiplication" operation with respect to the `Scalar` associated type. This applies to to prime-order fields, field extensions, and elliptic-curve groups used in cryptography. - [`Field`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/mod.rs#L66) - Interface for a generic finite field. - [`FftField`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/mod.rs#L419) - Exposes methods that allow for performing efficient FFTs on field elements. - [`PrimeField`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/mod.rs#L523) - Field with a prime `p` number of elements, also referred to as `Fp`. @@ -28,7 +29,7 @@ The models implemented are: - [`Cubic Extension`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/cubic_extension.rs) - [`CubicExtField`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/cubic_extension.rs#L72) - Struct representing a cubic extension field, holds three base field elements - [`CubicExtConfig`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/cubic_extension.rs#L27) - Trait defining the necessary parameters needed to instantiate a Cubic Extension Field - + The above two models serve as abstractions for constructing the extension fields `Fp^m` directly (i.e. `m` equal 2 or 3) or for creating extension towers to arrive at higher `m`. The latter is done by applying the extensions iteratively, e.g. cubic extension over a quadratic extension field. - [`Fp2`](https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/fp2.rs#L103) - Quadratic extension directly on the prime field, i.e. `BaseField == BasePrimeField` @@ -42,14 +43,48 @@ The above two models serve as abstractions for constructing the extension fields There are two important traits when working with finite fields: [`Field`], and [`PrimeField`]. Let's explore these via examples. -### [`Field`] +### [`AdditiveGroup`][additive_group] -The [`Field`] trait provides a generic interface for any finite field. -Types implementing [`Field`] support common field operations -such as addition, subtraction, multiplication, and inverses. +The [`AdditiveGroup`][additive_group] trait provides a generic interface for additive groups that have an associated scalar multiplication operations. Types implementing this trait support common group operations such as addition, subtraction, negation, as well as scalar multiplication by the [`Scalar`][group_scalar_type] associated type. ```rust -use ark_ff::Field; +use ark_ff::AdditiveGroup; +// We'll use a field associated with the BLS12-381 pairing-friendly +// group for this example. +use ark_test_curves::bls12_381::Fq2 as F; +// `ark-std` is a utility crate that enables `arkworks` libraries +// to easily support `std` and `no_std` workloads, and also re-exports +// useful crates that should be common across the entire ecosystem, such as `rand`. +use ark_std::{One, UniformRand}; + +let mut rng = ark_std::test_rng(); +// Let's sample uniformly random field elements: +let a = F::rand(&mut rng); +let b = F::rand(&mut rng); +let c = ::Scalar::rand(&mut rng); + +// We can add... +let c = a + b; +// ... subtract ... +let d = a - b; +// ... double elements ... +assert_eq!(c + d, a.double()); +// ... negate them ... +assert_ne!(d, -d); + +// ... and multiply them by scalars: +let e = d * c; +``` + +### [`Field`][field] + +The [`Field`][field] trait provides a generic interface for any finite field. +Types implementing [`Field`][field] support common field operations +such as addition, subtraction, multiplication, and inverses, and are required +to be [`AdditiveGroup`][additive_group]s too. + +```rust +use ark_ff::{AdditiveGroup, Field}; // We'll use a field associated with the BLS12-381 pairing-friendly // group for this example. use ark_test_curves::bls12_381::Fq2 as F; @@ -63,6 +98,7 @@ let mut rng = ark_std::test_rng(); let a = F::rand(&mut rng); let b = F::rand(&mut rng); +// We can perform all the operations from the `AdditiveGroup` trait: // We can add... let c = a + b; // ... subtract ... @@ -107,10 +143,10 @@ if a.legendre().is_qr() { } ``` -### [`PrimeField`] +### [`PrimeField`][prime_field] If the field is of prime order, then users can choose -to implement the [`PrimeField`] trait for it. This provides access to the following +to implement the [`PrimeField`][prime_field] trait for it. This provides access to the following additional APIs: ```rust @@ -133,3 +169,8 @@ assert_eq!(one, num_bigint::BigUint::one()); let n = F::from_le_bytes_mod_order(&modulus.to_bytes_le()); assert_eq!(n, F::zero()); ``` + +[additive_group]: https://docs.rs/ark-ff/latest/ark_ff/fields/trait.AdditiveGroup.html +[group_scalar_type]: https://docs.rs/ark-ff/latest/ark_ff/fields/trait.AdditiveGroup.html#associatedtype.Scalar +[field]: https://docs.rs/ark-ff/latest/ark_ff/fields/trait.Field.html +[prime_field]: https://docs.rs/ark-ff/latest/ark_ff/fields/trait.PrimeField.html diff --git a/ff/src/fields/mod.rs b/ff/src/fields/mod.rs index 27efa9771..08e3ebc45 100644 --- a/ff/src/fields/mod.rs +++ b/ff/src/fields/mod.rs @@ -1,3 +1,5 @@ +use core::iter::Product; + use crate::UniformRand; use ark_serialize::{ CanonicalDeserialize, CanonicalDeserializeWithFlags, CanonicalSerialize, @@ -42,14 +44,78 @@ use ark_std::cmp::max; #[cfg(feature = "parallel")] use rayon::prelude::*; -/// The interface for a generic field. +pub trait AdditiveGroup: + Eq + + 'static + + Sized + + CanonicalSerialize + + CanonicalDeserialize + + Copy + + Clone + + Default + + Send + + Sync + + Hash + + Debug + + Display + + UniformRand + + Zeroize + + Zero + + Neg + + Add + + Sub + + Mul<::Scalar, Output = Self> + + AddAssign + + SubAssign + + MulAssign<::Scalar> + + for<'a> Add<&'a Self, Output = Self> + + for<'a> Sub<&'a Self, Output = Self> + + for<'a> Mul<&'a ::Scalar, Output = Self> + + for<'a> AddAssign<&'a Self> + + for<'a> SubAssign<&'a Self> + + for<'a> MulAssign<&'a ::Scalar> + + for<'a> Add<&'a mut Self, Output = Self> + + for<'a> Sub<&'a mut Self, Output = Self> + + for<'a> Mul<&'a mut ::Scalar, Output = Self> + + for<'a> AddAssign<&'a mut Self> + + for<'a> SubAssign<&'a mut Self> + + for<'a> MulAssign<&'a mut ::Scalar> + + ark_std::iter::Sum + + for<'a> ark_std::iter::Sum<&'a Self> +{ + type Scalar: Field; + + /// The additive identity of the field. + const ZERO: Self; + + /// Doubles `self`. + #[must_use] + fn double(&self) -> Self { + let mut copy = *self; + copy.double_in_place(); + copy + } + /// Doubles `self` in place. + fn double_in_place(&mut self) -> &mut Self { + self.add_assign(*self); + self + } + + /// Negates `self` in place. + fn neg_in_place(&mut self) -> &mut Self { + *self = -(*self); + self + } +} + +/// The interface for a generic field. /// Types implementing [`Field`] support common field operations such as addition, subtraction, multiplication, and inverses. /// /// ## Defining your own field /// To demonstrate the various field operations, we can first define a prime ordered field $\mathbb{F}_{p}$ with $p = 17$. When defining a field $\mathbb{F}_p$, we need to provide the modulus(the $p$ in $\mathbb{F}_p$) and a generator. Recall that a generator $g \in \mathbb{F}_p$ is a field element whose powers comprise the entire field: $\mathbb{F}_p =\\{g, g^1, \ldots, g^{p-1}\\}$. /// We can then manually construct the field element associated with an integer with `Fp::from` and perform field addition, subtraction, multiplication, and inversion on it. /// ```rust -/// use ark_ff::fields::{Field, Fp64, MontBackend, MontConfig}; +/// use ark_ff::{AdditiveGroup, fields::{Field, Fp64, MontBackend, MontConfig}}; /// /// #[derive(MontConfig)] /// #[modulus = "17"] @@ -74,7 +140,7 @@ use rayon::prelude::*; /// ## Using pre-defined fields /// In the following example, we’ll use the field associated with the BLS12-381 pairing-friendly group. /// ```rust -/// use ark_ff::Field; +/// use ark_ff::{AdditiveGroup, Field}; /// use ark_test_curves::bls12_381::Fq as F; /// use ark_std::{One, UniformRand, test_rng}; /// @@ -113,33 +179,13 @@ pub trait Field: + CanonicalSerializeWithFlags + CanonicalDeserialize + CanonicalDeserializeWithFlags - + Add - + Sub - + Mul + + AdditiveGroup + Div - + AddAssign - + SubAssign - + MulAssign + DivAssign - + for<'a> Add<&'a Self, Output = Self> - + for<'a> Sub<&'a Self, Output = Self> - + for<'a> Mul<&'a Self, Output = Self> + for<'a> Div<&'a Self, Output = Self> - + for<'a> AddAssign<&'a Self> - + for<'a> SubAssign<&'a Self> - + for<'a> MulAssign<&'a Self> + for<'a> DivAssign<&'a Self> - + for<'a> Add<&'a mut Self, Output = Self> - + for<'a> Sub<&'a mut Self, Output = Self> - + for<'a> Mul<&'a mut Self, Output = Self> + for<'a> Div<&'a mut Self, Output = Self> - + for<'a> AddAssign<&'a mut Self> - + for<'a> SubAssign<&'a mut Self> - + for<'a> MulAssign<&'a mut Self> + for<'a> DivAssign<&'a mut Self> - + core::iter::Sum - + for<'a> core::iter::Sum<&'a Self> - + core::iter::Product + for<'a> core::iter::Product<&'a Self> + From + From @@ -147,6 +193,7 @@ pub trait Field: + From + From + From + + Product { type BasePrimeField: PrimeField; @@ -155,8 +202,6 @@ pub trait Field: /// Determines the algorithm for computing square roots. const SQRT_PRECOMP: Option>; - /// The additive identity of the field. - const ZERO: Self; /// The multiplicative identity of the field. const ONE: Self; @@ -186,16 +231,6 @@ pub trait Field: /// ``` fn from_base_prime_field(elem: Self::BasePrimeField) -> Self; - /// Returns `self + self`. - #[must_use] - fn double(&self) -> Self; - - /// Doubles `self` in place. - fn double_in_place(&mut self) -> &mut Self; - - /// Negates `self` in place. - fn neg_in_place(&mut self) -> &mut Self; - /// Attempt to deserialize a field element. Returns `None` if the /// deserialization fails. /// diff --git a/ff/src/fields/models/cubic_extension.rs b/ff/src/fields/models/cubic_extension.rs index c7e56fe2f..8369706be 100644 --- a/ff/src/fields/models/cubic_extension.rs +++ b/ff/src/fields/models/cubic_extension.rs @@ -21,7 +21,7 @@ use ark_std::rand::{ use crate::{ fields::{Field, PrimeField}, - LegendreSymbol, SqrtPrecomputation, ToConstraintField, UniformRand, + AdditiveGroup, LegendreSymbol, SqrtPrecomputation, ToConstraintField, UniformRand, }; /// Defines a Cubic extension field from a cubic non-residue. @@ -164,6 +164,32 @@ impl One for CubicExtField

{ } } +impl AdditiveGroup for CubicExtField

{ + type Scalar = Self; + + const ZERO: Self = Self::new(P::BaseField::ZERO, P::BaseField::ZERO, P::BaseField::ZERO); + + fn double(&self) -> Self { + let mut result = *self; + result.double_in_place(); + result + } + + fn double_in_place(&mut self) -> &mut Self { + self.c0.double_in_place(); + self.c1.double_in_place(); + self.c2.double_in_place(); + self + } + + fn neg_in_place(&mut self) -> &mut Self { + self.c0.neg_in_place(); + self.c1.neg_in_place(); + self.c2.neg_in_place(); + self + } +} + type BaseFieldIter

= <

::BaseField as Field>::BasePrimeFieldIter; impl Field for CubicExtField

{ type BasePrimeField = P::BasePrimeField; @@ -171,8 +197,6 @@ impl Field for CubicExtField

{ const SQRT_PRECOMP: Option> = P::SQRT_PRECOMP; - const ZERO: Self = Self::new(P::BaseField::ZERO, P::BaseField::ZERO, P::BaseField::ZERO); - const ONE: Self = Self::new(P::BaseField::ONE, P::BaseField::ZERO, P::BaseField::ZERO); fn extension_degree() -> u64 { @@ -205,26 +229,6 @@ impl Field for CubicExtField

{ )) } - fn double(&self) -> Self { - let mut result = *self; - result.double_in_place(); - result - } - - fn double_in_place(&mut self) -> &mut Self { - self.c0.double_in_place(); - self.c1.double_in_place(); - self.c2.double_in_place(); - self - } - - fn neg_in_place(&mut self) -> &mut Self { - self.c0.neg_in_place(); - self.c1.neg_in_place(); - self.c2.neg_in_place(); - self - } - #[inline] fn from_random_bytes_with_flags(bytes: &[u8]) -> Option<(Self, F)> { let split_at = bytes.len() / 3; diff --git a/ff/src/fields/models/fp/mod.rs b/ff/src/fields/models/fp/mod.rs index 7f417ed9a..1113c1222 100644 --- a/ff/src/fields/models/fp/mod.rs +++ b/ff/src/fields/models/fp/mod.rs @@ -18,7 +18,10 @@ use ark_std::{ mod montgomery_backend; pub use montgomery_backend::*; -use crate::{BigInt, BigInteger, FftField, Field, LegendreSymbol, PrimeField, SqrtPrecomputation}; +use crate::{ + AdditiveGroup, BigInt, BigInteger, FftField, Field, LegendreSymbol, PrimeField, + SqrtPrecomputation, +}; /// A trait that specifies the configuration of a prime field. /// Also specifies how to perform arithmetic on field elements. pub trait FpConfig: Send + Sync + 'static + Sized { @@ -186,12 +189,35 @@ impl, const N: usize> One for Fp { } } +impl, const N: usize> AdditiveGroup for Fp { + type Scalar = Self; + const ZERO: Self = P::ZERO; + + #[inline] + fn double(&self) -> Self { + let mut temp = *self; + temp.double_in_place(); + temp + } + + #[inline] + fn double_in_place(&mut self) -> &mut Self { + P::double_in_place(self); + self + } + + #[inline] + fn neg_in_place(&mut self) -> &mut Self { + P::neg_in_place(self); + self + } +} + impl, const N: usize> Field for Fp { type BasePrimeField = Self; type BasePrimeFieldIter = iter::Once; const SQRT_PRECOMP: Option> = P::SQRT_PRECOMP; - const ZERO: Self = P::ZERO; const ONE: Self = P::ONE; fn extension_degree() -> u64 { @@ -213,25 +239,6 @@ impl, const N: usize> Field for Fp { Some(elems[0]) } - #[inline] - fn double(&self) -> Self { - let mut temp = *self; - temp.double_in_place(); - temp - } - - #[inline] - fn double_in_place(&mut self) -> &mut Self { - P::double_in_place(self); - self - } - - #[inline] - fn neg_in_place(&mut self) -> &mut Self { - P::neg_in_place(self); - self - } - #[inline] fn characteristic() -> &'static [u64] { P::MODULUS.as_ref() diff --git a/ff/src/fields/models/fp12_2over3over2.rs b/ff/src/fields/models/fp12_2over3over2.rs index 7350a0c0c..16f0e2ba0 100644 --- a/ff/src/fields/models/fp12_2over3over2.rs +++ b/ff/src/fields/models/fp12_2over3over2.rs @@ -3,7 +3,7 @@ use ark_std::Zero; use super::quadratic_extension::*; use crate::{ fields::{fp6_3over2::*, Field, Fp2, Fp2Config as Fp2ConfigTrait}, - CyclotomicMultSubgroup, + AdditiveGroup, CyclotomicMultSubgroup, }; use core::{ marker::PhantomData, diff --git a/ff/src/fields/models/quadratic_extension.rs b/ff/src/fields/models/quadratic_extension.rs index 8e7f9b825..5d7f6de96 100644 --- a/ff/src/fields/models/quadratic_extension.rs +++ b/ff/src/fields/models/quadratic_extension.rs @@ -22,7 +22,7 @@ use ark_std::rand::{ use crate::{ biginteger::BigInteger, fields::{Field, LegendreSymbol, PrimeField}, - SqrtPrecomputation, ToConstraintField, UniformRand, + AdditiveGroup, SqrtPrecomputation, ToConstraintField, UniformRand, }; /// Defines a Quadratic extension field from a quadratic non-residue. @@ -193,6 +193,30 @@ impl One for QuadExtField

{ } } +impl AdditiveGroup for QuadExtField

{ + type Scalar = Self; + + const ZERO: Self = Self::new(P::BaseField::ZERO, P::BaseField::ZERO); + + fn double(&self) -> Self { + let mut result = *self; + result.double_in_place(); + result + } + + fn double_in_place(&mut self) -> &mut Self { + self.c0.double_in_place(); + self.c1.double_in_place(); + self + } + + fn neg_in_place(&mut self) -> &mut Self { + self.c0.neg_in_place(); + self.c1.neg_in_place(); + self + } +} + type BaseFieldIter

= <

::BaseField as Field>::BasePrimeFieldIter; impl Field for QuadExtField

{ type BasePrimeField = P::BasePrimeField; @@ -201,7 +225,6 @@ impl Field for QuadExtField

{ const SQRT_PRECOMP: Option> = None; - const ZERO: Self = Self::new(P::BaseField::ZERO, P::BaseField::ZERO); const ONE: Self = Self::new(P::BaseField::ONE, P::BaseField::ZERO); fn extension_degree() -> u64 { @@ -230,24 +253,6 @@ impl Field for QuadExtField

{ )) } - fn double(&self) -> Self { - let mut result = *self; - result.double_in_place(); - result - } - - fn double_in_place(&mut self) -> &mut Self { - self.c0.double_in_place(); - self.c1.double_in_place(); - self - } - - fn neg_in_place(&mut self) -> &mut Self { - self.c0.neg_in_place(); - self.c1.neg_in_place(); - self - } - fn square(&self) -> Self { let mut result = *self; result.square_in_place(); diff --git a/test-curves/src/bls12_381/g2.rs b/test-curves/src/bls12_381/g2.rs index f4c970910..4b0065eb1 100644 --- a/test-curves/src/bls12_381/g2.rs +++ b/test-curves/src/bls12_381/g2.rs @@ -6,9 +6,9 @@ use ark_ec::{ hashing::curve_maps::wb::{IsogenyMap, WBConfig}, models::CurveConfig, short_weierstrass::{self, *}, - AffineRepr, CurveGroup, Group, + AffineRepr, CurveGroup, PrimeGroup, }; -use ark_ff::{BigInt, Field, MontFp, Zero}; +use ark_ff::{AdditiveGroup, BigInt, Field, MontFp, Zero}; pub type G2Affine = bls12::G2Affine; pub type G2Projective = bls12::G2Projective; diff --git a/test-curves/src/bls12_381/g2_swu_iso.rs b/test-curves/src/bls12_381/g2_swu_iso.rs index 0790cf99f..988e30ef1 100644 --- a/test-curves/src/bls12_381/g2_swu_iso.rs +++ b/test-curves/src/bls12_381/g2_swu_iso.rs @@ -80,27 +80,27 @@ pub const ISOGENY_MAP_TO_G2 : IsogenyMap<'_, SwuIsoConfig, g2::Config> = Isogen x_map_numerator: &[ Fq2::new( MontFp!("889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542"), - MontFp!("889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542")), + MontFp!("889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542")), Fq2::new( MontFp!("0"), MontFp!("2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706522")), Fq2::new( MontFp!("2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706526"), - MontFp!("1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853261")), + MontFp!("1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853261")), Fq2::new( - MontFp!("3557697382419259905260257622876359250272784728834673675850718343221361467102966990615722337003569479144794908942033"), + MontFp!("3557697382419259905260257622876359250272784728834673675850718343221361467102966990615722337003569479144794908942033"), MontFp!("0")), ], x_map_denominator: &[ Fq2::new( - MontFp!("0"), - MontFp!("4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559715")), + MontFp!("0"), + MontFp!("4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559715")), Fq2::new( - MontFp!("12"), - MontFp!("4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559775")), + MontFp!("12"), + MontFp!("4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559775")), Fq2::new( - MontFp!("1"), + MontFp!("1"), MontFp!("0")), ], diff --git a/test-curves/src/bn384_small_two_adicity/tests.rs b/test-curves/src/bn384_small_two_adicity/tests.rs index 1313324c4..a5a835553 100644 --- a/test-curves/src/bn384_small_two_adicity/tests.rs +++ b/test-curves/src/bn384_small_two_adicity/tests.rs @@ -1,5 +1,7 @@ #![allow(unused_imports)] -use ark_ec::{models::short_weierstrass::SWCurveConfig, pairing::Pairing, AffineRepr, CurveGroup}; +use ark_ec::{ + models::short_weierstrass::SWCurveConfig, pairing::Pairing, AffineRepr, CurveGroup, PrimeGroup, +}; use ark_ff::{Field, One, UniformRand, Zero}; use ark_std::{rand::Rng, test_rng}; diff --git a/test-curves/src/secp256k1/g1.rs b/test-curves/src/secp256k1/g1.rs index 9e7e4de24..1613b481f 100644 --- a/test-curves/src/secp256k1/g1.rs +++ b/test-curves/src/secp256k1/g1.rs @@ -1,6 +1,6 @@ use crate::secp256k1::{Fq, Fr}; use ark_ec::{models::CurveConfig, short_weierstrass::*}; -use ark_ff::{Field, MontFp, Zero}; +use ark_ff::{AdditiveGroup, Field, MontFp, Zero}; pub type G1Affine = Affine; pub type G1Projective = Projective; diff --git a/test-templates/src/fields.rs b/test-templates/src/fields.rs index 309ea79ce..d82c580e5 100644 --- a/test-templates/src/fields.rs +++ b/test-templates/src/fields.rs @@ -2,6 +2,7 @@ #![allow(clippy::eq_op)] use ark_std::rand::Rng; + #[derive(Default, Clone, Copy, Debug)] pub struct DummyFlags; @@ -141,6 +142,8 @@ macro_rules! __test_field { #[test] fn test_add_properties() { use ark_std::UniformRand; + use ark_ff::AdditiveGroup; + let mut rng = test_rng(); let zero = <$field>::zero(); assert_eq!(-zero, zero); @@ -258,9 +261,9 @@ macro_rules! __test_field { assert_eq!(a * (b + c), a * b + a * c, "Distributivity failed"); assert_eq!(b * (a + c), b * a + b * c, "Distributivity failed"); assert_eq!(c * (a + b), c * a + c * b, "Distributivity failed"); - assert_eq!((a + b).square(), a.square() + b.square() + a * b.double(), "Distributivity for square failed"); - assert_eq!((b + c).square(), c.square() + b.square() + c * b.double(), "Distributivity for square failed"); - assert_eq!((c + a).square(), a.square() + c.square() + a * c.double(), "Distributivity for square failed"); + assert_eq!((a + b).square(), a.square() + b.square() + a * ark_ff::AdditiveGroup::double(&b), "Distributivity for square failed"); + assert_eq!((b + c).square(), c.square() + b.square() + c * ark_ff::AdditiveGroup::double(&b), "Distributivity for square failed"); + assert_eq!((c + a).square(), a.square() + c.square() + a * ark_ff::AdditiveGroup::double(&c), "Distributivity for square failed"); } } @@ -389,7 +392,8 @@ macro_rules! __test_field { #[test] fn test_sum_of_products_edge_case() { - use ark_ff::BigInteger; + use ark_ff::{AdditiveGroup, BigInteger}; + let mut a_max = <$field>::ZERO.into_bigint(); for (i, limb) in a_max.as_mut().iter_mut().enumerate() { if i == <$field as PrimeField>::BigInt::NUM_LIMBS - 1 { diff --git a/test-templates/src/glv.rs b/test-templates/src/glv.rs index ba42fb87b..866594faf 100644 --- a/test-templates/src/glv.rs +++ b/test-templates/src/glv.rs @@ -3,7 +3,7 @@ use std::ops::Mul; use ark_ec::{ scalar_mul::{glv::GLVConfig, sw_double_and_add_affine, sw_double_and_add_projective}, short_weierstrass::{Affine, Projective}, - AffineRepr, CurveGroup, Group, + AffineRepr, CurveGroup, PrimeGroup, }; use ark_ff::PrimeField; use ark_std::UniformRand; diff --git a/test-templates/src/groups.rs b/test-templates/src/groups.rs index 776ce0827..a17634956 100644 --- a/test-templates/src/groups.rs +++ b/test-templates/src/groups.rs @@ -2,7 +2,7 @@ #[doc(hidden)] macro_rules! __test_group { ($group: ty) => { - type ScalarField = <$group as Group>::ScalarField; + type ScalarField = <$group as PrimeGroup>::ScalarField; #[test] fn test_add_properties() { let mut rng = &mut ark_std::test_rng(); @@ -397,7 +397,7 @@ macro_rules! test_group { mod $mod_name { use super::*; use ark_ff::*; - use ark_ec::{Group, CurveGroup, ScalarMul, AffineRepr, CurveConfig, short_weierstrass::SWCurveConfig, twisted_edwards::TECurveConfig, scalar_mul::{*, wnaf::*}}; + use ark_ec::{PrimeGroup, CurveGroup, ScalarMul, AffineRepr, CurveConfig, short_weierstrass::SWCurveConfig, twisted_edwards::TECurveConfig, scalar_mul::{*, wnaf::*}}; use ark_serialize::*; use ark_std::{io::Cursor, rand::Rng, vec::Vec, test_rng, vec, Zero, One, UniformRand}; const ITERATIONS: usize = 500; diff --git a/test-templates/src/pairing.rs b/test-templates/src/pairing.rs index 8386969ca..ec4fd4e3e 100644 --- a/test-templates/src/pairing.rs +++ b/test-templates/src/pairing.rs @@ -3,7 +3,7 @@ macro_rules! test_pairing { ($mod_name: ident; $Pairing: ty) => { mod $mod_name { pub const ITERATIONS: usize = 100; - use ark_ec::{pairing::*, CurveGroup, Group}; + use ark_ec::{pairing::*, CurveGroup, PrimeGroup}; use ark_ff::{Field, PrimeField}; use ark_std::{test_rng, One, UniformRand, Zero}; #[test]