From 69f53febcfed8e695ac48747ab23d633f32cbe34 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 14 May 2020 18:10:06 +1200 Subject: [PATCH] group: Introduce Group and PrimeGroup traits Group represents a cryptographic group with a large prime-order subgroup and a small cofactor. PrimeGroup further constrains the group to have a cofactor of one. --- bellman/src/groth16/generator.rs | 2 +- bellman/src/groth16/tests/dummy_engine.rs | 16 +++++---- bellman/src/multiexp.rs | 1 + group/src/lib.rs | 43 +++++++++++------------ pairing/benches/bls12_381/ec.rs | 4 +-- pairing/benches/bls12_381/mod.rs | 2 +- pairing/src/bls12_381/ec.rs | 22 ++++++++---- pairing/src/bls12_381/tests/mod.rs | 2 +- pairing/src/tests/engine.rs | 2 +- 9 files changed, 53 insertions(+), 41 deletions(-) diff --git a/bellman/src/groth16/generator.rs b/bellman/src/groth16/generator.rs index 264d3ab2a..b270ab336 100644 --- a/bellman/src/groth16/generator.rs +++ b/bellman/src/groth16/generator.rs @@ -3,7 +3,7 @@ use std::ops::{AddAssign, MulAssign}; use std::sync::Arc; use ff::Field; -use group::{CurveAffine, CurveProjective, Wnaf}; +use group::{CurveAffine, CurveProjective, Group, Wnaf}; use pairing::Engine; use super::{Parameters, VerifyingKey}; diff --git a/bellman/src/groth16/tests/dummy_engine.rs b/bellman/src/groth16/tests/dummy_engine.rs index 841c05295..611be9752 100644 --- a/bellman/src/groth16/tests/dummy_engine.rs +++ b/bellman/src/groth16/tests/dummy_engine.rs @@ -1,5 +1,5 @@ use ff::{Field, PrimeField, ScalarEngine}; -use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError}; +use group::{CurveAffine, CurveProjective, EncodedPoint, Group, GroupDecodingError, PrimeGroup}; use pairing::{Engine, PairingCurveAffine}; use rand_core::RngCore; @@ -352,11 +352,7 @@ impl Engine for DummyEngine { } } -impl CurveProjective for Fr { - type Affine = Fr; - type Base = Fr; - type Scalar = Fr; - +impl Group for Fr { fn random(rng: &mut R) -> Self { ::random(rng) } @@ -372,6 +368,14 @@ impl CurveProjective for Fr { fn is_identity(&self) -> bool { ::is_zero(self) } +} + +impl PrimeGroup for Fr {} + +impl CurveProjective for Fr { + type Affine = Fr; + type Base = Fr; + type Scalar = Fr; fn batch_normalization(_: &mut [Self]) {} diff --git a/bellman/src/multiexp.rs b/bellman/src/multiexp.rs index 881dd21c1..643f74353 100644 --- a/bellman/src/multiexp.rs +++ b/bellman/src/multiexp.rs @@ -314,6 +314,7 @@ fn test_with_bls12() { acc } + use group::Group; use pairing::{bls12_381::Bls12, Engine}; use rand; diff --git a/group/src/lib.rs b/group/src/lib.rs index 3b730f444..977f48654 100644 --- a/group/src/lib.rs +++ b/group/src/lib.rs @@ -12,6 +12,26 @@ pub mod tests; mod wnaf; pub use self::wnaf::Wnaf; +/// This trait represents an element of a cryptographic group. +pub trait Group: + Clone + Copy + fmt::Debug + fmt::Display + Eq + Sized + Send + Sync + 'static +{ + /// Returns an element chosen uniformly at random using a user-provided RNG. + fn random(rng: &mut R) -> Self; + + /// Returns the additive identity, also known as the "neutral element". + fn identity() -> Self; + + /// Returns a fixed generator of the prime-order subgroup. + fn generator() -> Self; + + /// Determines if this point is the identity. + fn is_identity(&self) -> bool; +} + +/// This trait represents an element of a prime-order cryptographic group. +pub trait PrimeGroup: Group {} + /// A helper trait for types implementing group addition. pub trait CurveOps: Add + Sub + AddAssign + SubAssign @@ -30,16 +50,7 @@ impl CurveOpsOwned for T where T: for<'r> CurveOps< /// Projective representation of an elliptic curve point guaranteed to be /// in the correct prime order subgroup. pub trait CurveProjective: - PartialEq - + Eq - + Sized - + Copy - + Clone - + Send - + Sync - + fmt::Debug - + fmt::Display - + 'static + Group + Neg + CurveOps + CurveOpsOwned @@ -50,18 +61,6 @@ pub trait CurveProjective: type Base: Field; type Affine: CurveAffine; - /// Returns an element chosen uniformly at random using a user-provided RNG. - fn random(rng: &mut R) -> Self; - - /// Returns the additive identity. - fn identity() -> Self; - - /// Returns a fixed generator of unknown exponent. - fn generator() -> Self; - - /// Determines if this point is the point at infinity. - fn is_identity(&self) -> bool; - /// Normalizes a slice of projective elements so that /// conversion to affine is cheap. fn batch_normalization(v: &mut [Self]); diff --git a/pairing/benches/bls12_381/ec.rs b/pairing/benches/bls12_381/ec.rs index 28ce4bf84..d5ece1273 100644 --- a/pairing/benches/bls12_381/ec.rs +++ b/pairing/benches/bls12_381/ec.rs @@ -5,7 +5,7 @@ pub(crate) mod g1 { use std::ops::AddAssign; use ff::Field; - use group::CurveProjective; + use group::{CurveProjective, Group}; use pairing::bls12_381::*; fn bench_g1_mul_assign(c: &mut Criterion) { @@ -92,7 +92,7 @@ pub(crate) mod g2 { use std::ops::AddAssign; use ff::Field; - use group::CurveProjective; + use group::{CurveProjective, Group}; use pairing::bls12_381::*; fn bench_g2_mul_assign(c: &mut Criterion) { diff --git a/pairing/benches/bls12_381/mod.rs b/pairing/benches/bls12_381/mod.rs index aa2e2f087..212e7baaf 100644 --- a/pairing/benches/bls12_381/mod.rs +++ b/pairing/benches/bls12_381/mod.rs @@ -8,7 +8,7 @@ use criterion::{criterion_group, Criterion}; use rand_core::SeedableRng; use rand_xorshift::XorShiftRng; -use group::CurveProjective; +use group::Group; use pairing::bls12_381::*; use pairing::{Engine, PairingCurveAffine}; diff --git a/pairing/src/bls12_381/ec.rs b/pairing/src/bls12_381/ec.rs index 8f0c993ef..757076fcf 100644 --- a/pairing/src/bls12_381/ec.rs +++ b/pairing/src/bls12_381/ec.rs @@ -508,11 +508,7 @@ macro_rules! curve_impl { } } - impl CurveProjective for $projective { - type Scalar = $scalarfield; - type Base = $basefield; - type Affine = $affine; - + impl Group for $projective { fn random(rng: &mut R) -> Self { loop { let x = $basefield::random(rng); @@ -548,6 +544,14 @@ macro_rules! curve_impl { fn is_identity(&self) -> bool { self.z.is_zero() } + } + + impl PrimeGroup for $projective {} + + impl CurveProjective for $projective { + type Scalar = $scalarfield; + type Base = $basefield; + type Affine = $affine; fn is_normalized(&self) -> bool { self.is_identity() || self.z == $basefield::one() @@ -748,7 +752,9 @@ pub mod g1 { use super::g2::G2Affine; use crate::{Engine, PairingCurveAffine}; use ff::{BitIterator, Field, PrimeField}; - use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError}; + use group::{ + CurveAffine, CurveProjective, EncodedPoint, Group, GroupDecodingError, PrimeGroup, + }; use rand_core::RngCore; use std::fmt; use std::ops::{AddAssign, MulAssign, Neg, SubAssign}; @@ -1356,7 +1362,9 @@ pub mod g2 { use super::g1::G1Affine; use crate::{Engine, PairingCurveAffine}; use ff::{BitIterator, Field, PrimeField}; - use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError}; + use group::{ + CurveAffine, CurveProjective, EncodedPoint, Group, GroupDecodingError, PrimeGroup, + }; use rand_core::RngCore; use std::fmt; use std::ops::{AddAssign, MulAssign, Neg, SubAssign}; diff --git a/pairing/src/bls12_381/tests/mod.rs b/pairing/src/bls12_381/tests/mod.rs index 734e6f3cc..7bd819a69 100644 --- a/pairing/src/bls12_381/tests/mod.rs +++ b/pairing/src/bls12_381/tests/mod.rs @@ -1,5 +1,5 @@ use ff::PrimeField; -use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError}; +use group::{CurveAffine, CurveProjective, EncodedPoint, Group, GroupDecodingError}; use super::*; use crate::*; diff --git a/pairing/src/tests/engine.rs b/pairing/src/tests/engine.rs index f2277ba02..576954389 100644 --- a/pairing/src/tests/engine.rs +++ b/pairing/src/tests/engine.rs @@ -1,5 +1,5 @@ use ff::{Endianness, Field, PrimeField}; -use group::{CurveAffine, CurveProjective}; +use group::{CurveAffine, CurveProjective, Group}; use rand_core::SeedableRng; use rand_xorshift::XorShiftRng; use std::ops::MulAssign;