diff --git a/bellman/src/gadgets/lookup.rs b/bellman/src/gadgets/lookup.rs index 3be3ed957..bde86e2ba 100644 --- a/bellman/src/gadgets/lookup.rs +++ b/bellman/src/gadgets/lookup.rs @@ -1,7 +1,7 @@ //! Window table lookup gadgets. use ff::{Field, ScalarEngine}; -use std::ops::AddAssign; +use std::ops::{AddAssign, Neg}; use super::boolean::Boolean; use super::num::{AllocatedNum, Num}; @@ -16,8 +16,7 @@ where assert_eq!(assignment.len(), 1 << window_size); for (i, constant) in constants.into_iter().enumerate() { - let mut cur = assignment[i]; - cur.negate(); + let mut cur = assignment[i].neg(); cur.add_assign(constant); assignment[i] = cur; for (j, eval) in assignment.iter_mut().enumerate().skip(i + 1) { @@ -151,7 +150,7 @@ where let y = AllocatedNum::alloc(cs.namespace(|| "y"), || { let mut tmp = coords[*i.get()?].1; if *bits[2].get_value().get()? { - tmp.negate(); + tmp = tmp.neg(); } Ok(tmp) })?; @@ -281,7 +280,7 @@ mod test { assert_eq!(res.0.get_value().unwrap(), points[index].0); let mut tmp = points[index].1; if c_val { - tmp.negate() + tmp = tmp.neg() } assert_eq!(res.1.get_value().unwrap(), tmp); } diff --git a/bellman/src/gadgets/num.rs b/bellman/src/gadgets/num.rs index da3e4a060..bce55ced1 100644 --- a/bellman/src/gadgets/num.rs +++ b/bellman/src/gadgets/num.rs @@ -417,7 +417,7 @@ mod test { use pairing::bls12_381::{Bls12, Fr}; use rand_core::SeedableRng; use rand_xorshift::XorShiftRng; - use std::ops::SubAssign; + use std::ops::{Neg, SubAssign}; use super::{AllocatedNum, Boolean}; use crate::gadgets::test::*; @@ -519,8 +519,7 @@ mod test { #[test] fn test_into_bits_strict() { - let mut negone = Fr::one(); - negone.negate(); + let negone = Fr::one().neg(); let mut cs = TestConstraintSystem::::new(); diff --git a/bellman/src/gadgets/test/mod.rs b/bellman/src/gadgets/test/mod.rs index f0668b4a2..f4cc92744 100644 --- a/bellman/src/gadgets/test/mod.rs +++ b/bellman/src/gadgets/test/mod.rs @@ -6,7 +6,7 @@ use crate::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable use std::collections::HashMap; use std::fmt::Write; -use std::ops::{AddAssign, MulAssign}; +use std::ops::{AddAssign, MulAssign, Neg}; use byteorder::{BigEndian, ByteOrder}; use std::cmp::Ordering; @@ -152,11 +152,7 @@ impl TestConstraintSystem { pub fn pretty_print(&self) -> String { let mut s = String::new(); - let negone = { - let mut tmp = E::Fr::one(); - tmp.negate(); - tmp - }; + let negone = E::Fr::one().neg(); let powers_of_two = (0..E::Fr::NUM_BITS) .map(|i| E::Fr::from_str("2").unwrap().pow(&[u64::from(i)])) diff --git a/bellman/src/groth16/tests/dummy_engine.rs b/bellman/src/groth16/tests/dummy_engine.rs index 325c198d2..46641b347 100644 --- a/bellman/src/groth16/tests/dummy_engine.rs +++ b/bellman/src/groth16/tests/dummy_engine.rs @@ -9,7 +9,7 @@ use rand_core::RngCore; use std::cmp::Ordering; use std::fmt; 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 = Wrapping(64513); @@ -22,6 +22,17 @@ impl fmt::Display for Fr { } } +impl Neg for Fr { + type Output = Self; + + fn neg(mut self) -> Self { + if !::is_zero(&self) { + self.0 = MODULUS_R - self.0; + } + self + } +} + impl<'r> Add<&'r Fr> for Fr { type Output = Self; @@ -137,12 +148,6 @@ impl Field for Fr { self.0 = (self.0 << 1) % MODULUS_R; } - fn negate(&mut self) { - if !::is_zero(self) { - self.0 = MODULUS_R - self.0; - } - } - fn inverse(&self) -> Option { if ::is_zero(self) { None @@ -413,7 +418,7 @@ impl CurveProjective for Fr { } fn negate(&mut self) { - ::negate(self); + self.0 = self.neg().0; } fn mul_assign::Repr>>(&mut self, other: S) { @@ -495,7 +500,7 @@ impl CurveAffine for Fr { } fn negate(&mut self) { - ::negate(self); + self.0 = self.neg().0; } fn mul::Repr>>(&self, other: S) -> Self::Projective { diff --git a/bellman/src/lib.rs b/bellman/src/lib.rs index 3877c3f4d..1e48b0c79 100644 --- a/bellman/src/lib.rs +++ b/bellman/src/lib.rs @@ -148,7 +148,7 @@ use std::error::Error; use std::fmt; use std::io; 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 /// rank-1 quadratic constraint systems. The `Circuit` trait represents a @@ -216,10 +216,8 @@ impl Sub<(E::Fr, Variable)> for LinearCombination { type Output = LinearCombination; #[allow(clippy::suspicious_arithmetic_impl)] - fn sub(self, (mut coeff, var): (E::Fr, Variable)) -> LinearCombination { - coeff.negate(); - - self + (coeff, var) + fn sub(self, (coeff, var): (E::Fr, Variable)) -> LinearCombination { + self + (coeff.neg(), var) } } diff --git a/ff/ff_derive/src/lib.rs b/ff/ff_derive/src/lib.rs index b230e7f3e..0e804c786 100644 --- a/ff/ff_derive/src/lib.rs +++ b/ff/ff_derive/src/lib.rs @@ -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 { type Output = #name; @@ -1033,15 +1048,6 @@ fn prime_field_impl( 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 { if self.is_zero() { None diff --git a/ff/src/lib.rs b/ff/src/lib.rs index 71a58704e..c605f6433 100644 --- a/ff/src/lib.rs +++ b/ff/src/lib.rs @@ -11,7 +11,7 @@ use rand_core::RngCore; use std::error::Error; use std::fmt; 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. pub trait Field: @@ -27,6 +27,7 @@ pub trait Field: + Add + Sub + Mul + + Neg + for<'a> Add<&'a Self, Output = Self> + for<'a> Mul<&'a Self, Output = Self> + for<'a> Sub<&'a Self, Output = Self> @@ -55,9 +56,6 @@ pub trait Field: /// Doubles this element. fn double(&mut self); - /// Negates this element. - fn negate(&mut self); - /// Computes the multiplicative inverse of this element, if nonzero. fn inverse(&self) -> Option; diff --git a/group/src/tests/mod.rs b/group/src/tests/mod.rs index 1970667f8..949d934f2 100644 --- a/group/src/tests/mod.rs +++ b/group/src/tests/mod.rs @@ -1,6 +1,7 @@ use ff::{Field, PrimeField}; use rand::SeedableRng; use rand_xorshift::XorShiftRng; +use std::ops::Neg; use crate::{CurveAffine, CurveProjective, EncodedPoint}; @@ -199,8 +200,7 @@ fn random_negation_tests() { let r = G::random(&mut rng); let s = G::Scalar::random(&mut rng); - let mut sneg = s; - sneg.negate(); + let sneg = s.neg(); let mut t1 = r; t1.mul_assign(s); diff --git a/pairing/benches/bls12_381/fq.rs b/pairing/benches/bls12_381/fq.rs index 3ed810aec..046491e28 100644 --- a/pairing/benches/bls12_381/fq.rs +++ b/pairing/benches/bls12_381/fq.rs @@ -1,6 +1,6 @@ use rand_core::SeedableRng; use rand_xorshift::XorShiftRng; -use std::ops::{AddAssign, MulAssign, SubAssign}; +use std::ops::{AddAssign, MulAssign, Neg, SubAssign}; use ff::{Field, PrimeField, PrimeFieldRepr, SqrtField}; use pairing::bls12_381::*; @@ -236,7 +236,7 @@ fn bench_fq_inverse(b: &mut ::test::Bencher) { } #[bench] -fn bench_fq_negate(b: &mut ::test::Bencher) { +fn bench_fq_neg(b: &mut ::test::Bencher) { const SAMPLES: usize = 1000; let mut rng = XorShiftRng::from_seed([ @@ -248,8 +248,7 @@ fn bench_fq_negate(b: &mut ::test::Bencher) { let mut count = 0; b.iter(|| { - let mut tmp = v[count]; - tmp.negate(); + let tmp = v[count].neg(); count = (count + 1) % SAMPLES; tmp }); diff --git a/pairing/benches/bls12_381/fr.rs b/pairing/benches/bls12_381/fr.rs index 590543194..16a5c0854 100644 --- a/pairing/benches/bls12_381/fr.rs +++ b/pairing/benches/bls12_381/fr.rs @@ -1,6 +1,6 @@ use rand_core::SeedableRng; use rand_xorshift::XorShiftRng; -use std::ops::{AddAssign, MulAssign, SubAssign}; +use std::ops::{AddAssign, MulAssign, Neg, SubAssign}; use ff::{Field, PrimeField, PrimeFieldRepr, SqrtField}; use pairing::bls12_381::*; @@ -236,7 +236,7 @@ fn bench_fr_inverse(b: &mut ::test::Bencher) { } #[bench] -fn bench_fr_negate(b: &mut ::test::Bencher) { +fn bench_fr_neg(b: &mut ::test::Bencher) { const SAMPLES: usize = 1000; let mut rng = XorShiftRng::from_seed([ @@ -248,8 +248,7 @@ fn bench_fr_negate(b: &mut ::test::Bencher) { let mut count = 0; b.iter(|| { - let mut tmp = v[count]; - tmp.negate(); + let tmp = v[count].neg(); count = (count + 1) % SAMPLES; tmp }); diff --git a/pairing/src/bls12_381/ec.rs b/pairing/src/bls12_381/ec.rs index 1d740b3a2..c1da107c5 100644 --- a/pairing/src/bls12_381/ec.rs +++ b/pairing/src/bls12_381/ec.rs @@ -107,8 +107,7 @@ macro_rules! curve_impl { x3b.add_assign(&$affine::get_coeff_b()); x3b.sqrt().map(|y| { - let mut negy = y; - negy.negate(); + let negy = y.neg(); $affine { x: x, @@ -171,7 +170,7 @@ macro_rules! curve_impl { fn negate(&mut self) { if !self.is_zero() { - self.y.negate(); + self.y = self.y.neg(); } } @@ -527,7 +526,7 @@ macro_rules! curve_impl { fn negate(&mut self) { 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 rand_core::RngCore; use std::fmt; - use std::ops::{AddAssign, MulAssign, SubAssign}; + use std::ops::{AddAssign, MulAssign, Neg, SubAssign}; curve_impl!( "G1", @@ -849,8 +848,7 @@ pub mod g1 { affine.x.into_repr().write_be(&mut writer).unwrap(); } - let mut negy = affine.y; - negy.negate(); + let negy = affine.y.neg(); // Set the third most significant bit if the correct y-coordinate // is lexicographically largest. @@ -948,8 +946,7 @@ pub mod g1 { if let Some(y) = rhs.sqrt() { let yrepr = y.into_repr(); - let mut negy = y; - negy.negate(); + let negy = y.neg(); let negyrepr = negy.into_repr(); let p = G1Affine { @@ -1297,7 +1294,7 @@ pub mod g2 { use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError}; use rand_core::RngCore; use std::fmt; - use std::ops::{AddAssign, MulAssign, SubAssign}; + use std::ops::{AddAssign, MulAssign, Neg, SubAssign}; curve_impl!( "G2", @@ -1544,8 +1541,7 @@ pub mod g2 { affine.x.c0.into_repr().write_be(&mut writer).unwrap(); } - let mut negy = affine.y; - negy.negate(); + let negy = affine.y.neg(); // Set the third most significant bit if the correct y-coordinate // is lexicographically largest. @@ -1654,8 +1650,7 @@ pub mod g2 { rhs.add_assign(&G2Affine::get_coeff_b()); if let Some(y) = rhs.sqrt() { - let mut negy = y; - negy.negate(); + let negy = y.neg(); let p = G2Affine { x, diff --git a/pairing/src/bls12_381/fq.rs b/pairing/src/bls12_381/fq.rs index ce76b5434..f17a2783b 100644 --- a/pairing/src/bls12_381/fq.rs +++ b/pairing/src/bls12_381/fq.rs @@ -2,6 +2,9 @@ use super::fq2::Fq2; use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr}; use std::ops::{AddAssign, MulAssign, SubAssign}; +#[cfg(test)] +use std::ops::Neg; + // B coefficient of BLS12-381 curve, 4. pub const B_COEFF: Fq = Fq(FqRepr([ 0xaa270000000cfff3, @@ -456,8 +459,7 @@ fn test_b_coeff() { #[test] fn test_frob_coeffs() { - let mut nqr = Fq::one(); - nqr.negate(); + let nqr = Fq::one().neg(); assert_eq!(FROBENIUS_COEFF_FQ2_C1[0], Fq::one()); assert_eq!( @@ -1167,8 +1169,7 @@ fn test_frob_coeffs() { #[test] fn test_neg_one() { - let mut o = Fq::one(); - o.negate(); + let o = Fq::one().neg(); assert_eq!(NEGATIVE_ONE, o); } @@ -2009,10 +2010,9 @@ fn test_fq_double() { } #[test] -fn test_fq_negate() { +fn test_fq_neg() { { - let mut a = Fq::zero(); - a.negate(); + let a = Fq::zero().neg(); assert!(a.is_zero()); } @@ -2025,8 +2025,7 @@ fn test_fq_negate() { for _ in 0..1000 { // Ensure (a - (-a)) = 0. let mut a = Fq::random(&mut rng); - let mut b = a; - b.negate(); + let b = a.neg(); a.add_assign(&b); assert!(a.is_zero()); @@ -2074,8 +2073,7 @@ fn test_fq_sqrt() { for _ in 0..1000 { // Ensure sqrt(a^2) = a or -a let a = Fq::random(&mut rng); - let mut nega = a; - nega.negate(); + let nega = a.neg(); let mut b = a; b.square(); diff --git a/pairing/src/bls12_381/fq12.rs b/pairing/src/bls12_381/fq12.rs index 96b452d74..6bc66a45e 100644 --- a/pairing/src/bls12_381/fq12.rs +++ b/pairing/src/bls12_381/fq12.rs @@ -3,7 +3,7 @@ use super::fq2::Fq2; use super::fq6::Fq6; use ff::Field; 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. #[derive(Copy, Clone, Debug, Eq, PartialEq)] @@ -20,7 +20,7 @@ impl ::std::fmt::Display for Fq12 { impl Fq12 { 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) { @@ -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 { type Output = Self; @@ -177,11 +188,6 @@ impl Field for Fq12 { self.c1.double(); } - fn negate(&mut self) { - self.c0.negate(); - self.c1.negate(); - } - fn frobenius_map(&mut self, power: usize) { self.c0.frobenius_map(power); self.c1.frobenius_map(power); @@ -216,13 +222,9 @@ impl Field for Fq12 { c1s.mul_by_nonresidue(); c0s.sub_assign(&c1s); - c0s.inverse().map(|t| { - let mut tmp = Fq12 { c0: t, c1: t }; - tmp.c0.mul_assign(&self.c0); - tmp.c1.mul_assign(&self.c1); - tmp.c1.negate(); - - tmp + c0s.inverse().map(|t| Fq12 { + c0: t.mul(&self.c0), + c1: t.mul(&self.c1).neg(), }) } } diff --git a/pairing/src/bls12_381/fq2.rs b/pairing/src/bls12_381/fq2.rs index 699707269..e60c374d8 100644 --- a/pairing/src/bls12_381/fq2.rs +++ b/pairing/src/bls12_381/fq2.rs @@ -2,7 +2,7 @@ use super::fq::{Fq, FROBENIUS_COEFF_FQ2_C1, NEGATIVE_ONE}; use ff::{Field, SqrtField}; use rand_core::RngCore; 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. #[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 { type Output = Self; @@ -192,8 +203,7 @@ impl Field for Fq2 { ab.mul_assign(&self.c1); let mut c0c1 = self.c0; c0c1.add_assign(&self.c1); - let mut c0 = self.c1; - c0.negate(); + let mut c0 = self.c1.neg(); c0.add_assign(&self.c0); c0.mul_assign(&c0c1); c0.sub_assign(&ab); @@ -208,27 +218,15 @@ impl Field for Fq2 { self.c1.double(); } - fn negate(&mut self) { - self.c0.negate(); - self.c1.negate(); - } - fn inverse(&self) -> Option { let mut t1 = self.c1; t1.square(); let mut t0 = self.c0; t0.square(); t0.add_assign(&t1); - t0.inverse().map(|t| { - let mut tmp = Fq2 { - c0: self.c0, - c1: self.c1, - }; - tmp.c0.mul_assign(&t); - tmp.c1.mul_assign(&t); - tmp.c1.negate(); - - tmp + t0.inverse().map(|t| Fq2 { + c0: self.c0.mul(&t), + c1: self.c1.mul(&t).neg(), }) } @@ -372,10 +370,8 @@ fn test_fq2_squaring() { }; // u a.square(); assert_eq!(a, { - let mut neg1 = Fq::one(); - neg1.negate(); Fq2 { - c0: neg1, + c0: Fq::one().neg(), c1: Fq::zero(), } }); // -1 @@ -694,7 +690,7 @@ fn test_fq2_negation() { use super::fq::FqRepr; use ff::PrimeField; - let mut a = Fq2 { + let a = Fq2 { c0: Fq::from_repr(FqRepr([ 0x2d0078036923ffc7, 0x11e59ea221a3b6d2, @@ -713,8 +709,8 @@ fn test_fq2_negation() { 0x12d1137b8a6a837, ])) .unwrap(), - }; - a.negate(); + } + .neg(); assert_eq!( a, Fq2 { @@ -1000,8 +996,7 @@ fn test_fq2_legendre() { assert_eq!(Zero, Fq2::zero().legendre()); // i^2 = -1 - let mut m1 = Fq2::one(); - m1.negate(); + let mut m1 = Fq2::one().neg(); assert_eq!(QuadraticResidue, m1.legendre()); m1.mul_by_nonresidue(); assert_eq!(QuadraticNonResidue, m1.legendre()); diff --git a/pairing/src/bls12_381/fq6.rs b/pairing/src/bls12_381/fq6.rs index 444119ac0..a50e283d3 100644 --- a/pairing/src/bls12_381/fq6.rs +++ b/pairing/src/bls12_381/fq6.rs @@ -2,7 +2,7 @@ use super::fq::{FROBENIUS_COEFF_FQ6_C1, FROBENIUS_COEFF_FQ6_C2}; use super::fq2::Fq2; use ff::Field; 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). #[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 { type Output = Self; @@ -280,12 +292,6 @@ impl Field for Fq6 { self.c2.double(); } - fn negate(&mut self) { - self.c0.negate(); - self.c1.negate(); - self.c2.negate(); - } - fn frobenius_map(&mut self, power: usize) { self.c0.frobenius_map(power); self.c1.frobenius_map(power); @@ -332,7 +338,7 @@ impl Field for Fq6 { let mut c0 = self.c2; c0.mul_by_nonresidue(); c0.mul_assign(&self.c1); - c0.negate(); + c0 = c0.neg(); { let mut c0s = self.c0; c0s.square(); diff --git a/pairing/src/bls12_381/fr.rs b/pairing/src/bls12_381/fr.rs index ca9cd575a..d72557e6f 100644 --- a/pairing/src/bls12_381/fr.rs +++ b/pairing/src/bls12_381/fr.rs @@ -10,6 +10,8 @@ pub struct Fr(FrRepr); use rand_core::SeedableRng; #[cfg(test)] use rand_xorshift::XorShiftRng; +#[cfg(test)] +use std::ops::Neg; #[test] fn test_fr_repr_ordering() { @@ -767,10 +769,9 @@ fn test_fr_double() { } #[test] -fn test_fr_negate() { +fn test_fr_neg() { { - let mut a = Fr::zero(); - a.negate(); + let a = Fr::zero().neg(); assert!(a.is_zero()); } @@ -783,8 +784,7 @@ fn test_fr_negate() { for _ in 0..1000 { // Ensure (a - (-a)) = 0. let mut a = Fr::random(&mut rng); - let mut b = a; - b.negate(); + let b = a.neg(); a.add_assign(&b); assert!(a.is_zero()); @@ -832,8 +832,7 @@ fn test_fr_sqrt() { for _ in 0..1000 { // Ensure sqrt(a^2) = a or -a let a = Fr::random(&mut rng); - let mut nega = a; - nega.negate(); + let nega = a.neg(); let mut b = a; b.square(); diff --git a/pairing/src/bls12_381/mod.rs b/pairing/src/bls12_381/mod.rs index 04fd5ee5d..32e23e1a5 100644 --- a/pairing/src/bls12_381/mod.rs +++ b/pairing/src/bls12_381/mod.rs @@ -25,7 +25,7 @@ use super::{Engine, PairingCurveAffine}; use ff::{BitIterator, Field, ScalarEngine}; 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 const BLS_X: u64 = 0xd201000000010000; @@ -236,7 +236,7 @@ impl G2Prepared { tmp3 = tmp4; tmp3.mul_assign(&zsquared); tmp3.double(); - tmp3.negate(); + tmp3 = tmp3.neg(); tmp6.square(); tmp6.sub_assign(&tmp0); @@ -334,7 +334,7 @@ impl G2Prepared { t10 = r.z; t10.double(); - t6.negate(); + t6 = t6.neg(); t1 = t6; t1.double(); diff --git a/pairing/src/tests/field.rs b/pairing/src/tests/field.rs index 8f3d8d9e0..89b203887 100644 --- a/pairing/src/tests/field.rs +++ b/pairing/src/tests/field.rs @@ -36,8 +36,7 @@ pub fn random_sqrt_tests() { assert_eq!(b.legendre(), LegendreSymbol::QuadraticResidue); let b = b.sqrt().unwrap(); - let mut negb = b; - negb.negate(); + let negb = b.neg(); assert!(a == b || a == negb); } @@ -51,7 +50,7 @@ pub fn random_sqrt_tests() { b = b.sqrt().unwrap(); if b != c { - b.negate(); + b = b.neg(); } assert_eq!(b, c); @@ -77,8 +76,7 @@ pub fn random_field_tests() { assert!(F::zero().is_zero()); { - let mut z = F::zero(); - z.negate(); + let z = F::zero().neg(); assert!(z.is_zero()); } @@ -204,8 +202,7 @@ fn random_subtraction_tests(rng: &mut R) { fn random_negation_tests(rng: &mut R) { for _ in 0..10000 { let a = F::random(rng); - let mut b = a; - b.negate(); + let mut b = a.neg(); b.add_assign(&a); assert!(b.is_zero()); diff --git a/zcash_primitives/src/jubjub/edwards.rs b/zcash_primitives/src/jubjub/edwards.rs index 2865ce3d4..8c7df4c71 100644 --- a/zcash_primitives/src/jubjub/edwards.rs +++ b/zcash_primitives/src/jubjub/edwards.rs @@ -1,5 +1,5 @@ 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}; @@ -126,7 +126,7 @@ impl Point { match tmp1.sqrt() { Some(mut x) => { if x.into_repr().is_odd() != sign { - x.negate(); + x = x.neg(); } let mut t = x; @@ -213,12 +213,9 @@ impl Point { // only point of order 2 that is not the neutral element. if y.is_zero() { // This must be the point (0, 0) as above. - let mut neg1 = E::Fr::one(); - neg1.negate(); - Point { x: E::Fr::zero(), - y: neg1, + y: E::Fr::one().neg(), t: E::Fr::zero(), z: E::Fr::one(), _marker: PhantomData, @@ -324,8 +321,8 @@ impl Point { pub fn negate(&self) -> Self { let mut p = self.clone(); - p.x.negate(); - p.t.negate(); + p.x = p.x.neg(); + p.t = p.t.neg(); p } @@ -352,8 +349,7 @@ impl Point { // D = a*A // = -A - let mut d = a; - d.negate(); + let d = a.neg(); // E = (X1+Y1)^2 - A - B let mut e = self.x; diff --git a/zcash_primitives/src/jubjub/fs.rs b/zcash_primitives/src/jubjub/fs.rs index ddd2bceb1..53d0ee355 100644 --- a/zcash_primitives/src/jubjub/fs.rs +++ b/zcash_primitives/src/jubjub/fs.rs @@ -5,7 +5,7 @@ use ff::{ PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, SqrtField, }; 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; @@ -269,6 +269,20 @@ impl From 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 { type Output = Self; @@ -496,15 +510,6 @@ impl Field for Fs { 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 { if self.is_zero() { None @@ -742,8 +747,7 @@ impl SqrtField for Fs { #[test] fn test_neg_one() { - let mut o = Fs::one(); - o.negate(); + let o = Fs::one().neg(); assert_eq!(NEGATIVE_ONE, o); } @@ -1471,10 +1475,9 @@ fn test_fs_double() { } #[test] -fn test_fs_negate() { +fn test_fs_neg() { { - let mut a = Fs::zero(); - a.negate(); + let a = Fs::zero().neg(); assert!(a.is_zero()); } @@ -1487,8 +1490,7 @@ fn test_fs_negate() { for _ in 0..1000 { // Ensure (a - (-a)) = 0. let mut a = Fs::random(&mut rng); - let mut b = a; - b.negate(); + let b = a.neg(); a.add_assign(&b); assert!(a.is_zero()); @@ -1534,8 +1536,7 @@ fn test_fs_sqrt() { for _ in 0..1000 { // Ensure sqrt(a^2) = a or -a let a = Fs::random(&mut rng); - let mut nega = a; - nega.negate(); + let nega = a.neg(); let mut b = a; b.square(); diff --git a/zcash_primitives/src/jubjub/montgomery.rs b/zcash_primitives/src/jubjub/montgomery.rs index fc412742d..18acc0d50 100644 --- a/zcash_primitives/src/jubjub/montgomery.rs +++ b/zcash_primitives/src/jubjub/montgomery.rs @@ -1,5 +1,5 @@ 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}; @@ -62,7 +62,7 @@ impl Point { match rhs.sqrt() { Some(mut y) => { if y.into_repr().is_odd() != sign { - y.negate(); + y = y.neg(); } Some(Point { @@ -190,7 +190,7 @@ impl Point { pub fn negate(&self) -> Self { let mut p = self.clone(); - p.y.negate(); + p.y = p.y.neg(); p } @@ -242,7 +242,7 @@ impl Point { y3.sub_assign(&self.x); y3.mul_assign(&delta); y3.add_assign(&self.y); - y3.negate(); + y3 = y3.neg(); Point { x: x3, @@ -292,7 +292,7 @@ impl Point { y3.sub_assign(&self.x); y3.mul_assign(&delta); y3.add_assign(&self.y); - y3.negate(); + y3 = y3.neg(); Point { x: x3, diff --git a/zcash_primitives/src/jubjub/tests.rs b/zcash_primitives/src/jubjub/tests.rs index 56fad56ab..d1527378f 100644 --- a/zcash_primitives/src/jubjub/tests.rs +++ b/zcash_primitives/src/jubjub/tests.rs @@ -1,7 +1,7 @@ use super::{edwards, montgomery, JubjubEngine, JubjubParams, PrimeOrder}; 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_xorshift::XorShiftRng; @@ -310,8 +310,7 @@ fn test_back_and_forth(params: &E::Params) { fn test_jubjub_params(params: &E::Params) { // a = -1 - let mut a = E::Fr::one(); - a.negate(); + let a = E::Fr::one().neg(); { // Check that 2A is consistent with A @@ -339,7 +338,7 @@ fn test_jubjub_params(params: &E::Params) { assert!(tmp.inverse().unwrap().legendre() == LegendreSymbol::QuadraticNonResidue); // tmp = -d - tmp.negate(); + tmp = tmp.neg(); // -d is nonsquare assert!(tmp.legendre() == LegendreSymbol::QuadraticNonResidue); diff --git a/zcash_primitives/src/pedersen_hash.rs b/zcash_primitives/src/pedersen_hash.rs index 5fb73339f..d12b6a407 100644 --- a/zcash_primitives/src/pedersen_hash.rs +++ b/zcash_primitives/src/pedersen_hash.rs @@ -2,7 +2,7 @@ use crate::jubjub::*; use ff::{Field, PrimeField, PrimeFieldRepr}; -use std::ops::AddAssign; +use std::ops::{AddAssign, Neg}; #[derive(Copy, Clone)] pub enum Personalization { @@ -65,7 +65,7 @@ where // conditionally negate if c { - tmp.negate(); + tmp = tmp.neg(); } acc.add_assign(&tmp); diff --git a/zcash_primitives/src/redjubjub.rs b/zcash_primitives/src/redjubjub.rs index 61586856e..4633d6d6f 100644 --- a/zcash_primitives/src/redjubjub.rs +++ b/zcash_primitives/src/redjubjub.rs @@ -7,7 +7,7 @@ use crate::jubjub::{edwards::Point, FixedGenerators, JubjubEngine, JubjubParams, use ff::{Field, PrimeField, PrimeFieldRepr}; use rand_core::RngCore; use std::io::{self, Read, Write}; -use std::ops::{AddAssign, MulAssign}; +use std::ops::{AddAssign, MulAssign, Neg}; 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); s.mul_assign(&z); - s.negate(); + s = s.neg(); r = r.mul(z, params); diff --git a/zcash_proofs/src/circuit/ecc.rs b/zcash_proofs/src/circuit/ecc.rs index a35dfd779..7072f0147 100644 --- a/zcash_proofs/src/circuit/ecc.rs +++ b/zcash_proofs/src/circuit/ecc.rs @@ -2,7 +2,7 @@ use ff::Field; use pairing::Engine; -use std::ops::{AddAssign, MulAssign, SubAssign}; +use std::ops::{AddAssign, MulAssign, Neg, SubAssign}; use bellman::{ConstraintSystem, SynthesisError}; @@ -367,7 +367,7 @@ impl EdwardsPoint { let y3 = AllocatedNum::alloc(cs.namespace(|| "y3"), || { let mut t0 = *a.get_value().get()?; t0.double(); - t0.negate(); + t0 = t0.neg(); t0.add_assign(t.get_value().get()?); let mut t1 = E::Fr::one(); @@ -642,7 +642,7 @@ impl MontgomeryPoint { t0.sub_assign(self.x.get_value().get()?); t0.mul_assign(lambda.get_value().get()?); t0.add_assign(self.y.get_value().get()?); - t0.negate(); + t0 = t0.neg(); Ok(t0) })?; diff --git a/zcash_proofs/src/sapling/prover.rs b/zcash_proofs/src/sapling/prover.rs index e695ba12f..16424cca8 100644 --- a/zcash_proofs/src/sapling/prover.rs +++ b/zcash_proofs/src/sapling/prover.rs @@ -5,7 +5,7 @@ use bellman::{ use ff::Field; use pairing::bls12_381::{Bls12, Fr}; use rand_core::OsRng; -use std::ops::AddAssign; +use std::ops::{AddAssign, Neg}; use zcash_primitives::{ jubjub::{edwards, fs::Fs, FixedGenerators, JubjubBls12, Unknown}, primitives::{Diversifier, Note, PaymentAddress, ProofGenerationKey, ValueCommitment}, @@ -202,8 +202,7 @@ impl SaplingProvingContext { // Accumulate the value commitment randomness in the context { - let mut tmp = rcv; - tmp.negate(); // Outputs subtract from the total. + let mut tmp = rcv.neg(); // Outputs subtract from the total. tmp.add_assign(&self.bsk); // Update the context