Move Field operations to operator-backed traits

The ff_derive, pairing, zcash_primitives::jubjub, and bellman dummy_engine
changes are minimally implemented on top of the existing *_assign()
functions.
This commit is contained in:
Jack Grigg 2019-12-12 20:57:06 +00:00
parent 0aab37f418
commit c05b957e9d
12 changed files with 111 additions and 23 deletions

View File

@ -13,6 +13,7 @@
use ff::{Field, PrimeField, ScalarEngine};
use group::CurveProjective;
use std::ops::{AddAssign, MulAssign, SubAssign};
use super::SynthesisError;

View File

@ -1,6 +1,7 @@
//! Window table lookup gadgets.
use ff::{Field, ScalarEngine};
use std::ops::AddAssign;
use super::boolean::Boolean;
use super::num::{AllocatedNum, Num};

View File

@ -5,6 +5,7 @@ use super::num::Num;
use super::Assignment;
use crate::{ConstraintSystem, SynthesisError};
use ff::{Field, PrimeField, ScalarEngine};
use std::ops::AddAssign;
/// Takes a sequence of booleans and exposes them as compact
/// public inputs

View File

@ -1,6 +1,7 @@
//! Gadgets representing numbers in the scalar field of the underlying curve.
use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, ScalarEngine};
use std::ops::{AddAssign, MulAssign};
use crate::{ConstraintSystem, LinearCombination, SynthesisError, Variable};
@ -416,6 +417,7 @@ mod test {
use pairing::bls12_381::{Bls12, Fr};
use rand_core::SeedableRng;
use rand_xorshift::XorShiftRng;
use std::ops::SubAssign;
use super::{AllocatedNum, Boolean};
use crate::gadgets::test::*;

View File

@ -6,6 +6,7 @@ use crate::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable
use std::collections::HashMap;
use std::fmt::Write;
use std::ops::{AddAssign, MulAssign};
use byteorder::{BigEndian, ByteOrder};
use std::cmp::Ordering;

View File

@ -1,5 +1,5 @@
use rand_core::RngCore;
use std::ops::{AddAssign, MulAssign};
use std::sync::Arc;
use ff::{Field, PrimeField};

View File

@ -474,6 +474,7 @@ mod test_with_bls12_381 {
use ff::Field;
use pairing::bls12_381::{Bls12, Fr};
use rand::thread_rng;
use std::ops::MulAssign;
#[test]
fn serialization() {

View File

@ -1,5 +1,5 @@
use rand_core::RngCore;
use std::ops::{AddAssign, MulAssign};
use std::sync::Arc;
use futures::Future;

View File

@ -9,6 +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};
const MODULUS_R: Wrapping<u32> = Wrapping(64513);
@ -21,6 +22,96 @@ impl fmt::Display for Fr {
}
}
impl<'r> Add<&'r Fr> for Fr {
type Output = Self;
fn add(self, other: &Self) -> Self {
let mut ret = self;
AddAssign::add_assign(&mut ret, other);
ret
}
}
impl Add for Fr {
type Output = Self;
fn add(self, other: Self) -> Self {
self + &other
}
}
impl<'r> AddAssign<&'r Fr> for Fr {
fn add_assign(&mut self, other: &Self) {
self.0 = (self.0 + other.0) % MODULUS_R;
}
}
impl AddAssign for Fr {
fn add_assign(&mut self, other: Self) {
AddAssign::add_assign(self, &other);
}
}
impl<'r> Sub<&'r Fr> for Fr {
type Output = Self;
fn sub(self, other: &Self) -> Self {
let mut ret = self;
SubAssign::sub_assign(&mut ret, other);
ret
}
}
impl Sub for Fr {
type Output = Self;
fn sub(self, other: Self) -> Self {
self - &other
}
}
impl<'r> SubAssign<&'r Fr> for Fr {
fn sub_assign(&mut self, other: &Self) {
self.0 = ((MODULUS_R + self.0) - other.0) % MODULUS_R;
}
}
impl SubAssign for Fr {
fn sub_assign(&mut self, other: Self) {
SubAssign::sub_assign(self, &other);
}
}
impl<'r> Mul<&'r Fr> for Fr {
type Output = Self;
fn mul(self, other: &Self) -> Self {
let mut ret = self;
MulAssign::mul_assign(&mut ret, other);
ret
}
}
impl Mul for Fr {
type Output = Self;
fn mul(self, other: Self) -> Self {
self * &other
}
}
impl<'r> MulAssign<&'r Fr> for Fr {
fn mul_assign(&mut self, other: &Self) {
self.0 = (self.0 * other.0) % MODULUS_R;
}
}
impl MulAssign for Fr {
fn mul_assign(&mut self, other: Self) {
MulAssign::mul_assign(self, &other);
}
}
impl Field for Fr {
fn random<R: RngCore + ?std::marker::Sized>(rng: &mut R) -> Self {
Fr(Wrapping(rng.next_u32()) % MODULUS_R)
@ -52,18 +143,6 @@ impl Field for Fr {
}
}
fn add_assign(&mut self, other: &Self) {
self.0 = (self.0 + other.0) % MODULUS_R;
}
fn sub_assign(&mut self, other: &Self) {
self.0 = ((MODULUS_R + self.0) - other.0) % MODULUS_R;
}
fn mul_assign(&mut self, other: &Self) {
self.0 = (self.0 * other.0) % MODULUS_R;
}
fn inverse(&self) -> Option<Self> {
if <Fr as Field>::is_zero(self) {
None
@ -121,9 +200,9 @@ impl SqrtField for Fr {
for _ in 0..(m - i - 1) {
c.square();
}
<Fr as Field>::mul_assign(&mut r, &c);
MulAssign::mul_assign(&mut r, &c);
c.square();
<Fr as Field>::mul_assign(&mut t, &c);
MulAssign::mul_assign(&mut t, &c);
m = i;
}
@ -280,8 +359,8 @@ impl Engine for DummyEngine {
for &(a, b) in i {
let mut tmp = *a;
<Fr as Field>::mul_assign(&mut tmp, b);
<Fr as Field>::add_assign(&mut acc, &tmp);
MulAssign::mul_assign(&mut tmp, b);
AddAssign::add_assign(&mut acc, &tmp);
}
acc
@ -326,11 +405,11 @@ impl CurveProjective for Fr {
}
fn add_assign(&mut self, other: &Self) {
<Fr as Field>::add_assign(self, other);
AddAssign::add_assign(self, other);
}
fn add_assign_mixed(&mut self, other: &Self) {
<Fr as Field>::add_assign(self, other);
AddAssign::add_assign(self, other);
}
fn negate(&mut self) {
@ -340,7 +419,7 @@ impl CurveProjective for Fr {
fn mul_assign<S: Into<<Self::Scalar as PrimeField>::Repr>>(&mut self, other: S) {
let tmp = Fr::from_repr(other.into()).unwrap();
<Fr as Field>::mul_assign(self, &tmp);
MulAssign::mul_assign(self, &tmp);
}
fn into_affine(&self) -> Fr {
@ -423,7 +502,7 @@ impl CurveAffine for Fr {
let mut res = *self;
let tmp = Fr::from_repr(other.into()).unwrap();
<Fr as Field>::mul_assign(&mut res, &tmp);
MulAssign::mul_assign(&mut res, &tmp);
res
}

View File

@ -5,6 +5,7 @@ mod dummy_engine;
use self::dummy_engine::*;
use std::marker::PhantomData;
use std::ops::{AddAssign, MulAssign, SubAssign};
use crate::{Circuit, ConstraintSystem, SynthesisError};

View File

@ -161,7 +161,7 @@ use std::error::Error;
use std::fmt;
use std::io;
use std::marker::PhantomData;
use std::ops::{Add, Sub};
use std::ops::{Add, MulAssign, Sub};
/// Computations are expressed in terms of arithmetic circuits, in particular
/// rank-1 quadratic constraint systems. The `Circuit` trait represents a

View File

@ -7,6 +7,7 @@ use std::time::{Duration, Instant};
// Bring in some tools for using pairing-friendly curves
use ff::{Field, ScalarEngine};
use pairing::Engine;
use std::ops::{AddAssign, MulAssign};
// We're going to use the BLS12-381 pairing-friendly elliptic curve.
use pairing::bls12_381::Bls12;