Skip to content

Commit

Permalink
[RFC] Convert identity functions in Field, Group, and {Projective,Aff…
Browse files Browse the repository at this point in the history
…ine}Curve traits with One/Zero traits from num_traits.

- contributes to arkworks-rs#50,
- depends on arkworks-rs#53 and builds on it,
- due to coherence & requirements of `num_traits::{Zero, One}` to implement `std::ops::Add<Self, ..>` and (resp.) `std::ops::Mul<Self, ..>`, I've had to replace the afferent `impl<'a, P: ..> (Add|Mul)<&'a Self> for Group(Affine|Projective)<P>` by direct implementations on `Self`,
- I did not have to fight the borrow checker for this conversion => I think this hints arithmetic operations are called in contexts where the operand is owned,
- hence should this end up on a merge track, we may want to open an issue to convert the `impl<'a, P:..> (Neg|Sub|..)<&'a Self> for ..<P>` trait usage to direct `impl<P:..> (Neg|Sub|..)<Self> for ..<P>`
- the `impl AddAssign for GroupAffine<P>` in curves/models/short_weierstrass_jacobian.rs is provided to fit trait bounds, and without any guarantee of suitability for any particular purpose
- and that, even though I don't think it's used.
  • Loading branch information
huitseeker committed Jan 16, 2020
1 parent 9266087 commit cd18b99
Show file tree
Hide file tree
Showing 70 changed files with 385 additions and 282 deletions.
1 change: 1 addition & 0 deletions algebra/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ edition = "2018"
byteorder = { version = "1" }
rand = { version = "0.7" }
derivative = { version = "1" }
num-traits = { version = "0.2.11"}

colored = { version = "1", optional = true }
rayon = { version = "1", optional = true }
Expand Down
2 changes: 1 addition & 1 deletion algebra/src/curves/bls12_377/g1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use crate::{
curves::models::{ModelParameters, SWModelParameters},
fields::{
bls12_377::{Fq, Fr},
Field,
},
};
use num_traits::Zero;

#[derive(Copy, Clone, Default, PartialEq, Eq)]
pub struct Bls12_377G1Parameters;
Expand Down
2 changes: 1 addition & 1 deletion algebra/src/curves/bls12_377/g2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use crate::{
curves::models::{ModelParameters, SWModelParameters},
fields::{
bls12_377::{Fq, Fq2, Fr},
Field,
},
};
use num_traits::Zero;

#[derive(Copy, Clone, Default, PartialEq, Eq)]
pub struct Bls12_377G2Parameters;
Expand Down
1 change: 1 addition & 0 deletions algebra/src/curves/bls12_377/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::{
},
groups::tests::group_test,
};
use num_traits::{One, Zero};
use std::ops::{AddAssign, MulAssign};

#[test]
Expand Down
2 changes: 1 addition & 1 deletion algebra/src/curves/bls12_381/g1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ use crate::{
},
fields::{
bls12_381::{Fq, Fq12, Fr},
Field,
},
};
use num_traits::Zero;

pub type G1Affine = Bls12G1Affine<Bls12_381Parameters>;
pub type G1Projective = Bls12G1Projective<Bls12_381Parameters>;
Expand Down
2 changes: 1 addition & 1 deletion algebra/src/curves/bls12_381/g2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ use crate::{
},
fields::{
bls12_381::{Fq, Fq12, Fq2, Fr},
Field,
},
};
use num_traits::Zero;

pub type G2Affine = Bls12G2Affine<Bls12_381Parameters>;
pub type G2Projective = Bls12G2Projective<Bls12_381Parameters>;
Expand Down
1 change: 1 addition & 0 deletions algebra/src/curves/bls12_381/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::{
},
groups::tests::group_test,
};
use num_traits::{One, Zero};
use rand;
use std::ops::{AddAssign, MulAssign};

Expand Down
6 changes: 5 additions & 1 deletion algebra/src/curves/jubjub/tests.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
use crate::{
bytes::{FromBytes, ToBytes},
curves::{jubjub::*, tests::curve_tests, AffineCurve, ProjectiveCurve, models::twisted_edwards_extended::tests::montgomery_conversion_test},
curves::{
jubjub::*, models::twisted_edwards_extended::tests::montgomery_conversion_test,
tests::curve_tests, AffineCurve, ProjectiveCurve,
},
fields::jubjub::fr::Fr,
groups::tests::group_test,
};
use num_traits::Zero;
use rand;
use std::str::FromStr;

