mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-01-30 15:32:14 +00:00
Move additive CurveProjective operators to traits
This commit is contained in:
parent
049847f1a8
commit
8193324986
@ -413,10 +413,6 @@ impl CurveProjective for Fr {
|
||||
self.0 = <Fr as Field>::double(self).0;
|
||||
}
|
||||
|
||||
fn add_assign(&mut self, other: &Self) {
|
||||
AddAssign::add_assign(self, other);
|
||||
}
|
||||
|
||||
fn add_assign_mixed(&mut self, other: &Self) {
|
||||
AddAssign::add_assign(self, other);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
use ff::PrimeField;
|
||||
use group::{CurveAffine, CurveProjective};
|
||||
use pairing::{Engine, PairingCurveAffine};
|
||||
use std::ops::AddAssign;
|
||||
|
||||
use super::{PreparedVerifyingKey, Proof, VerifyingKey};
|
||||
|
||||
|
@ -5,6 +5,7 @@ use futures::Future;
|
||||
use group::{CurveAffine, CurveProjective};
|
||||
use std::io;
|
||||
use std::iter;
|
||||
use std::ops::AddAssign;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::SynthesisError;
|
||||
|
@ -5,6 +5,7 @@ use ff::{PrimeField, PrimeFieldDecodingError, ScalarEngine, SqrtField};
|
||||
use rand::RngCore;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::ops::{Add, AddAssign, Sub, SubAssign};
|
||||
|
||||
pub mod tests;
|
||||
|
||||
@ -14,7 +15,24 @@ pub use self::wnaf::Wnaf;
|
||||
/// 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
|
||||
PartialEq
|
||||
+ Eq
|
||||
+ Sized
|
||||
+ Copy
|
||||
+ Clone
|
||||
+ Send
|
||||
+ Sync
|
||||
+ fmt::Debug
|
||||
+ fmt::Display
|
||||
+ 'static
|
||||
+ Add<Output = Self>
|
||||
+ Sub<Output = Self>
|
||||
+ for<'a> Add<&'a Self, Output = Self>
|
||||
+ for<'a> Sub<&'a Self, Output = Self>
|
||||
+ AddAssign
|
||||
+ SubAssign
|
||||
+ for<'a> AddAssign<&'a Self>
|
||||
+ for<'a> SubAssign<&'a Self>
|
||||
{
|
||||
type Engine: ScalarEngine<Fr = Self::Scalar>;
|
||||
type Scalar: PrimeField + SqrtField;
|
||||
@ -44,16 +62,6 @@ pub trait CurveProjective:
|
||||
/// Doubles this element.
|
||||
fn double(&mut self);
|
||||
|
||||
/// Adds another element to this element.
|
||||
fn add_assign(&mut self, other: &Self);
|
||||
|
||||
/// Subtracts another element from this element.
|
||||
fn sub_assign(&mut self, other: &Self) {
|
||||
let mut tmp = *other;
|
||||
tmp.negate();
|
||||
self.add_assign(&tmp);
|
||||
}
|
||||
|
||||
/// Adds an affine element to this element.
|
||||
fn add_assign_mixed(&mut self, other: &Self::Affine);
|
||||
|
||||
|
@ -2,6 +2,7 @@ pub(crate) mod g1 {
|
||||
use criterion::{criterion_group, Criterion};
|
||||
use rand_core::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
use std::ops::AddAssign;
|
||||
|
||||
use ff::Field;
|
||||
use group::CurveProjective;
|
||||
@ -88,6 +89,7 @@ pub(crate) mod g2 {
|
||||
use criterion::{criterion_group, Criterion};
|
||||
use rand_core::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
use std::ops::AddAssign;
|
||||
|
||||
use ff::Field;
|
||||
use group::CurveProjective;
|
||||
|
@ -188,6 +188,155 @@ macro_rules! curve_impl {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r> ::std::ops::Add<&'r $projective> for $projective {
|
||||
type Output = Self;
|
||||
|
||||
#[inline]
|
||||
fn add(self, other: &Self) -> Self {
|
||||
let mut ret = self;
|
||||
ret.add_assign(other);
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Add for $projective {
|
||||
type Output = Self;
|
||||
|
||||
#[inline]
|
||||
fn add(self, other: Self) -> Self {
|
||||
self + &other
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r> ::std::ops::AddAssign<&'r $projective> for $projective {
|
||||
fn add_assign(&mut self, other: &Self) {
|
||||
if self.is_zero() {
|
||||
*self = *other;
|
||||
return;
|
||||
}
|
||||
|
||||
if other.is_zero() {
|
||||
return;
|
||||
}
|
||||
|
||||
// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
|
||||
|
||||
// Z1Z1 = Z1^2
|
||||
let z1z1 = self.z.square();
|
||||
|
||||
// Z2Z2 = Z2^2
|
||||
let z2z2 = other.z.square();
|
||||
|
||||
// U1 = X1*Z2Z2
|
||||
let mut u1 = self.x;
|
||||
u1.mul_assign(&z2z2);
|
||||
|
||||
// U2 = X2*Z1Z1
|
||||
let mut u2 = other.x;
|
||||
u2.mul_assign(&z1z1);
|
||||
|
||||
// S1 = Y1*Z2*Z2Z2
|
||||
let mut s1 = self.y;
|
||||
s1.mul_assign(&other.z);
|
||||
s1.mul_assign(&z2z2);
|
||||
|
||||
// S2 = Y2*Z1*Z1Z1
|
||||
let mut s2 = other.y;
|
||||
s2.mul_assign(&self.z);
|
||||
s2.mul_assign(&z1z1);
|
||||
|
||||
if u1 == u2 && s1 == s2 {
|
||||
// The two points are equal, so we double.
|
||||
self.double();
|
||||
} else {
|
||||
// If we're adding -a and a together, self.z becomes zero as H becomes zero.
|
||||
|
||||
// H = U2-U1
|
||||
let mut h = u2;
|
||||
h.sub_assign(&u1);
|
||||
|
||||
// I = (2*H)^2
|
||||
let i = h.double().square();
|
||||
|
||||
// J = H*I
|
||||
let mut j = h;
|
||||
j.mul_assign(&i);
|
||||
|
||||
// r = 2*(S2-S1)
|
||||
let mut r = s2;
|
||||
r.sub_assign(&s1);
|
||||
r = r.double();
|
||||
|
||||
// V = U1*I
|
||||
let mut v = u1;
|
||||
v.mul_assign(&i);
|
||||
|
||||
// X3 = r^2 - J - 2*V
|
||||
self.x = r.square();
|
||||
self.x.sub_assign(&j);
|
||||
self.x.sub_assign(&v);
|
||||
self.x.sub_assign(&v);
|
||||
|
||||
// Y3 = r*(V - X3) - 2*S1*J
|
||||
self.y = v;
|
||||
self.y.sub_assign(&self.x);
|
||||
self.y.mul_assign(&r);
|
||||
s1.mul_assign(&j); // S1 = S1 * J * 2
|
||||
s1 = s1.double();
|
||||
self.y.sub_assign(&s1);
|
||||
|
||||
// Z3 = ((Z1+Z2)^2 - Z1Z1 - Z2Z2)*H
|
||||
self.z.add_assign(&other.z);
|
||||
self.z = self.z.square();
|
||||
self.z.sub_assign(&z1z1);
|
||||
self.z.sub_assign(&z2z2);
|
||||
self.z.mul_assign(&h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::AddAssign for $projective {
|
||||
#[inline]
|
||||
fn add_assign(&mut self, other: Self) {
|
||||
self.add_assign(&other);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r> ::std::ops::Sub<&'r $projective> for $projective {
|
||||
type Output = Self;
|
||||
|
||||
#[inline]
|
||||
fn sub(self, other: &Self) -> Self {
|
||||
let mut ret = self;
|
||||
ret.sub_assign(other);
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Sub for $projective {
|
||||
type Output = Self;
|
||||
|
||||
#[inline]
|
||||
fn sub(self, other: Self) -> Self {
|
||||
self - &other
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r> ::std::ops::SubAssign<&'r $projective> for $projective {
|
||||
fn sub_assign(&mut self, other: &Self) {
|
||||
let mut tmp = *other;
|
||||
tmp.negate();
|
||||
self.add_assign(&tmp);
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::SubAssign for $projective {
|
||||
#[inline]
|
||||
fn sub_assign(&mut self, other: Self) {
|
||||
self.sub_assign(&other);
|
||||
}
|
||||
}
|
||||
|
||||
impl CurveProjective for $projective {
|
||||
type Engine = Bls12;
|
||||
type Scalar = $scalarfield;
|
||||
@ -340,91 +489,6 @@ macro_rules! curve_impl {
|
||||
self.y.sub_assign(&c);
|
||||
}
|
||||
|
||||
fn add_assign(&mut self, other: &Self) {
|
||||
if self.is_zero() {
|
||||
*self = *other;
|
||||
return;
|
||||
}
|
||||
|
||||
if other.is_zero() {
|
||||
return;
|
||||
}
|
||||
|
||||
// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
|
||||
|
||||
// Z1Z1 = Z1^2
|
||||
let z1z1 = self.z.square();
|
||||
|
||||
// Z2Z2 = Z2^2
|
||||
let z2z2 = other.z.square();
|
||||
|
||||
// U1 = X1*Z2Z2
|
||||
let mut u1 = self.x;
|
||||
u1.mul_assign(&z2z2);
|
||||
|
||||
// U2 = X2*Z1Z1
|
||||
let mut u2 = other.x;
|
||||
u2.mul_assign(&z1z1);
|
||||
|
||||
// S1 = Y1*Z2*Z2Z2
|
||||
let mut s1 = self.y;
|
||||
s1.mul_assign(&other.z);
|
||||
s1.mul_assign(&z2z2);
|
||||
|
||||
// S2 = Y2*Z1*Z1Z1
|
||||
let mut s2 = other.y;
|
||||
s2.mul_assign(&self.z);
|
||||
s2.mul_assign(&z1z1);
|
||||
|
||||
if u1 == u2 && s1 == s2 {
|
||||
// The two points are equal, so we double.
|
||||
self.double();
|
||||
} else {
|
||||
// If we're adding -a and a together, self.z becomes zero as H becomes zero.
|
||||
|
||||
// H = U2-U1
|
||||
let mut h = u2;
|
||||
h.sub_assign(&u1);
|
||||
|
||||
// I = (2*H)^2
|
||||
let i = h.double().square();
|
||||
|
||||
// J = H*I
|
||||
let mut j = h;
|
||||
j.mul_assign(&i);
|
||||
|
||||
// r = 2*(S2-S1)
|
||||
let mut r = s2;
|
||||
r.sub_assign(&s1);
|
||||
r = r.double();
|
||||
|
||||
// V = U1*I
|
||||
let mut v = u1;
|
||||
v.mul_assign(&i);
|
||||
|
||||
// X3 = r^2 - J - 2*V
|
||||
self.x = r.square();
|
||||
self.x.sub_assign(&j);
|
||||
self.x.sub_assign(&v);
|
||||
self.x.sub_assign(&v);
|
||||
|
||||
// Y3 = r*(V - X3) - 2*S1*J
|
||||
self.y = v;
|
||||
self.y.sub_assign(&self.x);
|
||||
self.y.mul_assign(&r);
|
||||
s1.mul_assign(&j); // S1 = S1 * J * 2
|
||||
s1 = s1.double();
|
||||
self.y.sub_assign(&s1);
|
||||
|
||||
// Z3 = ((Z1+Z2)^2 - Z1Z1 - Z2Z2)*H
|
||||
self.z.add_assign(&other.z);
|
||||
self.z = self.z.square();
|
||||
self.z.sub_assign(&z1z1);
|
||||
self.z.sub_assign(&z2z2);
|
||||
self.z.mul_assign(&h);
|
||||
}
|
||||
}
|
||||
|
||||
fn add_assign_mixed(&mut self, other: &Self::Affine) {
|
||||
if other.is_zero() {
|
||||
return;
|
||||
@ -521,7 +585,7 @@ macro_rules! curve_impl {
|
||||
}
|
||||
|
||||
if i {
|
||||
res.add_assign(self);
|
||||
res.add_assign(&*self);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user