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.
This commit is contained in:
Jack Grigg 2020-05-14 18:10:06 +12:00
parent 7203a7a30a
commit 69f53febcf
9 changed files with 53 additions and 41 deletions

View File

@ -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};

View File

@ -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<R: RngCore + ?Sized>(rng: &mut R) -> Self {
<Fr as Field>::random(rng)
}
@ -372,6 +368,14 @@ impl CurveProjective for Fr {
fn is_identity(&self) -> bool {
<Fr as Field>::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]) {}

View File

@ -314,6 +314,7 @@ fn test_with_bls12() {
acc
}
use group::Group;
use pairing::{bls12_381::Bls12, Engine};
use rand;

View File

@ -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<R: RngCore + ?Sized>(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<Rhs = Self, Output = Self>:
Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs>
@ -30,16 +50,7 @@ impl<T, Rhs, Output> CurveOpsOwned<Rhs, Output> 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<Output = Self>
+ CurveOps
+ CurveOpsOwned
@ -50,18 +61,6 @@ pub trait CurveProjective:
type Base: Field;
type Affine: CurveAffine<Projective = Self, Scalar = Self::Scalar>;
/// Returns an element chosen uniformly at random using a user-provided RNG.
fn random<R: RngCore + ?Sized>(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]);

View File

@ -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) {

View File

@ -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};

View File

@ -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<R: RngCore + ?Sized>(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};

View File

@ -1,5 +1,5 @@
use ff::PrimeField;
use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError};
use group::{CurveAffine, CurveProjective, EncodedPoint, Group, GroupDecodingError};
use super::*;
use crate::*;

View File

@ -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;