Make Field::double take &self and return Self

This commit is contained in:
Jack Grigg 2019-12-12 22:59:18 +00:00
parent 91c32f1c7c
commit 9dac748224
No known key found for this signature in database
GPG Key ID: 9E8255172BBF9898
23 changed files with 87 additions and 111 deletions

View File

@ -20,7 +20,7 @@ where
for bit in bits {
num = num.add_bool_with_coeff(CS::one(), bit, coeff);
coeff.double();
coeff = coeff.double();
}
let input = cs.alloc_input(|| format!("input {}", i), || Ok(*num.get_value().get()?))?;
@ -63,7 +63,7 @@ pub fn compute_multipacking<E: ScalarEngine>(bits: &[bool]) -> Vec<E::Fr> {
cur.add_assign(&coeff);
}
coeff.double();
coeff = coeff.double();
}
result.push(cur);

View File

@ -177,7 +177,7 @@ impl<E: ScalarEngine> AllocatedNum<E> {
for bit in result.iter().rev() {
lc = lc + (coeff, bit.get_variable());
coeff.double();
coeff = coeff.double();
}
lc = lc - self.variable;
@ -203,7 +203,7 @@ impl<E: ScalarEngine> AllocatedNum<E> {
for bit in bits.iter() {
lc = lc + (coeff, bit.get_variable());
coeff.double();
coeff = coeff.double();
}
lc = lc - self.variable;

View File

@ -330,7 +330,7 @@ impl UInt32 {
all_constants &= bit.is_constant();
coeff.double();
coeff = coeff.double();
}
}
@ -368,7 +368,7 @@ impl UInt32 {
max_value >>= 1;
i += 1;
coeff.double();
coeff = coeff.double();
}
// Enforce equality between the sum and result

View File

@ -144,8 +144,8 @@ impl Field for Fr {
self.0 = (self.0 * self.0) % MODULUS_R;
}
fn double(&mut self) {
self.0 = (self.0 << 1) % MODULUS_R;
fn double(&self) -> Self {
Fr((self.0 << 1) % MODULUS_R)
}
fn inverse(&self) -> Option<Self> {
@ -406,7 +406,7 @@ impl CurveProjective for Fr {
}
fn double(&mut self) {
<Fr as Field>::double(self);
self.0 = <Fr as Field>::double(self).0;
}
fn add_assign(&mut self, other: &Self) {

View File

@ -1040,12 +1040,16 @@ fn prime_field_impl(
}
#[inline]
fn double(&mut self) {
fn double(&self) -> Self {
let mut ret = *self;
// This cannot exceed the backing capacity.
self.0.mul2();
ret.0.mul2();
// However, it may need to be reduced.
self.reduce();
ret.reduce();
ret
}
fn inverse(&self) -> Option<Self> {

View File

@ -54,7 +54,8 @@ pub trait Field:
fn square(&mut self);
/// Doubles this element.
fn double(&mut self);
#[must_use]
fn double(&self) -> Self;
/// Computes the multiplicative inverse of this element, if nonzero.
fn inverse(&self) -> Option<Self>;

View File

@ -322,11 +322,10 @@ macro_rules! curve_impl {
d.square();
d.sub_assign(&a);
d.sub_assign(&c);
d.double();
d = d.double();
// E = 3*A
let mut e = a;
e.double();
let mut e = a.double();
e.add_assign(&a);
// F = E^2
@ -335,7 +334,7 @@ macro_rules! curve_impl {
// Z3 = 2*Y1*Z1
self.z.mul_assign(&self.y);
self.z.double();
self.z = self.z.double();
// X3 = F-2*D
self.x = f;
@ -346,9 +345,7 @@ macro_rules! curve_impl {
self.y = d;
self.y.sub_assign(&self.x);
self.y.mul_assign(&e);
c.double();
c.double();
c.double();
c = c.double().double().double();
self.y.sub_assign(&c);
}
@ -401,8 +398,7 @@ macro_rules! curve_impl {
h.sub_assign(&u1);
// I = (2*H)^2
let mut i = h;
i.double();
let mut i = h.double();
i.square();
// J = H*I
@ -412,7 +408,7 @@ macro_rules! curve_impl {
// r = 2*(S2-S1)
let mut r = s2;
r.sub_assign(&s1);
r.double();
r = r.double();
// V = U1*I
let mut v = u1;
@ -430,7 +426,7 @@ macro_rules! curve_impl {
self.y.sub_assign(&self.x);
self.y.mul_assign(&r);
s1.mul_assign(&j); // S1 = S1 * J * 2
s1.double();
s1 = s1.double();
self.y.sub_assign(&s1);
// Z3 = ((Z1+Z2)^2 - Z1Z1 - Z2Z2)*H
@ -484,9 +480,7 @@ macro_rules! curve_impl {
hh.square();
// I = 4*HH
let mut i = hh;
i.double();
i.double();
let i = hh.double().double();
// J = H*I
let mut j = h;
@ -495,7 +489,7 @@ macro_rules! curve_impl {
// r = 2*(S2-Y1)
let mut r = s2;
r.sub_assign(&self.y);
r.double();
r = r.double();
// V = X1*I
let mut v = self.x;
@ -510,7 +504,7 @@ macro_rules! curve_impl {
// Y3 = r*(V-X3)-2*Y1*J
j.mul_assign(&self.y); // J = 2*Y1*J
j.double();
j = j.double();
self.y = v;
self.y.sub_assign(&self.x);
self.y.mul_assign(&r);

View File

@ -2001,11 +2001,8 @@ fn test_fq_double() {
for _ in 0..1000 {
// Ensure doubling a is equivalent to adding a to itself.
let mut a = Fq::random(&mut rng);
let mut b = a;
b.add_assign(&a);
a.double();
assert_eq!(a, b);
let a = Fq::random(&mut rng);
assert_eq!(a.double(), a + a);
}
}

View File

@ -183,9 +183,11 @@ impl Field for Fq12 {
self.c0.is_zero() && self.c1.is_zero()
}
fn double(&mut self) {
self.c0.double();
self.c1.double();
fn double(&self) -> Self {
Fq12 {
c0: self.c0.double(),
c1: self.c1.double(),
}
}
fn frobenius_map(&mut self, power: usize) {

View File

@ -213,9 +213,11 @@ impl Field for Fq2 {
self.c0 = c0;
}
fn double(&mut self) {
self.c0.double();
self.c1.double();
fn double(&self) -> Self {
Fq2 {
c0: self.c0.double(),
c1: self.c1.double(),
}
}
fn inverse(&self) -> Option<Self> {
@ -741,7 +743,7 @@ fn test_fq2_doubling() {
use super::fq::FqRepr;
use ff::PrimeField;
let mut a = Fq2 {
let a = Fq2 {
c0: Fq::from_repr(FqRepr([
0x2d0078036923ffc7,
0x11e59ea221a3b6d2,
@ -761,9 +763,8 @@ fn test_fq2_doubling() {
]))
.unwrap(),
};
a.double();
assert_eq!(
a,
a.double(),
Fq2 {
c0: Fq::from_repr(FqRepr([
0x5a00f006d247ff8e,

View File

@ -286,10 +286,12 @@ impl Field for Fq6 {
self.c0.is_zero() && self.c1.is_zero() && self.c2.is_zero()
}
fn double(&mut self) {
self.c0.double();
self.c1.double();
self.c2.double();
fn double(&self) -> Self {
Fq6 {
c0: self.c0.double(),
c1: self.c1.double(),
c2: self.c2.double(),
}
}
fn frobenius_map(&mut self, power: usize) {
@ -306,16 +308,14 @@ impl Field for Fq6 {
s0.square();
let mut ab = self.c0;
ab.mul_assign(&self.c1);
let mut s1 = ab;
s1.double();
let s1 = ab.double();
let mut s2 = self.c0;
s2.sub_assign(&self.c1);
s2.add_assign(&self.c2);
s2.square();
let mut bc = self.c1;
bc.mul_assign(&self.c2);
let mut s3 = bc;
s3.double();
let s3 = bc.double();
let mut s4 = self.c2;
s4.square();

View File

@ -760,11 +760,8 @@ fn test_fr_double() {
for _ in 0..1000 {
// Ensure doubling a is equivalent to adding a to itself.
let mut a = Fr::random(&mut rng);
let mut b = a;
b.add_assign(&a);
a.double();
assert_eq!(a, b);
let a = Fr::random(&mut rng);
assert_eq!(a.double(), a + a);
}
}

View File

@ -199,10 +199,9 @@ impl G2Prepared {
tmp3.square();
tmp3.sub_assign(&tmp0);
tmp3.sub_assign(&tmp2);
tmp3.double();
tmp3 = tmp3.double();
let mut tmp4 = tmp0;
tmp4.double();
let mut tmp4 = tmp0.double();
tmp4.add_assign(&tmp0);
let mut tmp6 = r.x;
@ -227,29 +226,25 @@ impl G2Prepared {
r.y.sub_assign(&r.x);
r.y.mul_assign(&tmp4);
tmp2.double();
tmp2.double();
tmp2.double();
tmp2 = tmp2.double().double().double();
r.y.sub_assign(&tmp2);
tmp3 = tmp4;
tmp3.mul_assign(&zsquared);
tmp3.double();
tmp3 = tmp3.neg();
tmp3 = tmp3.double().neg();
tmp6.square();
tmp6.sub_assign(&tmp0);
tmp6.sub_assign(&tmp5);
tmp1.double();
tmp1.double();
tmp1 = tmp1.double().double();
tmp6.sub_assign(&tmp1);
tmp0 = r.z;
tmp0.mul_assign(&zsquared);
tmp0.double();
tmp0 = tmp0.double();
(tmp0, tmp3, tmp6)
}
@ -278,9 +273,7 @@ impl G2Prepared {
let mut t3 = t2;
t3.square();
let mut t4 = t3;
t4.double();
t4.double();
let t4 = t3.double().double();
let mut t5 = t4;
t5.mul_assign(&t2);
@ -315,7 +308,7 @@ impl G2Prepared {
t0 = r.y;
t0.mul_assign(&t5);
t0.double();
t0 = t0.double();
r.y = t8;
r.y.sub_assign(&t0);
@ -328,16 +321,14 @@ impl G2Prepared {
t10.sub_assign(&ztsquared);
t9.double();
t9 = t9.double();
t9.sub_assign(&t10);
t10 = r.z;
t10.double();
t10 = r.z.double();
t6 = t6.neg();
t1 = t6;
t1.double();
t1 = t6.double();
(t10, t1, t9)
}

View File

@ -211,12 +211,8 @@ fn random_negation_tests<F: Field, R: RngCore>(rng: &mut R) {
fn random_doubling_tests<F: Field, R: RngCore>(rng: &mut R) {
for _ in 0..10000 {
let mut a = F::random(rng);
let mut b = a;
a.add_assign(&b);
b.double();
assert_eq!(a, b);
let a = F::random(rng);
assert_eq!(a + a, a.double());
}
}

View File

@ -345,7 +345,7 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
// C = 2*Z1^2
let mut c = self.z;
c.square();
c.double();
c = c.double();
// D = a*A
// = -A

View File

@ -502,12 +502,16 @@ impl Field for Fs {
}
#[inline]
fn double(&mut self) {
fn double(&self) -> Self {
let mut ret = *self;
// This cannot exceed the backing capacity.
self.0.mul2();
ret.0.mul2();
// However, it may need to be reduced.
self.reduce();
ret.reduce();
ret
}
fn inverse(&self) -> Option<Self> {
@ -680,7 +684,7 @@ impl Fs {
fn mul_bits<S: AsRef<[u64]>>(&self, bits: BitIterator<S>) -> Self {
let mut res = Self::zero();
for bit in bits {
res.double();
res = res.double();
if bit {
res.add_assign(self)
@ -1466,11 +1470,8 @@ fn test_fs_double() {
for _ in 0..1000 {
// Ensure doubling a is equivalent to adding a to itself.
let mut a = Fs::random(&mut rng);
let mut b = a;
b.add_assign(&a);
a.double();
assert_eq!(a, b);
let a = Fs::random(&mut rng);
assert_eq!(a.double(), a + a);
}
}

View File

@ -195,8 +195,7 @@ impl JubjubParams<Bls12> for JubjubBls12 {
impl JubjubBls12 {
pub fn new() -> Self {
let montgomery_a = Fr::from_str("40962").unwrap();
let mut montgomery_2a = montgomery_a;
montgomery_2a.double();
let montgomery_2a = montgomery_a.double();
let mut tmp_params = JubjubBls12 {
// d = -(10240/10241)

View File

@ -216,19 +216,18 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
{
let mut tmp = *params.montgomery_a();
tmp.mul_assign(&self.x);
tmp.double();
tmp = tmp.double();
delta.add_assign(&tmp);
}
{
let mut tmp = self.x;
tmp.square();
delta.add_assign(&tmp);
tmp.double();
tmp = tmp.double();
delta.add_assign(&tmp);
}
{
let mut tmp = self.y;
tmp.double();
let tmp = self.y.double();
delta.mul_assign(&tmp.inverse().expect("y is nonzero so this must be nonzero"));
}

View File

@ -314,10 +314,7 @@ fn test_jubjub_params<E: JubjubEngine>(params: &E::Params) {
{
// Check that 2A is consistent with A
let mut tmp = *params.montgomery_a();
tmp.double();
assert_eq!(&tmp, params.montgomery_2a());
assert_eq!(&params.montgomery_a().double(), params.montgomery_2a());
}
{

View File

@ -58,7 +58,7 @@ where
if a {
tmp.add_assign(&cur);
}
cur.double(); // 2^1 * cur
cur = cur.double(); // 2^1 * cur
if b {
tmp.add_assign(&cur);
}
@ -75,9 +75,7 @@ where
if chunks_remaining == 0 {
break;
} else {
cur.double(); // 2^2 * cur
cur.double(); // 2^3 * cur
cur.double(); // 2^4 * cur
cur = cur.double().double().double(); // 2^4 * cur
}
}

View File

@ -340,7 +340,7 @@ impl<E: JubjubEngine> EdwardsPoint<E> {
// Compute x3 = (2.A) / (1 + C)
let x3 = AllocatedNum::alloc(cs.namespace(|| "x3"), || {
let mut t0 = *a.get_value().get()?;
t0.double();
t0 = t0.double();
let mut t1 = E::Fr::one();
t1.add_assign(c.get_value().get()?);
@ -366,8 +366,7 @@ impl<E: JubjubEngine> EdwardsPoint<E> {
// Compute y3 = (U - 2.A) / (1 - C)
let y3 = AllocatedNum::alloc(cs.namespace(|| "y3"), || {
let mut t0 = *a.get_value().get()?;
t0.double();
t0 = t0.neg();
t0 = t0.double().neg();
t0.add_assign(t.get_value().get()?);
let mut t1 = E::Fr::one();

View File

@ -245,7 +245,7 @@ impl<'a, E: JubjubEngine> Circuit<E> for Spend<'a, E> {
let mut coeff = E::Fr::one();
for bit in &value_bits {
value_num = value_num.add_bool_with_coeff(CS::one(), bit, coeff);
coeff.double();
coeff = coeff.double();
}
// Place the value in the note

View File

@ -268,7 +268,7 @@ impl NoteValue {
let mut coeff = E::Fr::one();
for b in &self.bits {
tmp = tmp + (coeff, b.get_variable());
coeff.double();
coeff = coeff.double();
}
tmp