Move from Field::negate to Neg operator

This commit is contained in:
Jack Grigg
2019-12-12 22:52:17 +00:00
parent 4a3350bc31
commit 91c32f1c7c
26 changed files with 175 additions and 189 deletions

View File

@@ -1,7 +1,7 @@
//! Window table lookup gadgets. //! Window table lookup gadgets.
use ff::{Field, ScalarEngine}; use ff::{Field, ScalarEngine};
use std::ops::AddAssign; use std::ops::{AddAssign, Neg};
use super::boolean::Boolean; use super::boolean::Boolean;
use super::num::{AllocatedNum, Num}; use super::num::{AllocatedNum, Num};
@@ -16,8 +16,7 @@ where
assert_eq!(assignment.len(), 1 << window_size); assert_eq!(assignment.len(), 1 << window_size);
for (i, constant) in constants.into_iter().enumerate() { for (i, constant) in constants.into_iter().enumerate() {
let mut cur = assignment[i]; let mut cur = assignment[i].neg();
cur.negate();
cur.add_assign(constant); cur.add_assign(constant);
assignment[i] = cur; assignment[i] = cur;
for (j, eval) in assignment.iter_mut().enumerate().skip(i + 1) { for (j, eval) in assignment.iter_mut().enumerate().skip(i + 1) {
@@ -151,7 +150,7 @@ where
let y = AllocatedNum::alloc(cs.namespace(|| "y"), || { let y = AllocatedNum::alloc(cs.namespace(|| "y"), || {
let mut tmp = coords[*i.get()?].1; let mut tmp = coords[*i.get()?].1;
if *bits[2].get_value().get()? { if *bits[2].get_value().get()? {
tmp.negate(); tmp = tmp.neg();
} }
Ok(tmp) Ok(tmp)
})?; })?;
@@ -281,7 +280,7 @@ mod test {
assert_eq!(res.0.get_value().unwrap(), points[index].0); assert_eq!(res.0.get_value().unwrap(), points[index].0);
let mut tmp = points[index].1; let mut tmp = points[index].1;
if c_val { if c_val {
tmp.negate() tmp = tmp.neg()
} }
assert_eq!(res.1.get_value().unwrap(), tmp); assert_eq!(res.1.get_value().unwrap(), tmp);
} }

View File

@@ -417,7 +417,7 @@ mod test {
use pairing::bls12_381::{Bls12, Fr}; use pairing::bls12_381::{Bls12, Fr};
use rand_core::SeedableRng; use rand_core::SeedableRng;
use rand_xorshift::XorShiftRng; use rand_xorshift::XorShiftRng;
use std::ops::SubAssign; use std::ops::{Neg, SubAssign};
use super::{AllocatedNum, Boolean}; use super::{AllocatedNum, Boolean};
use crate::gadgets::test::*; use crate::gadgets::test::*;
@@ -519,8 +519,7 @@ mod test {
#[test] #[test]
fn test_into_bits_strict() { fn test_into_bits_strict() {
let mut negone = Fr::one(); let negone = Fr::one().neg();
negone.negate();
let mut cs = TestConstraintSystem::<Bls12>::new(); let mut cs = TestConstraintSystem::<Bls12>::new();

View File

@@ -6,7 +6,7 @@ use crate::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt::Write; use std::fmt::Write;
use std::ops::{AddAssign, MulAssign}; use std::ops::{AddAssign, MulAssign, Neg};
use byteorder::{BigEndian, ByteOrder}; use byteorder::{BigEndian, ByteOrder};
use std::cmp::Ordering; use std::cmp::Ordering;
@@ -152,11 +152,7 @@ impl<E: ScalarEngine> TestConstraintSystem<E> {
pub fn pretty_print(&self) -> String { pub fn pretty_print(&self) -> String {
let mut s = String::new(); let mut s = String::new();
let negone = { let negone = E::Fr::one().neg();
let mut tmp = E::Fr::one();
tmp.negate();
tmp
};
let powers_of_two = (0..E::Fr::NUM_BITS) let powers_of_two = (0..E::Fr::NUM_BITS)
.map(|i| E::Fr::from_str("2").unwrap().pow(&[u64::from(i)])) .map(|i| E::Fr::from_str("2").unwrap().pow(&[u64::from(i)]))

View File

@@ -9,7 +9,7 @@ use rand_core::RngCore;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::fmt; use std::fmt;
use std::num::Wrapping; use std::num::Wrapping;
use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}; use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
const MODULUS_R: Wrapping<u32> = Wrapping(64513); const MODULUS_R: Wrapping<u32> = Wrapping(64513);
@@ -22,6 +22,17 @@ impl fmt::Display for Fr {
} }
} }
impl Neg for Fr {
type Output = Self;
fn neg(mut self) -> Self {
if !<Fr as Field>::is_zero(&self) {
self.0 = MODULUS_R - self.0;
}
self
}
}
impl<'r> Add<&'r Fr> for Fr { impl<'r> Add<&'r Fr> for Fr {
type Output = Self; type Output = Self;
@@ -137,12 +148,6 @@ impl Field for Fr {
self.0 = (self.0 << 1) % MODULUS_R; self.0 = (self.0 << 1) % MODULUS_R;
} }
fn negate(&mut self) {
if !<Fr as Field>::is_zero(self) {
self.0 = MODULUS_R - self.0;
}
}
fn inverse(&self) -> Option<Self> { fn inverse(&self) -> Option<Self> {
if <Fr as Field>::is_zero(self) { if <Fr as Field>::is_zero(self) {
None None
@@ -413,7 +418,7 @@ impl CurveProjective for Fr {
} }
fn negate(&mut self) { fn negate(&mut self) {
<Fr as Field>::negate(self); self.0 = self.neg().0;
} }
fn mul_assign<S: Into<<Self::Scalar as PrimeField>::Repr>>(&mut self, other: S) { fn mul_assign<S: Into<<Self::Scalar as PrimeField>::Repr>>(&mut self, other: S) {
@@ -495,7 +500,7 @@ impl CurveAffine for Fr {
} }
fn negate(&mut self) { fn negate(&mut self) {
<Fr as Field>::negate(self); self.0 = self.neg().0;
} }
fn mul<S: Into<<Self::Scalar as PrimeField>::Repr>>(&self, other: S) -> Self::Projective { fn mul<S: Into<<Self::Scalar as PrimeField>::Repr>>(&self, other: S) -> Self::Projective {

View File

@@ -148,7 +148,7 @@ use std::error::Error;
use std::fmt; use std::fmt;
use std::io; use std::io;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ops::{Add, MulAssign, Sub}; use std::ops::{Add, MulAssign, Neg, Sub};
/// Computations are expressed in terms of arithmetic circuits, in particular /// Computations are expressed in terms of arithmetic circuits, in particular
/// rank-1 quadratic constraint systems. The `Circuit` trait represents a /// rank-1 quadratic constraint systems. The `Circuit` trait represents a
@@ -216,10 +216,8 @@ impl<E: ScalarEngine> Sub<(E::Fr, Variable)> for LinearCombination<E> {
type Output = LinearCombination<E>; type Output = LinearCombination<E>;
#[allow(clippy::suspicious_arithmetic_impl)] #[allow(clippy::suspicious_arithmetic_impl)]
fn sub(self, (mut coeff, var): (E::Fr, Variable)) -> LinearCombination<E> { fn sub(self, (coeff, var): (E::Fr, Variable)) -> LinearCombination<E> {
coeff.negate(); self + (coeff.neg(), var)
self + (coeff, var)
} }
} }

View File

@@ -833,6 +833,21 @@ fn prime_field_impl(
} }
} }
impl ::std::ops::Neg for #name {
type Output = #name;
#[inline]
fn neg(self) -> #name {
let mut ret = self;
if !ret.is_zero() {
let mut tmp = MODULUS;
tmp.sub_noborrow(&ret.0);
ret.0 = tmp;
}
ret
}
}
impl<'r> ::std::ops::Add<&'r #name> for #name { impl<'r> ::std::ops::Add<&'r #name> for #name {
type Output = #name; type Output = #name;
@@ -1033,15 +1048,6 @@ fn prime_field_impl(
self.reduce(); self.reduce();
} }
#[inline]
fn negate(&mut self) {
if !self.is_zero() {
let mut tmp = MODULUS;
tmp.sub_noborrow(&self.0);
self.0 = tmp;
}
}
fn inverse(&self) -> Option<Self> { fn inverse(&self) -> Option<Self> {
if self.is_zero() { if self.is_zero() {
None None

View File

@@ -11,7 +11,7 @@ use rand_core::RngCore;
use std::error::Error; use std::error::Error;
use std::fmt; use std::fmt;
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}; use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
/// This trait represents an element of a field. /// This trait represents an element of a field.
pub trait Field: pub trait Field:
@@ -27,6 +27,7 @@ pub trait Field:
+ Add<Output = Self> + Add<Output = Self>
+ Sub<Output = Self> + Sub<Output = Self>
+ Mul<Output = Self> + Mul<Output = Self>
+ Neg<Output = Self>
+ for<'a> Add<&'a Self, Output = Self> + for<'a> Add<&'a Self, Output = Self>
+ for<'a> Mul<&'a Self, Output = Self> + for<'a> Mul<&'a Self, Output = Self>
+ for<'a> Sub<&'a Self, Output = Self> + for<'a> Sub<&'a Self, Output = Self>
@@ -55,9 +56,6 @@ pub trait Field:
/// Doubles this element. /// Doubles this element.
fn double(&mut self); fn double(&mut self);
/// Negates this element.
fn negate(&mut self);
/// Computes the multiplicative inverse of this element, if nonzero. /// Computes the multiplicative inverse of this element, if nonzero.
fn inverse(&self) -> Option<Self>; fn inverse(&self) -> Option<Self>;

View File

@@ -1,6 +1,7 @@
use ff::{Field, PrimeField}; use ff::{Field, PrimeField};
use rand::SeedableRng; use rand::SeedableRng;
use rand_xorshift::XorShiftRng; use rand_xorshift::XorShiftRng;
use std::ops::Neg;
use crate::{CurveAffine, CurveProjective, EncodedPoint}; use crate::{CurveAffine, CurveProjective, EncodedPoint};
@@ -199,8 +200,7 @@ fn random_negation_tests<G: CurveProjective>() {
let r = G::random(&mut rng); let r = G::random(&mut rng);
let s = G::Scalar::random(&mut rng); let s = G::Scalar::random(&mut rng);
let mut sneg = s; let sneg = s.neg();
sneg.negate();
let mut t1 = r; let mut t1 = r;
t1.mul_assign(s); t1.mul_assign(s);

View File

@@ -1,6 +1,6 @@
use rand_core::SeedableRng; use rand_core::SeedableRng;
use rand_xorshift::XorShiftRng; use rand_xorshift::XorShiftRng;
use std::ops::{AddAssign, MulAssign, SubAssign}; use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
use ff::{Field, PrimeField, PrimeFieldRepr, SqrtField}; use ff::{Field, PrimeField, PrimeFieldRepr, SqrtField};
use pairing::bls12_381::*; use pairing::bls12_381::*;
@@ -236,7 +236,7 @@ fn bench_fq_inverse(b: &mut ::test::Bencher) {
} }
#[bench] #[bench]
fn bench_fq_negate(b: &mut ::test::Bencher) { fn bench_fq_neg(b: &mut ::test::Bencher) {
const SAMPLES: usize = 1000; const SAMPLES: usize = 1000;
let mut rng = XorShiftRng::from_seed([ let mut rng = XorShiftRng::from_seed([
@@ -248,8 +248,7 @@ fn bench_fq_negate(b: &mut ::test::Bencher) {
let mut count = 0; let mut count = 0;
b.iter(|| { b.iter(|| {
let mut tmp = v[count]; let tmp = v[count].neg();
tmp.negate();
count = (count + 1) % SAMPLES; count = (count + 1) % SAMPLES;
tmp tmp
}); });

View File

@@ -1,6 +1,6 @@
use rand_core::SeedableRng; use rand_core::SeedableRng;
use rand_xorshift::XorShiftRng; use rand_xorshift::XorShiftRng;
use std::ops::{AddAssign, MulAssign, SubAssign}; use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
use ff::{Field, PrimeField, PrimeFieldRepr, SqrtField}; use ff::{Field, PrimeField, PrimeFieldRepr, SqrtField};
use pairing::bls12_381::*; use pairing::bls12_381::*;
@@ -236,7 +236,7 @@ fn bench_fr_inverse(b: &mut ::test::Bencher) {
} }
#[bench] #[bench]
fn bench_fr_negate(b: &mut ::test::Bencher) { fn bench_fr_neg(b: &mut ::test::Bencher) {
const SAMPLES: usize = 1000; const SAMPLES: usize = 1000;
let mut rng = XorShiftRng::from_seed([ let mut rng = XorShiftRng::from_seed([
@@ -248,8 +248,7 @@ fn bench_fr_negate(b: &mut ::test::Bencher) {
let mut count = 0; let mut count = 0;
b.iter(|| { b.iter(|| {
let mut tmp = v[count]; let tmp = v[count].neg();
tmp.negate();
count = (count + 1) % SAMPLES; count = (count + 1) % SAMPLES;
tmp tmp
}); });

View File

@@ -107,8 +107,7 @@ macro_rules! curve_impl {
x3b.add_assign(&$affine::get_coeff_b()); x3b.add_assign(&$affine::get_coeff_b());
x3b.sqrt().map(|y| { x3b.sqrt().map(|y| {
let mut negy = y; let negy = y.neg();
negy.negate();
$affine { $affine {
x: x, x: x,
@@ -171,7 +170,7 @@ macro_rules! curve_impl {
fn negate(&mut self) { fn negate(&mut self) {
if !self.is_zero() { if !self.is_zero() {
self.y.negate(); self.y = self.y.neg();
} }
} }
@@ -527,7 +526,7 @@ macro_rules! curve_impl {
fn negate(&mut self) { fn negate(&mut self) {
if !self.is_zero() { if !self.is_zero() {
self.y.negate() self.y = self.y.neg();
} }
} }
@@ -627,7 +626,7 @@ pub mod g1 {
use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError}; use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError};
use rand_core::RngCore; use rand_core::RngCore;
use std::fmt; use std::fmt;
use std::ops::{AddAssign, MulAssign, SubAssign}; use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
curve_impl!( curve_impl!(
"G1", "G1",
@@ -849,8 +848,7 @@ pub mod g1 {
affine.x.into_repr().write_be(&mut writer).unwrap(); affine.x.into_repr().write_be(&mut writer).unwrap();
} }
let mut negy = affine.y; let negy = affine.y.neg();
negy.negate();
// Set the third most significant bit if the correct y-coordinate // Set the third most significant bit if the correct y-coordinate
// is lexicographically largest. // is lexicographically largest.
@@ -948,8 +946,7 @@ pub mod g1 {
if let Some(y) = rhs.sqrt() { if let Some(y) = rhs.sqrt() {
let yrepr = y.into_repr(); let yrepr = y.into_repr();
let mut negy = y; let negy = y.neg();
negy.negate();
let negyrepr = negy.into_repr(); let negyrepr = negy.into_repr();
let p = G1Affine { let p = G1Affine {
@@ -1297,7 +1294,7 @@ pub mod g2 {
use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError}; use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError};
use rand_core::RngCore; use rand_core::RngCore;
use std::fmt; use std::fmt;
use std::ops::{AddAssign, MulAssign, SubAssign}; use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
curve_impl!( curve_impl!(
"G2", "G2",
@@ -1544,8 +1541,7 @@ pub mod g2 {
affine.x.c0.into_repr().write_be(&mut writer).unwrap(); affine.x.c0.into_repr().write_be(&mut writer).unwrap();
} }
let mut negy = affine.y; let negy = affine.y.neg();
negy.negate();
// Set the third most significant bit if the correct y-coordinate // Set the third most significant bit if the correct y-coordinate
// is lexicographically largest. // is lexicographically largest.
@@ -1654,8 +1650,7 @@ pub mod g2 {
rhs.add_assign(&G2Affine::get_coeff_b()); rhs.add_assign(&G2Affine::get_coeff_b());
if let Some(y) = rhs.sqrt() { if let Some(y) = rhs.sqrt() {
let mut negy = y; let negy = y.neg();
negy.negate();
let p = G2Affine { let p = G2Affine {
x, x,

View File

@@ -2,6 +2,9 @@ use super::fq2::Fq2;
use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr}; use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr};
use std::ops::{AddAssign, MulAssign, SubAssign}; use std::ops::{AddAssign, MulAssign, SubAssign};
#[cfg(test)]
use std::ops::Neg;
// B coefficient of BLS12-381 curve, 4. // B coefficient of BLS12-381 curve, 4.
pub const B_COEFF: Fq = Fq(FqRepr([ pub const B_COEFF: Fq = Fq(FqRepr([
0xaa270000000cfff3, 0xaa270000000cfff3,
@@ -456,8 +459,7 @@ fn test_b_coeff() {
#[test] #[test]
fn test_frob_coeffs() { fn test_frob_coeffs() {
let mut nqr = Fq::one(); let nqr = Fq::one().neg();
nqr.negate();
assert_eq!(FROBENIUS_COEFF_FQ2_C1[0], Fq::one()); assert_eq!(FROBENIUS_COEFF_FQ2_C1[0], Fq::one());
assert_eq!( assert_eq!(
@@ -1167,8 +1169,7 @@ fn test_frob_coeffs() {
#[test] #[test]
fn test_neg_one() { fn test_neg_one() {
let mut o = Fq::one(); let o = Fq::one().neg();
o.negate();
assert_eq!(NEGATIVE_ONE, o); assert_eq!(NEGATIVE_ONE, o);
} }
@@ -2009,10 +2010,9 @@ fn test_fq_double() {
} }
#[test] #[test]
fn test_fq_negate() { fn test_fq_neg() {
{ {
let mut a = Fq::zero(); let a = Fq::zero().neg();
a.negate();
assert!(a.is_zero()); assert!(a.is_zero());
} }
@@ -2025,8 +2025,7 @@ fn test_fq_negate() {
for _ in 0..1000 { for _ in 0..1000 {
// Ensure (a - (-a)) = 0. // Ensure (a - (-a)) = 0.
let mut a = Fq::random(&mut rng); let mut a = Fq::random(&mut rng);
let mut b = a; let b = a.neg();
b.negate();
a.add_assign(&b); a.add_assign(&b);
assert!(a.is_zero()); assert!(a.is_zero());
@@ -2074,8 +2073,7 @@ fn test_fq_sqrt() {
for _ in 0..1000 { for _ in 0..1000 {
// Ensure sqrt(a^2) = a or -a // Ensure sqrt(a^2) = a or -a
let a = Fq::random(&mut rng); let a = Fq::random(&mut rng);
let mut nega = a; let nega = a.neg();
nega.negate();
let mut b = a; let mut b = a;
b.square(); b.square();

View File

@@ -3,7 +3,7 @@ use super::fq2::Fq2;
use super::fq6::Fq6; use super::fq6::Fq6;
use ff::Field; use ff::Field;
use rand_core::RngCore; use rand_core::RngCore;
use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}; use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
/// An element of Fq12, represented by c0 + c1 * w. /// An element of Fq12, represented by c0 + c1 * w.
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
@@ -20,7 +20,7 @@ impl ::std::fmt::Display for Fq12 {
impl Fq12 { impl Fq12 {
pub fn conjugate(&mut self) { pub fn conjugate(&mut self) {
self.c1.negate(); self.c1 = self.c1.neg();
} }
pub fn mul_by_014(&mut self, c0: &Fq2, c1: &Fq2, c4: &Fq2) { pub fn mul_by_014(&mut self, c0: &Fq2, c1: &Fq2, c4: &Fq2) {
@@ -40,6 +40,17 @@ impl Fq12 {
} }
} }
impl Neg for Fq12 {
type Output = Self;
fn neg(self) -> Self {
Fq12 {
c0: self.c0.neg(),
c1: self.c1.neg(),
}
}
}
impl<'r> Add<&'r Fq12> for Fq12 { impl<'r> Add<&'r Fq12> for Fq12 {
type Output = Self; type Output = Self;
@@ -177,11 +188,6 @@ impl Field for Fq12 {
self.c1.double(); self.c1.double();
} }
fn negate(&mut self) {
self.c0.negate();
self.c1.negate();
}
fn frobenius_map(&mut self, power: usize) { fn frobenius_map(&mut self, power: usize) {
self.c0.frobenius_map(power); self.c0.frobenius_map(power);
self.c1.frobenius_map(power); self.c1.frobenius_map(power);
@@ -216,13 +222,9 @@ impl Field for Fq12 {
c1s.mul_by_nonresidue(); c1s.mul_by_nonresidue();
c0s.sub_assign(&c1s); c0s.sub_assign(&c1s);
c0s.inverse().map(|t| { c0s.inverse().map(|t| Fq12 {
let mut tmp = Fq12 { c0: t, c1: t }; c0: t.mul(&self.c0),
tmp.c0.mul_assign(&self.c0); c1: t.mul(&self.c1).neg(),
tmp.c1.mul_assign(&self.c1);
tmp.c1.negate();
tmp
}) })
} }
} }

View File

@@ -2,7 +2,7 @@ use super::fq::{Fq, FROBENIUS_COEFF_FQ2_C1, NEGATIVE_ONE};
use ff::{Field, SqrtField}; use ff::{Field, SqrtField};
use rand_core::RngCore; use rand_core::RngCore;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}; use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
/// An element of Fq2, represented by c0 + c1 * u. /// An element of Fq2, represented by c0 + c1 * u.
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
@@ -56,6 +56,17 @@ impl Fq2 {
} }
} }
impl Neg for Fq2 {
type Output = Self;
fn neg(self) -> Self {
Fq2 {
c0: self.c0.neg(),
c1: self.c1.neg(),
}
}
}
impl<'r> Add<&'r Fq2> for Fq2 { impl<'r> Add<&'r Fq2> for Fq2 {
type Output = Self; type Output = Self;
@@ -192,8 +203,7 @@ impl Field for Fq2 {
ab.mul_assign(&self.c1); ab.mul_assign(&self.c1);
let mut c0c1 = self.c0; let mut c0c1 = self.c0;
c0c1.add_assign(&self.c1); c0c1.add_assign(&self.c1);
let mut c0 = self.c1; let mut c0 = self.c1.neg();
c0.negate();
c0.add_assign(&self.c0); c0.add_assign(&self.c0);
c0.mul_assign(&c0c1); c0.mul_assign(&c0c1);
c0.sub_assign(&ab); c0.sub_assign(&ab);
@@ -208,27 +218,15 @@ impl Field for Fq2 {
self.c1.double(); self.c1.double();
} }
fn negate(&mut self) {
self.c0.negate();
self.c1.negate();
}
fn inverse(&self) -> Option<Self> { fn inverse(&self) -> Option<Self> {
let mut t1 = self.c1; let mut t1 = self.c1;
t1.square(); t1.square();
let mut t0 = self.c0; let mut t0 = self.c0;
t0.square(); t0.square();
t0.add_assign(&t1); t0.add_assign(&t1);
t0.inverse().map(|t| { t0.inverse().map(|t| Fq2 {
let mut tmp = Fq2 { c0: self.c0.mul(&t),
c0: self.c0, c1: self.c1.mul(&t).neg(),
c1: self.c1,
};
tmp.c0.mul_assign(&t);
tmp.c1.mul_assign(&t);
tmp.c1.negate();
tmp
}) })
} }
@@ -372,10 +370,8 @@ fn test_fq2_squaring() {
}; // u }; // u
a.square(); a.square();
assert_eq!(a, { assert_eq!(a, {
let mut neg1 = Fq::one();
neg1.negate();
Fq2 { Fq2 {
c0: neg1, c0: Fq::one().neg(),
c1: Fq::zero(), c1: Fq::zero(),
} }
}); // -1 }); // -1
@@ -694,7 +690,7 @@ fn test_fq2_negation() {
use super::fq::FqRepr; use super::fq::FqRepr;
use ff::PrimeField; use ff::PrimeField;
let mut a = Fq2 { let a = Fq2 {
c0: Fq::from_repr(FqRepr([ c0: Fq::from_repr(FqRepr([
0x2d0078036923ffc7, 0x2d0078036923ffc7,
0x11e59ea221a3b6d2, 0x11e59ea221a3b6d2,
@@ -713,8 +709,8 @@ fn test_fq2_negation() {
0x12d1137b8a6a837, 0x12d1137b8a6a837,
])) ]))
.unwrap(), .unwrap(),
}; }
a.negate(); .neg();
assert_eq!( assert_eq!(
a, a,
Fq2 { Fq2 {
@@ -1000,8 +996,7 @@ fn test_fq2_legendre() {
assert_eq!(Zero, Fq2::zero().legendre()); assert_eq!(Zero, Fq2::zero().legendre());
// i^2 = -1 // i^2 = -1
let mut m1 = Fq2::one(); let mut m1 = Fq2::one().neg();
m1.negate();
assert_eq!(QuadraticResidue, m1.legendre()); assert_eq!(QuadraticResidue, m1.legendre());
m1.mul_by_nonresidue(); m1.mul_by_nonresidue();
assert_eq!(QuadraticNonResidue, m1.legendre()); assert_eq!(QuadraticNonResidue, m1.legendre());

View File

@@ -2,7 +2,7 @@ use super::fq::{FROBENIUS_COEFF_FQ6_C1, FROBENIUS_COEFF_FQ6_C2};
use super::fq2::Fq2; use super::fq2::Fq2;
use ff::Field; use ff::Field;
use rand_core::RngCore; use rand_core::RngCore;
use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}; use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
/// An element of Fq6, represented by c0 + c1 * v + c2 * v^(2). /// An element of Fq6, represented by c0 + c1 * v + c2 * v^(2).
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
@@ -100,6 +100,18 @@ impl Fq6 {
} }
} }
impl Neg for Fq6 {
type Output = Self;
fn neg(self) -> Self {
Fq6 {
c0: self.c0.neg(),
c1: self.c1.neg(),
c2: self.c2.neg(),
}
}
}
impl<'r> Add<&'r Fq6> for Fq6 { impl<'r> Add<&'r Fq6> for Fq6 {
type Output = Self; type Output = Self;
@@ -280,12 +292,6 @@ impl Field for Fq6 {
self.c2.double(); self.c2.double();
} }
fn negate(&mut self) {
self.c0.negate();
self.c1.negate();
self.c2.negate();
}
fn frobenius_map(&mut self, power: usize) { fn frobenius_map(&mut self, power: usize) {
self.c0.frobenius_map(power); self.c0.frobenius_map(power);
self.c1.frobenius_map(power); self.c1.frobenius_map(power);
@@ -332,7 +338,7 @@ impl Field for Fq6 {
let mut c0 = self.c2; let mut c0 = self.c2;
c0.mul_by_nonresidue(); c0.mul_by_nonresidue();
c0.mul_assign(&self.c1); c0.mul_assign(&self.c1);
c0.negate(); c0 = c0.neg();
{ {
let mut c0s = self.c0; let mut c0s = self.c0;
c0s.square(); c0s.square();

View File

@@ -10,6 +10,8 @@ pub struct Fr(FrRepr);
use rand_core::SeedableRng; use rand_core::SeedableRng;
#[cfg(test)] #[cfg(test)]
use rand_xorshift::XorShiftRng; use rand_xorshift::XorShiftRng;
#[cfg(test)]
use std::ops::Neg;
#[test] #[test]
fn test_fr_repr_ordering() { fn test_fr_repr_ordering() {
@@ -767,10 +769,9 @@ fn test_fr_double() {
} }
#[test] #[test]
fn test_fr_negate() { fn test_fr_neg() {
{ {
let mut a = Fr::zero(); let a = Fr::zero().neg();
a.negate();
assert!(a.is_zero()); assert!(a.is_zero());
} }
@@ -783,8 +784,7 @@ fn test_fr_negate() {
for _ in 0..1000 { for _ in 0..1000 {
// Ensure (a - (-a)) = 0. // Ensure (a - (-a)) = 0.
let mut a = Fr::random(&mut rng); let mut a = Fr::random(&mut rng);
let mut b = a; let b = a.neg();
b.negate();
a.add_assign(&b); a.add_assign(&b);
assert!(a.is_zero()); assert!(a.is_zero());
@@ -832,8 +832,7 @@ fn test_fr_sqrt() {
for _ in 0..1000 { for _ in 0..1000 {
// Ensure sqrt(a^2) = a or -a // Ensure sqrt(a^2) = a or -a
let a = Fr::random(&mut rng); let a = Fr::random(&mut rng);
let mut nega = a; let nega = a.neg();
nega.negate();
let mut b = a; let mut b = a;
b.square(); b.square();

View File

@@ -25,7 +25,7 @@ use super::{Engine, PairingCurveAffine};
use ff::{BitIterator, Field, ScalarEngine}; use ff::{BitIterator, Field, ScalarEngine};
use group::CurveAffine; use group::CurveAffine;
use std::ops::{AddAssign, MulAssign, SubAssign}; use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
// The BLS parameter x for BLS12-381 is -0xd201000000010000 // The BLS parameter x for BLS12-381 is -0xd201000000010000
const BLS_X: u64 = 0xd201000000010000; const BLS_X: u64 = 0xd201000000010000;
@@ -236,7 +236,7 @@ impl G2Prepared {
tmp3 = tmp4; tmp3 = tmp4;
tmp3.mul_assign(&zsquared); tmp3.mul_assign(&zsquared);
tmp3.double(); tmp3.double();
tmp3.negate(); tmp3 = tmp3.neg();
tmp6.square(); tmp6.square();
tmp6.sub_assign(&tmp0); tmp6.sub_assign(&tmp0);
@@ -334,7 +334,7 @@ impl G2Prepared {
t10 = r.z; t10 = r.z;
t10.double(); t10.double();
t6.negate(); t6 = t6.neg();
t1 = t6; t1 = t6;
t1.double(); t1.double();

View File

@@ -36,8 +36,7 @@ pub fn random_sqrt_tests<F: SqrtField>() {
assert_eq!(b.legendre(), LegendreSymbol::QuadraticResidue); assert_eq!(b.legendre(), LegendreSymbol::QuadraticResidue);
let b = b.sqrt().unwrap(); let b = b.sqrt().unwrap();
let mut negb = b; let negb = b.neg();
negb.negate();
assert!(a == b || a == negb); assert!(a == b || a == negb);
} }
@@ -51,7 +50,7 @@ pub fn random_sqrt_tests<F: SqrtField>() {
b = b.sqrt().unwrap(); b = b.sqrt().unwrap();
if b != c { if b != c {
b.negate(); b = b.neg();
} }
assert_eq!(b, c); assert_eq!(b, c);
@@ -77,8 +76,7 @@ pub fn random_field_tests<F: Field>() {
assert!(F::zero().is_zero()); assert!(F::zero().is_zero());
{ {
let mut z = F::zero(); let z = F::zero().neg();
z.negate();
assert!(z.is_zero()); assert!(z.is_zero());
} }
@@ -204,8 +202,7 @@ fn random_subtraction_tests<F: Field, R: RngCore>(rng: &mut R) {
fn random_negation_tests<F: Field, R: RngCore>(rng: &mut R) { fn random_negation_tests<F: Field, R: RngCore>(rng: &mut R) {
for _ in 0..10000 { for _ in 0..10000 {
let a = F::random(rng); let a = F::random(rng);
let mut b = a; let mut b = a.neg();
b.negate();
b.add_assign(&a); b.add_assign(&a);
assert!(b.is_zero()); assert!(b.is_zero());

View File

@@ -1,5 +1,5 @@
use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField}; use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField};
use std::ops::{AddAssign, MulAssign, SubAssign}; use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
use super::{montgomery, JubjubEngine, JubjubParams, PrimeOrder, Unknown}; use super::{montgomery, JubjubEngine, JubjubParams, PrimeOrder, Unknown};
@@ -126,7 +126,7 @@ impl<E: JubjubEngine> Point<E, Unknown> {
match tmp1.sqrt() { match tmp1.sqrt() {
Some(mut x) => { Some(mut x) => {
if x.into_repr().is_odd() != sign { if x.into_repr().is_odd() != sign {
x.negate(); x = x.neg();
} }
let mut t = x; let mut t = x;
@@ -213,12 +213,9 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
// only point of order 2 that is not the neutral element. // only point of order 2 that is not the neutral element.
if y.is_zero() { if y.is_zero() {
// This must be the point (0, 0) as above. // This must be the point (0, 0) as above.
let mut neg1 = E::Fr::one();
neg1.negate();
Point { Point {
x: E::Fr::zero(), x: E::Fr::zero(),
y: neg1, y: E::Fr::one().neg(),
t: E::Fr::zero(), t: E::Fr::zero(),
z: E::Fr::one(), z: E::Fr::one(),
_marker: PhantomData, _marker: PhantomData,
@@ -324,8 +321,8 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
pub fn negate(&self) -> Self { pub fn negate(&self) -> Self {
let mut p = self.clone(); let mut p = self.clone();
p.x.negate(); p.x = p.x.neg();
p.t.negate(); p.t = p.t.neg();
p p
} }
@@ -352,8 +349,7 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
// D = a*A // D = a*A
// = -A // = -A
let mut d = a; let d = a.neg();
d.negate();
// E = (X1+Y1)^2 - A - B // E = (X1+Y1)^2 - A - B
let mut e = self.x; let mut e = self.x;

View File

@@ -5,7 +5,7 @@ use ff::{
PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, SqrtField, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, SqrtField,
}; };
use rand_core::RngCore; use rand_core::RngCore;
use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}; use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use super::ToUniform; use super::ToUniform;
@@ -269,6 +269,20 @@ impl From<Fs> for FsRepr {
} }
} }
impl Neg for Fs {
type Output = Self;
#[inline]
fn neg(mut self) -> Self {
if !self.is_zero() {
let mut tmp = MODULUS;
tmp.sub_noborrow(&self.0);
self.0 = tmp;
}
self
}
}
impl<'r> Add<&'r Fs> for Fs { impl<'r> Add<&'r Fs> for Fs {
type Output = Self; type Output = Self;
@@ -496,15 +510,6 @@ impl Field for Fs {
self.reduce(); self.reduce();
} }
#[inline]
fn negate(&mut self) {
if !self.is_zero() {
let mut tmp = MODULUS;
tmp.sub_noborrow(&self.0);
self.0 = tmp;
}
}
fn inverse(&self) -> Option<Self> { fn inverse(&self) -> Option<Self> {
if self.is_zero() { if self.is_zero() {
None None
@@ -742,8 +747,7 @@ impl SqrtField for Fs {
#[test] #[test]
fn test_neg_one() { fn test_neg_one() {
let mut o = Fs::one(); let o = Fs::one().neg();
o.negate();
assert_eq!(NEGATIVE_ONE, o); assert_eq!(NEGATIVE_ONE, o);
} }
@@ -1471,10 +1475,9 @@ fn test_fs_double() {
} }
#[test] #[test]
fn test_fs_negate() { fn test_fs_neg() {
{ {
let mut a = Fs::zero(); let a = Fs::zero().neg();
a.negate();
assert!(a.is_zero()); assert!(a.is_zero());
} }
@@ -1487,8 +1490,7 @@ fn test_fs_negate() {
for _ in 0..1000 { for _ in 0..1000 {
// Ensure (a - (-a)) = 0. // Ensure (a - (-a)) = 0.
let mut a = Fs::random(&mut rng); let mut a = Fs::random(&mut rng);
let mut b = a; let b = a.neg();
b.negate();
a.add_assign(&b); a.add_assign(&b);
assert!(a.is_zero()); assert!(a.is_zero());
@@ -1534,8 +1536,7 @@ fn test_fs_sqrt() {
for _ in 0..1000 { for _ in 0..1000 {
// Ensure sqrt(a^2) = a or -a // Ensure sqrt(a^2) = a or -a
let a = Fs::random(&mut rng); let a = Fs::random(&mut rng);
let mut nega = a; let nega = a.neg();
nega.negate();
let mut b = a; let mut b = a;
b.square(); b.square();

View File

@@ -1,5 +1,5 @@
use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField}; use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField};
use std::ops::{AddAssign, MulAssign, SubAssign}; use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
use super::{edwards, JubjubEngine, JubjubParams, PrimeOrder, Unknown}; use super::{edwards, JubjubEngine, JubjubParams, PrimeOrder, Unknown};
@@ -62,7 +62,7 @@ impl<E: JubjubEngine> Point<E, Unknown> {
match rhs.sqrt() { match rhs.sqrt() {
Some(mut y) => { Some(mut y) => {
if y.into_repr().is_odd() != sign { if y.into_repr().is_odd() != sign {
y.negate(); y = y.neg();
} }
Some(Point { Some(Point {
@@ -190,7 +190,7 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
pub fn negate(&self) -> Self { pub fn negate(&self) -> Self {
let mut p = self.clone(); let mut p = self.clone();
p.y.negate(); p.y = p.y.neg();
p p
} }
@@ -242,7 +242,7 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
y3.sub_assign(&self.x); y3.sub_assign(&self.x);
y3.mul_assign(&delta); y3.mul_assign(&delta);
y3.add_assign(&self.y); y3.add_assign(&self.y);
y3.negate(); y3 = y3.neg();
Point { Point {
x: x3, x: x3,
@@ -292,7 +292,7 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
y3.sub_assign(&self.x); y3.sub_assign(&self.x);
y3.mul_assign(&delta); y3.mul_assign(&delta);
y3.add_assign(&self.y); y3.add_assign(&self.y);
y3.negate(); y3 = y3.neg();
Point { Point {
x: x3, x: x3,

View File

@@ -1,7 +1,7 @@
use super::{edwards, montgomery, JubjubEngine, JubjubParams, PrimeOrder}; use super::{edwards, montgomery, JubjubEngine, JubjubParams, PrimeOrder};
use ff::{Field, LegendreSymbol, PrimeField, PrimeFieldRepr, SqrtField}; use ff::{Field, LegendreSymbol, PrimeField, PrimeFieldRepr, SqrtField};
use std::ops::{AddAssign, MulAssign, SubAssign}; use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
use rand_core::{RngCore, SeedableRng}; use rand_core::{RngCore, SeedableRng};
use rand_xorshift::XorShiftRng; use rand_xorshift::XorShiftRng;
@@ -310,8 +310,7 @@ fn test_back_and_forth<E: JubjubEngine>(params: &E::Params) {
fn test_jubjub_params<E: JubjubEngine>(params: &E::Params) { fn test_jubjub_params<E: JubjubEngine>(params: &E::Params) {
// a = -1 // a = -1
let mut a = E::Fr::one(); let a = E::Fr::one().neg();
a.negate();
{ {
// Check that 2A is consistent with A // Check that 2A is consistent with A
@@ -339,7 +338,7 @@ fn test_jubjub_params<E: JubjubEngine>(params: &E::Params) {
assert!(tmp.inverse().unwrap().legendre() == LegendreSymbol::QuadraticNonResidue); assert!(tmp.inverse().unwrap().legendre() == LegendreSymbol::QuadraticNonResidue);
// tmp = -d // tmp = -d
tmp.negate(); tmp = tmp.neg();
// -d is nonsquare // -d is nonsquare
assert!(tmp.legendre() == LegendreSymbol::QuadraticNonResidue); assert!(tmp.legendre() == LegendreSymbol::QuadraticNonResidue);

View File

@@ -2,7 +2,7 @@
use crate::jubjub::*; use crate::jubjub::*;
use ff::{Field, PrimeField, PrimeFieldRepr}; use ff::{Field, PrimeField, PrimeFieldRepr};
use std::ops::AddAssign; use std::ops::{AddAssign, Neg};
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum Personalization { pub enum Personalization {
@@ -65,7 +65,7 @@ where
// conditionally negate // conditionally negate
if c { if c {
tmp.negate(); tmp = tmp.neg();
} }
acc.add_assign(&tmp); acc.add_assign(&tmp);

View File

@@ -7,7 +7,7 @@ use crate::jubjub::{edwards::Point, FixedGenerators, JubjubEngine, JubjubParams,
use ff::{Field, PrimeField, PrimeFieldRepr}; use ff::{Field, PrimeField, PrimeFieldRepr};
use rand_core::RngCore; use rand_core::RngCore;
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
use std::ops::{AddAssign, MulAssign}; use std::ops::{AddAssign, MulAssign, Neg};
use crate::util::hash_to_scalar; use crate::util::hash_to_scalar;
@@ -194,7 +194,7 @@ pub fn batch_verify<'a, E: JubjubEngine, R: RngCore>(
let z = E::Fs::random(rng); let z = E::Fs::random(rng);
s.mul_assign(&z); s.mul_assign(&z);
s.negate(); s = s.neg();
r = r.mul(z, params); r = r.mul(z, params);

View File

@@ -2,7 +2,7 @@
use ff::Field; use ff::Field;
use pairing::Engine; use pairing::Engine;
use std::ops::{AddAssign, MulAssign, SubAssign}; use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
use bellman::{ConstraintSystem, SynthesisError}; use bellman::{ConstraintSystem, SynthesisError};
@@ -367,7 +367,7 @@ impl<E: JubjubEngine> EdwardsPoint<E> {
let y3 = AllocatedNum::alloc(cs.namespace(|| "y3"), || { let y3 = AllocatedNum::alloc(cs.namespace(|| "y3"), || {
let mut t0 = *a.get_value().get()?; let mut t0 = *a.get_value().get()?;
t0.double(); t0.double();
t0.negate(); t0 = t0.neg();
t0.add_assign(t.get_value().get()?); t0.add_assign(t.get_value().get()?);
let mut t1 = E::Fr::one(); let mut t1 = E::Fr::one();
@@ -642,7 +642,7 @@ impl<E: JubjubEngine> MontgomeryPoint<E> {
t0.sub_assign(self.x.get_value().get()?); t0.sub_assign(self.x.get_value().get()?);
t0.mul_assign(lambda.get_value().get()?); t0.mul_assign(lambda.get_value().get()?);
t0.add_assign(self.y.get_value().get()?); t0.add_assign(self.y.get_value().get()?);
t0.negate(); t0 = t0.neg();
Ok(t0) Ok(t0)
})?; })?;

View File

@@ -5,7 +5,7 @@ use bellman::{
use ff::Field; use ff::Field;
use pairing::bls12_381::{Bls12, Fr}; use pairing::bls12_381::{Bls12, Fr};
use rand_core::OsRng; use rand_core::OsRng;
use std::ops::AddAssign; use std::ops::{AddAssign, Neg};
use zcash_primitives::{ use zcash_primitives::{
jubjub::{edwards, fs::Fs, FixedGenerators, JubjubBls12, Unknown}, jubjub::{edwards, fs::Fs, FixedGenerators, JubjubBls12, Unknown},
primitives::{Diversifier, Note, PaymentAddress, ProofGenerationKey, ValueCommitment}, primitives::{Diversifier, Note, PaymentAddress, ProofGenerationKey, ValueCommitment},
@@ -202,8 +202,7 @@ impl SaplingProvingContext {
// Accumulate the value commitment randomness in the context // Accumulate the value commitment randomness in the context
{ {
let mut tmp = rcv; let mut tmp = rcv.neg(); // Outputs subtract from the total.
tmp.negate(); // Outputs subtract from the total.
tmp.add_assign(&self.bsk); tmp.add_assign(&self.bsk);
// Update the context // Update the context