Expand Down
1 change: 1 addition & 0 deletions algebra/src/curves/mnt6/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{
BitIterator, Field, FpParameters,
},
};
use num_traits::{One, Zero};

pub mod g1;
pub mod g2;
Expand Down
1 change: 1 addition & 0 deletions algebra/src/curves/mnt6/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
fields::mnt6::fr::Fr,
groups::tests::group_test,
};
use num_traits::One;
use rand;

#[test]
Expand Down
30 changes: 4 additions & 26 deletions algebra/src/curves/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{
groups::Group,
};
use crate::UniformRand;
use num_traits::Zero;
use std::{
fmt::{Debug, Display},
hash::Hash,
Expand Down Expand Up @@ -126,9 +127,11 @@ pub trait ProjectiveCurve:
+ Debug
+ Display
+ UniformRand
+ Zero
+ 'static
+ Neg<Output = Self>
+ for<'a> Add<&'a Self, Output = Self>
+ Add<Self, Output = Self>
+ for<'a> Sub<&'a Self, Output = Self>
+ for<'a> AddAssign<&'a Self>
+ for<'a> SubAssign<&'a Self>
Expand All @@ -137,18 +140,10 @@ pub trait ProjectiveCurve:
type BaseField: Field;
type Affine: AffineCurve<Projective = Self, ScalarField = Self::ScalarField>;

/// Returns the additive identity.
#[must_use]
fn zero() -> Self;

/// Returns a fixed generator of unknown exponent.
#[must_use]
fn prime_subgroup_generator() -> Self;

/// Determines if this point is the point at infinity.
#[must_use]
fn is_zero(&self) -> bool;

/// Normalizes a slice of projective elements so that
/// conversion to affine is cheap.
fn batch_normalization(v: &mut [Self]);
Expand Down Expand Up @@ -205,26 +200,18 @@ pub trait AffineCurve:
+ Hash
+ Debug
+ Display
+ Zero
+ Neg<Output = Self>
+ 'static
{
type ScalarField: PrimeField + SquareRootField + Into<<Self::ScalarField as PrimeField>::BigInt>;
type BaseField: Field;
type Projective: ProjectiveCurve<Affine = Self, ScalarField = Self::ScalarField>;

/// Returns the additive identity.
#[must_use]
fn zero() -> Self;

/// Returns a fixed generator of unknown exponent.
#[must_use]
fn prime_subgroup_generator() -> Self;

/// Determines if this point represents the point at infinity; the
/// additive identity.
#[must_use]
fn is_zero(&self) -> bool;

/// Performs scalar multiplication of this element with mixed addition.
#[must_use]
fn mul<S: Into<<Self::ScalarField as PrimeField>::BigInt>>(&self, other: S)
Expand Down Expand Up @@ -261,15 +248,6 @@ pub trait PairingCurve: AffineCurve {

impl<C: ProjectiveCurve> Group for C {
type ScalarField = C::ScalarField;
#[must_use]
fn zero() -> Self {
<C as ProjectiveCurve>::zero()
}

#[must_use]
fn is_zero(&self) -> bool {
<C as ProjectiveCurve>::is_zero(&self)
}

#[inline]
#[must_use]
Expand Down
1 change: 1 addition & 0 deletions algebra/src/curves/models/bls12/g1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{
AffineCurve,
},
};
use num_traits::Zero;
use std::io::{Result as IoResult, Write};

pub type G1Affine<P> = GroupAffine<<P as Bls12Parameters>::G1Parameters>;
Expand Down
1 change: 1 addition & 0 deletions algebra/src/curves/models/bls12/g2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
},
fields::{BitIterator, Field, Fp2},
};
use num_traits::{One, Zero};
use std::io::{Result as IoResult, Write};

pub type G2Affine<P> = GroupAffine<<P as Bls12Parameters>::G2Parameters>;
Expand Down
1 change: 1 addition & 0 deletions algebra/src/curves/models/bls12/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{
BitIterator, Field, Fp2, PrimeField, SquareRootField,
},
};
use num_traits::One;

use std::marker::PhantomData;

