mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-02-01 08:12:14 +00:00
Merge pull request #223 from str4d/remove-primefieldrepr
Remove ff::PrimeFieldRepr
This commit is contained in:
commit
b02cf3b467
@ -11,7 +11,7 @@
|
||||
//! [`EvaluationDomain`]: crate::domain::EvaluationDomain
|
||||
//! [Groth16]: https://eprint.iacr.org/2016/260
|
||||
|
||||
use ff::{Field, PrimeField, ScalarEngine};
|
||||
use ff::{Field, PowVartime, PrimeField, ScalarEngine};
|
||||
use group::CurveProjective;
|
||||
use std::ops::{AddAssign, MulAssign, SubAssign};
|
||||
|
||||
|
@ -313,12 +313,12 @@ pub fn field_into_allocated_bits_le<E: ScalarEngine, CS: ConstraintSystem<E>, F:
|
||||
// Deconstruct in big-endian bit order
|
||||
let values = match value {
|
||||
Some(ref value) => {
|
||||
let mut field_char = BitIterator::new(F::char());
|
||||
let mut field_char = BitIterator::<u8, _>::new(F::char());
|
||||
|
||||
let mut tmp = Vec::with_capacity(F::NUM_BITS as usize);
|
||||
|
||||
let mut found_one = false;
|
||||
for b in BitIterator::new(value.into_repr()) {
|
||||
for b in BitIterator::<u8, _>::new(value.into_repr()) {
|
||||
// Skip leading bits
|
||||
found_one |= field_char.next().unwrap();
|
||||
if !found_one {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use ff::{Field, PrimeField, ScalarEngine};
|
||||
use ff::{PowVartime, PrimeField, ScalarEngine};
|
||||
|
||||
use crate::{ConstraintSystem, LinearCombination, SynthesisError, Variable};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Gadgets representing numbers in the scalar field of the underlying curve.
|
||||
|
||||
use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, ScalarEngine};
|
||||
use ff::{BitIterator, Field, PrimeField, ScalarEngine};
|
||||
use std::ops::{AddAssign, MulAssign};
|
||||
|
||||
use crate::{ConstraintSystem, LinearCombination, SynthesisError, Variable};
|
||||
@ -103,9 +103,8 @@ impl<E: ScalarEngine> AllocatedNum<E> {
|
||||
|
||||
// We want to ensure that the bit representation of a is
|
||||
// less than or equal to r - 1.
|
||||
let mut a = self.value.map(|e| BitIterator::new(e.into_repr()));
|
||||
let mut b = E::Fr::char();
|
||||
b.sub_noborrow(&1.into());
|
||||
let mut a = self.value.map(|e| BitIterator::<u8, _>::new(e.into_repr()));
|
||||
let b = (-E::Fr::one()).into_repr();
|
||||
|
||||
let mut result = vec![];
|
||||
|
||||
@ -115,7 +114,7 @@ impl<E: ScalarEngine> AllocatedNum<E> {
|
||||
|
||||
let mut found_one = false;
|
||||
let mut i = 0;
|
||||
for b in BitIterator::new(b) {
|
||||
for b in BitIterator::<u8, _>::new(b) {
|
||||
let a_bit = a.as_mut().map(|e| e.next().unwrap());
|
||||
|
||||
// Skip over unset bits at the beginning
|
||||
@ -558,7 +557,7 @@ mod test {
|
||||
|
||||
assert!(cs.is_satisfied());
|
||||
|
||||
for (b, a) in BitIterator::new(r.into_repr())
|
||||
for (b, a) in BitIterator::<u8, _>::new(r.into_repr())
|
||||
.skip(1)
|
||||
.zip(bits.iter().rev())
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Helpers for testing circuit implementations.
|
||||
|
||||
use ff::{Field, PrimeField, PrimeFieldRepr, ScalarEngine};
|
||||
use ff::{Field, PowVartime, PrimeField, ScalarEngine};
|
||||
|
||||
use crate::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable};
|
||||
|
||||
@ -106,7 +106,12 @@ fn hash_lc<E: ScalarEngine>(terms: &[(Variable, E::Fr)], h: &mut Blake2sState) {
|
||||
}
|
||||
}
|
||||
|
||||
coeff.into_repr().write_be(&mut buf[9..]).unwrap();
|
||||
// BLS12-381's Fr is canonically serialized in little-endian, but the hasher
|
||||
// writes its coefficients in big endian. For now, we flip the endianness
|
||||
// manually, which is not necessarily correct for circuits using other curves.
|
||||
// TODO: Fix this in a standalone commit, and document the no-op change.
|
||||
let coeff_be: Vec<_> = coeff.into_repr().as_ref().iter().cloned().rev().collect();
|
||||
buf[9..].copy_from_slice(&coeff_be[..]);
|
||||
|
||||
h.update(&buf);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use rand_core::RngCore;
|
||||
use std::ops::{AddAssign, MulAssign};
|
||||
use std::sync::Arc;
|
||||
|
||||
use ff::{Field, PrimeField};
|
||||
use ff::{Field, PowVartime};
|
||||
use group::{CurveAffine, CurveProjective, Wnaf};
|
||||
use pairing::Engine;
|
||||
|
||||
@ -273,7 +273,7 @@ where
|
||||
exp.mul_assign(&coeff);
|
||||
|
||||
// Exponentiate
|
||||
*h = g1_wnaf.scalar(exp.into_repr());
|
||||
*h = g1_wnaf.scalar(&exp);
|
||||
}
|
||||
|
||||
// Batch normalize
|
||||
@ -376,14 +376,14 @@ where
|
||||
|
||||
// Compute A query (in G1)
|
||||
if !at.is_zero() {
|
||||
*a = g1_wnaf.scalar(at.into_repr());
|
||||
*a = g1_wnaf.scalar(&at);
|
||||
}
|
||||
|
||||
// Compute B query (in G1/G2)
|
||||
if !bt.is_zero() {
|
||||
let bt_repr = bt.into_repr();
|
||||
*b_g1 = g1_wnaf.scalar(bt_repr);
|
||||
*b_g2 = g2_wnaf.scalar(bt_repr);
|
||||
();
|
||||
*b_g1 = g1_wnaf.scalar(&bt);
|
||||
*b_g2 = g2_wnaf.scalar(&bt);
|
||||
}
|
||||
|
||||
at.mul_assign(&beta);
|
||||
@ -394,7 +394,7 @@ where
|
||||
e.add_assign(&ct);
|
||||
e.mul_assign(inv);
|
||||
|
||||
*ext = g1_wnaf.scalar(e.into_repr());
|
||||
*ext = g1_wnaf.scalar(&e);
|
||||
}
|
||||
|
||||
// Batch normalize
|
||||
|
@ -4,7 +4,7 @@ use std::sync::Arc;
|
||||
|
||||
use futures::Future;
|
||||
|
||||
use ff::{Field, PrimeField};
|
||||
use ff::Field;
|
||||
use group::{CurveAffine, CurveProjective};
|
||||
use pairing::Engine;
|
||||
|
||||
@ -229,26 +229,14 @@ where
|
||||
let a_len = a.len() - 1;
|
||||
a.truncate(a_len);
|
||||
// TODO: parallelize if it's even helpful
|
||||
let a = Arc::new(a.into_iter().map(|s| s.0.into_repr()).collect::<Vec<_>>());
|
||||
let a = Arc::new(a.into_iter().map(|s| s.0).collect::<Vec<_>>());
|
||||
|
||||
multiexp(&worker, params.get_h(a.len())?, FullDensity, a)
|
||||
};
|
||||
|
||||
// TODO: parallelize if it's even helpful
|
||||
let input_assignment = Arc::new(
|
||||
prover
|
||||
.input_assignment
|
||||
.into_iter()
|
||||
.map(|s| s.into_repr())
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
let aux_assignment = Arc::new(
|
||||
prover
|
||||
.aux_assignment
|
||||
.into_iter()
|
||||
.map(|s| s.into_repr())
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
let input_assignment = Arc::new(prover.input_assignment);
|
||||
let aux_assignment = Arc::new(prover.aux_assignment);
|
||||
|
||||
let l = multiexp(
|
||||
&worker,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, ScalarEngine, SqrtField};
|
||||
use ff::{Field, PowVartime, PrimeField, ScalarEngine, SqrtField};
|
||||
use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError};
|
||||
use pairing::{Engine, PairingCurveAffine};
|
||||
|
||||
@ -6,7 +6,7 @@ use rand_core::RngCore;
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
use std::num::Wrapping;
|
||||
use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||
use std::ops::{Add, AddAssign, BitAnd, Mul, MulAssign, Neg, Shr, Sub, SubAssign};
|
||||
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
|
||||
|
||||
const MODULUS_R: Wrapping<u32> = Wrapping(64513);
|
||||
@ -32,6 +32,12 @@ impl fmt::Display for Fr {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for Fr {
|
||||
fn from(v: u64) -> Fr {
|
||||
Fr(Wrapping((v % MODULUS_R.0 as u64) as u32))
|
||||
}
|
||||
}
|
||||
|
||||
impl ConditionallySelectable for Fr {
|
||||
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
|
||||
Fr(Wrapping(u32::conditional_select(
|
||||
@ -42,6 +48,18 @@ impl ConditionallySelectable for Fr {
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Fr {
|
||||
fn cmp(&self, other: &Fr) -> Ordering {
|
||||
(self.0).0.cmp(&(other.0).0)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Fr {
|
||||
fn partial_cmp(&self, other: &Fr) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Neg for Fr {
|
||||
type Output = Self;
|
||||
|
||||
@ -143,6 +161,23 @@ impl MulAssign for Fr {
|
||||
}
|
||||
}
|
||||
|
||||
impl BitAnd<u64> for Fr {
|
||||
type Output = u64;
|
||||
|
||||
fn bitand(self, rhs: u64) -> u64 {
|
||||
(self.0).0 as u64 & rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Shr<u32> for Fr {
|
||||
type Output = Fr;
|
||||
|
||||
fn shr(mut self, rhs: u32) -> Fr {
|
||||
self.0 = Wrapping((self.0).0 >> rhs);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Field for Fr {
|
||||
fn random<R: RngCore + ?std::marker::Sized>(rng: &mut R) -> Self {
|
||||
Fr(Wrapping(rng.next_u32()) % MODULUS_R)
|
||||
@ -190,9 +225,9 @@ impl SqrtField for Fr {
|
||||
// https://eprint.iacr.org/2012/685.pdf (page 12, algorithm 5)
|
||||
let mut c = Fr::root_of_unity();
|
||||
// r = self^((t + 1) // 2)
|
||||
let mut r = self.pow_vartime([32]);
|
||||
let mut r = self.pow_vartime([32u64]);
|
||||
// t = self^t
|
||||
let mut t = self.pow_vartime([63]);
|
||||
let mut t = self.pow_vartime([63u64]);
|
||||
let mut m = Fr::S;
|
||||
|
||||
while t != <Fr as Field>::one() {
|
||||
@ -222,86 +257,35 @@ impl SqrtField for Fr {
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub struct FrRepr([u64; 1]);
|
||||
|
||||
impl Ord for FrRepr {
|
||||
fn cmp(&self, other: &FrRepr) -> Ordering {
|
||||
(self.0)[0].cmp(&(other.0)[0])
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for FrRepr {
|
||||
fn partial_cmp(&self, other: &FrRepr) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FrRepr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||
write!(f, "{}", (self.0)[0])
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for FrRepr {
|
||||
fn from(v: u64) -> FrRepr {
|
||||
FrRepr([v])
|
||||
}
|
||||
}
|
||||
pub struct FrRepr([u8; 8]);
|
||||
|
||||
impl From<Fr> for FrRepr {
|
||||
fn from(v: Fr) -> FrRepr {
|
||||
FrRepr([(v.0).0 as u64])
|
||||
FrRepr::from(&v)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<[u64]> for FrRepr {
|
||||
fn as_mut(&mut self) -> &mut [u64] {
|
||||
impl<'a> From<&'a Fr> for FrRepr {
|
||||
fn from(v: &'a Fr) -> FrRepr {
|
||||
FrRepr(((v.0).0 as u64).to_le_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<[u8]> for FrRepr {
|
||||
fn as_mut(&mut self) -> &mut [u8] {
|
||||
&mut self.0[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u64]> for FrRepr {
|
||||
fn as_ref(&self) -> &[u64] {
|
||||
impl AsRef<[u8]> for FrRepr {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&self.0[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FrRepr {
|
||||
fn default() -> FrRepr {
|
||||
FrRepr::from(0u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl PrimeFieldRepr for FrRepr {
|
||||
fn sub_noborrow(&mut self, other: &Self) {
|
||||
self.0[0] = self.0[0].wrapping_sub(other.0[0]);
|
||||
}
|
||||
fn add_nocarry(&mut self, other: &Self) {
|
||||
self.0[0] = self.0[0].wrapping_add(other.0[0]);
|
||||
}
|
||||
fn num_bits(&self) -> u32 {
|
||||
64 - self.0[0].leading_zeros()
|
||||
}
|
||||
fn is_zero(&self) -> bool {
|
||||
self.0[0] == 0
|
||||
}
|
||||
fn is_odd(&self) -> bool {
|
||||
!self.is_even()
|
||||
}
|
||||
fn is_even(&self) -> bool {
|
||||
self.0[0] % 2 == 0
|
||||
}
|
||||
fn div2(&mut self) {
|
||||
self.shr(1)
|
||||
}
|
||||
fn shr(&mut self, amt: u32) {
|
||||
self.0[0] >>= amt;
|
||||
}
|
||||
fn mul2(&mut self) {
|
||||
self.shl(1)
|
||||
}
|
||||
fn shl(&mut self, amt: u32) {
|
||||
self.0[0] <<= amt;
|
||||
FrRepr([0; 8])
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,11 +296,12 @@ impl PrimeField for Fr {
|
||||
const CAPACITY: u32 = 15;
|
||||
const S: u32 = 10;
|
||||
|
||||
fn from_repr(repr: FrRepr) -> Result<Self, PrimeFieldDecodingError> {
|
||||
if repr.0[0] >= (MODULUS_R.0 as u64) {
|
||||
Err(PrimeFieldDecodingError::NotInField)
|
||||
fn from_repr(repr: FrRepr) -> Option<Self> {
|
||||
let v = u64::from_le_bytes(repr.0);
|
||||
if v >= (MODULUS_R.0 as u64) {
|
||||
None
|
||||
} else {
|
||||
Ok(Fr(Wrapping(repr.0[0] as u32)))
|
||||
Some(Fr(Wrapping(v as u32)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -324,6 +309,10 @@ impl PrimeField for Fr {
|
||||
FrRepr::from(*self)
|
||||
}
|
||||
|
||||
fn is_odd(&self) -> bool {
|
||||
(self.0).0 % 2 != 0
|
||||
}
|
||||
|
||||
fn char() -> FrRepr {
|
||||
Fr(MODULUS_R).into()
|
||||
}
|
||||
@ -423,7 +412,7 @@ impl CurveProjective for Fr {
|
||||
*self
|
||||
}
|
||||
|
||||
fn recommended_wnaf_for_scalar(_: <Self::Scalar as PrimeField>::Repr) -> usize {
|
||||
fn recommended_wnaf_for_scalar(_: &Self::Scalar) -> usize {
|
||||
3
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use ff::{Field, PrimeField};
|
||||
use ff::{Field, PowVartime, PrimeField};
|
||||
use pairing::Engine;
|
||||
|
||||
mod dummy_engine;
|
||||
@ -127,22 +127,22 @@ fn test_xordemo() {
|
||||
let mut root_of_unity = Fr::root_of_unity();
|
||||
|
||||
// We expect this to be a 2^10 root of unity
|
||||
assert_eq!(Fr::one(), root_of_unity.pow_vartime(&[1 << 10]));
|
||||
assert_eq!(Fr::one(), root_of_unity.pow_vartime(&[1u64 << 10]));
|
||||
|
||||
// Let's turn it into a 2^3 root of unity.
|
||||
root_of_unity = root_of_unity.pow_vartime(&[1 << 7]);
|
||||
assert_eq!(Fr::one(), root_of_unity.pow_vartime(&[1 << 3]));
|
||||
root_of_unity = root_of_unity.pow_vartime(&[1u64 << 7]);
|
||||
assert_eq!(Fr::one(), root_of_unity.pow_vartime(&[1u64 << 3]));
|
||||
assert_eq!(Fr::from_str("20201").unwrap(), root_of_unity);
|
||||
|
||||
// Let's compute all the points in our evaluation domain.
|
||||
let mut points = Vec::with_capacity(8);
|
||||
for i in 0..8 {
|
||||
for i in 0u64..8 {
|
||||
points.push(root_of_unity.pow_vartime(&[i]));
|
||||
}
|
||||
|
||||
// Let's compute t(tau) = (tau - p_0)(tau - p_1)...
|
||||
// = tau^8 - 1
|
||||
let mut t_at_tau = tau.pow_vartime(&[8]);
|
||||
let mut t_at_tau = tau.pow_vartime(&[8u64]);
|
||||
t_at_tau.sub_assign(&Fr::one());
|
||||
{
|
||||
let mut tmp = Fr::one();
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::multicore::Worker;
|
||||
use bit_vec::{self, BitVec};
|
||||
use ff::{Field, PrimeField, PrimeFieldRepr, ScalarEngine};
|
||||
use ff::{Field, PrimeField, ScalarEngine};
|
||||
use futures::Future;
|
||||
use group::{CurveAffine, CurveProjective};
|
||||
use std::io;
|
||||
@ -154,7 +154,7 @@ fn multiexp_inner<Q, D, G, S>(
|
||||
pool: &Worker,
|
||||
bases: S,
|
||||
density_map: D,
|
||||
exponents: Arc<Vec<<<G::Engine as ScalarEngine>::Fr as PrimeField>::Repr>>,
|
||||
exponents: Arc<Vec<<G::Engine as ScalarEngine>::Fr>>,
|
||||
mut skip: u32,
|
||||
c: u32,
|
||||
handle_trivial: bool,
|
||||
@ -181,13 +181,12 @@ where
|
||||
// Create space for the buckets
|
||||
let mut buckets = vec![G::zero(); (1 << c) - 1];
|
||||
|
||||
let zero = <G::Engine as ScalarEngine>::Fr::zero().into_repr();
|
||||
let one = <G::Engine as ScalarEngine>::Fr::one().into_repr();
|
||||
let one = <G::Engine as ScalarEngine>::Fr::one();
|
||||
|
||||
// Sort the bases into buckets
|
||||
for (&exp, density) in exponents.iter().zip(density_map.as_ref().iter()) {
|
||||
if density {
|
||||
if exp == zero {
|
||||
if exp.is_zero() {
|
||||
bases.skip(1)?;
|
||||
} else if exp == one {
|
||||
if handle_trivial {
|
||||
@ -196,9 +195,8 @@ where
|
||||
bases.skip(1)?;
|
||||
}
|
||||
} else {
|
||||
let mut exp = exp;
|
||||
exp.shr(skip);
|
||||
let exp = exp.as_ref()[0] % (1 << c);
|
||||
let exp = exp >> skip;
|
||||
let exp = exp & ((1 << c) - 1);
|
||||
|
||||
if exp != 0 {
|
||||
(&mut buckets[(exp - 1) as usize])
|
||||
@ -261,7 +259,7 @@ pub fn multiexp<Q, D, G, S>(
|
||||
pool: &Worker,
|
||||
bases: S,
|
||||
density_map: D,
|
||||
exponents: Arc<Vec<<<G::Engine as ScalarEngine>::Fr as PrimeField>::Repr>>,
|
||||
exponents: Arc<Vec<<G::Engine as ScalarEngine>::Fr>>,
|
||||
) -> Box<dyn Future<Item = G, Error = SynthesisError>>
|
||||
where
|
||||
for<'a> &'a Q: QueryDensity,
|
||||
@ -290,14 +288,14 @@ where
|
||||
fn test_with_bls12() {
|
||||
fn naive_multiexp<G: CurveProjective>(
|
||||
bases: Arc<Vec<<G as CurveProjective>::Affine>>,
|
||||
exponents: Arc<Vec<<G::Scalar as PrimeField>::Repr>>,
|
||||
exponents: Arc<Vec<G::Scalar>>,
|
||||
) -> G {
|
||||
assert_eq!(bases.len(), exponents.len());
|
||||
|
||||
let mut acc = G::zero();
|
||||
|
||||
for (base, exp) in bases.iter().zip(exponents.iter()) {
|
||||
AddAssign::<&G>::add_assign(&mut acc, &base.mul(*exp));
|
||||
AddAssign::<&G>::add_assign(&mut acc, &base.mul(exp.into_repr()));
|
||||
}
|
||||
|
||||
acc
|
||||
@ -311,7 +309,7 @@ fn test_with_bls12() {
|
||||
let rng = &mut rand::thread_rng();
|
||||
let v = Arc::new(
|
||||
(0..SAMPLES)
|
||||
.map(|_| <Bls12 as ScalarEngine>::Fr::random(rng).into_repr())
|
||||
.map(|_| <Bls12 as ScalarEngine>::Fr::random(rng))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
let g = Arc::new(
|
||||
|
File diff suppressed because it is too large
Load Diff
246
ff/src/lib.rs
246
ff/src/lib.rs
@ -12,8 +12,10 @@ extern crate std;
|
||||
#[cfg(feature = "derive")]
|
||||
pub use ff_derive::*;
|
||||
|
||||
use core::convert::TryFrom;
|
||||
use core::fmt;
|
||||
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||
use core::marker::PhantomData;
|
||||
use core::ops::{Add, AddAssign, BitAnd, Mul, MulAssign, Neg, Shr, Sub, SubAssign};
|
||||
use rand_core::RngCore;
|
||||
#[cfg(feature = "std")]
|
||||
use std::io::{self, Read, Write};
|
||||
@ -73,21 +75,36 @@ pub trait Field:
|
||||
/// Exponentiates this element by a power of the base prime modulus via
|
||||
/// the Frobenius automorphism.
|
||||
fn frobenius_map(&mut self, power: usize);
|
||||
}
|
||||
|
||||
pub trait PowVartime<L>: Field
|
||||
where
|
||||
L: Copy + PartialEq + PartialOrd + AddAssign,
|
||||
L: BitAnd<Output = L>,
|
||||
L: Shr<Output = L>,
|
||||
L: Sub<Output = L>,
|
||||
{
|
||||
const ZERO: L;
|
||||
const ONE: L;
|
||||
const LIMB_SIZE: L;
|
||||
|
||||
/// Exponentiates `self` by `exp`, where `exp` is a little-endian order
|
||||
/// integer exponent.
|
||||
///
|
||||
/// **This operation is variable time with respect to the exponent.** If the
|
||||
/// exponent is fixed, this operation is effectively constant time.
|
||||
fn pow_vartime<S: AsRef<[u64]>>(&self, exp: S) -> Self {
|
||||
fn pow_vartime<S: AsRef<[L]>>(&self, exp: S) -> Self {
|
||||
let mut res = Self::one();
|
||||
for e in exp.as_ref().iter().rev() {
|
||||
for i in (0..64).rev() {
|
||||
let mut i = Self::ZERO;
|
||||
while i < Self::LIMB_SIZE {
|
||||
res = res.square();
|
||||
|
||||
if ((*e >> i) & 1) == 1 {
|
||||
if ((*e >> (Self::LIMB_SIZE - Self::ONE - i)) & Self::ONE) == Self::ONE {
|
||||
res.mul_assign(self);
|
||||
}
|
||||
|
||||
i += Self::ONE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,6 +112,18 @@ pub trait Field:
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Field> PowVartime<u8> for T {
|
||||
const ZERO: u8 = 0;
|
||||
const ONE: u8 = 1;
|
||||
const LIMB_SIZE: u8 = 8;
|
||||
}
|
||||
|
||||
impl<T: Field> PowVartime<u64> for T {
|
||||
const ZERO: u64 = 0;
|
||||
const ONE: u64 = 1;
|
||||
const LIMB_SIZE: u64 = 64;
|
||||
}
|
||||
|
||||
/// This trait represents an element of a field that has a square root operation described for it.
|
||||
pub trait SqrtField: Field {
|
||||
/// Returns the square root of the field element, if it is
|
||||
@ -102,137 +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 {
|
||||
/// The prime field can be converted back and forth into this biginteger
|
||||
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 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.
|
||||
@ -247,7 +152,7 @@ pub trait PrimeField: Field {
|
||||
|
||||
let mut res = Self::zero();
|
||||
|
||||
let ten = Self::from_repr(Self::Repr::from(10)).unwrap();
|
||||
let ten = Self::from(10);
|
||||
|
||||
let mut first_digit = true;
|
||||
|
||||
@ -263,7 +168,7 @@ pub trait PrimeField: Field {
|
||||
}
|
||||
|
||||
res.mul_assign(&ten);
|
||||
res.add_assign(&Self::from_repr(Self::Repr::from(u64::from(c))).unwrap());
|
||||
res.add_assign(&Self::from(u64::from(c)));
|
||||
}
|
||||
None => {
|
||||
return None;
|
||||
@ -274,13 +179,31 @@ pub trait PrimeField: Field {
|
||||
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.
|
||||
fn is_odd(&self) -> bool;
|
||||
|
||||
/// Returns true iff this element is even.
|
||||
#[inline(always)]
|
||||
fn is_even(&self) -> bool {
|
||||
!self.is_odd()
|
||||
}
|
||||
|
||||
/// Returns the field characteristic; the modulus.
|
||||
fn char() -> Self::Repr;
|
||||
|
||||
@ -311,20 +234,25 @@ pub trait ScalarEngine: Sized + 'static + Clone {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BitIterator<E> {
|
||||
pub struct BitIterator<T, E: AsRef<[T]>> {
|
||||
t: E,
|
||||
n: usize,
|
||||
_limb: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<E: AsRef<[u64]>> BitIterator<E> {
|
||||
impl<E: AsRef<[u64]>> BitIterator<u64, E> {
|
||||
pub fn new(t: E) -> Self {
|
||||
let n = t.as_ref().len() * 64;
|
||||
|
||||
BitIterator { t, n }
|
||||
BitIterator {
|
||||
t,
|
||||
n,
|
||||
_limb: PhantomData::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: AsRef<[u64]>> Iterator for BitIterator<E> {
|
||||
impl<E: AsRef<[u64]>> Iterator for BitIterator<u64, E> {
|
||||
type Item = bool;
|
||||
|
||||
fn next(&mut self) -> Option<bool> {
|
||||
@ -340,9 +268,37 @@ impl<E: AsRef<[u64]>> Iterator for BitIterator<E> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: AsRef<[u8]>> BitIterator<u8, E> {
|
||||
pub fn new(t: E) -> Self {
|
||||
let n = t.as_ref().len() * 8;
|
||||
|
||||
BitIterator {
|
||||
t,
|
||||
n,
|
||||
_limb: PhantomData::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: AsRef<[u8]>> Iterator for BitIterator<u8, E> {
|
||||
type Item = bool;
|
||||
|
||||
fn next(&mut self) -> Option<bool> {
|
||||
if self.n == 0 {
|
||||
None
|
||||
} else {
|
||||
self.n -= 1;
|
||||
let part = self.n / 8;
|
||||
let bit = self.n - (8 * part);
|
||||
|
||||
Some(self.t.as_ref()[part] & (1 << bit) > 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_iterator() {
|
||||
let mut a = BitIterator::new([0xa953_d79b_83f6_ab59, 0x6dea_2059_e200_bd39]);
|
||||
let mut a = BitIterator::<u64, _>::new([0xa953_d79b_83f6_ab59, 0x6dea_2059_e200_bd39]);
|
||||
let expected = "01101101111010100010000001011001111000100000000010111101001110011010100101010011110101111001101110000011111101101010101101011001";
|
||||
|
||||
for e in expected.chars() {
|
||||
@ -353,7 +309,7 @@ fn test_bit_iterator() {
|
||||
|
||||
let expected = "1010010101111110101010000101101011101000011101110101001000011001100100100011011010001011011011010001011011101100110100111011010010110001000011110100110001100110011101101000101100011100100100100100001010011101010111110011101011000011101000111011011101011001";
|
||||
|
||||
let mut a = BitIterator::new([
|
||||
let mut a = BitIterator::<u64, _>::new([
|
||||
0x429d_5f3a_c3a3_b759,
|
||||
0xb10f_4c66_768b_1c92,
|
||||
0x9236_8b6d_16ec_d3b4,
|
||||
|
@ -15,6 +15,7 @@ repository = "https://github.com/ebfull/group"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
byteorder = { version = "1", default-features = false }
|
||||
ff = { version = "0.6", path = "../ff" }
|
||||
rand = "0.7"
|
||||
rand_xorshift = "0.2"
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Catch documentation errors caused by code changes.
|
||||
#![deny(intra_doc_link_resolution_failure)]
|
||||
|
||||
use ff::{PrimeField, PrimeFieldDecodingError, ScalarEngine, SqrtField};
|
||||
use ff::{PrimeField, ScalarEngine, SqrtField};
|
||||
use rand::RngCore;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
@ -82,7 +82,7 @@ pub trait CurveProjective:
|
||||
|
||||
/// 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;
|
||||
fn recommended_wnaf_for_scalar(scalar: &Self::Scalar) -> usize;
|
||||
|
||||
/// 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.
|
||||
@ -178,7 +178,7 @@ pub enum GroupDecodingError {
|
||||
/// The element is not part of the r-order subgroup.
|
||||
NotInSubgroup,
|
||||
/// One of the coordinates could not be decoded
|
||||
CoordinateDecodingError(&'static str, PrimeFieldDecodingError),
|
||||
CoordinateDecodingError(&'static str),
|
||||
/// The compression mode of the encoded element was not as expected
|
||||
UnexpectedCompressionMode,
|
||||
/// The encoding contained bits that should not have been set
|
||||
@ -202,8 +202,8 @@ impl Error for GroupDecodingError {
|
||||
impl fmt::Display for GroupDecodingError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||
match *self {
|
||||
GroupDecodingError::CoordinateDecodingError(description, ref err) => {
|
||||
write!(f, "{} decoding error: {}", description, err)
|
||||
GroupDecodingError::CoordinateDecodingError(description) => {
|
||||
write!(f, "{} decoding error", description)
|
||||
}
|
||||
_ => write!(f, "{}", self.description()),
|
||||
}
|
||||
|
@ -85,12 +85,12 @@ fn random_wnaf_tests<G: CurveProjective>() {
|
||||
for w in 2..14 {
|
||||
for _ in 0..100 {
|
||||
let g = G::random(&mut rng);
|
||||
let s = G::Scalar::random(&mut rng).into_repr();
|
||||
let s = G::Scalar::random(&mut rng);
|
||||
let mut g1 = g;
|
||||
g1.mul_assign(s);
|
||||
|
||||
wnaf_table(&mut table, g, w);
|
||||
wnaf_form(&mut wnaf, s, w);
|
||||
wnaf_form(&mut wnaf, s.into_repr(), w);
|
||||
let g2 = wnaf_exp(&table, &wnaf);
|
||||
|
||||
assert_eq!(g1, g2);
|
||||
@ -103,17 +103,17 @@ fn random_wnaf_tests<G: CurveProjective>() {
|
||||
|
||||
for _ in 0..100 {
|
||||
let g = G::random(&mut rng);
|
||||
let s = G::Scalar::random(&mut rng).into_repr();
|
||||
let s = G::Scalar::random(&mut rng);
|
||||
let mut g1 = g;
|
||||
g1.mul_assign(s);
|
||||
|
||||
let g2 = {
|
||||
let mut wnaf = Wnaf::new();
|
||||
wnaf.base(g, 1).scalar(s)
|
||||
wnaf.base(g, 1).scalar(&s)
|
||||
};
|
||||
let g3 = {
|
||||
let mut wnaf = Wnaf::new();
|
||||
wnaf.scalar(s).base(g)
|
||||
wnaf.scalar(&s).base(g)
|
||||
};
|
||||
let g4 = {
|
||||
let mut wnaf = Wnaf::new();
|
||||
@ -121,11 +121,11 @@ fn random_wnaf_tests<G: CurveProjective>() {
|
||||
|
||||
only_compiles_if_send(&shared);
|
||||
|
||||
shared.scalar(s)
|
||||
shared.scalar(&s)
|
||||
};
|
||||
let g5 = {
|
||||
let mut wnaf = Wnaf::new();
|
||||
let mut shared = wnaf.scalar(s).shared();
|
||||
let mut shared = wnaf.scalar(&s).shared();
|
||||
|
||||
only_compiles_if_send(&shared);
|
||||
|
||||
@ -137,40 +137,40 @@ fn random_wnaf_tests<G: CurveProjective>() {
|
||||
{
|
||||
// Populate the vectors.
|
||||
wnaf.base(G::random(&mut rng), 1)
|
||||
.scalar(G::Scalar::random(&mut rng).into_repr());
|
||||
.scalar(&G::Scalar::random(&mut rng));
|
||||
}
|
||||
wnaf.base(g, 1).scalar(s)
|
||||
wnaf.base(g, 1).scalar(&s)
|
||||
};
|
||||
let g7 = {
|
||||
let mut wnaf = Wnaf::new();
|
||||
{
|
||||
// Populate the vectors.
|
||||
wnaf.base(G::random(&mut rng), 1)
|
||||
.scalar(G::Scalar::random(&mut rng).into_repr());
|
||||
.scalar(&G::Scalar::random(&mut rng));
|
||||
}
|
||||
wnaf.scalar(s).base(g)
|
||||
wnaf.scalar(&s).base(g)
|
||||
};
|
||||
let g8 = {
|
||||
let mut wnaf = Wnaf::new();
|
||||
{
|
||||
// Populate the vectors.
|
||||
wnaf.base(G::random(&mut rng), 1)
|
||||
.scalar(G::Scalar::random(&mut rng).into_repr());
|
||||
.scalar(&G::Scalar::random(&mut rng));
|
||||
}
|
||||
let mut shared = wnaf.base(g, 1).shared();
|
||||
|
||||
only_compiles_if_send(&shared);
|
||||
|
||||
shared.scalar(s)
|
||||
shared.scalar(&s)
|
||||
};
|
||||
let g9 = {
|
||||
let mut wnaf = Wnaf::new();
|
||||
{
|
||||
// Populate the vectors.
|
||||
wnaf.base(G::random(&mut rng), 1)
|
||||
.scalar(G::Scalar::random(&mut rng).into_repr());
|
||||
.scalar(&G::Scalar::random(&mut rng));
|
||||
}
|
||||
let mut shared = wnaf.scalar(s).shared();
|
||||
let mut shared = wnaf.scalar(&s).shared();
|
||||
|
||||
only_compiles_if_send(&shared);
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
use ff::{PrimeField, PrimeFieldRepr};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use ff::PrimeField;
|
||||
use std::iter;
|
||||
|
||||
use super::CurveProjective;
|
||||
|
||||
@ -16,31 +18,60 @@ pub(crate) fn wnaf_table<G: CurveProjective>(table: &mut Vec<G>, mut base: G, wi
|
||||
}
|
||||
}
|
||||
|
||||
/// Replaces the contents of `wnaf` with the w-NAF representation of a scalar.
|
||||
pub(crate) fn wnaf_form<S: PrimeFieldRepr>(wnaf: &mut Vec<i64>, mut c: S, window: usize) {
|
||||
/// Replaces the contents of `wnaf` with the w-NAF representation of a little-endian
|
||||
/// scalar.
|
||||
pub(crate) fn wnaf_form<S: AsRef<[u8]>>(wnaf: &mut Vec<i64>, c: S, window: usize) {
|
||||
// Required by the NAF definition
|
||||
debug_assert!(window >= 2);
|
||||
// Required so that the NAF digits fit in i64
|
||||
debug_assert!(window <= 64);
|
||||
|
||||
wnaf.truncate(0);
|
||||
|
||||
while !c.is_zero() {
|
||||
let mut u;
|
||||
if c.is_odd() {
|
||||
u = (c.as_ref()[0] % (1 << (window + 1))) as i64;
|
||||
let bit_len = c.as_ref().len() * 8;
|
||||
let u64_len = (bit_len + 1) / 64;
|
||||
|
||||
if u > (1 << window) {
|
||||
u -= 1 << (window + 1);
|
||||
}
|
||||
let mut c_u64 = vec![0u64; u64_len + 1];
|
||||
LittleEndian::read_u64_into(c.as_ref(), &mut c_u64[0..u64_len]);
|
||||
|
||||
if u > 0 {
|
||||
c.sub_noborrow(&S::from(u as u64));
|
||||
let width = 1u64 << window;
|
||||
let window_mask = width - 1;
|
||||
|
||||
let mut pos = 0;
|
||||
let mut carry = 0;
|
||||
while pos < bit_len {
|
||||
// Construct a buffer of bits of the scalar, starting at bit `pos`
|
||||
let u64_idx = pos / 64;
|
||||
let bit_idx = pos % 64;
|
||||
let bit_buf = if bit_idx + window < 64 {
|
||||
// This window's bits are contained in a single u64
|
||||
c_u64[u64_idx] >> bit_idx
|
||||
} else {
|
||||
c.add_nocarry(&S::from((-u) as u64));
|
||||
}
|
||||
// Combine the current u64's bits with the bits from the next u64
|
||||
(c_u64[u64_idx] >> bit_idx) | (c_u64[u64_idx + 1] << (64 - bit_idx))
|
||||
};
|
||||
|
||||
// Add the carry into the current window
|
||||
let window_val = carry + (bit_buf & window_mask);
|
||||
|
||||
if window_val & 1 == 0 {
|
||||
// If the window value is even, preserve the carry and emit 0.
|
||||
// Why is the carry preserved?
|
||||
// If carry == 0 and window_val & 1 == 0, then the next carry should be 0
|
||||
// If carry == 1 and window_val & 1 == 0, then bit_buf & 1 == 1 so the next carry should be 1
|
||||
wnaf.push(0);
|
||||
pos += 1;
|
||||
} else {
|
||||
u = 0;
|
||||
wnaf.push(if window_val < width / 2 {
|
||||
carry = 0;
|
||||
window_val as i64
|
||||
} else {
|
||||
carry = 1;
|
||||
(window_val as i64).wrapping_sub(width as i64)
|
||||
});
|
||||
wnaf.extend(iter::repeat(0).take(window - 1));
|
||||
pos += window;
|
||||
}
|
||||
|
||||
wnaf.push(u);
|
||||
|
||||
c.div2();
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,13 +143,13 @@ impl<G: CurveProjective> Wnaf<(), Vec<G>, Vec<i64>> {
|
||||
/// exponentiations with `.base(..)`.
|
||||
pub fn scalar(
|
||||
&mut self,
|
||||
scalar: <<G as CurveProjective>::Scalar as PrimeField>::Repr,
|
||||
scalar: &<G as CurveProjective>::Scalar,
|
||||
) -> Wnaf<usize, &mut Vec<G>, &[i64]> {
|
||||
// Compute the appropriate window size for the scalar.
|
||||
let window_size = G::recommended_wnaf_for_scalar(scalar);
|
||||
let window_size = G::recommended_wnaf_for_scalar(&scalar);
|
||||
|
||||
// Compute the wNAF form of the scalar.
|
||||
wnaf_form(&mut self.scalar, scalar, window_size);
|
||||
wnaf_form(&mut self.scalar, scalar.into_repr(), window_size);
|
||||
|
||||
// Return a Wnaf object that mutably borrows the base storage location, but
|
||||
// immutably borrows the computed wNAF form scalar location.
|
||||
@ -168,14 +199,11 @@ impl<B, S: AsRef<[i64]>> Wnaf<usize, B, S> {
|
||||
|
||||
impl<B, S: AsMut<Vec<i64>>> Wnaf<usize, B, S> {
|
||||
/// Performs exponentiation given a scalar.
|
||||
pub fn scalar<G: CurveProjective>(
|
||||
&mut self,
|
||||
scalar: <<G as CurveProjective>::Scalar as PrimeField>::Repr,
|
||||
) -> G
|
||||
pub fn scalar<G: CurveProjective>(&mut self, scalar: &<G as CurveProjective>::Scalar) -> G
|
||||
where
|
||||
B: AsRef<[G]>,
|
||||
{
|
||||
wnaf_form(self.scalar.as_mut(), scalar, self.window_size);
|
||||
wnaf_form(self.scalar.as_mut(), scalar.into_repr(), self.window_size);
|
||||
wnaf_exp(self.base.as_ref(), self.scalar.as_mut())
|
||||
}
|
||||
}
|
||||
|
@ -3,140 +3,9 @@ use rand_core::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
|
||||
|
||||
use ff::{Field, PrimeField, PrimeFieldRepr, SqrtField};
|
||||
use ff::{Field, PrimeField, SqrtField};
|
||||
use pairing::bls12_381::*;
|
||||
|
||||
fn bench_fq_repr_add_nocarry(c: &mut Criterion) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
let v: Vec<(FqRepr, FqRepr)> = (0..SAMPLES)
|
||||
.map(|_| {
|
||||
let mut tmp1 = Fq::random(&mut rng).into_repr();
|
||||
let mut tmp2 = Fq::random(&mut rng).into_repr();
|
||||
// Shave a few bits off to avoid overflow.
|
||||
for _ in 0..3 {
|
||||
tmp1.div2();
|
||||
tmp2.div2();
|
||||
}
|
||||
(tmp1, tmp2)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
c.bench_function("FqRepr::add_nocarry", |b| {
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
tmp.add_nocarry(&v[count].1);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn bench_fq_repr_sub_noborrow(c: &mut Criterion) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
let v: Vec<(FqRepr, FqRepr)> = (0..SAMPLES)
|
||||
.map(|_| {
|
||||
let tmp1 = Fq::random(&mut rng).into_repr();
|
||||
let mut tmp2 = tmp1;
|
||||
// Ensure tmp2 is smaller than tmp1.
|
||||
for _ in 0..10 {
|
||||
tmp2.div2();
|
||||
}
|
||||
(tmp1, tmp2)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
c.bench_function("FqRepr::sub_noborrow", |b| {
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
tmp.sub_noborrow(&v[count].1);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn bench_fq_repr_num_bits(c: &mut Criterion) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
let v: Vec<FqRepr> = (0..SAMPLES)
|
||||
.map(|_| Fq::random(&mut rng).into_repr())
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
c.bench_function("FqRepr::num_bits", |b| {
|
||||
b.iter(|| {
|
||||
let tmp = v[count].num_bits();
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn bench_fq_repr_mul2(c: &mut Criterion) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
let v: Vec<FqRepr> = (0..SAMPLES)
|
||||
.map(|_| Fq::random(&mut rng).into_repr())
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
c.bench_function("FqRepr::mul2", |b| {
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count];
|
||||
tmp.mul2();
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn bench_fq_repr_div2(c: &mut Criterion) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
let v: Vec<FqRepr> = (0..SAMPLES)
|
||||
.map(|_| Fq::random(&mut rng).into_repr())
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
c.bench_function("FqRepr::div2", |b| {
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count];
|
||||
tmp.div2();
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn bench_fq_add_assign(c: &mut Criterion) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
@ -328,11 +197,6 @@ fn bench_fq_from_repr(c: &mut Criterion) {
|
||||
|
||||
criterion_group!(
|
||||
benches,
|
||||
bench_fq_repr_add_nocarry,
|
||||
bench_fq_repr_sub_noborrow,
|
||||
bench_fq_repr_num_bits,
|
||||
bench_fq_repr_mul2,
|
||||
bench_fq_repr_div2,
|
||||
bench_fq_add_assign,
|
||||
bench_fq_sub_assign,
|
||||
bench_fq_mul_assign,
|
||||
|
@ -3,140 +3,9 @@ use rand_core::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
|
||||
|
||||
use ff::{Field, PrimeField, PrimeFieldRepr, SqrtField};
|
||||
use ff::{Field, PrimeField, SqrtField};
|
||||
use pairing::bls12_381::*;
|
||||
|
||||
fn bench_fr_repr_add_nocarry(c: &mut Criterion) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
let v: Vec<(FrRepr, FrRepr)> = (0..SAMPLES)
|
||||
.map(|_| {
|
||||
let mut tmp1 = Fr::random(&mut rng).into_repr();
|
||||
let mut tmp2 = Fr::random(&mut rng).into_repr();
|
||||
// Shave a few bits off to avoid overflow.
|
||||
for _ in 0..3 {
|
||||
tmp1.div2();
|
||||
tmp2.div2();
|
||||
}
|
||||
(tmp1, tmp2)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
c.bench_function("FrRepr::add_nocarry", |b| {
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
tmp.add_nocarry(&v[count].1);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn bench_fr_repr_sub_noborrow(c: &mut Criterion) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
let v: Vec<(FrRepr, FrRepr)> = (0..SAMPLES)
|
||||
.map(|_| {
|
||||
let tmp1 = Fr::random(&mut rng).into_repr();
|
||||
let mut tmp2 = tmp1;
|
||||
// Ensure tmp2 is smaller than tmp1.
|
||||
for _ in 0..10 {
|
||||
tmp2.div2();
|
||||
}
|
||||
(tmp1, tmp2)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
c.bench_function("FrRepr::sub_noborrow", |b| {
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count].0;
|
||||
tmp.sub_noborrow(&v[count].1);
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn bench_fr_repr_num_bits(c: &mut Criterion) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
let v: Vec<FrRepr> = (0..SAMPLES)
|
||||
.map(|_| Fr::random(&mut rng).into_repr())
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
c.bench_function("FrRepr::num_bits", |b| {
|
||||
b.iter(|| {
|
||||
let tmp = v[count].num_bits();
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn bench_fr_repr_mul2(c: &mut Criterion) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
let v: Vec<FrRepr> = (0..SAMPLES)
|
||||
.map(|_| Fr::random(&mut rng).into_repr())
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
c.bench_function("FrRepr::mul2", |b| {
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count];
|
||||
tmp.mul2();
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn bench_fr_repr_div2(c: &mut Criterion) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
let v: Vec<FrRepr> = (0..SAMPLES)
|
||||
.map(|_| Fr::random(&mut rng).into_repr())
|
||||
.collect();
|
||||
|
||||
let mut count = 0;
|
||||
c.bench_function("FrRepr::div2", |b| {
|
||||
b.iter(|| {
|
||||
let mut tmp = v[count];
|
||||
tmp.div2();
|
||||
count = (count + 1) % SAMPLES;
|
||||
tmp
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn bench_fr_add_assign(c: &mut Criterion) {
|
||||
const SAMPLES: usize = 1000;
|
||||
|
||||
@ -328,11 +197,6 @@ fn bench_fr_from_repr(c: &mut Criterion) {
|
||||
|
||||
criterion_group!(
|
||||
benches,
|
||||
bench_fr_repr_add_nocarry,
|
||||
bench_fr_repr_sub_noborrow,
|
||||
bench_fr_repr_num_bits,
|
||||
bench_fr_repr_mul2,
|
||||
bench_fr_repr_div2,
|
||||
bench_fr_add_assign,
|
||||
bench_fr_sub_assign,
|
||||
bench_fr_mul_assign,
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
use super::fq::{Fq, FROBENIUS_COEFF_FQ2_C1, NEGATIVE_ONE};
|
||||
use ff::{Field, SqrtField};
|
||||
use ff::{Field, PowVartime, SqrtField};
|
||||
use rand_core::RngCore;
|
||||
use std::cmp::Ordering;
|
||||
use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||
@ -254,7 +254,7 @@ impl SqrtField for Fq2 {
|
||||
} else {
|
||||
// a1 = self^((q - 3) / 4)
|
||||
let mut a1 = self.pow_vartime([
|
||||
0xee7fbfffffffeaaa,
|
||||
0xee7fbfffffffeaaau64,
|
||||
0x7aaffffac54ffff,
|
||||
0xd9cc34a83dac3d89,
|
||||
0xd91dd2e13ce144af,
|
||||
@ -286,7 +286,7 @@ impl SqrtField for Fq2 {
|
||||
alpha.add_assign(&Fq2::one());
|
||||
// alpha = alpha^((q - 1) / 2)
|
||||
alpha = alpha.pow_vartime([
|
||||
0xdcff7fffffffd555,
|
||||
0xdcff7fffffffd555u64,
|
||||
0xf55ffff58a9ffff,
|
||||
0xb39869507b587b12,
|
||||
0xb23ba5c279c2895f,
|
||||
@ -302,6 +302,11 @@ impl SqrtField for Fq2 {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
use super::fq::FqRepr;
|
||||
#[cfg(test)]
|
||||
use ff::PrimeField;
|
||||
|
||||
#[test]
|
||||
fn test_fq2_ordering() {
|
||||
let mut a = Fq2 {
|
||||
@ -353,9 +358,6 @@ fn test_fq2_basics() {
|
||||
|
||||
#[test]
|
||||
fn test_fq2_squaring() {
|
||||
use super::fq::FqRepr;
|
||||
use ff::PrimeField;
|
||||
|
||||
let a = Fq2 {
|
||||
c0: Fq::one(),
|
||||
c1: Fq::one(),
|
||||
@ -364,7 +366,7 @@ fn test_fq2_squaring() {
|
||||
a.square(),
|
||||
Fq2 {
|
||||
c0: Fq::zero(),
|
||||
c1: Fq::from_repr(FqRepr::from(2)).unwrap(),
|
||||
c1: Fq::from(2),
|
||||
}
|
||||
); // 2u
|
||||
|
||||
@ -381,21 +383,17 @@ fn test_fq2_squaring() {
|
||||
|
||||
let a = Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x9c2c6309bbf8b598,
|
||||
0x4eef5c946536f602,
|
||||
0x90e34aab6fb6a6bd,
|
||||
0xf7f295a94e58ae7c,
|
||||
0x41b76dcc1c3fbe5e,
|
||||
0x7080c5fa1d8e042,
|
||||
0x07, 0x08, 0x0c, 0x5f, 0xa1, 0xd8, 0xe0, 0x42, 0x41, 0xb7, 0x6d, 0xcc, 0x1c, 0x3f,
|
||||
0xbe, 0x5e, 0xf7, 0xf2, 0x95, 0xa9, 0x4e, 0x58, 0xae, 0x7c, 0x90, 0xe3, 0x4a, 0xab,
|
||||
0x6f, 0xb6, 0xa6, 0xbd, 0x4e, 0xef, 0x5c, 0x94, 0x65, 0x36, 0xf6, 0x02, 0x9c, 0x2c,
|
||||
0x63, 0x09, 0xbb, 0xf8, 0xb5, 0x98,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x38f473b3c870a4ab,
|
||||
0x6ad3291177c8c7e5,
|
||||
0xdac5a4c911a4353e,
|
||||
0xbfb99020604137a0,
|
||||
0xfc58a7b7be815407,
|
||||
0x10d1615e75250a21,
|
||||
0x10, 0xd1, 0x61, 0x5e, 0x75, 0x25, 0x0a, 0x21, 0xfc, 0x58, 0xa7, 0xb7, 0xbe, 0x81,
|
||||
0x54, 0x07, 0xbf, 0xb9, 0x90, 0x20, 0x60, 0x41, 0x37, 0xa0, 0xda, 0xc5, 0xa4, 0xc9,
|
||||
0x11, 0xa4, 0x35, 0x3e, 0x6a, 0xd3, 0x29, 0x11, 0x77, 0xc8, 0xc7, 0xe5, 0x38, 0xf4,
|
||||
0x73, 0xb3, 0xc8, 0x70, 0xa4, 0xab,
|
||||
]))
|
||||
.unwrap(),
|
||||
};
|
||||
@ -403,21 +401,17 @@ fn test_fq2_squaring() {
|
||||
a.square(),
|
||||
Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0xf262c28c538bcf68,
|
||||
0xb9f2a66eae1073ba,
|
||||
0xdc46ab8fad67ae0,
|
||||
0xcb674157618da176,
|
||||
0x4cf17b5893c3d327,
|
||||
0x7eac81369c43361
|
||||
0x07, 0xea, 0xc8, 0x13, 0x69, 0xc4, 0x33, 0x61, 0x4c, 0xf1, 0x7b, 0x58, 0x93, 0xc3,
|
||||
0xd3, 0x27, 0xcb, 0x67, 0x41, 0x57, 0x61, 0x8d, 0xa1, 0x76, 0x0d, 0xc4, 0x6a, 0xb8,
|
||||
0xfa, 0xd6, 0x7a, 0xe0, 0xb9, 0xf2, 0xa6, 0x6e, 0xae, 0x10, 0x73, 0xba, 0xf2, 0x62,
|
||||
0xc2, 0x8c, 0x53, 0x8b, 0xcf, 0x68,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0xc1579cf58e980cf8,
|
||||
0xa23eb7e12dd54d98,
|
||||
0xe75138bce4cec7aa,
|
||||
0x38d0d7275a9689e1,
|
||||
0x739c983042779a65,
|
||||
0x1542a61c8a8db994
|
||||
0x15, 0x42, 0xa6, 0x1c, 0x8a, 0x8d, 0xb9, 0x94, 0x73, 0x9c, 0x98, 0x30, 0x42, 0x77,
|
||||
0x9a, 0x65, 0x38, 0xd0, 0xd7, 0x27, 0x5a, 0x96, 0x89, 0xe1, 0xe7, 0x51, 0x38, 0xbc,
|
||||
0xe4, 0xce, 0xc7, 0xaa, 0xa2, 0x3e, 0xb7, 0xe1, 0x2d, 0xd5, 0x4d, 0x98, 0xc1, 0x57,
|
||||
0x9c, 0xf5, 0x8e, 0x98, 0x0c, 0xf8,
|
||||
]))
|
||||
.unwrap(),
|
||||
}
|
||||
@ -431,41 +425,33 @@ fn test_fq2_mul() {
|
||||
|
||||
let mut a = Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x85c9f989e1461f03,
|
||||
0xa2e33c333449a1d6,
|
||||
0x41e461154a7354a3,
|
||||
0x9ee53e7e84d7532e,
|
||||
0x1c202d8ed97afb45,
|
||||
0x51d3f9253e2516f,
|
||||
0x05, 0x1d, 0x3f, 0x92, 0x53, 0xe2, 0x51, 0x6f, 0x1c, 0x20, 0x2d, 0x8e, 0xd9, 0x7a,
|
||||
0xfb, 0x45, 0x9e, 0xe5, 0x3e, 0x7e, 0x84, 0xd7, 0x53, 0x2e, 0x41, 0xe4, 0x61, 0x15,
|
||||
0x4a, 0x73, 0x54, 0xa3, 0xa2, 0xe3, 0x3c, 0x33, 0x34, 0x49, 0xa1, 0xd6, 0x85, 0xc9,
|
||||
0xf9, 0x89, 0xe1, 0x46, 0x1f, 0x03,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0xa7348a8b511aedcf,
|
||||
0x143c215d8176b319,
|
||||
0x4cc48081c09b8903,
|
||||
0x9533e4a9a5158be,
|
||||
0x7a5e1ecb676d65f9,
|
||||
0x180c3ee46656b008,
|
||||
0x18, 0x0c, 0x3e, 0xe4, 0x66, 0x56, 0xb0, 0x08, 0x7a, 0x5e, 0x1e, 0xcb, 0x67, 0x6d,
|
||||
0x65, 0xf9, 0x09, 0x53, 0x3e, 0x4a, 0x9a, 0x51, 0x58, 0xbe, 0x4c, 0xc4, 0x80, 0x81,
|
||||
0xc0, 0x9b, 0x89, 0x03, 0x14, 0x3c, 0x21, 0x5d, 0x81, 0x76, 0xb3, 0x19, 0xa7, 0x34,
|
||||
0x8a, 0x8b, 0x51, 0x1a, 0xed, 0xcf,
|
||||
]))
|
||||
.unwrap(),
|
||||
};
|
||||
a.mul_assign(&Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0xe21f9169805f537e,
|
||||
0xfc87e62e179c285d,
|
||||
0x27ece175be07a531,
|
||||
0xcd460f9f0c23e430,
|
||||
0x6c9110292bfa409,
|
||||
0x2c93a72eb8af83e,
|
||||
0x02, 0xc9, 0x3a, 0x72, 0xeb, 0x8a, 0xf8, 0x3e, 0x06, 0xc9, 0x11, 0x02, 0x92, 0xbf,
|
||||
0xa4, 0x09, 0xcd, 0x46, 0x0f, 0x9f, 0x0c, 0x23, 0xe4, 0x30, 0x27, 0xec, 0xe1, 0x75,
|
||||
0xbe, 0x07, 0xa5, 0x31, 0xfc, 0x87, 0xe6, 0x2e, 0x17, 0x9c, 0x28, 0x5d, 0xe2, 0x1f,
|
||||
0x91, 0x69, 0x80, 0x5f, 0x53, 0x7e,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x4b1c3f936d8992d4,
|
||||
0x1d2a72916dba4c8a,
|
||||
0x8871c508658d1e5f,
|
||||
0x57a06d3135a752ae,
|
||||
0x634cd3c6c565096d,
|
||||
0x19e17334d4e93558,
|
||||
0x19, 0xe1, 0x73, 0x34, 0xd4, 0xe9, 0x35, 0x58, 0x63, 0x4c, 0xd3, 0xc6, 0xc5, 0x65,
|
||||
0x09, 0x6d, 0x57, 0xa0, 0x6d, 0x31, 0x35, 0xa7, 0x52, 0xae, 0x88, 0x71, 0xc5, 0x08,
|
||||
0x65, 0x8d, 0x1e, 0x5f, 0x1d, 0x2a, 0x72, 0x91, 0x6d, 0xba, 0x4c, 0x8a, 0x4b, 0x1c,
|
||||
0x3f, 0x93, 0x6d, 0x89, 0x92, 0xd4,
|
||||
]))
|
||||
.unwrap(),
|
||||
});
|
||||
@ -473,21 +459,17 @@ fn test_fq2_mul() {
|
||||
a,
|
||||
Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x95b5127e6360c7e4,
|
||||
0xde29c31a19a6937e,
|
||||
0xf61a96dacf5a39bc,
|
||||
0x5511fe4d84ee5f78,
|
||||
0x5310a202d92f9963,
|
||||
0x1751afbe166e5399
|
||||
0x17, 0x51, 0xaf, 0xbe, 0x16, 0x6e, 0x53, 0x99, 0x53, 0x10, 0xa2, 0x02, 0xd9, 0x2f,
|
||||
0x99, 0x63, 0x55, 0x11, 0xfe, 0x4d, 0x84, 0xee, 0x5f, 0x78, 0xf6, 0x1a, 0x96, 0xda,
|
||||
0xcf, 0x5a, 0x39, 0xbc, 0xde, 0x29, 0xc3, 0x1a, 0x19, 0xa6, 0x93, 0x7e, 0x95, 0xb5,
|
||||
0x12, 0x7e, 0x63, 0x60, 0xc7, 0xe4,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x84af0e1bd630117a,
|
||||
0x6c63cd4da2c2aa7,
|
||||
0x5ba6e5430e883d40,
|
||||
0xc975106579c275ee,
|
||||
0x33a9ac82ce4c5083,
|
||||
0x1ef1a36c201589d
|
||||
0x01, 0xef, 0x1a, 0x36, 0xc2, 0x01, 0x58, 0x9d, 0x33, 0xa9, 0xac, 0x82, 0xce, 0x4c,
|
||||
0x50, 0x83, 0xc9, 0x75, 0x10, 0x65, 0x79, 0xc2, 0x75, 0xee, 0x5b, 0xa6, 0xe5, 0x43,
|
||||
0x0e, 0x88, 0x3d, 0x40, 0x06, 0xc6, 0x3c, 0xd4, 0xda, 0x2c, 0x2a, 0xa7, 0x84, 0xaf,
|
||||
0x0e, 0x1b, 0xd6, 0x30, 0x11, 0x7a,
|
||||
]))
|
||||
.unwrap(),
|
||||
}
|
||||
@ -503,21 +485,17 @@ fn test_fq2_invert() {
|
||||
|
||||
let a = Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x85c9f989e1461f03,
|
||||
0xa2e33c333449a1d6,
|
||||
0x41e461154a7354a3,
|
||||
0x9ee53e7e84d7532e,
|
||||
0x1c202d8ed97afb45,
|
||||
0x51d3f9253e2516f,
|
||||
0x05, 0x1d, 0x3f, 0x92, 0x53, 0xe2, 0x51, 0x6f, 0x1c, 0x20, 0x2d, 0x8e, 0xd9, 0x7a,
|
||||
0xfb, 0x45, 0x9e, 0xe5, 0x3e, 0x7e, 0x84, 0xd7, 0x53, 0x2e, 0x41, 0xe4, 0x61, 0x15,
|
||||
0x4a, 0x73, 0x54, 0xa3, 0xa2, 0xe3, 0x3c, 0x33, 0x34, 0x49, 0xa1, 0xd6, 0x85, 0xc9,
|
||||
0xf9, 0x89, 0xe1, 0x46, 0x1f, 0x03,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0xa7348a8b511aedcf,
|
||||
0x143c215d8176b319,
|
||||
0x4cc48081c09b8903,
|
||||
0x9533e4a9a5158be,
|
||||
0x7a5e1ecb676d65f9,
|
||||
0x180c3ee46656b008,
|
||||
0x18, 0x0c, 0x3e, 0xe4, 0x66, 0x56, 0xb0, 0x08, 0x7a, 0x5e, 0x1e, 0xcb, 0x67, 0x6d,
|
||||
0x65, 0xf9, 0x09, 0x53, 0x3e, 0x4a, 0x9a, 0x51, 0x58, 0xbe, 0x4c, 0xc4, 0x80, 0x81,
|
||||
0xc0, 0x9b, 0x89, 0x03, 0x14, 0x3c, 0x21, 0x5d, 0x81, 0x76, 0xb3, 0x19, 0xa7, 0x34,
|
||||
0x8a, 0x8b, 0x51, 0x1a, 0xed, 0xcf,
|
||||
]))
|
||||
.unwrap(),
|
||||
};
|
||||
@ -526,21 +504,17 @@ fn test_fq2_invert() {
|
||||
a,
|
||||
Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x70300f9bcb9e594,
|
||||
0xe5ecda5fdafddbb2,
|
||||
0x64bef617d2915a8f,
|
||||
0xdfba703293941c30,
|
||||
0xa6c3d8f9586f2636,
|
||||
0x1351ef01941b70c4
|
||||
0x13, 0x51, 0xef, 0x01, 0x94, 0x1b, 0x70, 0xc4, 0xa6, 0xc3, 0xd8, 0xf9, 0x58, 0x6f,
|
||||
0x26, 0x36, 0xdf, 0xba, 0x70, 0x32, 0x93, 0x94, 0x1c, 0x30, 0x64, 0xbe, 0xf6, 0x17,
|
||||
0xd2, 0x91, 0x5a, 0x8f, 0xe5, 0xec, 0xda, 0x5f, 0xda, 0xfd, 0xdb, 0xb2, 0x07, 0x03,
|
||||
0x00, 0xf9, 0xbc, 0xb9, 0xe5, 0x94,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x8c39fd76a8312cb4,
|
||||
0x15d7b6b95defbff0,
|
||||
0x947143f89faedee9,
|
||||
0xcbf651a0f367afb2,
|
||||
0xdf4e54f0d3ef15a6,
|
||||
0x103bdf241afb0019
|
||||
0x10, 0x3b, 0xdf, 0x24, 0x1a, 0xfb, 0x00, 0x19, 0xdf, 0x4e, 0x54, 0xf0, 0xd3, 0xef,
|
||||
0x15, 0xa6, 0xcb, 0xf6, 0x51, 0xa0, 0xf3, 0x67, 0xaf, 0xb2, 0x94, 0x71, 0x43, 0xf8,
|
||||
0x9f, 0xae, 0xde, 0xe9, 0x15, 0xd7, 0xb6, 0xb9, 0x5d, 0xef, 0xbf, 0xf0, 0x8c, 0x39,
|
||||
0xfd, 0x76, 0xa8, 0x31, 0x2c, 0xb4,
|
||||
]))
|
||||
.unwrap(),
|
||||
}
|
||||
@ -554,41 +528,33 @@ fn test_fq2_addition() {
|
||||
|
||||
let mut a = Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x2d0078036923ffc7,
|
||||
0x11e59ea221a3b6d2,
|
||||
0x8b1a52e0a90f59ed,
|
||||
0xb966ce3bc2108b13,
|
||||
0xccc649c4b9532bf3,
|
||||
0xf8d295b2ded9dc,
|
||||
0x00, 0xf8, 0xd2, 0x95, 0xb2, 0xde, 0xd9, 0xdc, 0xcc, 0xc6, 0x49, 0xc4, 0xb9, 0x53,
|
||||
0x2b, 0xf3, 0xb9, 0x66, 0xce, 0x3b, 0xc2, 0x10, 0x8b, 0x13, 0x8b, 0x1a, 0x52, 0xe0,
|
||||
0xa9, 0x0f, 0x59, 0xed, 0x11, 0xe5, 0x9e, 0xa2, 0x21, 0xa3, 0xb6, 0xd2, 0x2d, 0x00,
|
||||
0x78, 0x03, 0x69, 0x23, 0xff, 0xc7,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x977df6efcdaee0db,
|
||||
0x946ae52d684fa7ed,
|
||||
0xbe203411c66fb3a5,
|
||||
0xb3f8afc0ee248cad,
|
||||
0x4e464dea5bcfd41e,
|
||||
0x12d1137b8a6a837,
|
||||
0x01, 0x2d, 0x11, 0x37, 0xb8, 0xa6, 0xa8, 0x37, 0x4e, 0x46, 0x4d, 0xea, 0x5b, 0xcf,
|
||||
0xd4, 0x1e, 0xb3, 0xf8, 0xaf, 0xc0, 0xee, 0x24, 0x8c, 0xad, 0xbe, 0x20, 0x34, 0x11,
|
||||
0xc6, 0x6f, 0xb3, 0xa5, 0x94, 0x6a, 0xe5, 0x2d, 0x68, 0x4f, 0xa7, 0xed, 0x97, 0x7d,
|
||||
0xf6, 0xef, 0xcd, 0xae, 0xe0, 0xdb,
|
||||
]))
|
||||
.unwrap(),
|
||||
};
|
||||
a.add_assign(&Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x619a02d78dc70ef2,
|
||||
0xb93adfc9119e33e8,
|
||||
0x4bf0b99a9f0dca12,
|
||||
0x3b88899a42a6318f,
|
||||
0x986a4a62fa82a49d,
|
||||
0x13ce433fa26027f5,
|
||||
0x13, 0xce, 0x43, 0x3f, 0xa2, 0x60, 0x27, 0xf5, 0x98, 0x6a, 0x4a, 0x62, 0xfa, 0x82,
|
||||
0xa4, 0x9d, 0x3b, 0x88, 0x89, 0x9a, 0x42, 0xa6, 0x31, 0x8f, 0x4b, 0xf0, 0xb9, 0x9a,
|
||||
0x9f, 0x0d, 0xca, 0x12, 0xb9, 0x3a, 0xdf, 0xc9, 0x11, 0x9e, 0x33, 0xe8, 0x61, 0x9a,
|
||||
0x02, 0xd7, 0x8d, 0xc7, 0x0e, 0xf2,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x66323bf80b58b9b9,
|
||||
0xa1379b6facf6e596,
|
||||
0x402aef1fb797e32f,
|
||||
0x2236f55246d0d44d,
|
||||
0x4c8c1800eb104566,
|
||||
0x11d6e20e986c2085,
|
||||
0x11, 0xd6, 0xe2, 0x0e, 0x98, 0x6c, 0x20, 0x85, 0x4c, 0x8c, 0x18, 0x00, 0xeb, 0x10,
|
||||
0x45, 0x66, 0x22, 0x36, 0xf5, 0x52, 0x46, 0xd0, 0xd4, 0x4d, 0x40, 0x2a, 0xef, 0x1f,
|
||||
0xb7, 0x97, 0xe3, 0x2f, 0xa1, 0x37, 0x9b, 0x6f, 0xac, 0xf6, 0xe5, 0x96, 0x66, 0x32,
|
||||
0x3b, 0xf8, 0x0b, 0x58, 0xb9, 0xb9,
|
||||
]))
|
||||
.unwrap(),
|
||||
});
|
||||
@ -596,21 +562,17 @@ fn test_fq2_addition() {
|
||||
a,
|
||||
Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x8e9a7adaf6eb0eb9,
|
||||
0xcb207e6b3341eaba,
|
||||
0xd70b0c7b481d23ff,
|
||||
0xf4ef57d604b6bca2,
|
||||
0x65309427b3d5d090,
|
||||
0x14c715d5553f01d2
|
||||
0x14, 0xc7, 0x15, 0xd5, 0x55, 0x3f, 0x01, 0xd2, 0x65, 0x30, 0x94, 0x27, 0xb3, 0xd5,
|
||||
0xd0, 0x90, 0xf4, 0xef, 0x57, 0xd6, 0x04, 0xb6, 0xbc, 0xa2, 0xd7, 0x0b, 0x0c, 0x7b,
|
||||
0x48, 0x1d, 0x23, 0xff, 0xcb, 0x20, 0x7e, 0x6b, 0x33, 0x41, 0xea, 0xba, 0x8e, 0x9a,
|
||||
0x7a, 0xda, 0xf6, 0xeb, 0x0e, 0xb9,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0xfdb032e7d9079a94,
|
||||
0x35a2809d15468d83,
|
||||
0xfe4b23317e0796d5,
|
||||
0xd62fa51334f560fa,
|
||||
0x9ad265eb46e01984,
|
||||
0x1303f3465112c8bc
|
||||
0x13, 0x03, 0xf3, 0x46, 0x51, 0x12, 0xc8, 0xbc, 0x9a, 0xd2, 0x65, 0xeb, 0x46, 0xe0,
|
||||
0x19, 0x84, 0xd6, 0x2f, 0xa5, 0x13, 0x34, 0xf5, 0x60, 0xfa, 0xfe, 0x4b, 0x23, 0x31,
|
||||
0x7e, 0x07, 0x96, 0xd5, 0x35, 0xa2, 0x80, 0x9d, 0x15, 0x46, 0x8d, 0x83, 0xfd, 0xb0,
|
||||
0x32, 0xe7, 0xd9, 0x07, 0x9a, 0x94,
|
||||
]))
|
||||
.unwrap(),
|
||||
}
|
||||
@ -624,41 +586,33 @@ fn test_fq2_subtraction() {
|
||||
|
||||
let mut a = Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x2d0078036923ffc7,
|
||||
0x11e59ea221a3b6d2,
|
||||
0x8b1a52e0a90f59ed,
|
||||
0xb966ce3bc2108b13,
|
||||
0xccc649c4b9532bf3,
|
||||
0xf8d295b2ded9dc,
|
||||
0x00, 0xf8, 0xd2, 0x95, 0xb2, 0xde, 0xd9, 0xdc, 0xcc, 0xc6, 0x49, 0xc4, 0xb9, 0x53,
|
||||
0x2b, 0xf3, 0xb9, 0x66, 0xce, 0x3b, 0xc2, 0x10, 0x8b, 0x13, 0x8b, 0x1a, 0x52, 0xe0,
|
||||
0xa9, 0x0f, 0x59, 0xed, 0x11, 0xe5, 0x9e, 0xa2, 0x21, 0xa3, 0xb6, 0xd2, 0x2d, 0x00,
|
||||
0x78, 0x03, 0x69, 0x23, 0xff, 0xc7,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x977df6efcdaee0db,
|
||||
0x946ae52d684fa7ed,
|
||||
0xbe203411c66fb3a5,
|
||||
0xb3f8afc0ee248cad,
|
||||
0x4e464dea5bcfd41e,
|
||||
0x12d1137b8a6a837,
|
||||
0x01, 0x2d, 0x11, 0x37, 0xb8, 0xa6, 0xa8, 0x37, 0x4e, 0x46, 0x4d, 0xea, 0x5b, 0xcf,
|
||||
0xd4, 0x1e, 0xb3, 0xf8, 0xaf, 0xc0, 0xee, 0x24, 0x8c, 0xad, 0xbe, 0x20, 0x34, 0x11,
|
||||
0xc6, 0x6f, 0xb3, 0xa5, 0x94, 0x6a, 0xe5, 0x2d, 0x68, 0x4f, 0xa7, 0xed, 0x97, 0x7d,
|
||||
0xf6, 0xef, 0xcd, 0xae, 0xe0, 0xdb,
|
||||
]))
|
||||
.unwrap(),
|
||||
};
|
||||
a.sub_assign(&Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x619a02d78dc70ef2,
|
||||
0xb93adfc9119e33e8,
|
||||
0x4bf0b99a9f0dca12,
|
||||
0x3b88899a42a6318f,
|
||||
0x986a4a62fa82a49d,
|
||||
0x13ce433fa26027f5,
|
||||
0x13, 0xce, 0x43, 0x3f, 0xa2, 0x60, 0x27, 0xf5, 0x98, 0x6a, 0x4a, 0x62, 0xfa, 0x82,
|
||||
0xa4, 0x9d, 0x3b, 0x88, 0x89, 0x9a, 0x42, 0xa6, 0x31, 0x8f, 0x4b, 0xf0, 0xb9, 0x9a,
|
||||
0x9f, 0x0d, 0xca, 0x12, 0xb9, 0x3a, 0xdf, 0xc9, 0x11, 0x9e, 0x33, 0xe8, 0x61, 0x9a,
|
||||
0x02, 0xd7, 0x8d, 0xc7, 0x0e, 0xf2,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x66323bf80b58b9b9,
|
||||
0xa1379b6facf6e596,
|
||||
0x402aef1fb797e32f,
|
||||
0x2236f55246d0d44d,
|
||||
0x4c8c1800eb104566,
|
||||
0x11d6e20e986c2085,
|
||||
0x11, 0xd6, 0xe2, 0x0e, 0x98, 0x6c, 0x20, 0x85, 0x4c, 0x8c, 0x18, 0x00, 0xeb, 0x10,
|
||||
0x45, 0x66, 0x22, 0x36, 0xf5, 0x52, 0x46, 0xd0, 0xd4, 0x4d, 0x40, 0x2a, 0xef, 0x1f,
|
||||
0xb7, 0x97, 0xe3, 0x2f, 0xa1, 0x37, 0x9b, 0x6f, 0xac, 0xf6, 0xe5, 0x96, 0x66, 0x32,
|
||||
0x3b, 0xf8, 0x0b, 0x58, 0xb9, 0xb9,
|
||||
]))
|
||||
.unwrap(),
|
||||
});
|
||||
@ -666,21 +620,17 @@ fn test_fq2_subtraction() {
|
||||
a,
|
||||
Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x8565752bdb5c9b80,
|
||||
0x7756bed7c15982e9,
|
||||
0xa65a6be700b285fe,
|
||||
0xe255902672ef6c43,
|
||||
0x7f77a718021c342d,
|
||||
0x72ba14049fe9881
|
||||
0x07, 0x2b, 0xa1, 0x40, 0x49, 0xfe, 0x98, 0x81, 0x7f, 0x77, 0xa7, 0x18, 0x02, 0x1c,
|
||||
0x34, 0x2d, 0xe2, 0x55, 0x90, 0x26, 0x72, 0xef, 0x6c, 0x43, 0xa6, 0x5a, 0x6b, 0xe7,
|
||||
0x00, 0xb2, 0x85, 0xfe, 0x77, 0x56, 0xbe, 0xd7, 0xc1, 0x59, 0x82, 0xe9, 0x85, 0x65,
|
||||
0x75, 0x2b, 0xdb, 0x5c, 0x9b, 0x80,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0xeb4abaf7c255d1cd,
|
||||
0x11df49bc6cacc256,
|
||||
0xe52617930588c69a,
|
||||
0xf63905f39ad8cb1f,
|
||||
0x4cd5dd9fb40b3b8f,
|
||||
0x957411359ba6e4c
|
||||
0x09, 0x57, 0x41, 0x13, 0x59, 0xba, 0x6e, 0x4c, 0x4c, 0xd5, 0xdd, 0x9f, 0xb4, 0x0b,
|
||||
0x3b, 0x8f, 0xf6, 0x39, 0x05, 0xf3, 0x9a, 0xd8, 0xcb, 0x1f, 0xe5, 0x26, 0x17, 0x93,
|
||||
0x05, 0x88, 0xc6, 0x9a, 0x11, 0xdf, 0x49, 0xbc, 0x6c, 0xac, 0xc2, 0x56, 0xeb, 0x4a,
|
||||
0xba, 0xf7, 0xc2, 0x55, 0xd1, 0xcd,
|
||||
]))
|
||||
.unwrap(),
|
||||
}
|
||||
@ -694,21 +644,17 @@ fn test_fq2_negation() {
|
||||
|
||||
let a = Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x2d0078036923ffc7,
|
||||
0x11e59ea221a3b6d2,
|
||||
0x8b1a52e0a90f59ed,
|
||||
0xb966ce3bc2108b13,
|
||||
0xccc649c4b9532bf3,
|
||||
0xf8d295b2ded9dc,
|
||||
0x00, 0xf8, 0xd2, 0x95, 0xb2, 0xde, 0xd9, 0xdc, 0xcc, 0xc6, 0x49, 0xc4, 0xb9, 0x53,
|
||||
0x2b, 0xf3, 0xb9, 0x66, 0xce, 0x3b, 0xc2, 0x10, 0x8b, 0x13, 0x8b, 0x1a, 0x52, 0xe0,
|
||||
0xa9, 0x0f, 0x59, 0xed, 0x11, 0xe5, 0x9e, 0xa2, 0x21, 0xa3, 0xb6, 0xd2, 0x2d, 0x00,
|
||||
0x78, 0x03, 0x69, 0x23, 0xff, 0xc7,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x977df6efcdaee0db,
|
||||
0x946ae52d684fa7ed,
|
||||
0xbe203411c66fb3a5,
|
||||
0xb3f8afc0ee248cad,
|
||||
0x4e464dea5bcfd41e,
|
||||
0x12d1137b8a6a837,
|
||||
0x01, 0x2d, 0x11, 0x37, 0xb8, 0xa6, 0xa8, 0x37, 0x4e, 0x46, 0x4d, 0xea, 0x5b, 0xcf,
|
||||
0xd4, 0x1e, 0xb3, 0xf8, 0xaf, 0xc0, 0xee, 0x24, 0x8c, 0xad, 0xbe, 0x20, 0x34, 0x11,
|
||||
0xc6, 0x6f, 0xb3, 0xa5, 0x94, 0x6a, 0xe5, 0x2d, 0x68, 0x4f, 0xa7, 0xed, 0x97, 0x7d,
|
||||
0xf6, 0xef, 0xcd, 0xae, 0xe0, 0xdb,
|
||||
]))
|
||||
.unwrap(),
|
||||
}
|
||||
@ -717,21 +663,17 @@ fn test_fq2_negation() {
|
||||
a,
|
||||
Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x8cfe87fc96dbaae4,
|
||||
0xcc6615c8fb0492d,
|
||||
0xdc167fc04da19c37,
|
||||
0xab107d49317487ab,
|
||||
0x7e555df189f880e3,
|
||||
0x19083f5486a10cbd
|
||||
0x19, 0x08, 0x3f, 0x54, 0x86, 0xa1, 0x0c, 0xbd, 0x7e, 0x55, 0x5d, 0xf1, 0x89, 0xf8,
|
||||
0x80, 0xe3, 0xab, 0x10, 0x7d, 0x49, 0x31, 0x74, 0x87, 0xab, 0xdc, 0x16, 0x7f, 0xc0,
|
||||
0x4d, 0xa1, 0x9c, 0x37, 0x0c, 0xc6, 0x61, 0x5c, 0x8f, 0xb0, 0x49, 0x2d, 0x8c, 0xfe,
|
||||
0x87, 0xfc, 0x96, 0xdb, 0xaa, 0xe4,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x228109103250c9d0,
|
||||
0x8a411ad149045812,
|
||||
0xa9109e8f3041427e,
|
||||
0xb07e9bc405608611,
|
||||
0xfcd559cbe77bd8b8,
|
||||
0x18d400b280d93e62
|
||||
0x18, 0xd4, 0x00, 0xb2, 0x80, 0xd9, 0x3e, 0x62, 0xfc, 0xd5, 0x59, 0xcb, 0xe7, 0x7b,
|
||||
0xd8, 0xb8, 0xb0, 0x7e, 0x9b, 0xc4, 0x05, 0x60, 0x86, 0x11, 0xa9, 0x10, 0x9e, 0x8f,
|
||||
0x30, 0x41, 0x42, 0x7e, 0x8a, 0x41, 0x1a, 0xd1, 0x49, 0x04, 0x58, 0x12, 0x22, 0x81,
|
||||
0x09, 0x10, 0x32, 0x50, 0xc9, 0xd0,
|
||||
]))
|
||||
.unwrap(),
|
||||
}
|
||||
@ -745,21 +687,17 @@ fn test_fq2_doubling() {
|
||||
|
||||
let a = Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x2d0078036923ffc7,
|
||||
0x11e59ea221a3b6d2,
|
||||
0x8b1a52e0a90f59ed,
|
||||
0xb966ce3bc2108b13,
|
||||
0xccc649c4b9532bf3,
|
||||
0xf8d295b2ded9dc,
|
||||
0x00, 0xf8, 0xd2, 0x95, 0xb2, 0xde, 0xd9, 0xdc, 0xcc, 0xc6, 0x49, 0xc4, 0xb9, 0x53,
|
||||
0x2b, 0xf3, 0xb9, 0x66, 0xce, 0x3b, 0xc2, 0x10, 0x8b, 0x13, 0x8b, 0x1a, 0x52, 0xe0,
|
||||
0xa9, 0x0f, 0x59, 0xed, 0x11, 0xe5, 0x9e, 0xa2, 0x21, 0xa3, 0xb6, 0xd2, 0x2d, 0x00,
|
||||
0x78, 0x03, 0x69, 0x23, 0xff, 0xc7,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x977df6efcdaee0db,
|
||||
0x946ae52d684fa7ed,
|
||||
0xbe203411c66fb3a5,
|
||||
0xb3f8afc0ee248cad,
|
||||
0x4e464dea5bcfd41e,
|
||||
0x12d1137b8a6a837,
|
||||
0x01, 0x2d, 0x11, 0x37, 0xb8, 0xa6, 0xa8, 0x37, 0x4e, 0x46, 0x4d, 0xea, 0x5b, 0xcf,
|
||||
0xd4, 0x1e, 0xb3, 0xf8, 0xaf, 0xc0, 0xee, 0x24, 0x8c, 0xad, 0xbe, 0x20, 0x34, 0x11,
|
||||
0xc6, 0x6f, 0xb3, 0xa5, 0x94, 0x6a, 0xe5, 0x2d, 0x68, 0x4f, 0xa7, 0xed, 0x97, 0x7d,
|
||||
0xf6, 0xef, 0xcd, 0xae, 0xe0, 0xdb,
|
||||
]))
|
||||
.unwrap(),
|
||||
};
|
||||
@ -767,21 +705,17 @@ fn test_fq2_doubling() {
|
||||
a.double(),
|
||||
Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x5a00f006d247ff8e,
|
||||
0x23cb3d4443476da4,
|
||||
0x1634a5c1521eb3da,
|
||||
0x72cd9c7784211627,
|
||||
0x998c938972a657e7,
|
||||
0x1f1a52b65bdb3b9
|
||||
0x01, 0xf1, 0xa5, 0x2b, 0x65, 0xbd, 0xb3, 0xb9, 0x99, 0x8c, 0x93, 0x89, 0x72, 0xa6,
|
||||
0x57, 0xe7, 0x72, 0xcd, 0x9c, 0x77, 0x84, 0x21, 0x16, 0x27, 0x16, 0x34, 0xa5, 0xc1,
|
||||
0x52, 0x1e, 0xb3, 0xda, 0x23, 0xcb, 0x3d, 0x44, 0x43, 0x47, 0x6d, 0xa4, 0x5a, 0x00,
|
||||
0xf0, 0x06, 0xd2, 0x47, 0xff, 0x8e,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x2efbeddf9b5dc1b6,
|
||||
0x28d5ca5ad09f4fdb,
|
||||
0x7c4068238cdf674b,
|
||||
0x67f15f81dc49195b,
|
||||
0x9c8c9bd4b79fa83d,
|
||||
0x25a226f714d506e
|
||||
0x02, 0x5a, 0x22, 0x6f, 0x71, 0x4d, 0x50, 0x6e, 0x9c, 0x8c, 0x9b, 0xd4, 0xb7, 0x9f,
|
||||
0xa8, 0x3d, 0x67, 0xf1, 0x5f, 0x81, 0xdc, 0x49, 0x19, 0x5b, 0x7c, 0x40, 0x68, 0x23,
|
||||
0x8c, 0xdf, 0x67, 0x4b, 0x28, 0xd5, 0xca, 0x5a, 0xd0, 0x9f, 0x4f, 0xdb, 0x2e, 0xfb,
|
||||
0xed, 0xdf, 0x9b, 0x5d, 0xc1, 0xb6,
|
||||
]))
|
||||
.unwrap(),
|
||||
}
|
||||
@ -795,21 +729,17 @@ fn test_fq2_frobenius_map() {
|
||||
|
||||
let mut a = Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x2d0078036923ffc7,
|
||||
0x11e59ea221a3b6d2,
|
||||
0x8b1a52e0a90f59ed,
|
||||
0xb966ce3bc2108b13,
|
||||
0xccc649c4b9532bf3,
|
||||
0xf8d295b2ded9dc,
|
||||
0x00, 0xf8, 0xd2, 0x95, 0xb2, 0xde, 0xd9, 0xdc, 0xcc, 0xc6, 0x49, 0xc4, 0xb9, 0x53,
|
||||
0x2b, 0xf3, 0xb9, 0x66, 0xce, 0x3b, 0xc2, 0x10, 0x8b, 0x13, 0x8b, 0x1a, 0x52, 0xe0,
|
||||
0xa9, 0x0f, 0x59, 0xed, 0x11, 0xe5, 0x9e, 0xa2, 0x21, 0xa3, 0xb6, 0xd2, 0x2d, 0x00,
|
||||
0x78, 0x03, 0x69, 0x23, 0xff, 0xc7,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x977df6efcdaee0db,
|
||||
0x946ae52d684fa7ed,
|
||||
0xbe203411c66fb3a5,
|
||||
0xb3f8afc0ee248cad,
|
||||
0x4e464dea5bcfd41e,
|
||||
0x12d1137b8a6a837,
|
||||
0x01, 0x2d, 0x11, 0x37, 0xb8, 0xa6, 0xa8, 0x37, 0x4e, 0x46, 0x4d, 0xea, 0x5b, 0xcf,
|
||||
0xd4, 0x1e, 0xb3, 0xf8, 0xaf, 0xc0, 0xee, 0x24, 0x8c, 0xad, 0xbe, 0x20, 0x34, 0x11,
|
||||
0xc6, 0x6f, 0xb3, 0xa5, 0x94, 0x6a, 0xe5, 0x2d, 0x68, 0x4f, 0xa7, 0xed, 0x97, 0x7d,
|
||||
0xf6, 0xef, 0xcd, 0xae, 0xe0, 0xdb,
|
||||
]))
|
||||
.unwrap(),
|
||||
};
|
||||
@ -818,21 +748,17 @@ fn test_fq2_frobenius_map() {
|
||||
a,
|
||||
Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x2d0078036923ffc7,
|
||||
0x11e59ea221a3b6d2,
|
||||
0x8b1a52e0a90f59ed,
|
||||
0xb966ce3bc2108b13,
|
||||
0xccc649c4b9532bf3,
|
||||
0xf8d295b2ded9dc
|
||||
0x00, 0xf8, 0xd2, 0x95, 0xb2, 0xde, 0xd9, 0xdc, 0xcc, 0xc6, 0x49, 0xc4, 0xb9, 0x53,
|
||||
0x2b, 0xf3, 0xb9, 0x66, 0xce, 0x3b, 0xc2, 0x10, 0x8b, 0x13, 0x8b, 0x1a, 0x52, 0xe0,
|
||||
0xa9, 0x0f, 0x59, 0xed, 0x11, 0xe5, 0x9e, 0xa2, 0x21, 0xa3, 0xb6, 0xd2, 0x2d, 0x00,
|
||||
0x78, 0x03, 0x69, 0x23, 0xff, 0xc7,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x977df6efcdaee0db,
|
||||
0x946ae52d684fa7ed,
|
||||
0xbe203411c66fb3a5,
|
||||
0xb3f8afc0ee248cad,
|
||||
0x4e464dea5bcfd41e,
|
||||
0x12d1137b8a6a837
|
||||
0x01, 0x2d, 0x11, 0x37, 0xb8, 0xa6, 0xa8, 0x37, 0x4e, 0x46, 0x4d, 0xea, 0x5b, 0xcf,
|
||||
0xd4, 0x1e, 0xb3, 0xf8, 0xaf, 0xc0, 0xee, 0x24, 0x8c, 0xad, 0xbe, 0x20, 0x34, 0x11,
|
||||
0xc6, 0x6f, 0xb3, 0xa5, 0x94, 0x6a, 0xe5, 0x2d, 0x68, 0x4f, 0xa7, 0xed, 0x97, 0x7d,
|
||||
0xf6, 0xef, 0xcd, 0xae, 0xe0, 0xdb,
|
||||
]))
|
||||
.unwrap(),
|
||||
}
|
||||
@ -842,21 +768,17 @@ fn test_fq2_frobenius_map() {
|
||||
a,
|
||||
Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x2d0078036923ffc7,
|
||||
0x11e59ea221a3b6d2,
|
||||
0x8b1a52e0a90f59ed,
|
||||
0xb966ce3bc2108b13,
|
||||
0xccc649c4b9532bf3,
|
||||
0xf8d295b2ded9dc
|
||||
0x00, 0xf8, 0xd2, 0x95, 0xb2, 0xde, 0xd9, 0xdc, 0xcc, 0xc6, 0x49, 0xc4, 0xb9, 0x53,
|
||||
0x2b, 0xf3, 0xb9, 0x66, 0xce, 0x3b, 0xc2, 0x10, 0x8b, 0x13, 0x8b, 0x1a, 0x52, 0xe0,
|
||||
0xa9, 0x0f, 0x59, 0xed, 0x11, 0xe5, 0x9e, 0xa2, 0x21, 0xa3, 0xb6, 0xd2, 0x2d, 0x00,
|
||||
0x78, 0x03, 0x69, 0x23, 0xff, 0xc7,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x228109103250c9d0,
|
||||
0x8a411ad149045812,
|
||||
0xa9109e8f3041427e,
|
||||
0xb07e9bc405608611,
|
||||
0xfcd559cbe77bd8b8,
|
||||
0x18d400b280d93e62
|
||||
0x18, 0xd4, 0x00, 0xb2, 0x80, 0xd9, 0x3e, 0x62, 0xfc, 0xd5, 0x59, 0xcb, 0xe7, 0x7b,
|
||||
0xd8, 0xb8, 0xb0, 0x7e, 0x9b, 0xc4, 0x05, 0x60, 0x86, 0x11, 0xa9, 0x10, 0x9e, 0x8f,
|
||||
0x30, 0x41, 0x42, 0x7e, 0x8a, 0x41, 0x1a, 0xd1, 0x49, 0x04, 0x58, 0x12, 0x22, 0x81,
|
||||
0x09, 0x10, 0x32, 0x50, 0xc9, 0xd0,
|
||||
]))
|
||||
.unwrap(),
|
||||
}
|
||||
@ -866,21 +788,17 @@ fn test_fq2_frobenius_map() {
|
||||
a,
|
||||
Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x2d0078036923ffc7,
|
||||
0x11e59ea221a3b6d2,
|
||||
0x8b1a52e0a90f59ed,
|
||||
0xb966ce3bc2108b13,
|
||||
0xccc649c4b9532bf3,
|
||||
0xf8d295b2ded9dc
|
||||
0x00, 0xf8, 0xd2, 0x95, 0xb2, 0xde, 0xd9, 0xdc, 0xcc, 0xc6, 0x49, 0xc4, 0xb9, 0x53,
|
||||
0x2b, 0xf3, 0xb9, 0x66, 0xce, 0x3b, 0xc2, 0x10, 0x8b, 0x13, 0x8b, 0x1a, 0x52, 0xe0,
|
||||
0xa9, 0x0f, 0x59, 0xed, 0x11, 0xe5, 0x9e, 0xa2, 0x21, 0xa3, 0xb6, 0xd2, 0x2d, 0x00,
|
||||
0x78, 0x03, 0x69, 0x23, 0xff, 0xc7,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x977df6efcdaee0db,
|
||||
0x946ae52d684fa7ed,
|
||||
0xbe203411c66fb3a5,
|
||||
0xb3f8afc0ee248cad,
|
||||
0x4e464dea5bcfd41e,
|
||||
0x12d1137b8a6a837
|
||||
0x01, 0x2d, 0x11, 0x37, 0xb8, 0xa6, 0xa8, 0x37, 0x4e, 0x46, 0x4d, 0xea, 0x5b, 0xcf,
|
||||
0xd4, 0x1e, 0xb3, 0xf8, 0xaf, 0xc0, 0xee, 0x24, 0x8c, 0xad, 0xbe, 0x20, 0x34, 0x11,
|
||||
0xc6, 0x6f, 0xb3, 0xa5, 0x94, 0x6a, 0xe5, 0x2d, 0x68, 0x4f, 0xa7, 0xed, 0x97, 0x7d,
|
||||
0xf6, 0xef, 0xcd, 0xae, 0xe0, 0xdb,
|
||||
]))
|
||||
.unwrap(),
|
||||
}
|
||||
@ -890,21 +808,17 @@ fn test_fq2_frobenius_map() {
|
||||
a,
|
||||
Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x2d0078036923ffc7,
|
||||
0x11e59ea221a3b6d2,
|
||||
0x8b1a52e0a90f59ed,
|
||||
0xb966ce3bc2108b13,
|
||||
0xccc649c4b9532bf3,
|
||||
0xf8d295b2ded9dc
|
||||
0x00, 0xf8, 0xd2, 0x95, 0xb2, 0xde, 0xd9, 0xdc, 0xcc, 0xc6, 0x49, 0xc4, 0xb9, 0x53,
|
||||
0x2b, 0xf3, 0xb9, 0x66, 0xce, 0x3b, 0xc2, 0x10, 0x8b, 0x13, 0x8b, 0x1a, 0x52, 0xe0,
|
||||
0xa9, 0x0f, 0x59, 0xed, 0x11, 0xe5, 0x9e, 0xa2, 0x21, 0xa3, 0xb6, 0xd2, 0x2d, 0x00,
|
||||
0x78, 0x03, 0x69, 0x23, 0xff, 0xc7,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0x977df6efcdaee0db,
|
||||
0x946ae52d684fa7ed,
|
||||
0xbe203411c66fb3a5,
|
||||
0xb3f8afc0ee248cad,
|
||||
0x4e464dea5bcfd41e,
|
||||
0x12d1137b8a6a837
|
||||
0x01, 0x2d, 0x11, 0x37, 0xb8, 0xa6, 0xa8, 0x37, 0x4e, 0x46, 0x4d, 0xea, 0x5b, 0xcf,
|
||||
0xd4, 0x1e, 0xb3, 0xf8, 0xaf, 0xc0, 0xee, 0x24, 0x8c, 0xad, 0xbe, 0x20, 0x34, 0x11,
|
||||
0xc6, 0x6f, 0xb3, 0xa5, 0x94, 0x6a, 0xe5, 0x2d, 0x68, 0x4f, 0xa7, 0xed, 0x97, 0x7d,
|
||||
0xf6, 0xef, 0xcd, 0xae, 0xe0, 0xdb,
|
||||
]))
|
||||
.unwrap(),
|
||||
}
|
||||
@ -919,21 +833,17 @@ fn test_fq2_sqrt() {
|
||||
assert_eq!(
|
||||
Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x476b4c309720e227,
|
||||
0x34c2d04faffdab6,
|
||||
0xa57e6fc1bab51fd9,
|
||||
0xdb4a116b5bf74aa1,
|
||||
0x1e58b2159dfe10e2,
|
||||
0x7ca7da1f13606ac
|
||||
0x07, 0xca, 0x7d, 0xa1, 0xf1, 0x36, 0x06, 0xac, 0x1e, 0x58, 0xb2, 0x15, 0x9d, 0xfe,
|
||||
0x10, 0xe2, 0xdb, 0x4a, 0x11, 0x6b, 0x5b, 0xf7, 0x4a, 0xa1, 0xa5, 0x7e, 0x6f, 0xc1,
|
||||
0xba, 0xb5, 0x1f, 0xd9, 0x03, 0x4c, 0x2d, 0x04, 0xfa, 0xff, 0xda, 0xb6, 0x47, 0x6b,
|
||||
0x4c, 0x30, 0x97, 0x20, 0xe2, 0x27,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0xfa8de88b7516d2c3,
|
||||
0x371a75ed14f41629,
|
||||
0x4cec2dca577a3eb6,
|
||||
0x212611bca4e99121,
|
||||
0x8ee5394d77afb3d,
|
||||
0xec92336650e49d5
|
||||
0x0e, 0xc9, 0x23, 0x36, 0x65, 0x0e, 0x49, 0xd5, 0x08, 0xee, 0x53, 0x94, 0xd7, 0x7a,
|
||||
0xfb, 0x3d, 0x21, 0x26, 0x11, 0xbc, 0xa4, 0xe9, 0x91, 0x21, 0x4c, 0xec, 0x2d, 0xca,
|
||||
0x57, 0x7a, 0x3e, 0xb6, 0x37, 0x1a, 0x75, 0xed, 0x14, 0xf4, 0x16, 0x29, 0xfa, 0x8d,
|
||||
0xe8, 0x8b, 0x75, 0x16, 0xd2, 0xc3,
|
||||
]))
|
||||
.unwrap(),
|
||||
}
|
||||
@ -941,21 +851,17 @@ fn test_fq2_sqrt() {
|
||||
.unwrap(),
|
||||
Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0x40b299b2704258c5,
|
||||
0x6ef7de92e8c68b63,
|
||||
0x6d2ddbe552203e82,
|
||||
0x8d7f1f723d02c1d3,
|
||||
0x881b3e01b611c070,
|
||||
0x10f6963bbad2ebc5
|
||||
0x10, 0xf6, 0x96, 0x3b, 0xba, 0xd2, 0xeb, 0xc5, 0x88, 0x1b, 0x3e, 0x01, 0xb6, 0x11,
|
||||
0xc0, 0x70, 0x8d, 0x7f, 0x1f, 0x72, 0x3d, 0x02, 0xc1, 0xd3, 0x6d, 0x2d, 0xdb, 0xe5,
|
||||
0x52, 0x20, 0x3e, 0x82, 0x6e, 0xf7, 0xde, 0x92, 0xe8, 0xc6, 0x8b, 0x63, 0x40, 0xb2,
|
||||
0x99, 0xb2, 0x70, 0x42, 0x58, 0xc5,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0xc099534fc209e752,
|
||||
0x7670594665676447,
|
||||
0x28a20faed211efe7,
|
||||
0x6b852aeaf2afcb1b,
|
||||
0xa4c93b08105d71a9,
|
||||
0x8d7cfff94216330
|
||||
0x08, 0xd7, 0xcf, 0xff, 0x94, 0x21, 0x63, 0x30, 0xa4, 0xc9, 0x3b, 0x08, 0x10, 0x5d,
|
||||
0x71, 0xa9, 0x6b, 0x85, 0x2a, 0xea, 0xf2, 0xaf, 0xcb, 0x1b, 0x28, 0xa2, 0x0f, 0xae,
|
||||
0xd2, 0x11, 0xef, 0xe7, 0x76, 0x70, 0x59, 0x46, 0x65, 0x67, 0x64, 0x47, 0xc0, 0x99,
|
||||
0x53, 0x4f, 0xc2, 0x09, 0xe7, 0x52,
|
||||
]))
|
||||
.unwrap(),
|
||||
}
|
||||
@ -964,12 +870,10 @@ fn test_fq2_sqrt() {
|
||||
assert_eq!(
|
||||
Fq2 {
|
||||
c0: Fq::from_repr(FqRepr([
|
||||
0xb9f78429d1517a6b,
|
||||
0x1eabfffeb153ffff,
|
||||
0x6730d2a0f6b0f624,
|
||||
0x64774b84f38512bf,
|
||||
0x4b1ba7b6434bacd7,
|
||||
0x1a0111ea397fe69a
|
||||
0x1a, 0x01, 0x11, 0xea, 0x39, 0x7f, 0xe6, 0x9a, 0x4b, 0x1b, 0xa7, 0xb6, 0x43, 0x4b,
|
||||
0xac, 0xd7, 0x64, 0x77, 0x4b, 0x84, 0xf3, 0x85, 0x12, 0xbf, 0x67, 0x30, 0xd2, 0xa0,
|
||||
0xf6, 0xb0, 0xf6, 0x24, 0x1e, 0xab, 0xff, 0xfe, 0xb1, 0x53, 0xff, 0xff, 0xb9, 0xf7,
|
||||
0x84, 0x29, 0xd1, 0x51, 0x7a, 0x6b,
|
||||
]))
|
||||
.unwrap(),
|
||||
c1: Fq::zero(),
|
||||
@ -979,12 +883,10 @@ fn test_fq2_sqrt() {
|
||||
Fq2 {
|
||||
c0: Fq::zero(),
|
||||
c1: Fq::from_repr(FqRepr([
|
||||
0xb9fefffffd4357a3,
|
||||
0x1eabfffeb153ffff,
|
||||
0x6730d2a0f6b0f624,
|
||||
0x64774b84f38512bf,
|
||||
0x4b1ba7b6434bacd7,
|
||||
0x1a0111ea397fe69a
|
||||
0x1a, 0x01, 0x11, 0xea, 0x39, 0x7f, 0xe6, 0x9a, 0x4b, 0x1b, 0xa7, 0xb6, 0x43, 0x4b,
|
||||
0xac, 0xd7, 0x64, 0x77, 0x4b, 0x84, 0xf3, 0x85, 0x12, 0xbf, 0x67, 0x30, 0xd2, 0xa0,
|
||||
0xf6, 0xb0, 0xf6, 0x24, 0x1e, 0xab, 0xff, 0xfe, 0xb1, 0x53, 0xff, 0xff, 0xb9, 0xfe,
|
||||
0xff, 0xff, 0xfd, 0x43, 0x57, 0xa3,
|
||||
]))
|
||||
.unwrap(),
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr};
|
||||
use ff::{Field, PrimeField};
|
||||
use std::ops::{AddAssign, MulAssign, SubAssign};
|
||||
|
||||
#[derive(PrimeField)]
|
||||
#[PrimeFieldModulus = "52435875175126190479447740508185965837690552500527637822603658699938581184513"]
|
||||
#[PrimeFieldGenerator = "7"]
|
||||
pub struct Fr(FrRepr);
|
||||
#[PrimeFieldReprEndianness = "little"]
|
||||
pub struct Fr([u64; 4]);
|
||||
|
||||
#[cfg(test)]
|
||||
use ff::PowVartime;
|
||||
#[cfg(test)]
|
||||
use rand_core::SeedableRng;
|
||||
#[cfg(test)]
|
||||
@ -13,373 +16,26 @@ use rand_xorshift::XorShiftRng;
|
||||
#[cfg(test)]
|
||||
use std::ops::Neg;
|
||||
|
||||
#[test]
|
||||
fn test_fr_repr_ordering() {
|
||||
fn assert_equality(a: FrRepr, b: FrRepr) {
|
||||
assert_eq!(a, b);
|
||||
assert!(a.cmp(&b) == ::std::cmp::Ordering::Equal);
|
||||
}
|
||||
|
||||
fn assert_lt(a: FrRepr, b: FrRepr) {
|
||||
assert!(a < b);
|
||||
assert!(b > a);
|
||||
}
|
||||
|
||||
assert_equality(
|
||||
FrRepr([9999, 9999, 9999, 9999]),
|
||||
FrRepr([9999, 9999, 9999, 9999]),
|
||||
);
|
||||
assert_equality(
|
||||
FrRepr([9999, 9998, 9999, 9999]),
|
||||
FrRepr([9999, 9998, 9999, 9999]),
|
||||
);
|
||||
assert_equality(
|
||||
FrRepr([9999, 9999, 9999, 9997]),
|
||||
FrRepr([9999, 9999, 9999, 9997]),
|
||||
);
|
||||
assert_lt(
|
||||
FrRepr([9999, 9997, 9999, 9998]),
|
||||
FrRepr([9999, 9997, 9999, 9999]),
|
||||
);
|
||||
assert_lt(
|
||||
FrRepr([9999, 9997, 9998, 9999]),
|
||||
FrRepr([9999, 9997, 9999, 9999]),
|
||||
);
|
||||
assert_lt(
|
||||
FrRepr([9, 9999, 9999, 9997]),
|
||||
FrRepr([9999, 9999, 9999, 9997]),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_repr_from() {
|
||||
assert_eq!(FrRepr::from(100), FrRepr([100, 0, 0, 0]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_repr_is_odd() {
|
||||
assert!(!FrRepr::from(0).is_odd());
|
||||
assert!(FrRepr::from(0).is_even());
|
||||
assert!(FrRepr::from(1).is_odd());
|
||||
assert!(!FrRepr::from(1).is_even());
|
||||
assert!(!FrRepr::from(324834872).is_odd());
|
||||
assert!(FrRepr::from(324834872).is_even());
|
||||
assert!(FrRepr::from(324834873).is_odd());
|
||||
assert!(!FrRepr::from(324834873).is_even());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_repr_is_zero() {
|
||||
assert!(FrRepr::from(0).is_zero());
|
||||
assert!(!FrRepr::from(1).is_zero());
|
||||
assert!(!FrRepr([0, 0, 1, 0]).is_zero());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_repr_div2() {
|
||||
let mut a = FrRepr([
|
||||
0xbd2920b19c972321,
|
||||
0x174ed0466a3be37e,
|
||||
0xd468d5e3b551f0b5,
|
||||
0xcb67c072733beefc,
|
||||
]);
|
||||
a.div2();
|
||||
assert_eq!(
|
||||
a,
|
||||
FrRepr([
|
||||
0x5e949058ce4b9190,
|
||||
0x8ba76823351df1bf,
|
||||
0x6a346af1daa8f85a,
|
||||
0x65b3e039399df77e
|
||||
])
|
||||
);
|
||||
for _ in 0..10 {
|
||||
a.div2();
|
||||
}
|
||||
assert_eq!(
|
||||
a,
|
||||
FrRepr([
|
||||
0x6fd7a524163392e4,
|
||||
0x16a2e9da08cd477c,
|
||||
0xdf9a8d1abc76aa3e,
|
||||
0x196cf80e4e677d
|
||||
])
|
||||
);
|
||||
for _ in 0..200 {
|
||||
a.div2();
|
||||
}
|
||||
assert_eq!(a, FrRepr([0x196cf80e4e67, 0x0, 0x0, 0x0]));
|
||||
for _ in 0..40 {
|
||||
a.div2();
|
||||
}
|
||||
assert_eq!(a, FrRepr([0x19, 0x0, 0x0, 0x0]));
|
||||
for _ in 0..4 {
|
||||
a.div2();
|
||||
}
|
||||
assert_eq!(a, FrRepr([0x1, 0x0, 0x0, 0x0]));
|
||||
a.div2();
|
||||
assert!(a.is_zero());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_repr_shr() {
|
||||
let mut a = FrRepr([
|
||||
0xb33fbaec482a283f,
|
||||
0x997de0d3a88cb3df,
|
||||
0x9af62d2a9a0e5525,
|
||||
0x36003ab08de70da1,
|
||||
]);
|
||||
a.shr(0);
|
||||
assert_eq!(
|
||||
a,
|
||||
FrRepr([
|
||||
0xb33fbaec482a283f,
|
||||
0x997de0d3a88cb3df,
|
||||
0x9af62d2a9a0e5525,
|
||||
0x36003ab08de70da1
|
||||
])
|
||||
);
|
||||
a.shr(1);
|
||||
assert_eq!(
|
||||
a,
|
||||
FrRepr([
|
||||
0xd99fdd762415141f,
|
||||
0xccbef069d44659ef,
|
||||
0xcd7b16954d072a92,
|
||||
0x1b001d5846f386d0
|
||||
])
|
||||
);
|
||||
a.shr(50);
|
||||
assert_eq!(
|
||||
a,
|
||||
FrRepr([
|
||||
0xbc1a7511967bf667,
|
||||
0xc5a55341caa4b32f,
|
||||
0x75611bce1b4335e,
|
||||
0x6c0
|
||||
])
|
||||
);
|
||||
a.shr(130);
|
||||
assert_eq!(a, FrRepr([0x1d5846f386d0cd7, 0x1b0, 0x0, 0x0]));
|
||||
a.shr(64);
|
||||
assert_eq!(a, FrRepr([0x1b0, 0x0, 0x0, 0x0]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_repr_mul2() {
|
||||
let mut a = FrRepr::from(23712937547);
|
||||
a.mul2();
|
||||
assert_eq!(a, FrRepr([0xb0acd6c96, 0x0, 0x0, 0x0]));
|
||||
for _ in 0..60 {
|
||||
a.mul2();
|
||||
}
|
||||
assert_eq!(a, FrRepr([0x6000000000000000, 0xb0acd6c9, 0x0, 0x0]));
|
||||
for _ in 0..128 {
|
||||
a.mul2();
|
||||
}
|
||||
assert_eq!(a, FrRepr([0x0, 0x0, 0x6000000000000000, 0xb0acd6c9]));
|
||||
for _ in 0..60 {
|
||||
a.mul2();
|
||||
}
|
||||
assert_eq!(a, FrRepr([0x0, 0x0, 0x0, 0x9600000000000000]));
|
||||
for _ in 0..7 {
|
||||
a.mul2();
|
||||
}
|
||||
assert!(a.is_zero());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_repr_num_bits() {
|
||||
let mut a = FrRepr::from(0);
|
||||
assert_eq!(0, a.num_bits());
|
||||
a = FrRepr::from(1);
|
||||
for i in 1..257 {
|
||||
assert_eq!(i, a.num_bits());
|
||||
a.mul2();
|
||||
}
|
||||
assert_eq!(0, a.num_bits());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_repr_sub_noborrow() {
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
let mut t = FrRepr([
|
||||
0x8e62a7e85264e2c3,
|
||||
0xb23d34c1941d3ca,
|
||||
0x5976930b7502dd15,
|
||||
0x600f3fb517bf5495,
|
||||
]);
|
||||
t.sub_noborrow(&FrRepr([
|
||||
0xd64f669809cbc6a4,
|
||||
0xfa76cb9d90cf7637,
|
||||
0xfefb0df9038d43b3,
|
||||
0x298a30c744b31acf,
|
||||
]));
|
||||
assert!(
|
||||
t == FrRepr([
|
||||
0xb813415048991c1f,
|
||||
0x10ad07ae88725d92,
|
||||
0x5a7b851271759961,
|
||||
0x36850eedd30c39c5
|
||||
])
|
||||
);
|
||||
|
||||
for _ in 0..1000 {
|
||||
let mut a = Fr::random(&mut rng).into_repr();
|
||||
a.0[3] >>= 30;
|
||||
let mut b = a;
|
||||
for _ in 0..10 {
|
||||
b.mul2();
|
||||
}
|
||||
let mut c = b;
|
||||
for _ in 0..10 {
|
||||
c.mul2();
|
||||
}
|
||||
|
||||
assert!(a < b);
|
||||
assert!(b < c);
|
||||
|
||||
let mut csub_ba = c;
|
||||
csub_ba.sub_noborrow(&b);
|
||||
csub_ba.sub_noborrow(&a);
|
||||
|
||||
let mut csub_ab = c;
|
||||
csub_ab.sub_noborrow(&a);
|
||||
csub_ab.sub_noborrow(&b);
|
||||
|
||||
assert_eq!(csub_ab, csub_ba);
|
||||
}
|
||||
|
||||
// Subtracting r+1 from r should produce -1 (mod 2**256)
|
||||
let mut qplusone = FrRepr([
|
||||
0xffffffff00000001,
|
||||
0x53bda402fffe5bfe,
|
||||
0x3339d80809a1d805,
|
||||
0x73eda753299d7d48,
|
||||
]);
|
||||
qplusone.sub_noborrow(&FrRepr([
|
||||
0xffffffff00000002,
|
||||
0x53bda402fffe5bfe,
|
||||
0x3339d80809a1d805,
|
||||
0x73eda753299d7d48,
|
||||
]));
|
||||
assert_eq!(
|
||||
qplusone,
|
||||
FrRepr([
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_repr_add_nocarry() {
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
let mut t = FrRepr([
|
||||
0xd64f669809cbc6a4,
|
||||
0xfa76cb9d90cf7637,
|
||||
0xfefb0df9038d43b3,
|
||||
0x298a30c744b31acf,
|
||||
]);
|
||||
t.add_nocarry(&FrRepr([
|
||||
0x8e62a7e85264e2c3,
|
||||
0xb23d34c1941d3ca,
|
||||
0x5976930b7502dd15,
|
||||
0x600f3fb517bf5495,
|
||||
]));
|
||||
assert_eq!(
|
||||
t,
|
||||
FrRepr([
|
||||
0x64b20e805c30a967,
|
||||
0x59a9ee9aa114a02,
|
||||
0x5871a104789020c9,
|
||||
0x8999707c5c726f65
|
||||
])
|
||||
);
|
||||
|
||||
// Test for the associativity of addition.
|
||||
for _ in 0..1000 {
|
||||
let mut a = Fr::random(&mut rng).into_repr();
|
||||
let mut b = Fr::random(&mut rng).into_repr();
|
||||
let mut c = Fr::random(&mut rng).into_repr();
|
||||
|
||||
// Unset the first few bits, so that overflow won't occur.
|
||||
a.0[3] >>= 3;
|
||||
b.0[3] >>= 3;
|
||||
c.0[3] >>= 3;
|
||||
|
||||
let mut abc = a;
|
||||
abc.add_nocarry(&b);
|
||||
abc.add_nocarry(&c);
|
||||
|
||||
let mut acb = a;
|
||||
acb.add_nocarry(&c);
|
||||
acb.add_nocarry(&b);
|
||||
|
||||
let mut bac = b;
|
||||
bac.add_nocarry(&a);
|
||||
bac.add_nocarry(&c);
|
||||
|
||||
let mut bca = b;
|
||||
bca.add_nocarry(&c);
|
||||
bca.add_nocarry(&a);
|
||||
|
||||
let mut cab = c;
|
||||
cab.add_nocarry(&a);
|
||||
cab.add_nocarry(&b);
|
||||
|
||||
let mut cba = c;
|
||||
cba.add_nocarry(&b);
|
||||
cba.add_nocarry(&a);
|
||||
|
||||
assert_eq!(abc, acb);
|
||||
assert_eq!(abc, bac);
|
||||
assert_eq!(abc, bca);
|
||||
assert_eq!(abc, cab);
|
||||
assert_eq!(abc, cba);
|
||||
}
|
||||
|
||||
// Adding 1 to (2^256 - 1) should produce zero
|
||||
let mut x = FrRepr([
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
]);
|
||||
x.add_nocarry(&FrRepr::from(1));
|
||||
assert!(x.is_zero());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_is_valid() {
|
||||
let mut a = Fr(MODULUS);
|
||||
let mut a = MODULUS_LIMBS;
|
||||
assert!(!a.is_valid());
|
||||
a.0.sub_noborrow(&FrRepr::from(1));
|
||||
a.sub_noborrow(&Fr([1, 0, 0, 0]));
|
||||
assert!(a.is_valid());
|
||||
assert!(Fr(FrRepr::from(0)).is_valid());
|
||||
assert!(Fr(FrRepr([
|
||||
assert!(Fr::from(0).is_valid());
|
||||
assert!(Fr([
|
||||
0xffffffff00000000,
|
||||
0x53bda402fffe5bfe,
|
||||
0x3339d80809a1d805,
|
||||
0x73eda753299d7d48
|
||||
]))
|
||||
])
|
||||
.is_valid());
|
||||
assert!(!Fr(FrRepr([
|
||||
assert!(!Fr([
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff
|
||||
]))
|
||||
])
|
||||
.is_valid());
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
@ -397,85 +53,85 @@ fn test_fr_is_valid() {
|
||||
fn test_fr_add_assign() {
|
||||
{
|
||||
// Random number
|
||||
let mut tmp = Fr(FrRepr([
|
||||
let mut tmp = Fr([
|
||||
0x437ce7616d580765,
|
||||
0xd42d1ccb29d1235b,
|
||||
0xed8f753821bd1423,
|
||||
0x4eede1c9c89528ca,
|
||||
]));
|
||||
]);
|
||||
assert!(tmp.is_valid());
|
||||
// Test that adding zero has no effect.
|
||||
tmp.add_assign(&Fr(FrRepr::from(0)));
|
||||
tmp.add_assign(&Fr([0, 0, 0, 0]));
|
||||
assert_eq!(
|
||||
tmp,
|
||||
Fr(FrRepr([
|
||||
Fr([
|
||||
0x437ce7616d580765,
|
||||
0xd42d1ccb29d1235b,
|
||||
0xed8f753821bd1423,
|
||||
0x4eede1c9c89528ca
|
||||
]))
|
||||
])
|
||||
);
|
||||
// Add one and test for the result.
|
||||
tmp.add_assign(&Fr(FrRepr::from(1)));
|
||||
tmp.add_assign(&Fr([1, 0, 0, 0]));
|
||||
assert_eq!(
|
||||
tmp,
|
||||
Fr(FrRepr([
|
||||
Fr([
|
||||
0x437ce7616d580766,
|
||||
0xd42d1ccb29d1235b,
|
||||
0xed8f753821bd1423,
|
||||
0x4eede1c9c89528ca
|
||||
]))
|
||||
])
|
||||
);
|
||||
// Add another random number that exercises the reduction.
|
||||
tmp.add_assign(&Fr(FrRepr([
|
||||
tmp.add_assign(&Fr([
|
||||
0x946f435944f7dc79,
|
||||
0xb55e7ee6533a9b9b,
|
||||
0x1e43b84c2f6194ca,
|
||||
0x58717ab525463496,
|
||||
])));
|
||||
]));
|
||||
assert_eq!(
|
||||
tmp,
|
||||
Fr(FrRepr([
|
||||
Fr([
|
||||
0xd7ec2abbb24fe3de,
|
||||
0x35cdf7ae7d0d62f7,
|
||||
0xd899557c477cd0e9,
|
||||
0x3371b52bc43de018
|
||||
]))
|
||||
])
|
||||
);
|
||||
// Add one to (r - 1) and test for the result.
|
||||
tmp = Fr(FrRepr([
|
||||
tmp = Fr([
|
||||
0xffffffff00000000,
|
||||
0x53bda402fffe5bfe,
|
||||
0x3339d80809a1d805,
|
||||
0x73eda753299d7d48,
|
||||
]));
|
||||
tmp.add_assign(&Fr(FrRepr::from(1)));
|
||||
assert!(tmp.0.is_zero());
|
||||
]);
|
||||
tmp.add_assign(&Fr([1, 0, 0, 0]));
|
||||
assert!(tmp.is_zero());
|
||||
// Add a random number to another one such that the result is r - 1
|
||||
tmp = Fr(FrRepr([
|
||||
tmp = Fr([
|
||||
0xade5adacdccb6190,
|
||||
0xaa21ee0f27db3ccd,
|
||||
0x2550f4704ae39086,
|
||||
0x591d1902e7c5ba27,
|
||||
]));
|
||||
tmp.add_assign(&Fr(FrRepr([
|
||||
]);
|
||||
tmp.add_assign(&Fr([
|
||||
0x521a525223349e70,
|
||||
0xa99bb5f3d8231f31,
|
||||
0xde8e397bebe477e,
|
||||
0x1ad08e5041d7c321,
|
||||
])));
|
||||
]));
|
||||
assert_eq!(
|
||||
tmp,
|
||||
Fr(FrRepr([
|
||||
Fr([
|
||||
0xffffffff00000000,
|
||||
0x53bda402fffe5bfe,
|
||||
0x3339d80809a1d805,
|
||||
0x73eda753299d7d48
|
||||
]))
|
||||
])
|
||||
);
|
||||
// Add one to the result and test for it.
|
||||
tmp.add_assign(&Fr(FrRepr::from(1)));
|
||||
assert!(tmp.0.is_zero());
|
||||
tmp.add_assign(&Fr([1, 0, 0, 0]));
|
||||
assert!(tmp.is_zero());
|
||||
}
|
||||
|
||||
// Test associativity
|
||||
@ -509,71 +165,71 @@ fn test_fr_add_assign() {
|
||||
fn test_fr_sub_assign() {
|
||||
{
|
||||
// Test arbitrary subtraction that tests reduction.
|
||||
let mut tmp = Fr(FrRepr([
|
||||
let mut tmp = Fr([
|
||||
0x6a68c64b6f735a2b,
|
||||
0xd5f4d143fe0a1972,
|
||||
0x37c17f3829267c62,
|
||||
0xa2f37391f30915c,
|
||||
]));
|
||||
tmp.sub_assign(&Fr(FrRepr([
|
||||
]);
|
||||
tmp.sub_assign(&Fr([
|
||||
0xade5adacdccb6190,
|
||||
0xaa21ee0f27db3ccd,
|
||||
0x2550f4704ae39086,
|
||||
0x591d1902e7c5ba27,
|
||||
])));
|
||||
]));
|
||||
assert_eq!(
|
||||
tmp,
|
||||
Fr(FrRepr([
|
||||
Fr([
|
||||
0xbc83189d92a7f89c,
|
||||
0x7f908737d62d38a3,
|
||||
0x45aa62cfe7e4c3e1,
|
||||
0x24ffc5896108547d
|
||||
]))
|
||||
])
|
||||
);
|
||||
|
||||
// Test the opposite subtraction which doesn't test reduction.
|
||||
tmp = Fr(FrRepr([
|
||||
tmp = Fr([
|
||||
0xade5adacdccb6190,
|
||||
0xaa21ee0f27db3ccd,
|
||||
0x2550f4704ae39086,
|
||||
0x591d1902e7c5ba27,
|
||||
]));
|
||||
tmp.sub_assign(&Fr(FrRepr([
|
||||
]);
|
||||
tmp.sub_assign(&Fr([
|
||||
0x6a68c64b6f735a2b,
|
||||
0xd5f4d143fe0a1972,
|
||||
0x37c17f3829267c62,
|
||||
0xa2f37391f30915c,
|
||||
])));
|
||||
]));
|
||||
assert_eq!(
|
||||
tmp,
|
||||
Fr(FrRepr([
|
||||
Fr([
|
||||
0x437ce7616d580765,
|
||||
0xd42d1ccb29d1235b,
|
||||
0xed8f753821bd1423,
|
||||
0x4eede1c9c89528ca
|
||||
]))
|
||||
])
|
||||
);
|
||||
|
||||
// Test for sensible results with zero
|
||||
tmp = Fr(FrRepr::from(0));
|
||||
tmp.sub_assign(&Fr(FrRepr::from(0)));
|
||||
tmp = Fr::from(0);
|
||||
tmp.sub_assign(&Fr::from(0));
|
||||
assert!(tmp.is_zero());
|
||||
|
||||
tmp = Fr(FrRepr([
|
||||
tmp = Fr([
|
||||
0x437ce7616d580765,
|
||||
0xd42d1ccb29d1235b,
|
||||
0xed8f753821bd1423,
|
||||
0x4eede1c9c89528ca,
|
||||
]));
|
||||
tmp.sub_assign(&Fr(FrRepr::from(0)));
|
||||
]);
|
||||
tmp.sub_assign(&Fr::from(0));
|
||||
assert_eq!(
|
||||
tmp,
|
||||
Fr(FrRepr([
|
||||
Fr([
|
||||
0x437ce7616d580765,
|
||||
0xd42d1ccb29d1235b,
|
||||
0xed8f753821bd1423,
|
||||
0x4eede1c9c89528ca
|
||||
]))
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
@ -600,25 +256,25 @@ fn test_fr_sub_assign() {
|
||||
|
||||
#[test]
|
||||
fn test_fr_mul_assign() {
|
||||
let mut tmp = Fr(FrRepr([
|
||||
let mut tmp = Fr([
|
||||
0x6b7e9b8faeefc81a,
|
||||
0xe30a8463f348ba42,
|
||||
0xeff3cb67a8279c9c,
|
||||
0x3d303651bd7c774d,
|
||||
]));
|
||||
tmp.mul_assign(&Fr(FrRepr([
|
||||
]);
|
||||
tmp.mul_assign(&Fr([
|
||||
0x13ae28e3bc35ebeb,
|
||||
0xa10f4488075cae2c,
|
||||
0x8160e95a853c3b5d,
|
||||
0x5ae3f03b561a841d,
|
||||
])));
|
||||
]));
|
||||
assert!(
|
||||
tmp == Fr(FrRepr([
|
||||
tmp == Fr([
|
||||
0x23717213ce710f71,
|
||||
0xdbee1fe53a16e1af,
|
||||
0xf565d3e1c2a48000,
|
||||
0x4426507ee75df9d7
|
||||
]))
|
||||
])
|
||||
);
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
@ -667,22 +323,76 @@ fn test_fr_mul_assign() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_shr() {
|
||||
let mut a = Fr::from_repr(FrRepr([
|
||||
0x3f, 0x28, 0x2a, 0x48, 0xec, 0xba, 0x3f, 0xb3, 0xdf, 0xb3, 0x8c, 0xa8, 0xd3, 0xe0, 0x7d,
|
||||
0x99, 0x25, 0x55, 0x0e, 0x9a, 0x2a, 0x2d, 0xf6, 0x9a, 0xa1, 0x0d, 0xe7, 0x8d, 0xb0, 0x3a,
|
||||
0x00, 0x36,
|
||||
]))
|
||||
.unwrap();
|
||||
a = a >> 0;
|
||||
assert_eq!(
|
||||
a.into_repr(),
|
||||
FrRepr([
|
||||
0x3f, 0x28, 0x2a, 0x48, 0xec, 0xba, 0x3f, 0xb3, 0xdf, 0xb3, 0x8c, 0xa8, 0xd3, 0xe0,
|
||||
0x7d, 0x99, 0x25, 0x55, 0x0e, 0x9a, 0x2a, 0x2d, 0xf6, 0x9a, 0xa1, 0x0d, 0xe7, 0x8d,
|
||||
0xb0, 0x3a, 0x00, 0x36,
|
||||
])
|
||||
);
|
||||
a = a >> 1;
|
||||
assert_eq!(
|
||||
a.into_repr(),
|
||||
FrRepr([
|
||||
0x1f, 0x14, 0x15, 0x24, 0x76, 0xdd, 0x9f, 0xd9, 0xef, 0x59, 0x46, 0xd4, 0x69, 0xf0,
|
||||
0xbe, 0xcc, 0x92, 0x2a, 0x07, 0x4d, 0x95, 0x16, 0x7b, 0xcd, 0xd0, 0x86, 0xf3, 0x46,
|
||||
0x58, 0x1d, 0x00, 0x1b,
|
||||
])
|
||||
);
|
||||
a = a >> 50;
|
||||
assert_eq!(
|
||||
a.into_repr(),
|
||||
FrRepr([
|
||||
0x67, 0xf6, 0x7b, 0x96, 0x11, 0x75, 0x1a, 0xbc, 0x2f, 0xb3, 0xa4, 0xca, 0x41, 0x53,
|
||||
0xa5, 0xc5, 0x5e, 0x33, 0xb4, 0xe1, 0xbc, 0x11, 0x56, 0x07, 0xc0, 0x06, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
])
|
||||
);
|
||||
a = a >> 130;
|
||||
assert_eq!(
|
||||
a.into_repr(),
|
||||
FrRepr([
|
||||
0xd7, 0x0c, 0x6d, 0x38, 0x6f, 0x84, 0xd5, 0x01, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
])
|
||||
);
|
||||
a = a >> 64;
|
||||
assert_eq!(
|
||||
a.into_repr(),
|
||||
FrRepr([
|
||||
0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_squaring() {
|
||||
let a = Fr(FrRepr([
|
||||
let a = Fr([
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0x73eda753299d7d47,
|
||||
]));
|
||||
]);
|
||||
assert!(a.is_valid());
|
||||
assert_eq!(
|
||||
a.square(),
|
||||
Fr::from_repr(FrRepr([
|
||||
0xc0d698e7bde077b8,
|
||||
0xb79a310579e76ec2,
|
||||
0xac1da8d0a9af4e5f,
|
||||
0x13f629c49bf23e97
|
||||
0xb8, 0x77, 0xe0, 0xbd, 0xe7, 0x98, 0xd6, 0xc0, 0xc2, 0x6e, 0xe7, 0x79, 0x05, 0x31,
|
||||
0x9a, 0xb7, 0x5f, 0x4e, 0xaf, 0xa9, 0xd0, 0xa8, 0x1d, 0xac, 0x97, 0x3e, 0xf2, 0x9b,
|
||||
0xc4, 0x29, 0xf6, 0x13,
|
||||
]))
|
||||
.unwrap()
|
||||
);
|
||||
@ -763,7 +473,7 @@ fn test_fr_pow() {
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
for i in 0..1000 {
|
||||
for i in 0u64..1000 {
|
||||
// Exponentiate by various small numbers and ensure it consists with repeated
|
||||
// multiplication.
|
||||
let a = Fr::random(&mut rng);
|
||||
@ -820,42 +530,38 @@ fn test_fr_sqrt() {
|
||||
fn test_fr_from_into_repr() {
|
||||
// r + 1 should not be in the field
|
||||
assert!(Fr::from_repr(FrRepr([
|
||||
0xffffffff00000002,
|
||||
0x53bda402fffe5bfe,
|
||||
0x3339d80809a1d805,
|
||||
0x73eda753299d7d48
|
||||
0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x5b, 0xfe, 0xff, 0x02, 0xa4, 0xbd,
|
||||
0x53, 0x05, 0xd8, 0xa1, 0x09, 0x08, 0xd8, 0x39, 0x33, 0x48, 0x7d, 0x9d, 0x29, 0x53, 0xa7,
|
||||
0xed, 0x73,
|
||||
]))
|
||||
.is_err());
|
||||
.is_none());
|
||||
|
||||
// r should not be in the field
|
||||
assert!(Fr::from_repr(Fr::char()).is_err());
|
||||
assert!(Fr::from_repr(Fr::char()).is_none());
|
||||
|
||||
// Multiply some arbitrary representations to see if the result is as expected.
|
||||
let a = FrRepr([
|
||||
0x25ebe3a3ad3c0c6a,
|
||||
0x6990e39d092e817c,
|
||||
0x941f900d42f5658e,
|
||||
0x44f8a103b38a71e0,
|
||||
0x6a, 0x0c, 0x3c, 0xad, 0xa3, 0xe3, 0xeb, 0x25, 0x7c, 0x81, 0x2e, 0x09, 0x9d, 0xe3, 0x90,
|
||||
0x69, 0x8e, 0x65, 0xf5, 0x42, 0x0d, 0x90, 0x1f, 0x94, 0xe0, 0x71, 0x8a, 0xb3, 0x03, 0xa1,
|
||||
0xf8, 0x44,
|
||||
]);
|
||||
let mut a_fr = Fr::from_repr(a).unwrap();
|
||||
let b = FrRepr([
|
||||
0x264e9454885e2475,
|
||||
0x46f7746bb0308370,
|
||||
0x4683ef5347411f9,
|
||||
0x58838d7f208d4492,
|
||||
0x75, 0x24, 0x5e, 0x88, 0x54, 0x94, 0x4e, 0x26, 0x70, 0x83, 0x30, 0xb0, 0x6b, 0x74, 0xf7,
|
||||
0x46, 0xf9, 0x11, 0x74, 0x34, 0xf5, 0x3e, 0x68, 0x04, 0x92, 0x44, 0x8d, 0x20, 0x7f, 0x8d,
|
||||
0x83, 0x58,
|
||||
]);
|
||||
let b_fr = Fr::from_repr(b).unwrap();
|
||||
let c = FrRepr([
|
||||
0x48a09ab93cfc740d,
|
||||
0x3a6600fbfc7a671,
|
||||
0x838567017501d767,
|
||||
0x7161d6da77745512,
|
||||
0x0d, 0x74, 0xfc, 0x3c, 0xb9, 0x9a, 0xa0, 0x48, 0x71, 0xa6, 0xc7, 0xbf, 0x0f, 0x60, 0xa6,
|
||||
0x03, 0x67, 0xd7, 0x01, 0x75, 0x01, 0x67, 0x85, 0x83, 0x12, 0x55, 0x74, 0x77, 0xda, 0xd6,
|
||||
0x61, 0x71,
|
||||
]);
|
||||
a_fr.mul_assign(&b_fr);
|
||||
assert_eq!(a_fr.into_repr(), c);
|
||||
|
||||
// Zero should be in the field.
|
||||
assert!(Fr::from_repr(FrRepr::from(0)).unwrap().is_zero());
|
||||
assert!(Fr::from_repr(FrRepr([0; 32])).unwrap().is_zero());
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
@ -874,60 +580,15 @@ fn test_fr_from_into_repr() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_repr_display() {
|
||||
assert_eq!(
|
||||
format!(
|
||||
"{}",
|
||||
FrRepr([
|
||||
0x2829c242fa826143,
|
||||
0x1f32cf4dd4330917,
|
||||
0x932e4e479d168cd9,
|
||||
0x513c77587f563f64
|
||||
])
|
||||
),
|
||||
"0x513c77587f563f64932e4e479d168cd91f32cf4dd43309172829c242fa826143".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
format!(
|
||||
"{}",
|
||||
FrRepr([
|
||||
0x25ebe3a3ad3c0c6a,
|
||||
0x6990e39d092e817c,
|
||||
0x941f900d42f5658e,
|
||||
0x44f8a103b38a71e0
|
||||
])
|
||||
),
|
||||
"0x44f8a103b38a71e0941f900d42f5658e6990e39d092e817c25ebe3a3ad3c0c6a".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
format!(
|
||||
"{}",
|
||||
FrRepr([
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff,
|
||||
0xffffffffffffffff
|
||||
])
|
||||
),
|
||||
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
format!("{}", FrRepr([0, 0, 0, 0])),
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000".to_string()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_display() {
|
||||
assert_eq!(
|
||||
format!(
|
||||
"{}",
|
||||
Fr::from_repr(FrRepr([
|
||||
0xc3cae746a3b5ecc7,
|
||||
0x185ec8eb3f5b5aee,
|
||||
0x684499ffe4b9dd99,
|
||||
0x7c9bba7afb68faa
|
||||
0xc7, 0xec, 0xb5, 0xa3, 0x46, 0xe7, 0xca, 0xc3, 0xee, 0x5a, 0x5b, 0x3f, 0xeb, 0xc8,
|
||||
0x5e, 0x18, 0x99, 0xdd, 0xb9, 0xe4, 0xff, 0x99, 0x44, 0x68, 0xaa, 0x8f, 0xb6, 0xaf,
|
||||
0xa7, 0xbb, 0xc9, 0x07,
|
||||
]))
|
||||
.unwrap()
|
||||
),
|
||||
@ -937,10 +598,9 @@ fn test_fr_display() {
|
||||
format!(
|
||||
"{}",
|
||||
Fr::from_repr(FrRepr([
|
||||
0x44c71298ff198106,
|
||||
0xb0ad10817df79b6a,
|
||||
0xd034a80a2b74132b,
|
||||
0x41cf9a1336f50719
|
||||
0x06, 0x81, 0x19, 0xff, 0x98, 0x12, 0xc7, 0x44, 0x6a, 0x9b, 0xf7, 0x7d, 0x81, 0x10,
|
||||
0xad, 0xb0, 0x2b, 0x13, 0x74, 0x2b, 0x0a, 0xa8, 0x34, 0xd0, 0x19, 0x07, 0xf5, 0x36,
|
||||
0x13, 0x9a, 0xcf, 0x41,
|
||||
]))
|
||||
.unwrap()
|
||||
),
|
||||
@ -948,6 +608,18 @@ fn test_fr_display() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_is_odd() {
|
||||
assert!(!Fr::from(0).is_odd());
|
||||
assert!(Fr::from(0).is_even());
|
||||
assert!(Fr::from(1).is_odd());
|
||||
assert!(!Fr::from(1).is_even());
|
||||
assert!(!Fr::from(324834872).is_odd());
|
||||
assert!(Fr::from(324834872).is_even());
|
||||
assert!(Fr::from(324834873).is_odd());
|
||||
assert!(!Fr::from(324834873).is_even());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fr_num_bits() {
|
||||
assert_eq!(Fr::NUM_BITS, 255);
|
||||
@ -959,20 +631,17 @@ fn test_fr_root_of_unity() {
|
||||
use ff::SqrtField;
|
||||
|
||||
assert_eq!(Fr::S, 32);
|
||||
assert_eq!(
|
||||
Fr::multiplicative_generator(),
|
||||
Fr::from_repr(FrRepr::from(7)).unwrap()
|
||||
);
|
||||
assert_eq!(Fr::multiplicative_generator(), Fr::from(7));
|
||||
assert_eq!(
|
||||
Fr::multiplicative_generator().pow_vartime([
|
||||
0xfffe5bfeffffffff,
|
||||
0xfffe5bfeffffffffu64,
|
||||
0x9a1d80553bda402,
|
||||
0x299d7d483339d808,
|
||||
0x73eda753
|
||||
]),
|
||||
Fr::root_of_unity()
|
||||
);
|
||||
assert_eq!(Fr::root_of_unity().pow_vartime([1 << Fr::S]), Fr::one());
|
||||
assert_eq!(Fr::root_of_unity().pow_vartime([1u64 << Fr::S]), Fr::one());
|
||||
assert!(bool::from(Fr::multiplicative_generator().sqrt().is_none()));
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ pub use self::fr::{Fr, FrRepr};
|
||||
|
||||
use super::{Engine, PairingCurveAffine};
|
||||
|
||||
use ff::{BitIterator, Field, ScalarEngine};
|
||||
use ff::{BitIterator, Field, PowVartime, ScalarEngine};
|
||||
use group::CurveAffine;
|
||||
use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
|
||||
use subtle::CtOption;
|
||||
@ -82,7 +82,7 @@ impl Engine for Bls12 {
|
||||
let mut f = Fq12::one();
|
||||
|
||||
let mut found_one = false;
|
||||
for i in BitIterator::new(&[BLS_X >> 1]) {
|
||||
for i in BitIterator::<u64, _>::new(&[BLS_X >> 1]) {
|
||||
if !found_one {
|
||||
found_one = i;
|
||||
continue;
|
||||
@ -324,7 +324,7 @@ impl G2Prepared {
|
||||
let mut r: G2 = q.into();
|
||||
|
||||
let mut found_one = false;
|
||||
for i in BitIterator::new([BLS_X >> 1]) {
|
||||
for i in BitIterator::<u64, _>::new([BLS_X >> 1]) {
|
||||
if !found_one {
|
||||
found_one = i;
|
||||
continue;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use ff::PrimeFieldRepr;
|
||||
use ff::PrimeField;
|
||||
use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError};
|
||||
|
||||
use super::*;
|
||||
@ -147,13 +147,15 @@ fn test_g1_uncompressed_invalid_vectors() {
|
||||
}
|
||||
}
|
||||
|
||||
let m = Fq::char();
|
||||
// PrimeField::char() returns the modulus in its little-endian byte representation,
|
||||
// but Fq field elements use big-endian encoding, so flip the endianness.
|
||||
let m: Vec<_> = Fq::char().as_ref().iter().cloned().rev().collect();
|
||||
|
||||
{
|
||||
let mut o = o;
|
||||
m.write_be(&mut o.as_mut()[0..]).unwrap();
|
||||
o.as_mut()[..48].copy_from_slice(&m[..]);
|
||||
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate, _)) = o.into_affine() {
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() {
|
||||
assert_eq!(coordinate, "x coordinate");
|
||||
} else {
|
||||
panic!("should have rejected the point")
|
||||
@ -162,9 +164,9 @@ fn test_g1_uncompressed_invalid_vectors() {
|
||||
|
||||
{
|
||||
let mut o = o;
|
||||
m.write_be(&mut o.as_mut()[48..]).unwrap();
|
||||
o.as_mut()[48..].copy_from_slice(&m[..]);
|
||||
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate, _)) = o.into_affine() {
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() {
|
||||
assert_eq!(coordinate, "y coordinate");
|
||||
} else {
|
||||
panic!("should have rejected the point")
|
||||
@ -175,7 +177,7 @@ fn test_g1_uncompressed_invalid_vectors() {
|
||||
let m = Fq::zero().into_repr();
|
||||
|
||||
let mut o = o;
|
||||
m.write_be(&mut o.as_mut()[0..]).unwrap();
|
||||
o.as_mut()[..48].copy_from_slice(m.as_ref());
|
||||
|
||||
if let Err(GroupDecodingError::NotOnCurve) = o.into_affine() {
|
||||
// :)
|
||||
@ -191,15 +193,15 @@ fn test_g1_uncompressed_invalid_vectors() {
|
||||
loop {
|
||||
let mut x3b = x.square();
|
||||
x3b.mul_assign(&x);
|
||||
x3b.add_assign(&Fq::from_repr(FqRepr::from(4)).unwrap()); // TODO: perhaps expose coeff_b through API?
|
||||
x3b.add_assign(&Fq::from(4)); // TODO: perhaps expose coeff_b through API?
|
||||
|
||||
let y = x3b.sqrt();
|
||||
if y.is_some().into() {
|
||||
let y = y.unwrap();
|
||||
|
||||
// We know this is on the curve, but it's likely not going to be in the correct subgroup.
|
||||
x.into_repr().write_be(&mut o.as_mut()[0..]).unwrap();
|
||||
y.into_repr().write_be(&mut o.as_mut()[48..]).unwrap();
|
||||
o.as_mut()[..48].copy_from_slice(x.into_repr().as_ref());
|
||||
o.as_mut()[48..].copy_from_slice(y.into_repr().as_ref());
|
||||
|
||||
if let Err(GroupDecodingError::NotInSubgroup) = o.into_affine() {
|
||||
break;
|
||||
@ -263,13 +265,15 @@ fn test_g2_uncompressed_invalid_vectors() {
|
||||
}
|
||||
}
|
||||
|
||||
let m = Fq::char();
|
||||
// PrimeField::char() returns the modulus in its little-endian byte representation,
|
||||
// but Fq field elements use big-endian encoding, so flip the endianness.
|
||||
let m: Vec<_> = Fq::char().as_ref().iter().cloned().rev().collect();
|
||||
|
||||
{
|
||||
let mut o = o;
|
||||
m.write_be(&mut o.as_mut()[0..]).unwrap();
|
||||
o.as_mut()[..48].copy_from_slice(&m[..]);
|
||||
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate, _)) = o.into_affine() {
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() {
|
||||
assert_eq!(coordinate, "x coordinate (c1)");
|
||||
} else {
|
||||
panic!("should have rejected the point")
|
||||
@ -278,9 +282,9 @@ fn test_g2_uncompressed_invalid_vectors() {
|
||||
|
||||
{
|
||||
let mut o = o;
|
||||
m.write_be(&mut o.as_mut()[48..]).unwrap();
|
||||
o.as_mut()[48..96].copy_from_slice(&m[..]);
|
||||
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate, _)) = o.into_affine() {
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() {
|
||||
assert_eq!(coordinate, "x coordinate (c0)");
|
||||
} else {
|
||||
panic!("should have rejected the point")
|
||||
@ -289,9 +293,9 @@ fn test_g2_uncompressed_invalid_vectors() {
|
||||
|
||||
{
|
||||
let mut o = o;
|
||||
m.write_be(&mut o.as_mut()[96..]).unwrap();
|
||||
o.as_mut()[96..144].copy_from_slice(&m[..]);
|
||||
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate, _)) = o.into_affine() {
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() {
|
||||
assert_eq!(coordinate, "y coordinate (c1)");
|
||||
} else {
|
||||
panic!("should have rejected the point")
|
||||
@ -300,9 +304,9 @@ fn test_g2_uncompressed_invalid_vectors() {
|
||||
|
||||
{
|
||||
let mut o = o;
|
||||
m.write_be(&mut o.as_mut()[144..]).unwrap();
|
||||
o.as_mut()[144..].copy_from_slice(&m[..]);
|
||||
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate, _)) = o.into_affine() {
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() {
|
||||
assert_eq!(coordinate, "y coordinate (c0)");
|
||||
} else {
|
||||
panic!("should have rejected the point")
|
||||
@ -313,8 +317,8 @@ fn test_g2_uncompressed_invalid_vectors() {
|
||||
let m = Fq::zero().into_repr();
|
||||
|
||||
let mut o = o;
|
||||
m.write_be(&mut o.as_mut()[0..]).unwrap();
|
||||
m.write_be(&mut o.as_mut()[48..]).unwrap();
|
||||
o.as_mut()[..48].copy_from_slice(m.as_ref());
|
||||
o.as_mut()[48..96].copy_from_slice(m.as_ref());
|
||||
|
||||
if let Err(GroupDecodingError::NotOnCurve) = o.into_affine() {
|
||||
// :)
|
||||
@ -331,8 +335,8 @@ fn test_g2_uncompressed_invalid_vectors() {
|
||||
let mut x3b = x.square();
|
||||
x3b.mul_assign(&x);
|
||||
x3b.add_assign(&Fq2 {
|
||||
c0: Fq::from_repr(FqRepr::from(4)).unwrap(),
|
||||
c1: Fq::from_repr(FqRepr::from(4)).unwrap(),
|
||||
c0: Fq::from(4),
|
||||
c1: Fq::from(4),
|
||||
}); // TODO: perhaps expose coeff_b through API?
|
||||
|
||||
let y = x3b.sqrt();
|
||||
@ -340,10 +344,10 @@ fn test_g2_uncompressed_invalid_vectors() {
|
||||
let y = y.unwrap();
|
||||
|
||||
// We know this is on the curve, but it's likely not going to be in the correct subgroup.
|
||||
x.c1.into_repr().write_be(&mut o.as_mut()[0..]).unwrap();
|
||||
x.c0.into_repr().write_be(&mut o.as_mut()[48..]).unwrap();
|
||||
y.c1.into_repr().write_be(&mut o.as_mut()[96..]).unwrap();
|
||||
y.c0.into_repr().write_be(&mut o.as_mut()[144..]).unwrap();
|
||||
o.as_mut()[..48].copy_from_slice(x.c1.into_repr().as_ref());
|
||||
o.as_mut()[48..96].copy_from_slice(x.c0.into_repr().as_ref());
|
||||
o.as_mut()[96..144].copy_from_slice(y.c1.into_repr().as_ref());
|
||||
o.as_mut()[144..].copy_from_slice(y.c0.into_repr().as_ref());
|
||||
|
||||
if let Err(GroupDecodingError::NotInSubgroup) = o.into_affine() {
|
||||
break;
|
||||
@ -407,14 +411,16 @@ fn test_g1_compressed_invalid_vectors() {
|
||||
}
|
||||
}
|
||||
|
||||
let m = Fq::char();
|
||||
// PrimeField::char() returns the modulus in its little-endian byte representation,
|
||||
// but Fq field elements use big-endian encoding, so flip the endianness.
|
||||
let m: Vec<_> = Fq::char().as_ref().iter().cloned().rev().collect();
|
||||
|
||||
{
|
||||
let mut o = o;
|
||||
m.write_be(&mut o.as_mut()[0..]).unwrap();
|
||||
o.as_mut()[..48].copy_from_slice(&m[..]);
|
||||
o.as_mut()[0] |= 0b1000_0000;
|
||||
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate, _)) = o.into_affine() {
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() {
|
||||
assert_eq!(coordinate, "x coordinate");
|
||||
} else {
|
||||
panic!("should have rejected the point")
|
||||
@ -428,12 +434,12 @@ fn test_g1_compressed_invalid_vectors() {
|
||||
loop {
|
||||
let mut x3b = x.square();
|
||||
x3b.mul_assign(&x);
|
||||
x3b.add_assign(&Fq::from_repr(FqRepr::from(4)).unwrap()); // TODO: perhaps expose coeff_b through API?
|
||||
x3b.add_assign(&Fq::from(4)); // TODO: perhaps expose coeff_b through API?
|
||||
|
||||
if x3b.sqrt().is_some().into() {
|
||||
x.add_assign(&Fq::one());
|
||||
} else {
|
||||
x.into_repr().write_be(&mut o.as_mut()[0..]).unwrap();
|
||||
o.as_mut().copy_from_slice(x.into_repr().as_ref());
|
||||
o.as_mut()[0] |= 0b1000_0000;
|
||||
|
||||
if let Err(GroupDecodingError::NotOnCurve) = o.into_affine() {
|
||||
@ -452,11 +458,11 @@ fn test_g1_compressed_invalid_vectors() {
|
||||
loop {
|
||||
let mut x3b = x.square();
|
||||
x3b.mul_assign(&x);
|
||||
x3b.add_assign(&Fq::from_repr(FqRepr::from(4)).unwrap()); // TODO: perhaps expose coeff_b through API?
|
||||
x3b.add_assign(&Fq::from(4)); // TODO: perhaps expose coeff_b through API?
|
||||
|
||||
if x3b.sqrt().is_some().into() {
|
||||
// We know this is on the curve, but it's likely not going to be in the correct subgroup.
|
||||
x.into_repr().write_be(&mut o.as_mut()[0..]).unwrap();
|
||||
o.as_mut().copy_from_slice(x.into_repr().as_ref());
|
||||
o.as_mut()[0] |= 0b1000_0000;
|
||||
|
||||
if let Err(GroupDecodingError::NotInSubgroup) = o.into_affine() {
|
||||
@ -521,14 +527,16 @@ fn test_g2_compressed_invalid_vectors() {
|
||||
}
|
||||
}
|
||||
|
||||
let m = Fq::char();
|
||||
// PrimeField::char() returns the modulus in its little-endian byte representation,
|
||||
// but Fq field elements use big-endian encoding, so flip the endianness.
|
||||
let m: Vec<_> = Fq::char().as_ref().iter().cloned().rev().collect();
|
||||
|
||||
{
|
||||
let mut o = o;
|
||||
m.write_be(&mut o.as_mut()[0..]).unwrap();
|
||||
o.as_mut()[..48].copy_from_slice(&m[..]);
|
||||
o.as_mut()[0] |= 0b1000_0000;
|
||||
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate, _)) = o.into_affine() {
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() {
|
||||
assert_eq!(coordinate, "x coordinate (c1)");
|
||||
} else {
|
||||
panic!("should have rejected the point")
|
||||
@ -537,10 +545,10 @@ fn test_g2_compressed_invalid_vectors() {
|
||||
|
||||
{
|
||||
let mut o = o;
|
||||
m.write_be(&mut o.as_mut()[48..]).unwrap();
|
||||
o.as_mut()[48..96].copy_from_slice(&m[..]);
|
||||
o.as_mut()[0] |= 0b1000_0000;
|
||||
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate, _)) = o.into_affine() {
|
||||
if let Err(GroupDecodingError::CoordinateDecodingError(coordinate)) = o.into_affine() {
|
||||
assert_eq!(coordinate, "x coordinate (c0)");
|
||||
} else {
|
||||
panic!("should have rejected the point")
|
||||
@ -558,15 +566,15 @@ fn test_g2_compressed_invalid_vectors() {
|
||||
let mut x3b = x.square();
|
||||
x3b.mul_assign(&x);
|
||||
x3b.add_assign(&Fq2 {
|
||||
c0: Fq::from_repr(FqRepr::from(4)).unwrap(),
|
||||
c1: Fq::from_repr(FqRepr::from(4)).unwrap(),
|
||||
c0: Fq::from(4),
|
||||
c1: Fq::from(4),
|
||||
}); // TODO: perhaps expose coeff_b through API?
|
||||
|
||||
if x3b.sqrt().is_some().into() {
|
||||
x.add_assign(&Fq2::one());
|
||||
} else {
|
||||
x.c1.into_repr().write_be(&mut o.as_mut()[0..]).unwrap();
|
||||
x.c0.into_repr().write_be(&mut o.as_mut()[48..]).unwrap();
|
||||
o.as_mut()[..48].copy_from_slice(x.c1.into_repr().as_ref());
|
||||
o.as_mut()[48..].copy_from_slice(x.c0.into_repr().as_ref());
|
||||
o.as_mut()[0] |= 0b1000_0000;
|
||||
|
||||
if let Err(GroupDecodingError::NotOnCurve) = o.into_affine() {
|
||||
@ -589,14 +597,14 @@ fn test_g2_compressed_invalid_vectors() {
|
||||
let mut x3b = x.square();
|
||||
x3b.mul_assign(&x);
|
||||
x3b.add_assign(&Fq2 {
|
||||
c0: Fq::from_repr(FqRepr::from(4)).unwrap(),
|
||||
c1: Fq::from_repr(FqRepr::from(4)).unwrap(),
|
||||
c0: Fq::from(4),
|
||||
c1: Fq::from(4),
|
||||
}); // TODO: perhaps expose coeff_b through API?
|
||||
|
||||
if x3b.sqrt().is_some().into() {
|
||||
// We know this is on the curve, but it's likely not going to be in the correct subgroup.
|
||||
x.c1.into_repr().write_be(&mut o.as_mut()[0..]).unwrap();
|
||||
x.c0.into_repr().write_be(&mut o.as_mut()[48..]).unwrap();
|
||||
o.as_mut()[..48].copy_from_slice(x.c1.into_repr().as_ref());
|
||||
o.as_mut()[48..].copy_from_slice(x.c0.into_repr().as_ref());
|
||||
o.as_mut()[0] |= 0b1000_0000;
|
||||
|
||||
if let Err(GroupDecodingError::NotInSubgroup) = o.into_affine() {
|
||||
|
@ -1,3 +1,4 @@
|
||||
use ff::PowVartime;
|
||||
use group::{CurveAffine, CurveProjective};
|
||||
use rand_core::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
|
@ -1,8 +1,8 @@
|
||||
use ff::{Field, PrimeField, SqrtField};
|
||||
use ff::{Field, PowVartime, PrimeField, SqrtField};
|
||||
use rand_core::{RngCore, SeedableRng};
|
||||
use rand_xorshift::XorShiftRng;
|
||||
|
||||
pub fn random_frobenius_tests<F: Field, C: AsRef<[u64]>>(characteristic: C, maxpower: usize) {
|
||||
pub fn random_frobenius_tests<F: Field, C: AsRef<[u8]>>(characteristic: C, maxpower: usize) {
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
0xe5,
|
||||
@ -119,7 +119,7 @@ pub fn from_str_tests<F: PrimeField>() {
|
||||
let n = rng.next_u64();
|
||||
|
||||
let a = F::from_str(&format!("{}", n)).unwrap();
|
||||
let b = F::from_repr(n.into()).unwrap();
|
||||
let b = F::from(n);
|
||||
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
use ff::{PrimeField, PrimeFieldRepr};
|
||||
use ff::PrimeField;
|
||||
use rand_core::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
|
||||
pub fn random_repr_tests<P: PrimeField>() {
|
||||
random_encoding_tests::<P>();
|
||||
random_shl_tests::<P>();
|
||||
random_shr_tests::<P>();
|
||||
}
|
||||
|
||||
@ -15,72 +14,13 @@ fn random_encoding_tests<P: PrimeField>() {
|
||||
]);
|
||||
|
||||
for _ in 0..1000 {
|
||||
let r = P::random(&mut rng).into_repr();
|
||||
let r = P::random(&mut rng);
|
||||
|
||||
// Big endian
|
||||
{
|
||||
let mut rdecoded = <P as PrimeField>::Repr::default();
|
||||
|
||||
let mut v: Vec<u8> = vec![];
|
||||
r.write_be(&mut v).unwrap();
|
||||
rdecoded.read_be(&v[0..]).unwrap();
|
||||
let v = r.into_repr();
|
||||
let rdecoded = P::from_repr(v).unwrap();
|
||||
|
||||
assert_eq!(r, rdecoded);
|
||||
}
|
||||
|
||||
// Little endian
|
||||
{
|
||||
let mut rdecoded = <P as PrimeField>::Repr::default();
|
||||
|
||||
let mut v: Vec<u8> = vec![];
|
||||
r.write_le(&mut v).unwrap();
|
||||
rdecoded.read_le(&v[0..]).unwrap();
|
||||
|
||||
assert_eq!(r, rdecoded);
|
||||
}
|
||||
|
||||
{
|
||||
let mut rdecoded_le = <P as PrimeField>::Repr::default();
|
||||
let mut rdecoded_be_flip = <P as PrimeField>::Repr::default();
|
||||
|
||||
let mut v: Vec<u8> = vec![];
|
||||
r.write_le(&mut v).unwrap();
|
||||
|
||||
// This reads in little-endian, so we are done.
|
||||
rdecoded_le.read_le(&v[..]).unwrap();
|
||||
|
||||
// This reads in big-endian, so we perform a swap of the
|
||||
// bytes beforehand.
|
||||
let v: Vec<u8> = v.into_iter().rev().collect();
|
||||
rdecoded_be_flip.read_be(&v[..]).unwrap();
|
||||
|
||||
assert_eq!(rdecoded_le, rdecoded_be_flip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn random_shl_tests<P: PrimeField>() {
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
for _ in 0..100 {
|
||||
let r = P::random(&mut rng).into_repr();
|
||||
|
||||
for shift in 0..=r.num_bits() {
|
||||
let mut r1 = r;
|
||||
let mut r2 = r;
|
||||
|
||||
for _ in 0..shift {
|
||||
r1.mul2();
|
||||
}
|
||||
|
||||
r2.shl(shift);
|
||||
|
||||
assert_eq!(r1, r2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn random_shr_tests<P: PrimeField>() {
|
||||
@ -90,19 +30,22 @@ fn random_shr_tests<P: PrimeField>() {
|
||||
]);
|
||||
|
||||
for _ in 0..100 {
|
||||
let r = P::random(&mut rng).into_repr();
|
||||
let r = P::random(&mut rng);
|
||||
|
||||
for shift in 0..=r.num_bits() {
|
||||
let mut r1 = r;
|
||||
let mut r2 = r;
|
||||
for shift in 0..P::NUM_BITS {
|
||||
let r1 = r >> shift;
|
||||
|
||||
// Doubling the shifted element inserts zeros on the right; re-shifting should
|
||||
// undo the doubling.
|
||||
let mut r2 = r1;
|
||||
for _ in 0..shift {
|
||||
r1.div2();
|
||||
r2 = r2.double();
|
||||
}
|
||||
|
||||
r2.shr(shift);
|
||||
r2 = r2 >> shift;
|
||||
|
||||
assert_eq!(r1, r2);
|
||||
}
|
||||
|
||||
assert_eq!(r >> P::NUM_BITS, P::zero());
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Generated code for handling light client protobuf structs.
|
||||
|
||||
use ff::{PrimeField, PrimeFieldRepr};
|
||||
use ff::PrimeField;
|
||||
use pairing::bls12_381::{Bls12, Fr, FrRepr};
|
||||
use zcash_primitives::{
|
||||
block::{BlockHash, BlockHeader},
|
||||
@ -67,8 +67,8 @@ impl compact_formats::CompactOutput {
|
||||
/// [`CompactOutput.cmu`]: #structfield.cmu
|
||||
pub fn cmu(&self) -> Result<Fr, ()> {
|
||||
let mut repr = FrRepr::default();
|
||||
repr.read_le(&self.cmu[..]).map_err(|_| ())?;
|
||||
Fr::from_repr(repr).map_err(|_| ())
|
||||
repr.as_mut().copy_from_slice(&self.cmu[..]);
|
||||
Fr::from_repr(repr).ok_or(())
|
||||
}
|
||||
|
||||
/// Returns the ephemeral public key for this output.
|
||||
|
@ -183,7 +183,7 @@ pub fn scan_block(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ff::{Field, PrimeField, PrimeFieldRepr};
|
||||
use ff::{Field, PrimeField};
|
||||
use pairing::bls12_381::{Bls12, Fr};
|
||||
use rand_core::{OsRng, RngCore};
|
||||
use zcash_primitives::{
|
||||
@ -207,9 +207,7 @@ mod tests {
|
||||
};
|
||||
let fake_cmu = {
|
||||
let fake_cmu = Fr::random(rng);
|
||||
let mut bytes = vec![];
|
||||
fake_cmu.into_repr().write_le(&mut bytes).unwrap();
|
||||
bytes
|
||||
fake_cmu.into_repr().as_ref().to_owned()
|
||||
};
|
||||
let fake_epk = {
|
||||
let mut buffer = vec![0; 64];
|
||||
@ -264,8 +262,7 @@ mod tests {
|
||||
Memo::default(),
|
||||
&mut rng,
|
||||
);
|
||||
let mut cmu = vec![];
|
||||
note.cm(&JUBJUB).into_repr().write_le(&mut cmu).unwrap();
|
||||
let cmu = note.cm(&JUBJUB).into_repr().as_ref().to_owned();
|
||||
let mut epk = vec![];
|
||||
encryptor.epk().write(&mut epk).unwrap();
|
||||
let enc_ciphertext = encryptor.encrypt_note_plaintext();
|
||||
|
@ -1,4 +1,4 @@
|
||||
use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField};
|
||||
use ff::{BitIterator, Field, PrimeField, SqrtField};
|
||||
use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
|
||||
use subtle::CtOption;
|
||||
|
||||
@ -83,15 +83,15 @@ impl<E: JubjubEngine, Subgroup> PartialEq for Point<E, Subgroup> {
|
||||
}
|
||||
|
||||
impl<E: JubjubEngine> Point<E, Unknown> {
|
||||
pub fn read<R: Read>(reader: R, params: &E::Params) -> io::Result<Self> {
|
||||
pub fn read<R: Read>(mut reader: R, params: &E::Params) -> io::Result<Self> {
|
||||
let mut y_repr = <E::Fr as PrimeField>::Repr::default();
|
||||
y_repr.read_le(reader)?;
|
||||
reader.read_exact(y_repr.as_mut())?;
|
||||
|
||||
let x_sign = (y_repr.as_ref()[3] >> 63) == 1;
|
||||
y_repr.as_mut()[3] &= 0x7fffffffffffffff;
|
||||
let x_sign = (y_repr.as_ref()[31] >> 7) == 1;
|
||||
y_repr.as_mut()[31] &= 0x7f;
|
||||
|
||||
match E::Fr::from_repr(y_repr) {
|
||||
Ok(y) => {
|
||||
Some(y) => {
|
||||
let p = Self::get_for_y(y, x_sign, params);
|
||||
if bool::from(p.is_some()) {
|
||||
Ok(p.unwrap())
|
||||
@ -99,7 +99,7 @@ impl<E: JubjubEngine> Point<E, Unknown> {
|
||||
Err(io::Error::new(io::ErrorKind::InvalidInput, "not on curve"))
|
||||
}
|
||||
}
|
||||
Err(_) => Err(io::Error::new(
|
||||
None => Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"y is not in field",
|
||||
)),
|
||||
@ -127,7 +127,7 @@ impl<E: JubjubEngine> Point<E, Unknown> {
|
||||
tmp1.mul_assign(&tmp2);
|
||||
|
||||
tmp1.sqrt().map(|mut x| {
|
||||
if x.into_repr().is_odd() != sign {
|
||||
if x.is_odd() != sign {
|
||||
x = x.neg();
|
||||
}
|
||||
|
||||
@ -167,18 +167,17 @@ impl<E: JubjubEngine> Point<E, Unknown> {
|
||||
}
|
||||
|
||||
impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
|
||||
pub fn write<W: Write>(&self, writer: W) -> io::Result<()> {
|
||||
pub fn write<W: Write>(&self, mut writer: W) -> io::Result<()> {
|
||||
let (x, y) = self.to_xy();
|
||||
|
||||
assert_eq!(E::Fr::NUM_BITS, 255);
|
||||
|
||||
let x_repr = x.into_repr();
|
||||
let mut y_repr = y.into_repr();
|
||||
if x_repr.is_odd() {
|
||||
y_repr.as_mut()[3] |= 0x8000000000000000u64;
|
||||
if x.is_odd() {
|
||||
y_repr.as_mut()[31] |= 0x80;
|
||||
}
|
||||
|
||||
y_repr.write_le(writer)
|
||||
writer.write_all(y_repr.as_ref())
|
||||
}
|
||||
|
||||
/// Convert from a Montgomery point
|
||||
@ -468,7 +467,7 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
|
||||
|
||||
let mut res = Self::zero();
|
||||
|
||||
for b in BitIterator::new(scalar.into()) {
|
||||
for b in BitIterator::<u8, _>::new(scalar.into()) {
|
||||
res = res.double(params);
|
||||
|
||||
if b {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField};
|
||||
use ff::{BitIterator, Field, PrimeField, SqrtField};
|
||||
use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
|
||||
use subtle::CtOption;
|
||||
|
||||
@ -60,7 +60,7 @@ impl<E: JubjubEngine> Point<E, Unknown> {
|
||||
rhs.add_assign(&x2);
|
||||
|
||||
rhs.sqrt().map(|mut y| {
|
||||
if y.into_repr().is_odd() != sign {
|
||||
if y.is_odd() != sign {
|
||||
y = y.neg();
|
||||
}
|
||||
|
||||
@ -304,7 +304,7 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
|
||||
|
||||
let mut res = Self::zero();
|
||||
|
||||
for b in BitIterator::new(scalar.into()) {
|
||||
for b in BitIterator::<u8, _>::new(scalar.into()) {
|
||||
res = res.double(params);
|
||||
|
||||
if b {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::{edwards, montgomery, JubjubEngine, JubjubParams, PrimeOrder};
|
||||
|
||||
use ff::{Field, PrimeField, PrimeFieldRepr, SqrtField};
|
||||
use ff::{Field, PrimeField, SqrtField};
|
||||
use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
|
||||
|
||||
use rand_core::{RngCore, SeedableRng};
|
||||
@ -237,7 +237,7 @@ fn test_get_for<E: JubjubEngine>(params: &E::Params) {
|
||||
let p = edwards::Point::<E, _>::get_for_y(y, sign, params);
|
||||
if bool::from(p.is_some()) {
|
||||
let mut p = p.unwrap();
|
||||
assert!(p.to_xy().0.into_repr().is_odd() == sign);
|
||||
assert!(p.to_xy().0.is_odd() == sign);
|
||||
p = p.negate();
|
||||
assert!(edwards::Point::<E, _>::get_for_y(y, !sign, params).unwrap() == p);
|
||||
}
|
||||
@ -370,32 +370,26 @@ fn test_jubjub_params<E: JubjubEngine>(params: &E::Params) {
|
||||
// Check that the number of windows per generator
|
||||
// in the Pedersen hash does not allow for collisions
|
||||
|
||||
let mut cur = E::Fs::one().into_repr();
|
||||
let mut cur = E::Fs::one();
|
||||
|
||||
let mut max = E::Fs::char();
|
||||
{
|
||||
max.sub_noborrow(&E::Fs::one().into_repr());
|
||||
max.div2();
|
||||
}
|
||||
let max = (-E::Fs::one()) >> 1;
|
||||
|
||||
let mut pacc = E::Fs::zero().into_repr();
|
||||
let mut nacc = E::Fs::char();
|
||||
let mut pacc = E::Fs::zero();
|
||||
let mut nacc = E::Fs::zero();
|
||||
|
||||
for _ in 0..params.pedersen_hash_chunks_per_generator() {
|
||||
// tmp = cur * 4
|
||||
let mut tmp = cur;
|
||||
tmp.mul2();
|
||||
tmp.mul2();
|
||||
let tmp = cur.double().double();
|
||||
|
||||
pacc.add_nocarry(&tmp);
|
||||
nacc.sub_noborrow(&tmp);
|
||||
pacc += &tmp;
|
||||
nacc -= &tmp; // The first subtraction wraps intentionally.
|
||||
|
||||
assert!(pacc < max);
|
||||
assert!(pacc < nacc);
|
||||
|
||||
// cur = cur * 16
|
||||
for _ in 0..4 {
|
||||
cur.mul2();
|
||||
cur = cur.double();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||
primitives::{ProofGenerationKey, ViewingKey},
|
||||
};
|
||||
use blake2b_simd::{Hash as Blake2bHash, Params as Blake2bParams};
|
||||
use ff::{PrimeField, PrimeFieldRepr};
|
||||
use ff::PrimeField;
|
||||
use std::io::{self, Read, Write};
|
||||
|
||||
pub const PRF_EXPAND_PERSONALIZATION: &[u8; 16] = b"Zcash_ExpandSeed";
|
||||
@ -71,14 +71,14 @@ impl<E: JubjubEngine> ExpandedSpendingKey<E> {
|
||||
|
||||
pub fn read<R: Read>(mut reader: R) -> io::Result<Self> {
|
||||
let mut ask_repr = <E::Fs as PrimeField>::Repr::default();
|
||||
ask_repr.read_le(&mut reader)?;
|
||||
reader.read_exact(ask_repr.as_mut())?;
|
||||
let ask = E::Fs::from_repr(ask_repr)
|
||||
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "ask not in field"))?;
|
||||
|
||||
let mut nsk_repr = <E::Fs as PrimeField>::Repr::default();
|
||||
nsk_repr.read_le(&mut reader)?;
|
||||
reader.read_exact(nsk_repr.as_mut())?;
|
||||
let nsk = E::Fs::from_repr(nsk_repr)
|
||||
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "nsk not in field"))?;
|
||||
|
||||
let mut ovk = [0; 32];
|
||||
reader.read_exact(&mut ovk)?;
|
||||
@ -91,8 +91,8 @@ impl<E: JubjubEngine> ExpandedSpendingKey<E> {
|
||||
}
|
||||
|
||||
pub fn write<W: Write>(&self, mut writer: W) -> io::Result<()> {
|
||||
self.ask.into_repr().write_le(&mut writer)?;
|
||||
self.nsk.into_repr().write_le(&mut writer)?;
|
||||
writer.write_all(self.ask.into_repr().as_ref())?;
|
||||
writer.write_all(self.nsk.into_repr().as_ref())?;
|
||||
writer.write_all(&self.ovk.0)?;
|
||||
|
||||
Ok(())
|
||||
|
@ -511,9 +511,9 @@ mod tests {
|
||||
use super::{CommitmentTree, Hashable, IncrementalWitness, MerklePath, PathFiller};
|
||||
use crate::sapling::Node;
|
||||
|
||||
use ff::PrimeFieldRepr;
|
||||
use hex;
|
||||
use pairing::bls12_381::FrRepr;
|
||||
use std::convert::TryInto;
|
||||
use std::io::{self, Read, Write};
|
||||
|
||||
const HEX_EMPTY_ROOTS: [&str; 33] = [
|
||||
@ -1016,9 +1016,7 @@ mod tests {
|
||||
let mut paths_i = 0;
|
||||
let mut witness_ser_i = 0;
|
||||
for i in 0..16 {
|
||||
let mut cm = FrRepr::default();
|
||||
cm.read_le(&hex::decode(commitments[i]).unwrap()[..])
|
||||
.expect("length is 32 bytes");
|
||||
let cm = FrRepr(hex::decode(commitments[i]).unwrap()[..].try_into().unwrap());
|
||||
|
||||
let cm = Node::new(cm);
|
||||
|
||||
|
@ -11,9 +11,10 @@ use crate::{
|
||||
use blake2b_simd::{Hash as Blake2bHash, Params as Blake2bParams};
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use crypto_api_chachapoly::{ChaCha20Ietf, ChachaPolyIetf};
|
||||
use ff::{PrimeField, PrimeFieldRepr};
|
||||
use ff::PrimeField;
|
||||
use pairing::bls12_381::{Bls12, Fr};
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
use std::convert::TryInto;
|
||||
use std::fmt;
|
||||
use std::str;
|
||||
|
||||
@ -192,7 +193,7 @@ fn prf_ock(
|
||||
let mut ock_input = [0u8; 128];
|
||||
ock_input[0..32].copy_from_slice(&ovk.0);
|
||||
cv.write(&mut ock_input[32..64]).unwrap();
|
||||
cmu.into_repr().write_le(&mut ock_input[64..96]).unwrap();
|
||||
ock_input[64..96].copy_from_slice(cmu.into_repr().as_ref());
|
||||
epk.write(&mut ock_input[96..128]).unwrap();
|
||||
|
||||
Blake2bParams::new()
|
||||
@ -302,11 +303,7 @@ impl SaplingNoteEncryption {
|
||||
(&mut input[12..20])
|
||||
.write_u64::<LittleEndian>(self.note.value)
|
||||
.unwrap();
|
||||
self.note
|
||||
.r
|
||||
.into_repr()
|
||||
.write_le(&mut input[20..COMPACT_NOTE_SIZE])
|
||||
.unwrap();
|
||||
input[20..COMPACT_NOTE_SIZE].copy_from_slice(self.note.r.into_repr().as_ref());
|
||||
input[COMPACT_NOTE_SIZE..NOTE_PLAINTEXT_SIZE].copy_from_slice(&self.memo.0);
|
||||
|
||||
let mut output = [0u8; ENC_CIPHERTEXT_SIZE];
|
||||
@ -330,10 +327,7 @@ impl SaplingNoteEncryption {
|
||||
|
||||
let mut input = [0u8; OUT_PLAINTEXT_SIZE];
|
||||
self.note.pk_d.write(&mut input[0..32]).unwrap();
|
||||
self.esk
|
||||
.into_repr()
|
||||
.write_le(&mut input[32..OUT_PLAINTEXT_SIZE])
|
||||
.unwrap();
|
||||
input[32..OUT_PLAINTEXT_SIZE].copy_from_slice(self.esk.into_repr().as_ref());
|
||||
|
||||
let mut output = [0u8; OUT_CIPHERTEXT_SIZE];
|
||||
assert_eq!(
|
||||
@ -363,9 +357,11 @@ fn parse_note_plaintext_without_memo(
|
||||
|
||||
let v = (&plaintext[12..20]).read_u64::<LittleEndian>().ok()?;
|
||||
|
||||
let mut rcm = FsRepr::default();
|
||||
rcm.read_le(&plaintext[20..COMPACT_NOTE_SIZE]).ok()?;
|
||||
let rcm = Fs::from_repr(rcm).ok()?;
|
||||
let rcm = Fs::from_repr(FsRepr(
|
||||
plaintext[20..COMPACT_NOTE_SIZE]
|
||||
.try_into()
|
||||
.expect("slice is the correct length"),
|
||||
))?;
|
||||
|
||||
let diversifier = Diversifier(d);
|
||||
let pk_d = diversifier
|
||||
@ -483,9 +479,11 @@ pub fn try_sapling_output_recovery(
|
||||
.ok()?
|
||||
.as_prime_order(&JUBJUB)?;
|
||||
|
||||
let mut esk = FsRepr::default();
|
||||
esk.read_le(&op[32..OUT_PLAINTEXT_SIZE]).ok()?;
|
||||
let esk = Fs::from_repr(esk).ok()?;
|
||||
let esk = Fs::from_repr(FsRepr(
|
||||
op[32..OUT_PLAINTEXT_SIZE]
|
||||
.try_into()
|
||||
.expect("slice is the correct length"),
|
||||
))?;
|
||||
|
||||
let shared_secret = sapling_ka_agree(&esk, &pk_d);
|
||||
let key = kdf_sapling(shared_secret, &epk);
|
||||
@ -515,9 +513,11 @@ pub fn try_sapling_output_recovery(
|
||||
|
||||
let v = (&plaintext[12..20]).read_u64::<LittleEndian>().ok()?;
|
||||
|
||||
let mut rcm = FsRepr::default();
|
||||
rcm.read_le(&plaintext[20..COMPACT_NOTE_SIZE]).ok()?;
|
||||
let rcm = Fs::from_repr(rcm).ok()?;
|
||||
let rcm = Fs::from_repr(FsRepr(
|
||||
plaintext[20..COMPACT_NOTE_SIZE]
|
||||
.try_into()
|
||||
.expect("slice is the correct length"),
|
||||
))?;
|
||||
|
||||
let mut memo = [0u8; 512];
|
||||
memo.copy_from_slice(&plaintext[COMPACT_NOTE_SIZE..NOTE_PLAINTEXT_SIZE]);
|
||||
@ -554,10 +554,11 @@ mod tests {
|
||||
primitives::{Diversifier, PaymentAddress, ValueCommitment},
|
||||
};
|
||||
use crypto_api_chachapoly::ChachaPolyIetf;
|
||||
use ff::{Field, PrimeField, PrimeFieldRepr};
|
||||
use ff::{Field, PrimeField};
|
||||
use pairing::bls12_381::{Bls12, Fr, FrRepr};
|
||||
use rand_core::OsRng;
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
use std::convert::TryInto;
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::{
|
||||
@ -791,9 +792,7 @@ mod tests {
|
||||
.as_prime_order(&JUBJUB)
|
||||
.unwrap();
|
||||
|
||||
let mut esk = FsRepr::default();
|
||||
esk.read_le(&op[32..OUT_PLAINTEXT_SIZE]).unwrap();
|
||||
let esk = Fs::from_repr(esk).unwrap();
|
||||
let esk = Fs::from_repr(FsRepr(op[32..OUT_PLAINTEXT_SIZE].try_into().unwrap())).unwrap();
|
||||
|
||||
let shared_secret = sapling_ka_agree(&esk, &pk_d);
|
||||
let key = kdf_sapling(shared_secret, &epk);
|
||||
@ -1292,17 +1291,13 @@ mod tests {
|
||||
|
||||
macro_rules! read_fr {
|
||||
($field:expr) => {{
|
||||
let mut repr = FrRepr::default();
|
||||
repr.read_le(&$field[..]).unwrap();
|
||||
Fr::from_repr(repr).unwrap()
|
||||
Fr::from_repr(FrRepr($field[..].try_into().unwrap())).unwrap()
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! read_fs {
|
||||
($field:expr) => {{
|
||||
let mut repr = FsRepr::default();
|
||||
repr.read_le(&$field[..]).unwrap();
|
||||
Fs::from_repr(repr).unwrap()
|
||||
Fs::from_repr(FsRepr($field[..].try_into().unwrap())).unwrap()
|
||||
}};
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Implementation of the Pedersen hash function used in Sapling.
|
||||
|
||||
use crate::jubjub::*;
|
||||
use ff::{Field, PrimeField, PrimeFieldRepr};
|
||||
use ff::Field;
|
||||
use std::ops::{AddAssign, Neg};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
@ -88,16 +88,14 @@ where
|
||||
let window = JubjubBls12::pedersen_hash_exp_window_size();
|
||||
let window_mask = (1 << window) - 1;
|
||||
|
||||
let mut acc = acc.into_repr();
|
||||
|
||||
let mut tmp = edwards::Point::zero();
|
||||
|
||||
while !acc.is_zero() {
|
||||
let i = (acc.as_ref()[0] & window_mask) as usize;
|
||||
let i = (acc & window_mask) as usize;
|
||||
|
||||
tmp = tmp.add(&table[0][i], params);
|
||||
|
||||
acc.shr(window);
|
||||
acc = acc >> window;
|
||||
table = &table[1..];
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Structs for core Zcash primitives.
|
||||
|
||||
use ff::{Field, PrimeField, PrimeFieldRepr};
|
||||
use ff::{Field, PrimeField};
|
||||
|
||||
use crate::constants;
|
||||
|
||||
@ -24,7 +24,7 @@ impl<E: JubjubEngine> ValueCommitment<E> {
|
||||
pub fn cm(&self, params: &E::Params) -> edwards::Point<E, PrimeOrder> {
|
||||
params
|
||||
.generator(FixedGenerators::ValueCommitmentValue)
|
||||
.mul(self.value, params)
|
||||
.mul(E::Fs::from(self.value), params)
|
||||
.add(
|
||||
¶ms
|
||||
.generator(FixedGenerators::ValueCommitmentRandomness)
|
||||
@ -86,7 +86,7 @@ impl<E: JubjubEngine> ViewingKey<E> {
|
||||
h[31] &= 0b0000_0111;
|
||||
|
||||
let mut e = <E::Fs as PrimeField>::Repr::default();
|
||||
e.read_le(&h[..]).unwrap();
|
||||
e.as_mut().copy_from_slice(&h[..]);
|
||||
|
||||
E::Fs::from_repr(e).expect("should be a valid scalar")
|
||||
}
|
||||
@ -291,7 +291,7 @@ impl<E: JubjubEngine> Note<E> {
|
||||
let rho = self.cm_full_point(params).add(
|
||||
¶ms
|
||||
.generator(FixedGenerators::NullifierPosition)
|
||||
.mul(position, params),
|
||||
.mul(E::Fs::from(position), params),
|
||||
params,
|
||||
);
|
||||
|
||||
|
@ -4,23 +4,23 @@
|
||||
//! [RedJubjub]: https://zips.z.cash/protocol/protocol.pdf#concretereddsa
|
||||
|
||||
use crate::jubjub::{edwards::Point, FixedGenerators, JubjubEngine, JubjubParams, Unknown};
|
||||
use ff::{Field, PrimeField, PrimeFieldRepr};
|
||||
use ff::{Field, PrimeField};
|
||||
use rand_core::RngCore;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::ops::{AddAssign, MulAssign, Neg};
|
||||
|
||||
use crate::util::hash_to_scalar;
|
||||
|
||||
fn read_scalar<E: JubjubEngine, R: Read>(reader: R) -> io::Result<E::Fs> {
|
||||
fn read_scalar<E: JubjubEngine, R: Read>(mut reader: R) -> io::Result<E::Fs> {
|
||||
let mut s_repr = <E::Fs as PrimeField>::Repr::default();
|
||||
s_repr.read_le(reader)?;
|
||||
reader.read_exact(s_repr.as_mut())?;
|
||||
|
||||
E::Fs::from_repr(s_repr)
|
||||
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "scalar is not in field"))
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "scalar is not in field"))
|
||||
}
|
||||
|
||||
fn write_scalar<E: JubjubEngine, W: Write>(s: &E::Fs, writer: W) -> io::Result<()> {
|
||||
s.into_repr().write_le(writer)
|
||||
fn write_scalar<E: JubjubEngine, W: Write>(s: &E::Fs, mut writer: W) -> io::Result<()> {
|
||||
writer.write_all(s.into_repr().as_ref())
|
||||
}
|
||||
|
||||
fn h_star<E: JubjubEngine>(a: &[u8], b: &[u8]) -> E::Fs {
|
||||
|
@ -5,7 +5,7 @@ use crate::{
|
||||
pedersen_hash::{pedersen_hash, Personalization},
|
||||
primitives::Note,
|
||||
};
|
||||
use ff::{BitIterator, PrimeField, PrimeFieldRepr};
|
||||
use ff::{BitIterator, PrimeField};
|
||||
use lazy_static::lazy_static;
|
||||
use pairing::bls12_381::{Bls12, Fr, FrRepr};
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
@ -21,7 +21,7 @@ pub const SAPLING_COMMITMENT_TREE_DEPTH: usize = 32;
|
||||
pub fn merkle_hash(depth: usize, lhs: &FrRepr, rhs: &FrRepr) -> FrRepr {
|
||||
let lhs = {
|
||||
let mut tmp = [false; 256];
|
||||
for (a, b) in tmp.iter_mut().rev().zip(BitIterator::new(lhs)) {
|
||||
for (a, b) in tmp.iter_mut().rev().zip(BitIterator::<u8, _>::new(lhs)) {
|
||||
*a = b;
|
||||
}
|
||||
tmp
|
||||
@ -29,7 +29,7 @@ pub fn merkle_hash(depth: usize, lhs: &FrRepr, rhs: &FrRepr) -> FrRepr {
|
||||
|
||||
let rhs = {
|
||||
let mut tmp = [false; 256];
|
||||
for (a, b) in tmp.iter_mut().rev().zip(BitIterator::new(rhs)) {
|
||||
for (a, b) in tmp.iter_mut().rev().zip(BitIterator::<u8, _>::new(rhs)) {
|
||||
*a = b;
|
||||
}
|
||||
tmp
|
||||
@ -62,13 +62,13 @@ impl Node {
|
||||
|
||||
impl Hashable for Node {
|
||||
fn read<R: Read>(mut reader: R) -> io::Result<Self> {
|
||||
let mut repr = FrRepr::default();
|
||||
repr.read_le(&mut reader)?;
|
||||
let mut repr = FrRepr([0; 32]);
|
||||
reader.read_exact(&mut repr.0)?;
|
||||
Ok(Node::new(repr))
|
||||
}
|
||||
|
||||
fn write<W: Write>(&self, mut writer: W) -> io::Result<()> {
|
||||
self.repr.write_le(&mut writer)
|
||||
writer.write_all(self.repr.as_ref())
|
||||
}
|
||||
|
||||
fn combine(depth: usize, lhs: &Self, rhs: &Self) -> Self {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use crate::jubjub::{edwards, Unknown};
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use ff::{PrimeField, PrimeFieldRepr};
|
||||
use ff::PrimeField;
|
||||
use pairing::bls12_381::{Bls12, Fr, FrRepr};
|
||||
use std::io::{self, Read, Write};
|
||||
|
||||
@ -138,9 +138,10 @@ impl SpendDescription {
|
||||
|
||||
// Consensus rule (§7.3): Canonical encoding is enforced here
|
||||
let anchor = {
|
||||
let mut f = FrRepr::default();
|
||||
f.read_le(&mut reader)?;
|
||||
Fr::from_repr(f).map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?
|
||||
let mut f = FrRepr([0; 32]);
|
||||
reader.read_exact(&mut f.0)?;
|
||||
Fr::from_repr(f)
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "anchor not in field"))?
|
||||
};
|
||||
|
||||
let mut nullifier = [0; 32];
|
||||
@ -175,7 +176,7 @@ impl SpendDescription {
|
||||
|
||||
pub fn write<W: Write>(&self, mut writer: W) -> io::Result<()> {
|
||||
self.cv.write(&mut writer)?;
|
||||
self.anchor.into_repr().write_le(&mut writer)?;
|
||||
writer.write_all(self.anchor.into_repr().as_ref())?;
|
||||
writer.write_all(&self.nullifier)?;
|
||||
self.rk.write(&mut writer)?;
|
||||
writer.write_all(&self.zkproof)?;
|
||||
@ -218,9 +219,10 @@ impl OutputDescription {
|
||||
|
||||
// Consensus rule (§7.4): Canonical encoding is enforced here
|
||||
let cmu = {
|
||||
let mut f = FrRepr::default();
|
||||
f.read_le(&mut reader)?;
|
||||
Fr::from_repr(f).map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?
|
||||
let mut f = FrRepr([0; 32]);
|
||||
reader.read_exact(&mut f.0)?;
|
||||
Fr::from_repr(f)
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "cmu not in field"))?
|
||||
};
|
||||
|
||||
// Consensus rules (§4.5):
|
||||
@ -252,7 +254,7 @@ impl OutputDescription {
|
||||
|
||||
pub fn write<W: Write>(&self, mut writer: W) -> io::Result<()> {
|
||||
self.cv.write(&mut writer)?;
|
||||
self.cmu.into_repr().write_le(&mut writer)?;
|
||||
writer.write_all(self.cmu.into_repr().as_ref())?;
|
||||
self.ephemeral_key.write(&mut writer)?;
|
||||
writer.write_all(&self.enc_ciphertext)?;
|
||||
writer.write_all(&self.out_ciphertext)?;
|
||||
|
@ -1,6 +1,6 @@
|
||||
use blake2b_simd::{Hash as Blake2bHash, Params as Blake2bParams};
|
||||
use byteorder::{LittleEndian, WriteBytesExt};
|
||||
use ff::{PrimeField, PrimeFieldRepr};
|
||||
use ff::PrimeField;
|
||||
|
||||
use super::{
|
||||
components::{Amount, TxOut},
|
||||
@ -128,7 +128,7 @@ fn shielded_spends_hash(tx: &TransactionData) -> Blake2bHash {
|
||||
let mut data = Vec::with_capacity(tx.shielded_spends.len() * 384);
|
||||
for s_spend in &tx.shielded_spends {
|
||||
s_spend.cv.write(&mut data).unwrap();
|
||||
s_spend.anchor.into_repr().write_le(&mut data).unwrap();
|
||||
data.extend_from_slice(s_spend.anchor.into_repr().as_ref());
|
||||
data.extend_from_slice(&s_spend.nullifier);
|
||||
s_spend.rk.write(&mut data).unwrap();
|
||||
data.extend_from_slice(&s_spend.zkproof);
|
||||
|
@ -453,7 +453,7 @@ impl ExtendedFullViewingKey {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use ff::{PrimeField, PrimeFieldRepr};
|
||||
use ff::PrimeField;
|
||||
|
||||
#[test]
|
||||
fn derive_nonhardened_child() {
|
||||
@ -1014,11 +1014,8 @@ mod tests {
|
||||
let xsk = &xsks[j];
|
||||
let tv = &test_vectors[j];
|
||||
|
||||
let mut buf = [0; 32];
|
||||
xsk.expsk.ask.into_repr().write_le(&mut buf[..]).unwrap();
|
||||
assert_eq!(buf, tv.ask.unwrap());
|
||||
xsk.expsk.nsk.into_repr().write_le(&mut buf[..]).unwrap();
|
||||
assert_eq!(buf, tv.nsk.unwrap());
|
||||
assert_eq!(xsk.expsk.ask.into_repr().as_ref(), tv.ask.unwrap());
|
||||
assert_eq!(xsk.expsk.nsk.into_repr().as_ref(), tv.nsk.unwrap());
|
||||
|
||||
assert_eq!(xsk.expsk.ovk.0, tv.ovk);
|
||||
assert_eq!(xsk.dk.0, tv.dk);
|
||||
@ -1043,13 +1040,7 @@ mod tests {
|
||||
assert_eq!(xfvk.dk.0, tv.dk);
|
||||
assert_eq!(xfvk.chain_code.0, tv.c);
|
||||
|
||||
xfvk.fvk
|
||||
.vk
|
||||
.ivk()
|
||||
.into_repr()
|
||||
.write_le(&mut buf[..])
|
||||
.unwrap();
|
||||
assert_eq!(buf, tv.ivk);
|
||||
assert_eq!(xfvk.fvk.vk.ivk().into_repr().as_ref(), tv.ivk);
|
||||
|
||||
let mut ser = vec![];
|
||||
xfvk.write(&mut ser).unwrap();
|
||||
|
@ -769,7 +769,7 @@ mod test {
|
||||
let q = p.mul(s, params);
|
||||
let (x1, y1) = q.to_xy();
|
||||
|
||||
let mut s_bits = BitIterator::new(s.into_repr()).collect::<Vec<_>>();
|
||||
let mut s_bits = BitIterator::<u8, _>::new(s.into_repr()).collect::<Vec<_>>();
|
||||
s_bits.reverse();
|
||||
s_bits.truncate(Fs::NUM_BITS as usize);
|
||||
|
||||
@ -822,7 +822,7 @@ mod test {
|
||||
y: num_y0,
|
||||
};
|
||||
|
||||
let mut s_bits = BitIterator::new(s.into_repr()).collect::<Vec<_>>();
|
||||
let mut s_bits = BitIterator::<u8, _>::new(s.into_repr()).collect::<Vec<_>>();
|
||||
s_bits.reverse();
|
||||
s_bits.truncate(Fs::NUM_BITS as usize);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! The Sapling circuits.
|
||||
|
||||
use ff::{Field, PrimeField, PrimeFieldRepr};
|
||||
use ff::{Field, PrimeField};
|
||||
|
||||
use bellman::{Circuit, ConstraintSystem, SynthesisError};
|
||||
|
||||
@ -478,7 +478,7 @@ impl<'a, E: JubjubEngine> Circuit<E> for Output<'a, E> {
|
||||
// Witness the sign bit
|
||||
let sign_bit = boolean::Boolean::from(boolean::AllocatedBit::alloc(
|
||||
cs.namespace(|| "pk_d bit of x"),
|
||||
pk_d.map(|e| e.0.into_repr().is_odd()),
|
||||
pk_d.map(|e| e.0.is_odd()),
|
||||
)?);
|
||||
|
||||
// Extend the note with pk_d representation
|
||||
@ -615,8 +615,8 @@ fn test_input_circuit_with_bls12_381() {
|
||||
::std::mem::swap(&mut lhs, &mut rhs);
|
||||
}
|
||||
|
||||
let mut lhs: Vec<bool> = BitIterator::new(lhs.into_repr()).collect();
|
||||
let mut rhs: Vec<bool> = BitIterator::new(rhs.into_repr()).collect();
|
||||
let mut lhs: Vec<bool> = BitIterator::<u8, _>::new(lhs.into_repr()).collect();
|
||||
let mut rhs: Vec<bool> = BitIterator::<u8, _>::new(rhs.into_repr()).collect();
|
||||
|
||||
lhs.reverse();
|
||||
rhs.reverse();
|
||||
@ -799,8 +799,8 @@ fn test_input_circuit_with_bls12_381_external_test_vectors() {
|
||||
::std::mem::swap(&mut lhs, &mut rhs);
|
||||
}
|
||||
|
||||
let mut lhs: Vec<bool> = BitIterator::new(lhs.into_repr()).collect();
|
||||
let mut rhs: Vec<bool> = BitIterator::new(rhs.into_repr()).collect();
|
||||
let mut lhs: Vec<bool> = BitIterator::<u8, _>::new(lhs.into_repr()).collect();
|
||||
let mut rhs: Vec<bool> = BitIterator::<u8, _>::new(rhs.into_repr()).collect();
|
||||
|
||||
lhs.reverse();
|
||||
rhs.reverse();
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use pairing::bls12_381::Bls12;
|
||||
use zcash_primitives::jubjub::{
|
||||
edwards, fs::FsRepr, FixedGenerators, JubjubBls12, JubjubParams, Unknown,
|
||||
edwards, fs::Fs, FixedGenerators, JubjubBls12, JubjubParams, Unknown,
|
||||
};
|
||||
use zcash_primitives::transaction::components::Amount;
|
||||
|
||||
@ -30,7 +30,7 @@ fn compute_value_balance(
|
||||
// Compute it in the exponent
|
||||
let mut value_balance = params
|
||||
.generator(FixedGenerators::ValueCommitmentValue)
|
||||
.mul(FsRepr::from(abs), params);
|
||||
.mul(Fs::from(abs), params);
|
||||
|
||||
// Negate if necessary
|
||||
if is_negative {
|
||||
|
Loading…
Reference in New Issue
Block a user