2017-07-16 20:50:03 -07:00
|
|
|
// This library relies on the Rust nightly compiler's `i128_type` feature.
|
2017-08-15 12:54:51 -07:00
|
|
|
// If that's not okay for you, disable the u128-support feature. (Pass
|
|
|
|
// --no-default-features for example.)
|
|
|
|
#![cfg_attr(feature = "u128-support", feature(i128_type))]
|
2017-07-08 09:55:43 -07:00
|
|
|
|
2017-07-16 20:50:03 -07:00
|
|
|
// `clippy` is a code linting tool for improving code quality by catching
|
|
|
|
// common mistakes or strange code patterns. If the `clippy` feature is
|
|
|
|
// provided, it is enabled and all compiler warnings are prohibited.
|
|
|
|
#![cfg_attr(feature = "clippy", deny(warnings))]
|
|
|
|
#![cfg_attr(feature = "clippy", feature(plugin))]
|
|
|
|
#![cfg_attr(feature = "clippy", plugin(clippy))]
|
|
|
|
#![cfg_attr(feature = "clippy", allow(inline_always))]
|
|
|
|
#![cfg_attr(feature = "clippy", allow(too_many_arguments))]
|
2017-08-01 10:37:51 -07:00
|
|
|
#![cfg_attr(feature = "clippy", allow(unreadable_literal))]
|
2017-09-28 07:12:37 -07:00
|
|
|
#![cfg_attr(feature = "clippy", allow(new_without_default_derive))]
|
2017-07-16 20:50:03 -07:00
|
|
|
|
2017-09-26 07:59:50 -07:00
|
|
|
// Force public structures to implement Debug
|
|
|
|
#![deny(missing_debug_implementations)]
|
|
|
|
|
2017-07-08 09:55:43 -07:00
|
|
|
extern crate rand;
|
2017-07-11 14:01:31 -07:00
|
|
|
extern crate byteorder;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
pub mod tests;
|
|
|
|
|
|
|
|
pub mod bls12_381;
|
2017-07-14 10:56:55 -07:00
|
|
|
|
2017-09-27 18:09:59 -07:00
|
|
|
mod wnaf;
|
|
|
|
pub use self::wnaf::Wnaf;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
use std::fmt;
|
2017-07-17 08:06:03 -07:00
|
|
|
use std::error::Error;
|
2017-07-17 12:35:12 -07:00
|
|
|
use std::io::{self, Read, Write};
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
/// An "engine" is a collection of types (fields, elliptic curve groups, etc.)
|
|
|
|
/// with well-defined relationships. In particular, the G1/G2 curve groups are
|
|
|
|
/// of prime order `r`, and are equipped with a bilinear pairing function.
|
2017-07-29 23:54:23 -07:00
|
|
|
pub trait Engine: Sized {
|
2017-07-08 09:55:43 -07:00
|
|
|
/// This is the scalar field of the G1/G2 groups.
|
|
|
|
type Fr: PrimeField;
|
|
|
|
|
|
|
|
/// The projective representation of an element in G1.
|
2017-07-29 23:54:23 -07:00
|
|
|
type G1: CurveProjective<Engine=Self, Base=Self::Fq, Scalar=Self::Fr, Affine=Self::G1Affine> + From<Self::G1Affine>;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
/// The affine representation of an element in G1.
|
2017-07-29 23:54:23 -07:00
|
|
|
type G1Affine: CurveAffine<Engine=Self, Base=Self::Fq, Scalar=Self::Fr, Projective=Self::G1, Pair=Self::G2Affine, PairingResult=Self::Fqk> + From<Self::G1>;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
/// The projective representation of an element in G2.
|
2017-07-29 23:54:23 -07:00
|
|
|
type G2: CurveProjective<Engine=Self, Base=Self::Fqe, Scalar=Self::Fr, Affine=Self::G2Affine> + From<Self::G2Affine>;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
/// The affine representation of an element in G2.
|
2017-07-29 23:54:23 -07:00
|
|
|
type G2Affine: CurveAffine<Engine=Self, Base=Self::Fqe, Scalar=Self::Fr, Projective=Self::G2, Pair=Self::G1Affine, PairingResult=Self::Fqk> + From<Self::G2>;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
/// The base field that hosts G1.
|
|
|
|
type Fq: PrimeField + SqrtField;
|
|
|
|
|
|
|
|
/// The extension field that hosts G2.
|
|
|
|
type Fqe: SqrtField;
|
|
|
|
|
|
|
|
/// The extension field that hosts the target group of the pairing.
|
|
|
|
type Fqk: Field;
|
|
|
|
|
|
|
|
/// Perform a miller loop with some number of (G1, G2) pairs.
|
|
|
|
fn miller_loop<'a, I>(i: I) -> Self::Fqk
|
|
|
|
where I: IntoIterator<Item=&'a (
|
|
|
|
&'a <Self::G1Affine as CurveAffine>::Prepared,
|
|
|
|
&'a <Self::G2Affine as CurveAffine>::Prepared
|
|
|
|
)>;
|
|
|
|
|
|
|
|
/// Perform final exponentiation of the result of a miller loop.
|
|
|
|
fn final_exponentiation(&Self::Fqk) -> Option<Self::Fqk>;
|
|
|
|
|
|
|
|
/// Performs a complete pairing operation `(p, q)`.
|
|
|
|
fn pairing<G1, G2>(p: G1, q: G2) -> Self::Fqk
|
|
|
|
where G1: Into<Self::G1Affine>,
|
|
|
|
G2: Into<Self::G2Affine>
|
|
|
|
{
|
|
|
|
Self::final_exponentiation(&Self::miller_loop(
|
|
|
|
[(
|
|
|
|
&(p.into().prepare()),
|
|
|
|
&(q.into().prepare())
|
|
|
|
)].into_iter()
|
|
|
|
)).unwrap()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Projective representation of an elliptic curve point guaranteed to be
|
|
|
|
/// in the correct prime order subgroup.
|
|
|
|
pub trait CurveProjective: PartialEq +
|
|
|
|
Eq +
|
|
|
|
Sized +
|
|
|
|
Copy +
|
|
|
|
Clone +
|
|
|
|
Send +
|
|
|
|
Sync +
|
|
|
|
fmt::Debug +
|
2017-07-17 11:20:01 -07:00
|
|
|
fmt::Display +
|
2017-07-08 09:55:43 -07:00
|
|
|
rand::Rand +
|
|
|
|
'static
|
|
|
|
{
|
2017-07-29 23:54:23 -07:00
|
|
|
type Engine: Engine;
|
2017-07-08 09:55:43 -07:00
|
|
|
type Scalar: PrimeField;
|
|
|
|
type Base: SqrtField;
|
|
|
|
type Affine: CurveAffine<Projective=Self, Scalar=Self::Scalar>;
|
|
|
|
|
|
|
|
/// Returns the additive identity.
|
|
|
|
fn zero() -> Self;
|
|
|
|
|
|
|
|
/// Returns a fixed generator of unknown exponent.
|
|
|
|
fn one() -> Self;
|
|
|
|
|
|
|
|
/// Determines if this point is the point at infinity.
|
|
|
|
fn is_zero(&self) -> bool;
|
|
|
|
|
|
|
|
/// Normalizes a slice of projective elements so that
|
|
|
|
/// conversion to affine is cheap.
|
|
|
|
fn batch_normalization(v: &mut [Self]);
|
|
|
|
|
|
|
|
/// Checks if the point is already "normalized" so that
|
|
|
|
/// cheap affine conversion is possible.
|
|
|
|
fn is_normalized(&self) -> bool;
|
|
|
|
|
|
|
|
/// Doubles this element.
|
|
|
|
fn double(&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) {
|
|
|
|
let mut tmp = *other;
|
|
|
|
tmp.negate();
|
|
|
|
self.add_assign(&tmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Adds an affine element to this element.
|
|
|
|
fn add_assign_mixed(&mut self, other: &Self::Affine);
|
|
|
|
|
|
|
|
/// Negates this element.
|
|
|
|
fn negate(&mut self);
|
|
|
|
|
|
|
|
/// Performs scalar multiplication of this element.
|
|
|
|
fn mul_assign<S: Into<<Self::Scalar as PrimeField>::Repr>>(&mut self, other: S);
|
|
|
|
|
|
|
|
/// Converts this element into its affine representation.
|
2017-07-11 22:37:29 -07:00
|
|
|
fn into_affine(&self) -> Self::Affine;
|
2017-07-09 23:39:38 -07:00
|
|
|
|
2017-09-28 07:38:13 -07:00
|
|
|
/// Recommends a wNAF window table size given a scalar. Always returns a number
|
|
|
|
/// between 2 and 22, inclusive.
|
|
|
|
fn recommended_wnaf_for_scalar(scalar: <Self::Scalar as PrimeField>::Repr) -> usize;
|
2017-07-09 23:39:38 -07:00
|
|
|
|
|
|
|
/// Recommends a wNAF window size given the number of scalars you intend to multiply
|
|
|
|
/// a base by. Always returns a number between 2 and 22, inclusive.
|
|
|
|
fn recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize;
|
2017-07-08 09:55:43 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Affine representation of an elliptic curve point guaranteed to be
|
|
|
|
/// in the correct prime order subgroup.
|
|
|
|
pub trait CurveAffine: Copy +
|
|
|
|
Clone +
|
|
|
|
Sized +
|
|
|
|
Send +
|
|
|
|
Sync +
|
|
|
|
fmt::Debug +
|
2017-07-17 11:20:01 -07:00
|
|
|
fmt::Display +
|
2017-07-08 09:55:43 -07:00
|
|
|
PartialEq +
|
|
|
|
Eq +
|
|
|
|
'static
|
|
|
|
{
|
2017-07-29 23:54:23 -07:00
|
|
|
type Engine: Engine;
|
2017-07-08 09:55:43 -07:00
|
|
|
type Scalar: PrimeField;
|
|
|
|
type Base: SqrtField;
|
|
|
|
type Projective: CurveProjective<Affine=Self, Scalar=Self::Scalar>;
|
|
|
|
type Prepared: Clone + Send + Sync + 'static;
|
2017-07-11 14:01:31 -07:00
|
|
|
type Uncompressed: EncodedPoint<Affine=Self>;
|
|
|
|
type Compressed: EncodedPoint<Affine=Self>;
|
2017-07-20 19:52:36 -07:00
|
|
|
type Pair: CurveAffine<Pair=Self>;
|
|
|
|
type PairingResult: Field;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
/// Returns the additive identity.
|
|
|
|
fn zero() -> Self;
|
|
|
|
|
|
|
|
/// Returns a fixed generator of unknown exponent.
|
|
|
|
fn one() -> Self;
|
|
|
|
|
|
|
|
/// Determines if this point represents the point at infinity; the
|
|
|
|
/// additive identity.
|
|
|
|
fn is_zero(&self) -> bool;
|
|
|
|
|
|
|
|
/// Negates this element.
|
|
|
|
fn negate(&mut self);
|
|
|
|
|
|
|
|
/// Performs scalar multiplication of this element with mixed addition.
|
|
|
|
fn mul<S: Into<<Self::Scalar as PrimeField>::Repr>>(&self, other: S) -> Self::Projective;
|
|
|
|
|
|
|
|
/// Prepares this element for pairing purposes.
|
|
|
|
fn prepare(&self) -> Self::Prepared;
|
|
|
|
|
2017-07-20 19:52:36 -07:00
|
|
|
/// Perform a pairing
|
|
|
|
fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult;
|
|
|
|
|
2017-07-08 09:55:43 -07:00
|
|
|
/// Converts this element into its affine representation.
|
2017-07-11 22:37:29 -07:00
|
|
|
fn into_projective(&self) -> Self::Projective;
|
2017-07-11 14:01:31 -07:00
|
|
|
|
|
|
|
/// Converts this element into its compressed encoding, so long as it's not
|
|
|
|
/// the point at infinity.
|
2017-07-16 19:52:00 -07:00
|
|
|
fn into_compressed(&self) -> Self::Compressed {
|
2017-07-11 14:01:31 -07:00
|
|
|
<Self::Compressed as EncodedPoint>::from_affine(*self)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Converts this element into its uncompressed encoding, so long as it's not
|
|
|
|
/// the point at infinity.
|
2017-07-16 19:52:00 -07:00
|
|
|
fn into_uncompressed(&self) -> Self::Uncompressed {
|
2017-07-11 14:01:31 -07:00
|
|
|
<Self::Uncompressed as EncodedPoint>::from_affine(*self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// An encoded elliptic curve point, which should essentially wrap a `[u8; N]`.
|
|
|
|
pub trait EncodedPoint: Sized +
|
|
|
|
Send +
|
|
|
|
Sync +
|
|
|
|
AsRef<[u8]> +
|
|
|
|
AsMut<[u8]> +
|
2017-07-17 12:05:16 -07:00
|
|
|
Clone +
|
|
|
|
Copy +
|
2017-07-11 14:01:31 -07:00
|
|
|
'static
|
|
|
|
{
|
|
|
|
type Affine: CurveAffine;
|
|
|
|
|
|
|
|
/// Creates an empty representation.
|
|
|
|
fn empty() -> Self;
|
|
|
|
|
|
|
|
/// Returns the number of bytes consumed by this representation.
|
|
|
|
fn size() -> usize;
|
|
|
|
|
|
|
|
/// Converts an `EncodedPoint` into a `CurveAffine` element,
|
2017-07-17 08:06:03 -07:00
|
|
|
/// if the encoding represents a valid element.
|
|
|
|
fn into_affine(&self) -> Result<Self::Affine, GroupDecodingError>;
|
2017-07-11 14:01:31 -07:00
|
|
|
|
|
|
|
/// Converts an `EncodedPoint` into a `CurveAffine` element,
|
2017-07-17 08:06:03 -07:00
|
|
|
/// without guaranteeing that the encoding represents a valid
|
|
|
|
/// element. This is useful when the caller knows the encoding is
|
|
|
|
/// valid already.
|
|
|
|
///
|
|
|
|
/// If the encoding is invalid, this can break API invariants,
|
|
|
|
/// so caution is strongly encouraged.
|
|
|
|
fn into_affine_unchecked(&self) -> Result<Self::Affine, GroupDecodingError>;
|
2017-07-11 14:01:31 -07:00
|
|
|
|
|
|
|
/// Creates an `EncodedPoint` from an affine point, as long as the
|
|
|
|
/// point is not the point at infinity.
|
2017-07-16 19:52:00 -07:00
|
|
|
fn from_affine(affine: Self::Affine) -> Self;
|
2017-07-08 09:55:43 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// This trait represents an element of a field.
|
|
|
|
pub trait Field: Sized +
|
|
|
|
Eq +
|
|
|
|
Copy +
|
|
|
|
Clone +
|
|
|
|
Send +
|
|
|
|
Sync +
|
|
|
|
fmt::Debug +
|
2017-07-17 11:20:01 -07:00
|
|
|
fmt::Display +
|
2017-07-08 09:55:43 -07:00
|
|
|
'static +
|
|
|
|
rand::Rand
|
|
|
|
{
|
|
|
|
/// Returns the zero element of the field, the additive identity.
|
|
|
|
fn zero() -> Self;
|
|
|
|
|
|
|
|
/// Returns the one element of the field, the multiplicative identity.
|
|
|
|
fn one() -> Self;
|
|
|
|
|
|
|
|
/// Returns true iff this element is zero.
|
|
|
|
fn is_zero(&self) -> bool;
|
|
|
|
|
|
|
|
/// Squares this element.
|
|
|
|
fn square(&mut self);
|
|
|
|
|
|
|
|
/// Doubles this element.
|
|
|
|
fn double(&mut self);
|
|
|
|
|
|
|
|
/// 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>;
|
|
|
|
|
|
|
|
/// Exponentiates this element by a power of the base prime modulus via
|
|
|
|
/// the Frobenius automorphism.
|
|
|
|
fn frobenius_map(&mut self, power: usize);
|
|
|
|
|
|
|
|
/// Exponentiates this element by a number represented with `u64` limbs,
|
|
|
|
/// least significant digit first.
|
|
|
|
fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self
|
|
|
|
{
|
|
|
|
let mut res = Self::one();
|
|
|
|
|
2017-07-09 20:11:29 -07:00
|
|
|
let mut found_one = false;
|
|
|
|
|
2017-07-08 09:55:43 -07:00
|
|
|
for i in BitIterator::new(exp) {
|
2017-07-09 20:11:29 -07:00
|
|
|
if found_one {
|
|
|
|
res.square();
|
|
|
|
} else {
|
|
|
|
found_one = i;
|
|
|
|
}
|
|
|
|
|
2017-07-08 09:55:43 -07:00
|
|
|
if i {
|
|
|
|
res.mul_assign(self);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
res
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// This trait represents an element of a field that has a square root operation described for it.
|
|
|
|
pub trait SqrtField: Field
|
|
|
|
{
|
2017-08-11 06:12:15 -07:00
|
|
|
/// Returns the Legendre symbol of the field element.
|
2017-08-10 09:28:17 -07:00
|
|
|
fn legendre(&self) -> LegendreSymbol;
|
|
|
|
|
2017-07-08 09:55:43 -07:00
|
|
|
/// Returns the square root of the field element, if it is
|
|
|
|
/// quadratic residue.
|
|
|
|
fn sqrt(&self) -> Option<Self>;
|
|
|
|
}
|
|
|
|
|
2017-08-06 06:24:01 -07:00
|
|
|
|
2017-07-08 09:55:43 -07:00
|
|
|
/// 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 +
|
2017-07-18 10:18:42 -07:00
|
|
|
Default +
|
2017-07-08 09:55:43 -07:00
|
|
|
fmt::Debug +
|
2017-07-17 11:20:01 -07:00
|
|
|
fmt::Display +
|
2017-07-08 09:55:43 -07:00
|
|
|
'static +
|
|
|
|
rand::Rand +
|
|
|
|
AsRef<[u64]> +
|
2017-07-17 12:35:12 -07:00
|
|
|
AsMut<[u64]> +
|
2017-07-08 09:55:43 -07:00
|
|
|
From<u64>
|
|
|
|
{
|
2017-08-14 01:46:55 -07:00
|
|
|
/// Subtract another represetation from this one, returning the borrow bit.
|
2017-07-08 09:55:43 -07:00
|
|
|
fn sub_noborrow(&mut self, other: &Self) -> bool;
|
|
|
|
|
|
|
|
/// Add another representation to this one, returning the carry bit.
|
|
|
|
fn add_nocarry(&mut self, other: &Self) -> bool;
|
|
|
|
|
2017-07-29 22:20:59 -07:00
|
|
|
/// Compute the number of bits needed to encode this number. Always a
|
|
|
|
/// multiple of 64.
|
2017-07-08 09:55:43 -07:00
|
|
|
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.
|
2017-07-29 21:50:48 -07:00
|
|
|
fn divn(&mut self, amt: u32);
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
/// Performs a leftwise bitshift of this number, effectively multiplying
|
|
|
|
/// it by 2. Overflow is ignored.
|
|
|
|
fn mul2(&mut self);
|
2017-07-17 12:35:12 -07:00
|
|
|
|
2017-07-29 22:20:59 -07:00
|
|
|
/// Performs a leftwise bitshift of this number by some amount.
|
|
|
|
fn muln(&mut self, amt: u32);
|
|
|
|
|
2017-07-17 12:35:12 -07:00
|
|
|
/// Writes this `PrimeFieldRepr` as a big endian integer. Always writes
|
|
|
|
/// `(num_bits` / 8) bytes.
|
|
|
|
fn write_be<W: Write>(&self, mut writer: W) -> io::Result<()> {
|
|
|
|
use byteorder::{WriteBytesExt, BigEndian};
|
|
|
|
|
|
|
|
for digit in self.as_ref().iter().rev() {
|
|
|
|
writer.write_u64::<BigEndian>(*digit)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Reads a big endian integer occupying (`num_bits` / 8) bytes into this
|
|
|
|
/// representation.
|
|
|
|
fn read_be<R: Read>(&mut self, mut reader: R) -> io::Result<()> {
|
|
|
|
use byteorder::{ReadBytesExt, BigEndian};
|
|
|
|
|
|
|
|
for digit in self.as_mut().iter_mut().rev() {
|
|
|
|
*digit = reader.read_u64::<BigEndian>()?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
2017-07-08 09:55:43 -07:00
|
|
|
}
|
|
|
|
|
2017-08-09 05:09:54 -07:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum LegendreSymbol {
|
|
|
|
Zero = 0,
|
2017-08-12 02:50:30 -07:00
|
|
|
QuadraticResidue = 1,
|
|
|
|
QuadraticNonResidue = -1
|
2017-08-09 05:09:54 -07:00
|
|
|
}
|
|
|
|
|
2017-07-17 11:24:00 -07:00
|
|
|
/// An error that may occur when trying to interpret a `PrimeFieldRepr` as a
|
|
|
|
/// `PrimeField` element.
|
2017-07-17 08:06:03 -07:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum PrimeFieldDecodingError {
|
2017-07-17 11:24:00 -07:00
|
|
|
/// The encoded value is not in the field
|
2017-07-17 09:31:22 -07:00
|
|
|
NotInField(String)
|
2017-07-17 08:06:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Error for PrimeFieldDecodingError {
|
|
|
|
fn description(&self) -> &str {
|
2017-07-18 09:16:49 -07:00
|
|
|
match *self {
|
|
|
|
PrimeFieldDecodingError::NotInField(..) => "not an element of the field"
|
2017-07-17 08:06:03 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for PrimeFieldDecodingError {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
2017-07-18 09:16:49 -07:00
|
|
|
match *self {
|
|
|
|
PrimeFieldDecodingError::NotInField(ref repr) => {
|
2017-07-17 09:31:22 -07:00
|
|
|
write!(f, "{} is not an element of the field", repr)
|
|
|
|
}
|
|
|
|
}
|
2017-07-17 08:06:03 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-17 11:24:00 -07:00
|
|
|
/// An error that may occur when trying to decode an `EncodedPoint`.
|
2017-07-17 08:06:03 -07:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum GroupDecodingError {
|
|
|
|
/// The coordinate(s) do not lie on the curve.
|
|
|
|
NotOnCurve,
|
|
|
|
/// The element is not part of the r-order subgroup.
|
|
|
|
NotInSubgroup,
|
|
|
|
/// One of the coordinates could not be decoded
|
|
|
|
CoordinateDecodingError(&'static str, PrimeFieldDecodingError),
|
2017-08-14 01:46:55 -07:00
|
|
|
/// The compression mode of the encoded element was not as expected
|
2017-07-17 08:06:03 -07:00
|
|
|
UnexpectedCompressionMode,
|
|
|
|
/// The encoding contained bits that should not have been set
|
|
|
|
UnexpectedInformation
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Error for GroupDecodingError {
|
|
|
|
fn description(&self) -> &str {
|
2017-07-18 09:16:49 -07:00
|
|
|
match *self {
|
|
|
|
GroupDecodingError::NotOnCurve => "coordinate(s) do not lie on the curve",
|
|
|
|
GroupDecodingError::NotInSubgroup => "the element is not part of an r-order subgroup",
|
|
|
|
GroupDecodingError::CoordinateDecodingError(..) => "coordinate(s) could not be decoded",
|
|
|
|
GroupDecodingError::UnexpectedCompressionMode => "encoding has unexpected compression mode",
|
|
|
|
GroupDecodingError::UnexpectedInformation => "encoding has unexpected information"
|
2017-07-17 08:06:03 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for GroupDecodingError {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
2017-07-18 09:16:49 -07:00
|
|
|
match *self {
|
|
|
|
GroupDecodingError::CoordinateDecodingError(description, ref err) => {
|
2017-07-17 08:06:03 -07:00
|
|
|
write!(f, "{} decoding error: {}", description, err)
|
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
write!(f, "{}", self.description())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-08 09:55:43 -07:00
|
|
|
/// This represents an element of a prime field.
|
|
|
|
pub trait PrimeField: Field
|
|
|
|
{
|
|
|
|
/// The prime field can be converted back and forth into this biginteger
|
|
|
|
/// representation.
|
|
|
|
type Repr: PrimeFieldRepr + From<Self>;
|
|
|
|
|
2017-07-29 23:11:34 -07:00
|
|
|
/// 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> {
|
2017-07-31 08:39:57 -07:00
|
|
|
if s.is_empty() {
|
2017-07-29 23:11:34 -07:00
|
|
|
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(c as u64)).unwrap());
|
|
|
|
},
|
|
|
|
None => {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Some(res)
|
|
|
|
}
|
|
|
|
|
2017-07-08 09:55:43 -07:00
|
|
|
/// Convert this prime field element into a biginteger representation.
|
2017-07-17 08:06:03 -07:00
|
|
|
fn from_repr(Self::Repr) -> Result<Self, PrimeFieldDecodingError>;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
2017-08-14 01:46:55 -07:00
|
|
|
/// Convert a biginteger representation into a prime field element, if
|
2017-07-08 09:55:43 -07:00
|
|
|
/// the number is an element of the field.
|
|
|
|
fn into_repr(&self) -> Self::Repr;
|
|
|
|
|
|
|
|
/// Returns the field characteristic; the modulus.
|
|
|
|
fn char() -> Self::Repr;
|
|
|
|
|
2017-09-28 15:08:56 -07:00
|
|
|
/// How many bits are needed to represent an element of this field.
|
|
|
|
const NUM_BITS: u32;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
2017-09-28 15:08:56 -07:00
|
|
|
/// How many bits of information can be reliably stored in the field element.
|
|
|
|
const CAPACITY: u32;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
/// Returns the multiplicative generator of `char()` - 1 order. This element
|
|
|
|
/// must also be quadratic nonresidue.
|
|
|
|
fn multiplicative_generator() -> Self;
|
|
|
|
|
2017-09-28 15:08:56 -07:00
|
|
|
/// 2^s * t = `char()` - 1 with t odd.
|
|
|
|
const S: u32;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
/// Returns the 2^s root of unity computed by exponentiating the `multiplicative_generator()`
|
|
|
|
/// by t.
|
|
|
|
fn root_of_unity() -> Self;
|
|
|
|
}
|
|
|
|
|
2017-09-26 07:59:50 -07:00
|
|
|
#[derive(Debug)]
|
2017-07-08 09:55:43 -07:00
|
|
|
pub struct BitIterator<E> {
|
|
|
|
t: E,
|
|
|
|
n: usize
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<E: AsRef<[u64]>> BitIterator<E> {
|
|
|
|
pub fn new(t: E) -> Self {
|
|
|
|
let n = t.as_ref().len() * 64;
|
|
|
|
|
|
|
|
BitIterator {
|
|
|
|
t: t,
|
|
|
|
n: n
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<E: AsRef<[u64]>> Iterator for BitIterator<E> {
|
|
|
|
type Item = bool;
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<bool> {
|
|
|
|
if self.n == 0 {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
self.n -= 1;
|
|
|
|
let part = self.n / 64;
|
|
|
|
let bit = self.n - (64 * part);
|
|
|
|
|
|
|
|
Some(self.t.as_ref()[part] & (1 << bit) > 0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_bit_iterator() {
|
|
|
|
let mut a = BitIterator::new([0xa953d79b83f6ab59, 0x6dea2059e200bd39]);
|
|
|
|
let expected = "01101101111010100010000001011001111000100000000010111101001110011010100101010011110101111001101110000011111101101010101101011001";
|
|
|
|
|
|
|
|
for e in expected.chars() {
|
|
|
|
assert!(a.next().unwrap() == (e == '1'));
|
|
|
|
}
|
|
|
|
|
|
|
|
assert!(a.next().is_none());
|
|
|
|
|
|
|
|
let expected = "1010010101111110101010000101101011101000011101110101001000011001100100100011011010001011011011010001011011101100110100111011010010110001000011110100110001100110011101101000101100011100100100100100001010011101010111110011101011000011101000111011011101011001";
|
|
|
|
|
|
|
|
let mut a = BitIterator::new([0x429d5f3ac3a3b759, 0xb10f4c66768b1c92, 0x92368b6d16ecd3b4, 0xa57ea85ae8775219]);
|
|
|
|
|
|
|
|
for e in expected.chars() {
|
|
|
|
assert!(a.next().unwrap() == (e == '1'));
|
|
|
|
}
|
|
|
|
|
|
|
|
assert!(a.next().is_none());
|
|
|
|
}
|
|
|
|
|
2017-08-15 11:53:22 -07:00
|
|
|
use self::arith::*;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
2017-08-15 11:53:22 -07:00
|
|
|
#[cfg(feature = "u128-support")]
|
|
|
|
mod arith {
|
2017-07-08 09:55:43 -07:00
|
|
|
|
2017-08-15 11:53:22 -07:00
|
|
|
/// Calculate a - b - borrow, returning the result and modifying
|
|
|
|
/// the borrow value.
|
|
|
|
#[inline(always)]
|
|
|
|
pub(crate) fn sbb(a: u64, b: u64, borrow: &mut u64) -> u64 {
|
|
|
|
let tmp = (1u128 << 64) + (a as u128) - (b as u128) - (*borrow as u128);
|
|
|
|
|
|
|
|
*borrow = if tmp >> 64 == 0 { 1 } else { 0 };
|
|
|
|
|
|
|
|
tmp as u64
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Calculate a + b + carry, returning the sum and modifying the
|
|
|
|
/// carry value.
|
|
|
|
#[inline(always)]
|
|
|
|
pub(crate) fn adc(a: u64, b: u64, carry: &mut u64) -> u64 {
|
|
|
|
let tmp = (a as u128) + (b as u128) + (*carry as u128);
|
2017-07-08 09:55:43 -07:00
|
|
|
|
2017-08-15 11:53:22 -07:00
|
|
|
*carry = (tmp >> 64) as u64;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
2017-08-15 11:53:22 -07:00
|
|
|
tmp as u64
|
|
|
|
}
|
2017-07-08 09:55:43 -07:00
|
|
|
|
2017-08-15 11:53:22 -07:00
|
|
|
/// Calculate a + (b * c) + carry, returning the least significant digit
|
|
|
|
/// and setting carry to the most significant digit.
|
|
|
|
#[inline(always)]
|
|
|
|
pub(crate) fn mac_with_carry(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
|
|
|
|
let tmp = (a as u128) + (b as u128) * (c as u128) + (*carry as u128);
|
|
|
|
|
|
|
|
*carry = (tmp >> 64) as u64;
|
|
|
|
|
|
|
|
tmp as u64
|
|
|
|
}
|
2017-07-08 09:55:43 -07:00
|
|
|
}
|
|
|
|
|
2017-08-15 11:53:22 -07:00
|
|
|
#[cfg(not(feature = "u128-support"))]
|
|
|
|
mod arith {
|
|
|
|
#[inline(always)]
|
|
|
|
fn split_u64(i: u64) -> (u64, u64) {
|
|
|
|
(i >> 32, i & 0xFFFFFFFF)
|
|
|
|
}
|
2017-07-08 09:55:43 -07:00
|
|
|
|
2017-08-15 11:53:22 -07:00
|
|
|
#[inline(always)]
|
|
|
|
fn combine_u64(hi: u64, lo: u64) -> u64 {
|
|
|
|
(hi << 32) | lo
|
|
|
|
}
|
2017-07-08 09:55:43 -07:00
|
|
|
|
2017-08-15 11:53:22 -07:00
|
|
|
#[inline(always)]
|
|
|
|
pub(crate) fn sbb(a: u64, b: u64, borrow: &mut u64) -> u64 {
|
|
|
|
let (a_hi, a_lo) = split_u64(a);
|
|
|
|
let (b_hi, b_lo) = split_u64(b);
|
|
|
|
let (b, r0) = split_u64((1 << 32) + a_lo - b_lo - *borrow);
|
|
|
|
let (b, r1) = split_u64((1 << 32) + a_hi - b_hi - ((b == 0) as u64));
|
|
|
|
|
|
|
|
*borrow = (b == 0) as u64;
|
|
|
|
|
|
|
|
combine_u64(r1, r0)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
pub(crate) fn adc(a: u64, b: u64, carry: &mut u64) -> u64 {
|
|
|
|
let (a_hi, a_lo) = split_u64(a);
|
|
|
|
let (b_hi, b_lo) = split_u64(b);
|
|
|
|
let (carry_hi, carry_lo) = split_u64(*carry);
|
|
|
|
|
|
|
|
let (t, r0) = split_u64(a_lo + b_lo + carry_lo);
|
|
|
|
let (t, r1) = split_u64(t + a_hi + b_hi + carry_hi);
|
|
|
|
|
|
|
|
*carry = t;
|
|
|
|
|
|
|
|
combine_u64(r1, r0)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
pub(crate) fn mac_with_carry(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
|
|
|
|
/*
|
|
|
|
[ b_hi | b_lo ]
|
|
|
|
[ c_hi | c_lo ] *
|
|
|
|
-------------------------------------------
|
|
|
|
[ b_lo * c_lo ] <-- w
|
|
|
|
[ b_hi * c_lo ] <-- x
|
|
|
|
[ b_lo * c_hi ] <-- y
|
|
|
|
[ b_hi * c_lo ] <-- z
|
|
|
|
[ a_hi | a_lo ]
|
|
|
|
[ C_hi | C_lo ]
|
|
|
|
*/
|
|
|
|
|
|
|
|
let (a_hi, a_lo) = split_u64(a);
|
|
|
|
let (b_hi, b_lo) = split_u64(b);
|
|
|
|
let (c_hi, c_lo) = split_u64(c);
|
|
|
|
let (carry_hi, carry_lo) = split_u64(*carry);
|
|
|
|
|
|
|
|
let (w_hi, w_lo) = split_u64(b_lo * c_lo);
|
|
|
|
let (x_hi, x_lo) = split_u64(b_hi * c_lo);
|
|
|
|
let (y_hi, y_lo) = split_u64(b_lo * c_hi);
|
|
|
|
let (z_hi, z_lo) = split_u64(b_hi * c_hi);
|
|
|
|
|
|
|
|
let (t, r0) = split_u64(w_lo + a_lo + carry_lo);
|
|
|
|
let (t, r1) = split_u64(t + w_hi + x_lo + y_lo + a_hi + carry_hi);
|
|
|
|
let (t, r2) = split_u64(t + x_hi + y_hi + z_lo);
|
|
|
|
let (_, r3) = split_u64(t + z_hi);
|
|
|
|
|
|
|
|
*carry = combine_u64(r3, r2);
|
|
|
|
|
|
|
|
combine_u64(r1, r0)
|
|
|
|
}
|
2017-07-08 09:55:43 -07:00
|
|
|
}
|