Expand Down
73 changes: 48 additions & 25 deletions algebra/src/curves/models/short_weierstrass_jacobian.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::curves::models::SWModelParameters as Parameters;
use rand::{Rng, distributions::{Standard, Distribution}};
use crate::UniformRand;
use num_traits::{One, Zero};
use std::{
fmt::{Display, Formatter, Result as FmtResult},
io::{Read, Result as IoResult, Write},
Expand Down Expand Up @@ -102,16 +103,43 @@ impl<P: Parameters> GroupAffine<P> {
}
}

impl<P: Parameters> Zero for GroupAffine<P> {
#[inline]
fn zero() -> Self {
Self::new(P::BaseField::zero(), P::BaseField::one(), true)
}

#[inline]
fn is_zero(&self) -> bool {
self.infinity
}
}

impl<P: Parameters> Add<Self> for GroupAffine<P> {
type Output = Self;
fn add(self, other: Self) -> Self {
let mut copy = self;
copy += &other;
copy
}
}

impl<'a, P: Parameters> AddAssign<&'a Self> for GroupAffine<P> {
fn add_assign(&mut self, other: &'a Self) {
let lambda = (other.y - &self.y) / &(other.x - &self.y);
let x3 = lambda * lambda - &self.x - &other.x;
let y3 = (self.x - &x3) * lambda - &self.y;

self.x = x3;
self.y = y3;
}
}

impl<P: Parameters> AffineCurve for GroupAffine<P> {
type BaseField = P::BaseField;
type ScalarField = P::ScalarField;
type Projective = GroupProjective<P>;

#[inline]
fn zero() -> Self {
Self::new(Self::BaseField::zero(), Self::BaseField::one(), true)
}

#[inline]
fn prime_subgroup_generator() -> Self {
Self::new(
Expand All @@ -121,11 +149,6 @@ impl<P: Parameters> AffineCurve for GroupAffine<P> {
)
}

#[inline]
fn is_zero(&self) -> bool {
self.infinity
}

#[inline]
fn mul<S: Into<<Self::ScalarField as PrimeField>::BigInt>>(&self, by: S) -> GroupProjective<P> {
let bits = BitIterator::new(by.into());
Expand Down Expand Up @@ -238,8 +261,6 @@ impl<P: Parameters> Distribution<GroupProjective<P>> for Standard {
}
}



impl<P: Parameters> ToBytes for GroupProjective<P> {
#[inline]
fn write<W: Write>(&self, mut writer: W) -> IoResult<()> {
Expand Down Expand Up @@ -277,11 +298,7 @@ impl<P: Parameters> GroupProjective<P> {
}
}

impl<P: Parameters> ProjectiveCurve for GroupProjective<P> {
type BaseField = P::BaseField;
type ScalarField = P::ScalarField;
type Affine = GroupAffine<P>;

impl<P: Parameters> Zero for GroupProjective<P> {
// The point at infinity is always represented by
// Z = 0.
#[inline]
Expand All @@ -293,17 +310,23 @@ impl<P: Parameters> ProjectiveCurve for GroupProjective<P> {
)
}

#[inline]
fn prime_subgroup_generator() -> Self {
GroupAffine::prime_subgroup_generator().into()
}

// The point at infinity is always represented by
// Z = 0.
#[inline]
fn is_zero(&self) -> bool {
self.z.is_zero()
}
}

impl<P: Parameters> ProjectiveCurve for GroupProjective<P> {
type BaseField = P::BaseField;
type ScalarField = P::ScalarField;
type Affine = GroupAffine<P>;

#[inline]
fn prime_subgroup_generator() -> Self {
GroupAffine::prime_subgroup_generator().into()
}

#[inline]
fn is_normalized(&self) -> bool {
Expand Down Expand Up @@ -557,13 +580,13 @@ impl<P: Parameters> Neg for GroupProjective<P> {
}
}

impl<'a, P: Parameters> Add<&'a Self> for GroupProjective<P> {
impl<P: Parameters> Add<Self> for GroupProjective<P> {
type Output = Self;

#[inline]
fn add(self, other: &'a Self) -> Self {
fn add(self, other: Self) -> Self {
let mut copy = self;
copy += other;
copy += &other;
copy
}
}
Expand Down
Loading

0 comments on commit cd18b99

Please sign in to comment.