ff: Remove PrimeFieldRepr trait

The ff::PrimeField::Repr associated type now has the minimal necessary
bounds, which can be satisfied by a newtype around a byte array.
This commit is contained in:
Jack Grigg
2020-04-23 17:32:04 +12:00
parent 1fe3e3784c
commit 49f119fb03
35 changed files with 1705 additions and 3634 deletions

View File

@@ -12,6 +12,7 @@ extern crate std;
#[cfg(feature = "derive")]
pub use ff_derive::*;
use core::convert::TryFrom;
use core::fmt;
use core::marker::PhantomData;
use core::ops::{Add, AddAssign, BitAnd, Mul, MulAssign, Neg, Shr, Sub, SubAssign};
@@ -130,139 +131,13 @@ pub trait SqrtField: Field {
fn sqrt(&self) -> CtOption<Self>;
}
/// This trait represents a wrapper around a biginteger which can encode any element of a particular
/// prime field. It is a smart wrapper around a sequence of `u64` limbs, least-significant digit
/// first.
pub trait PrimeFieldRepr:
Sized
+ Copy
+ Clone
+ Eq
+ Ord
+ Send
+ Sync
+ Default
+ fmt::Debug
+ fmt::Display
+ 'static
+ AsRef<[u64]>
+ AsMut<[u64]>
+ From<u64>
{
/// Subtract another represetation from this one.
fn sub_noborrow(&mut self, other: &Self);
/// Add another representation to this one.
fn add_nocarry(&mut self, other: &Self);
/// Compute the number of bits needed to encode this number. Always a
/// multiple of 64.
fn num_bits(&self) -> u32;
/// Returns true iff this number is zero.
fn is_zero(&self) -> bool;
/// Returns true iff this number is odd.
fn is_odd(&self) -> bool;
/// Returns true iff this number is even.
fn is_even(&self) -> bool;
/// Performs a rightwise bitshift of this number, effectively dividing
/// it by 2.
fn div2(&mut self);
/// Performs a rightwise bitshift of this number by some amount.
fn shr(&mut self, amt: u32);
/// Performs a leftwise bitshift of this number, effectively multiplying
/// it by 2. Overflow is ignored.
fn mul2(&mut self);
/// Performs a leftwise bitshift of this number by some amount.
fn shl(&mut self, amt: u32);
/// Writes this `PrimeFieldRepr` as a big endian integer.
#[cfg(feature = "std")]
fn write_be<W: Write>(&self, mut writer: W) -> io::Result<()> {
use byteorder::{BigEndian, WriteBytesExt};
for digit in self.as_ref().iter().rev() {
writer.write_u64::<BigEndian>(*digit)?;
}
Ok(())
}
/// Reads a big endian integer into this representation.
#[cfg(feature = "std")]
fn read_be<R: Read>(&mut self, mut reader: R) -> io::Result<()> {
use byteorder::{BigEndian, ReadBytesExt};
for digit in self.as_mut().iter_mut().rev() {
*digit = reader.read_u64::<BigEndian>()?;
}
Ok(())
}
/// Writes this `PrimeFieldRepr` as a little endian integer.
#[cfg(feature = "std")]
fn write_le<W: Write>(&self, mut writer: W) -> io::Result<()> {
use byteorder::{LittleEndian, WriteBytesExt};
for digit in self.as_ref().iter() {
writer.write_u64::<LittleEndian>(*digit)?;
}
Ok(())
}
/// Reads a little endian integer into this representation.
#[cfg(feature = "std")]
fn read_le<R: Read>(&mut self, mut reader: R) -> io::Result<()> {
use byteorder::{LittleEndian, ReadBytesExt};
for digit in self.as_mut().iter_mut() {
*digit = reader.read_u64::<LittleEndian>()?;
}
Ok(())
}
}
/// An error that may occur when trying to interpret a `PrimeFieldRepr` as a
/// `PrimeField` element.
#[derive(Debug)]
pub enum PrimeFieldDecodingError {
/// The encoded value is not in the field
NotInField,
}
#[cfg(feature = "std")]
impl std::error::Error for PrimeFieldDecodingError {
fn description(&self) -> &str {
match *self {
PrimeFieldDecodingError::NotInField => "not an element of the field",
}
}
}
impl fmt::Display for PrimeFieldDecodingError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match *self {
PrimeFieldDecodingError::NotInField => write!(f, "not an element of the field"),
}
}
}
/// This represents an element of a prime field.
pub trait PrimeField:
Field + Ord + From<u64> + BitAnd<u64, Output = u64> + Shr<u32, Output = Self>
{
/// The prime field can be converted back and forth into this biginteger
/// The prime field can be converted back and forth into this binary
/// representation.
type Repr: PrimeFieldRepr + From<Self>;
type Repr: Default + AsRef<[u8]> + AsMut<[u8]> + From<Self> + for<'r> From<&'r Self>;
/// Interpret a string of numbers as a (congruent) prime field element.
/// Does not accept unnecessary leading zeroes or a blank string.
@@ -304,11 +179,20 @@ pub trait PrimeField:
Some(res)
}
/// Convert this prime field element into a biginteger representation.
fn from_repr(_: Self::Repr) -> Result<Self, PrimeFieldDecodingError>;
/// Attempts to convert a byte representation of a field element into an element of
/// this prime field, failing if the input is not canonical (is not smaller than the
/// field's modulus).
///
/// The byte representation is interpreted with the same endianness as is returned
/// by [`PrimeField::into_repr`].
fn from_repr(_: Self::Repr) -> Option<Self>;
/// Convert a biginteger representation into a prime field element, if
/// the number is an element of the field.
/// Converts an element of the prime field into the standard byte representation for
/// this field.
///
/// Endianness of the byte representation is defined by the field implementation.
/// Callers should assume that it is the standard endianness used to represent encoded
/// elements of this particular field.
fn into_repr(&self) -> Self::Repr;
/// Returns true iff this element is odd.