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 std::sync::Arc;
use ff::Field; use ff::Field;
use group::{CurveAffine, CurveProjective, Wnaf}; use group::{CurveAffine, CurveProjective, Group, Wnaf};
use pairing::Engine; use pairing::Engine;
use super::{Parameters, VerifyingKey}; use super::{Parameters, VerifyingKey};

View File

@ -1,5 +1,5 @@
use ff::{Field, PrimeField, ScalarEngine}; use ff::{Field, PrimeField, ScalarEngine};
use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError}; use group::{CurveAffine, CurveProjective, EncodedPoint, Group, GroupDecodingError, PrimeGroup};
use pairing::{Engine, PairingCurveAffine}; use pairing::{Engine, PairingCurveAffine};
use rand_core::RngCore; use rand_core::RngCore;
@ -352,11 +352,7 @@ impl Engine for DummyEngine {
} }
} }
impl CurveProjective for Fr { impl Group for Fr {
type Affine = Fr;
type Base = Fr;
type Scalar = Fr;
fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self { fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self {
<Fr as Field>::random(rng) <Fr as Field>::random(rng)
} }
@ -372,6 +368,14 @@ impl CurveProjective for Fr {
fn is_identity(&self) -> bool { fn is_identity(&self) -> bool {
<Fr as Field>::is_zero(self) <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]) {} fn batch_normalization(_: &mut [Self]) {}

View File

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

View File

@ -12,6 +12,26 @@ pub mod tests;
mod wnaf; mod wnaf;
pub use self::wnaf::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. /// A helper trait for types implementing group addition.
pub trait CurveOps<Rhs = Self, Output = Self>: pub trait CurveOps<Rhs = Self, Output = Self>:
Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs> 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 /// Projective representation of an elliptic curve point guaranteed to be
/// in the correct prime order subgroup. /// in the correct prime order subgroup.
pub trait CurveProjective: pub trait CurveProjective:
PartialEq Group
+ Eq
+ Sized
+ Copy
+ Clone
+ Send
+ Sync
+ fmt::Debug
+ fmt::Display
+ 'static
+ Neg<Output = Self> + Neg<Output = Self>
+ CurveOps + CurveOps
+ CurveOpsOwned + CurveOpsOwned
@ -50,18 +61,6 @@ pub trait CurveProjective:
type Base: Field; type Base: Field;
type Affine: CurveAffine<Projective = Self, Scalar = Self::Scalar>; 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 /// Normalizes a slice of projective elements so that
/// conversion to affine is cheap. /// conversion to affine is cheap.
fn batch_normalization(v: &mut [Self]); fn batch_normalization(v: &mut [Self]);

View File

@ -5,7 +5,7 @@ pub(crate) mod g1 {
use std::ops::AddAssign; use std::ops::AddAssign;
use ff::Field; use ff::Field;
use group::CurveProjective; use group::{CurveProjective, Group};
use pairing::bls12_381::*; use pairing::bls12_381::*;
fn bench_g1_mul_assign(c: &mut Criterion) { fn bench_g1_mul_assign(c: &mut Criterion) {
@ -92,7 +92,7 @@ pub(crate) mod g2 {
use std::ops::AddAssign; use std::ops::AddAssign;
use ff::Field; use ff::Field;
use group::CurveProjective; use group::{CurveProjective, Group};
use pairing::bls12_381::*; use pairing::bls12_381::*;
fn bench_g2_mul_assign(c: &mut Criterion) { 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_core::SeedableRng;
use rand_xorshift::XorShiftRng; use rand_xorshift::XorShiftRng;
use group::CurveProjective; use group::Group;
use pairing::bls12_381::*; use pairing::bls12_381::*;
use pairing::{Engine, PairingCurveAffine}; use pairing::{Engine, PairingCurveAffine};

View File

@ -508,11 +508,7 @@ macro_rules! curve_impl {
} }
} }
impl CurveProjective for $projective { impl Group for $projective {
type Scalar = $scalarfield;
type Base = $basefield;
type Affine = $affine;
fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self { fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self {
loop { loop {
let x = $basefield::random(rng); let x = $basefield::random(rng);
@ -548,6 +544,14 @@ macro_rules! curve_impl {
fn is_identity(&self) -> bool { fn is_identity(&self) -> bool {
self.z.is_zero() 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 { fn is_normalized(&self) -> bool {
self.is_identity() || self.z == $basefield::one() self.is_identity() || self.z == $basefield::one()
@ -748,7 +752,9 @@ pub mod g1 {
use super::g2::G2Affine; use super::g2::G2Affine;
use crate::{Engine, PairingCurveAffine}; use crate::{Engine, PairingCurveAffine};
use ff::{BitIterator, Field, PrimeField}; use ff::{BitIterator, Field, PrimeField};
use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError}; use group::{
CurveAffine, CurveProjective, EncodedPoint, Group, GroupDecodingError, PrimeGroup,
};
use rand_core::RngCore; use rand_core::RngCore;
use std::fmt; use std::fmt;
use std::ops::{AddAssign, MulAssign, Neg, SubAssign}; use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
@ -1356,7 +1362,9 @@ pub mod g2 {
use super::g1::G1Affine; use super::g1::G1Affine;
use crate::{Engine, PairingCurveAffine}; use crate::{Engine, PairingCurveAffine};
use ff::{BitIterator, Field, PrimeField}; use ff::{BitIterator, Field, PrimeField};
use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError}; use group::{
CurveAffine, CurveProjective, EncodedPoint, Group, GroupDecodingError, PrimeGroup,
};
use rand_core::RngCore; use rand_core::RngCore;
use std::fmt; use std::fmt;
use std::ops::{AddAssign, MulAssign, Neg, SubAssign}; use std::ops::{AddAssign, MulAssign, Neg, SubAssign};

View File

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

View File

@ -1,5 +1,5 @@
use ff::{Endianness, Field, PrimeField}; use ff::{Endianness, Field, PrimeField};
use group::{CurveAffine, CurveProjective}; use group::{CurveAffine, CurveProjective, Group};
use rand_core::SeedableRng; use rand_core::SeedableRng;
use rand_xorshift::XorShiftRng; use rand_xorshift::XorShiftRng;
use std::ops::MulAssign; use std::ops::MulAssign;