mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-11-01 20:07:02 +00:00
Pull in trait changes from pairing
This commit is contained in:
@@ -9,6 +9,7 @@ license = "MIT/Apache-2.0"
|
|||||||
repository = "https://github.com/ebfull/ff"
|
repository = "https://github.com/ebfull/ff"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
byteorder = "1"
|
||||||
rand = "0.3"
|
rand = "0.3"
|
||||||
ff_derive = { version = "0.2.0", path = "ff_derive" }
|
ff_derive = { version = "0.2.0", path = "ff_derive" }
|
||||||
|
|
||||||
|
|||||||
180
src/lib.rs
180
src/lib.rs
@@ -1,6 +1,6 @@
|
|||||||
#![feature(i128_type)]
|
|
||||||
#![allow(unused_imports)]
|
#![allow(unused_imports)]
|
||||||
|
|
||||||
|
extern crate byteorder;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@@ -8,11 +8,13 @@ extern crate ff_derive;
|
|||||||
|
|
||||||
pub use ff_derive::*;
|
pub use ff_derive::*;
|
||||||
|
|
||||||
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::io::{self, Read, Write};
|
||||||
|
|
||||||
/// This trait represents an element of a field.
|
/// This trait represents an element of a field.
|
||||||
pub trait Field:
|
pub trait Field:
|
||||||
Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + 'static + rand::Rand
|
Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display + 'static + rand::Rand
|
||||||
{
|
{
|
||||||
/// Returns the zero element of the field, the additive identity.
|
/// Returns the zero element of the field, the additive identity.
|
||||||
fn zero() -> Self;
|
fn zero() -> Self;
|
||||||
@@ -53,8 +55,15 @@ pub trait Field:
|
|||||||
fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
|
fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
|
||||||
let mut res = Self::one();
|
let mut res = Self::one();
|
||||||
|
|
||||||
|
let mut found_one = false;
|
||||||
|
|
||||||
for i in BitIterator::new(exp) {
|
for i in BitIterator::new(exp) {
|
||||||
res.square();
|
if found_one {
|
||||||
|
res.square();
|
||||||
|
} else {
|
||||||
|
found_one = i;
|
||||||
|
}
|
||||||
|
|
||||||
if i {
|
if i {
|
||||||
res.mul_assign(self);
|
res.mul_assign(self);
|
||||||
}
|
}
|
||||||
@@ -66,6 +75,9 @@ pub trait Field:
|
|||||||
|
|
||||||
/// This trait represents an element of a field that has a square root operation described for it.
|
/// This trait represents an element of a field that has a square root operation described for it.
|
||||||
pub trait SqrtField: Field {
|
pub trait SqrtField: Field {
|
||||||
|
/// Returns the Legendre symbol of the field element.
|
||||||
|
fn legendre(&self) -> LegendreSymbol;
|
||||||
|
|
||||||
/// Returns the square root of the field element, if it is
|
/// Returns the square root of the field element, if it is
|
||||||
/// quadratic residue.
|
/// quadratic residue.
|
||||||
fn sqrt(&self) -> Option<Self>;
|
fn sqrt(&self) -> Option<Self>;
|
||||||
@@ -82,19 +94,23 @@ pub trait PrimeFieldRepr:
|
|||||||
+ Ord
|
+ Ord
|
||||||
+ Send
|
+ Send
|
||||||
+ Sync
|
+ Sync
|
||||||
|
+ Default
|
||||||
+ fmt::Debug
|
+ fmt::Debug
|
||||||
|
+ fmt::Display
|
||||||
+ 'static
|
+ 'static
|
||||||
+ rand::Rand
|
+ rand::Rand
|
||||||
+ AsRef<[u64]>
|
+ AsRef<[u64]>
|
||||||
|
+ AsMut<[u64]>
|
||||||
+ From<u64>
|
+ From<u64>
|
||||||
{
|
{
|
||||||
/// Subtract another reprensetation from this one, returning the borrow bit.
|
/// Subtract another represetation from this one.
|
||||||
fn sub_noborrow(&mut self, other: &Self) -> bool;
|
fn sub_noborrow(&mut self, other: &Self);
|
||||||
|
|
||||||
/// Add another representation to this one, returning the carry bit.
|
/// Add another representation to this one.
|
||||||
fn add_nocarry(&mut self, other: &Self) -> bool;
|
fn add_nocarry(&mut self, other: &Self);
|
||||||
|
|
||||||
/// Compute the number of bits needed to encode this number.
|
/// Compute the number of bits needed to encode this number. Always a
|
||||||
|
/// multiple of 64.
|
||||||
fn num_bits(&self) -> u32;
|
fn num_bits(&self) -> u32;
|
||||||
|
|
||||||
/// Returns true iff this number is zero.
|
/// Returns true iff this number is zero.
|
||||||
@@ -110,57 +126,179 @@ pub trait PrimeFieldRepr:
|
|||||||
/// it by 2.
|
/// it by 2.
|
||||||
fn div2(&mut self);
|
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
|
/// Performs a leftwise bitshift of this number, effectively multiplying
|
||||||
/// it by 2. Overflow is ignored.
|
/// it by 2. Overflow is ignored.
|
||||||
fn mul2(&mut self);
|
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.
|
||||||
|
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.
|
||||||
|
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.
|
||||||
|
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.
|
||||||
|
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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum LegendreSymbol {
|
||||||
|
Zero = 0,
|
||||||
|
QuadraticResidue = 1,
|
||||||
|
QuadraticNonResidue = -1,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl 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(ref repr) => {
|
||||||
|
write!(f, "{} is not an element of the field", repr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This represents an element of a prime field.
|
/// This represents an element of a prime field.
|
||||||
pub trait PrimeField: Field {
|
pub trait PrimeField: Field {
|
||||||
/// The prime field can be converted back and forth into this biginteger
|
/// The prime field can be converted back and forth into this biginteger
|
||||||
/// representation.
|
/// representation.
|
||||||
type Repr: PrimeFieldRepr;
|
type Repr: PrimeFieldRepr + From<Self>;
|
||||||
|
|
||||||
|
/// Interpret a string of numbers as a (congruent) prime field element.
|
||||||
|
/// Does not accept unnecessary leading zeroes or a blank string.
|
||||||
|
fn from_str(s: &str) -> Option<Self> {
|
||||||
|
if s.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if s == "0" {
|
||||||
|
return Some(Self::zero());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut res = Self::zero();
|
||||||
|
|
||||||
|
let ten = Self::from_repr(Self::Repr::from(10)).unwrap();
|
||||||
|
|
||||||
|
let mut first_digit = true;
|
||||||
|
|
||||||
|
for c in s.chars() {
|
||||||
|
match c.to_digit(10) {
|
||||||
|
Some(c) => {
|
||||||
|
if first_digit {
|
||||||
|
if c == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
first_digit = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.mul_assign(&ten);
|
||||||
|
res.add_assign(&Self::from_repr(Self::Repr::from(u64::from(c))).unwrap());
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(res)
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert this prime field element into a biginteger representation.
|
/// Convert this prime field element into a biginteger representation.
|
||||||
fn from_repr(Self::Repr) -> Result<Self, ()>;
|
fn from_repr(Self::Repr) -> Result<Self, PrimeFieldDecodingError>;
|
||||||
|
|
||||||
/// Convert a biginteger reprensentation into a prime field element, if
|
/// Convert a biginteger representation into a prime field element, if
|
||||||
/// the number is an element of the field.
|
/// the number is an element of the field.
|
||||||
fn into_repr(&self) -> Self::Repr;
|
fn into_repr(&self) -> Self::Repr;
|
||||||
|
|
||||||
/// Returns the field characteristic; the modulus.
|
/// Returns the field characteristic; the modulus.
|
||||||
fn char() -> Self::Repr;
|
fn char() -> Self::Repr;
|
||||||
|
|
||||||
/// Returns how many bits are needed to represent an element of this
|
/// How many bits are needed to represent an element of this field.
|
||||||
/// field.
|
const NUM_BITS: u32;
|
||||||
fn num_bits() -> u32;
|
|
||||||
|
|
||||||
/// Returns how many bits of information can be reliably stored in the
|
/// How many bits of information can be reliably stored in the field element.
|
||||||
/// field element.
|
const CAPACITY: u32;
|
||||||
fn capacity() -> u32;
|
|
||||||
|
|
||||||
/// Returns the multiplicative generator of `char()` - 1 order. This element
|
/// Returns the multiplicative generator of `char()` - 1 order. This element
|
||||||
/// must also be quadratic nonresidue.
|
/// must also be quadratic nonresidue.
|
||||||
fn multiplicative_generator() -> Self;
|
fn multiplicative_generator() -> Self;
|
||||||
|
|
||||||
/// Returns s such that 2^s * t = `char()` - 1 with t odd.
|
/// 2^s * t = `char()` - 1 with t odd.
|
||||||
fn s() -> usize;
|
const S: u32;
|
||||||
|
|
||||||
/// Returns the 2^s root of unity computed by exponentiating the `multiplicative_generator()`
|
/// Returns the 2^s root of unity computed by exponentiating the `multiplicative_generator()`
|
||||||
/// by t.
|
/// by t.
|
||||||
fn root_of_unity() -> Self;
|
fn root_of_unity() -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct BitIterator<E> {
|
pub struct BitIterator<E> {
|
||||||
t: E,
|
t: E,
|
||||||
n: usize,
|
n: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: AsRef<[u64]>> BitIterator<E> {
|
impl<E: AsRef<[u64]>> BitIterator<E> {
|
||||||
fn new(t: E) -> Self {
|
pub fn new(t: E) -> Self {
|
||||||
let n = t.as_ref().len() * 64;
|
let n = t.as_ref().len() * 64;
|
||||||
|
|
||||||
BitIterator { t: t, n: n }
|
BitIterator { t, n }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user