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 2f7dd6094c
commit 27c8f34601
35 changed files with 771 additions and 233 deletions

View File

@@ -833,6 +833,119 @@ fn prime_field_impl(
}
}
impl<'r> ::std::ops::Add<&'r #name> for #name {
type Output = #name;
#[inline]
fn add(self, other: &#name) -> #name {
let mut ret = self;
ret.add_assign(other);
ret
}
}
impl ::std::ops::Add for #name {
type Output = #name;
#[inline]
fn add(self, other: #name) -> Self {
self + &other
}
}
impl<'r> ::std::ops::AddAssign<&'r #name> for #name {
#[inline]
fn add_assign(&mut self, other: &#name) {
// This cannot exceed the backing capacity.
self.0.add_nocarry(&other.0);
// However, it may need to be reduced.
self.reduce();
}
}
impl ::std::ops::AddAssign for #name {
#[inline]
fn add_assign(&mut self, other: #name) {
self.add_assign(&other);
}
}
impl<'r> ::std::ops::Sub<&'r #name> for #name {
type Output = #name;
#[inline]
fn sub(self, other: &#name) -> Self {
let mut ret = self;
ret.sub_assign(other);
ret
}
}
impl ::std::ops::Sub for #name {
type Output = #name;
#[inline]
fn sub(self, other: #name) -> Self {
self - &other
}
}
impl<'r> ::std::ops::SubAssign<&'r #name> for #name {
#[inline]
fn sub_assign(&mut self, other: &#name) {
// If `other` is larger than `self`, we'll need to add the modulus to self first.
if other.0 > self.0 {
self.0.add_nocarry(&MODULUS);
}
self.0.sub_noborrow(&other.0);
}
}
impl ::std::ops::SubAssign for #name {
#[inline]
fn sub_assign(&mut self, other: #name) {
self.sub_assign(&other);
}
}
impl<'r> ::std::ops::Mul<&'r #name> for #name {
type Output = #name;
#[inline]
fn mul(self, other: &#name) -> Self {
let mut ret = self;
ret.mul_assign(other);
ret
}
}
impl ::std::ops::Mul for #name {
type Output = #name;
#[inline]
fn mul(self, other: #name) -> Self {
self * &other
}
}
impl<'r> ::std::ops::MulAssign<&'r #name> for #name {
#[inline]
fn mul_assign(&mut self, other: &#name)
{
#multiply_impl
}
}
impl ::std::ops::MulAssign for #name {
#[inline]
fn mul_assign(&mut self, other: #name)
{
self.mul_assign(&other);
}
}
impl ::ff::PrimeField for #name {
type Repr = #repr;
@@ -911,15 +1024,6 @@ fn prime_field_impl(
self.0.is_zero()
}
#[inline]
fn add_assign(&mut self, other: &#name) {
// This cannot exceed the backing capacity.
self.0.add_nocarry(&other.0);
// However, it may need to be reduced.
self.reduce();
}
#[inline]
fn double(&mut self) {
// This cannot exceed the backing capacity.
@@ -929,16 +1033,6 @@ fn prime_field_impl(
self.reduce();
}
#[inline]
fn sub_assign(&mut self, other: &#name) {
// If `other` is larger than `self`, we'll need to add the modulus to self first.
if other.0 > self.0 {
self.0.add_nocarry(&MODULUS);
}
self.0.sub_noborrow(&other.0);
}
#[inline]
fn negate(&mut self) {
if !self.is_zero() {
@@ -1008,12 +1102,6 @@ fn prime_field_impl(
// This has no effect in a prime field.
}
#[inline]
fn mul_assign(&mut self, other: &#name)
{
#multiply_impl
}
#[inline]
fn square(&mut self)
{

View File

@@ -11,10 +11,31 @@ 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};
/// This trait represents an element of a field.
pub trait Field:
Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display + 'static
Sized
+ Eq
+ Copy
+ Clone
+ Send
+ Sync
+ fmt::Debug
+ fmt::Display
+ 'static
+ Add<Output = Self>
+ Sub<Output = Self>
+ Mul<Output = Self>
+ for<'a> Add<&'a Self, Output = Self>
+ for<'a> Mul<&'a Self, Output = Self>
+ for<'a> Sub<&'a Self, Output = Self>
+ MulAssign
+ AddAssign
+ SubAssign
+ for<'a> MulAssign<&'a Self>
+ for<'a> AddAssign<&'a Self>
+ for<'a> SubAssign<&'a Self>
{
/// Returns an element chosen uniformly at random using a user-provided RNG.
fn random<R: RngCore>(rng: &mut R) -> Self;
@@ -37,15 +58,6 @@ pub trait Field:
/// Negates this element.
fn negate(&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);
/// Multiplies another element by this element.
fn mul_assign(&mut self, other: &Self);
/// Computes the multiplicative inverse of this element, if nonzero.
fn inverse(&self) -> Option<Self>;