group: Separate prime and cofactor traits into modules
Instead of having the Group crate hold a Subgroup associated type (and thus needing to define the subgroup of a prime-order group as itself), we specify two separate sets of traits for prime-order groups and ones with a cofactor. Protocol implementors can either restrict their implementations to only work with PrimeGroup, or can explicitly choose to support CofactorGroup and then explicitly handle the subgroup edge cases with e.g. CofactorGroup::mul_by_cofactor (which would be a no-op for PrimeGroup). Protocol implementors can also choose to specialise to elliptic curves if they want to leverage an affine representation and mixed addition in their protocol for efficiency, or they can ignore those traits and stick with the simpler group-focused traits.
This commit is contained in:
parent
a77b2c8623
commit
0c9e783172
|
@ -12,7 +12,7 @@
|
|||
//! [Groth16]: https://eprint.iacr.org/2016/260
|
||||
|
||||
use ff::PrimeField;
|
||||
use group::CofactorCurve;
|
||||
use group::cofactor::CofactorCurve;
|
||||
|
||||
use super::SynthesisError;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::ops::{AddAssign, MulAssign};
|
|||
use std::sync::Arc;
|
||||
|
||||
use ff::{Field, PrimeField};
|
||||
use group::{CurveAffine, CofactorCurve, Group, Wnaf};
|
||||
use group::{cofactor::CofactorCurveAffine, Curve, Group, Wnaf};
|
||||
use pairing::Engine;
|
||||
|
||||
use super::{Parameters, VerifyingKey};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//!
|
||||
//! [Groth16]: https://eprint.iacr.org/2016/260
|
||||
|
||||
use group::{CurveAffine, GroupEncoding, UncompressedEncoding};
|
||||
use group::{cofactor::CofactorCurveAffine, GroupEncoding, UncompressedEncoding};
|
||||
use pairing::{Engine, MultiMillerLoop};
|
||||
|
||||
use crate::SynthesisError;
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::sync::Arc;
|
|||
use futures::Future;
|
||||
|
||||
use ff::{Field, PrimeField};
|
||||
use group::{CurveAffine, CofactorCurve};
|
||||
use group::{cofactor::CofactorCurveAffine, Curve};
|
||||
use pairing::Engine;
|
||||
|
||||
use super::{ParameterSource, Proof};
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
use ff::{Field, PrimeField};
|
||||
use group::{CurveAffine, CofactorCurve, Group, GroupEncoding, PrimeGroup, UncompressedEncoding};
|
||||
use group::{
|
||||
cofactor::{CofactorCurve, CofactorCurveAffine, CofactorGroup},
|
||||
prime::PrimeGroup,
|
||||
Curve, Group, GroupEncoding, UncompressedEncoding,
|
||||
};
|
||||
use pairing::{Engine, MillerLoopResult, MultiMillerLoop, PairingCurveAffine};
|
||||
|
||||
use rand_core::RngCore;
|
||||
|
@ -367,7 +371,6 @@ impl MillerLoopResult for Fr {
|
|||
}
|
||||
|
||||
impl Group for Fr {
|
||||
type Subgroup = Fr;
|
||||
type Scalar = Fr;
|
||||
|
||||
fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self {
|
||||
|
@ -393,8 +396,20 @@ impl Group for Fr {
|
|||
|
||||
impl PrimeGroup for Fr {}
|
||||
|
||||
impl CofactorCurve for Fr {
|
||||
type Affine = Fr;
|
||||
impl CofactorGroup for Fr {
|
||||
type Subgroup = Fr;
|
||||
|
||||
fn mul_by_cofactor(&self) -> Self::Subgroup {
|
||||
*self
|
||||
}
|
||||
|
||||
fn into_subgroup(self) -> CtOption<Self::Subgroup> {
|
||||
CtOption::new(self, Choice::from(1))
|
||||
}
|
||||
}
|
||||
|
||||
impl Curve for Fr {
|
||||
type AffineRepr = Fr;
|
||||
|
||||
fn to_affine(&self) -> Fr {
|
||||
*self
|
||||
|
@ -409,6 +424,10 @@ impl CofactorCurve for Fr {
|
|||
}
|
||||
}
|
||||
|
||||
impl CofactorCurve for Fr {
|
||||
type Affine = Fr;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Default)]
|
||||
pub struct FakePoint;
|
||||
|
||||
|
@ -424,7 +443,7 @@ impl AsRef<[u8]> for FakePoint {
|
|||
}
|
||||
}
|
||||
|
||||
impl CurveAffine for Fr {
|
||||
impl CofactorCurveAffine for Fr {
|
||||
type Curve = Fr;
|
||||
type Scalar = Fr;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use group::{CurveAffine, CofactorCurve};
|
||||
use group::{cofactor::CofactorCurveAffine, Curve};
|
||||
use pairing::{MillerLoopResult, MultiMillerLoop};
|
||||
use std::ops::{AddAssign, Neg};
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use super::multicore::Worker;
|
|||
use bit_vec::{self, BitVec};
|
||||
use ff::{Endianness, Field, PrimeField};
|
||||
use futures::Future;
|
||||
use group::{CofactorCurve, CurveAffine};
|
||||
use group::cofactor::{CofactorCurve, CofactorCurveAffine};
|
||||
use std::io;
|
||||
use std::iter;
|
||||
use std::ops::AddAssign;
|
||||
|
@ -11,14 +11,14 @@ use std::sync::Arc;
|
|||
use super::SynthesisError;
|
||||
|
||||
/// An object that builds a source of bases.
|
||||
pub trait SourceBuilder<G: CurveAffine>: Send + Sync + 'static + Clone {
|
||||
pub trait SourceBuilder<G: CofactorCurveAffine>: Send + Sync + 'static + Clone {
|
||||
type Source: Source<G>;
|
||||
|
||||
fn new(self) -> Self::Source;
|
||||
}
|
||||
|
||||
/// A source of bases, like an iterator.
|
||||
pub trait Source<G: CurveAffine> {
|
||||
pub trait Source<G: CofactorCurveAffine> {
|
||||
fn next(&mut self) -> Result<&G, SynthesisError>;
|
||||
|
||||
/// Skips `amt` elements from the source, avoiding deserialization.
|
||||
|
@ -37,7 +37,7 @@ pub trait AddAssignFromSource: CofactorCurve {
|
|||
}
|
||||
impl<G> AddAssignFromSource for G where G: CofactorCurve {}
|
||||
|
||||
impl<G: CurveAffine> SourceBuilder<G> for (Arc<Vec<G>>, usize) {
|
||||
impl<G: CofactorCurveAffine> SourceBuilder<G> for (Arc<Vec<G>>, usize) {
|
||||
type Source = (Arc<Vec<G>>, usize);
|
||||
|
||||
fn new(self) -> (Arc<Vec<G>>, usize) {
|
||||
|
@ -45,7 +45,7 @@ impl<G: CurveAffine> SourceBuilder<G> for (Arc<Vec<G>>, usize) {
|
|||
}
|
||||
}
|
||||
|
||||
impl<G: CurveAffine> Source<G> for (Arc<Vec<G>>, usize) {
|
||||
impl<G: CofactorCurveAffine> Source<G> for (Arc<Vec<G>>, usize) {
|
||||
fn next(&mut self) -> Result<&G, SynthesisError> {
|
||||
if self.0.len() <= self.1 {
|
||||
return Err(io::Error::new(
|
||||
|
@ -311,7 +311,7 @@ fn test_with_bls12() {
|
|||
acc
|
||||
}
|
||||
|
||||
use group::Group;
|
||||
use group::{Curve, Group};
|
||||
use pairing::{
|
||||
bls12_381::{Bls12, Fr},
|
||||
Engine,
|
||||
|
|
Loading…
Reference in New Issue