mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-02-01 08:12:14 +00:00
ff: Move pow_vartime back into Field trait
The only places we don't use constant u64 limbs, we use PrimeField::char instead (except in a single test where we use a field element).
This commit is contained in:
parent
fb31d09218
commit
15e229509a
@ -11,7 +11,7 @@
|
|||||||
//! [`EvaluationDomain`]: crate::domain::EvaluationDomain
|
//! [`EvaluationDomain`]: crate::domain::EvaluationDomain
|
||||||
//! [Groth16]: https://eprint.iacr.org/2016/260
|
//! [Groth16]: https://eprint.iacr.org/2016/260
|
||||||
|
|
||||||
use ff::{Field, PowVartime, PrimeField, ScalarEngine};
|
use ff::{Field, PrimeField, ScalarEngine};
|
||||||
use group::CurveProjective;
|
use group::CurveProjective;
|
||||||
use std::ops::{AddAssign, MulAssign, SubAssign};
|
use std::ops::{AddAssign, MulAssign, SubAssign};
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use ff::{PowVartime, PrimeField, ScalarEngine};
|
use ff::{Field, PrimeField, ScalarEngine};
|
||||||
|
|
||||||
use crate::{ConstraintSystem, LinearCombination, SynthesisError, Variable};
|
use crate::{ConstraintSystem, LinearCombination, SynthesisError, Variable};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Helpers for testing circuit implementations.
|
//! Helpers for testing circuit implementations.
|
||||||
|
|
||||||
use ff::{Endianness, Field, PowVartime, PrimeField, ScalarEngine};
|
use ff::{Endianness, Field, PrimeField, ScalarEngine};
|
||||||
|
|
||||||
use crate::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable};
|
use crate::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable};
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ use rand_core::RngCore;
|
|||||||
use std::ops::{AddAssign, MulAssign};
|
use std::ops::{AddAssign, MulAssign};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ff::{Field, PowVartime};
|
use ff::Field;
|
||||||
use group::{CurveAffine, CurveProjective, Wnaf};
|
use group::{CurveAffine, CurveProjective, Wnaf};
|
||||||
use pairing::Engine;
|
use pairing::Engine;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use ff::{Field, PowVartime, PrimeField, ScalarEngine};
|
use ff::{Field, PrimeField, ScalarEngine};
|
||||||
use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError};
|
use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError};
|
||||||
use pairing::{Engine, PairingCurveAffine};
|
use pairing::{Engine, PairingCurveAffine};
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use ff::{Field, PowVartime, PrimeField};
|
use ff::{Field, PrimeField};
|
||||||
use pairing::Engine;
|
use pairing::Engine;
|
||||||
|
|
||||||
mod dummy_engine;
|
mod dummy_engine;
|
||||||
|
@ -76,36 +76,21 @@ pub trait Field:
|
|||||||
/// Returns the square root of the field element, if it is
|
/// Returns the square root of the field element, if it is
|
||||||
/// quadratic residue.
|
/// quadratic residue.
|
||||||
fn sqrt(&self) -> CtOption<Self>;
|
fn sqrt(&self) -> CtOption<Self>;
|
||||||
}
|
|
||||||
|
|
||||||
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
|
/// Exponentiates `self` by `exp`, where `exp` is a little-endian order
|
||||||
/// integer exponent.
|
/// integer exponent.
|
||||||
///
|
///
|
||||||
/// **This operation is variable time with respect to the exponent.** If the
|
/// **This operation is variable time with respect to the exponent.** If the
|
||||||
/// exponent is fixed, this operation is effectively constant time.
|
/// exponent is fixed, this operation is effectively constant time.
|
||||||
fn pow_vartime<S: AsRef<[L]>>(&self, exp: S) -> Self {
|
fn pow_vartime<S: AsRef<[u64]>>(&self, exp: S) -> Self {
|
||||||
let mut res = Self::one();
|
let mut res = Self::one();
|
||||||
for e in exp.as_ref().iter().rev() {
|
for e in exp.as_ref().iter().rev() {
|
||||||
let mut i = Self::ZERO;
|
for i in (0..64).rev() {
|
||||||
while i < Self::LIMB_SIZE {
|
|
||||||
res = res.square();
|
res = res.square();
|
||||||
|
|
||||||
if ((*e >> (Self::LIMB_SIZE - Self::ONE - i)) & Self::ONE) == Self::ONE {
|
if ((*e >> i) & 1) == 1 {
|
||||||
res.mul_assign(self);
|
res.mul_assign(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
i += Self::ONE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,18 +98,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper trait for converting the binary representation of a prime field element into a
|
/// Helper trait for converting the binary representation of a prime field element into a
|
||||||
/// specific endianness. This is useful when you need to act on the bit representation
|
/// specific endianness. This is useful when you need to act on the bit representation
|
||||||
/// of an element generically, as the native binary representation of a prime field is
|
/// of an element generically, as the native binary representation of a prime field is
|
||||||
|
@ -2,8 +2,6 @@ use super::fq2::Fq2;
|
|||||||
use ff::{Field, PrimeField};
|
use ff::{Field, PrimeField};
|
||||||
use std::ops::{AddAssign, MulAssign, SubAssign};
|
use std::ops::{AddAssign, MulAssign, SubAssign};
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
use ff::PowVartime;
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use std::ops::Neg;
|
use std::ops::Neg;
|
||||||
|
|
||||||
@ -1644,11 +1642,15 @@ fn test_fq_pow() {
|
|||||||
assert_eq!(c, target);
|
assert_eq!(c, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use byteorder::ByteOrder;
|
||||||
|
let mut char_limbs = [0; 6];
|
||||||
|
byteorder::LittleEndian::read_u64_into(Fq::char().as_ref(), &mut char_limbs);
|
||||||
|
|
||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
// Exponentiating by the modulus should have no effect in a prime field.
|
// Exponentiating by the modulus should have no effect in a prime field.
|
||||||
let a = Fq::random(&mut rng);
|
let a = Fq::random(&mut rng);
|
||||||
|
|
||||||
assert_eq!(a, a.pow_vartime(Fq::char()));
|
assert_eq!(a, a.pow_vartime(char_limbs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use super::fq::{Fq, FROBENIUS_COEFF_FQ2_C1, NEGATIVE_ONE};
|
use super::fq::{Fq, FROBENIUS_COEFF_FQ2_C1, NEGATIVE_ONE};
|
||||||
use ff::{Field, PowVartime};
|
use ff::Field;
|
||||||
use rand_core::RngCore;
|
use rand_core::RngCore;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||||
|
@ -7,8 +7,6 @@ use std::ops::{AddAssign, MulAssign, SubAssign};
|
|||||||
#[PrimeFieldReprEndianness = "little"]
|
#[PrimeFieldReprEndianness = "little"]
|
||||||
pub struct Fr([u64; 4]);
|
pub struct Fr([u64; 4]);
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
use ff::PowVartime;
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use rand_core::SeedableRng;
|
use rand_core::SeedableRng;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -430,11 +428,15 @@ fn test_fr_pow() {
|
|||||||
assert_eq!(c, target);
|
assert_eq!(c, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use byteorder::ByteOrder;
|
||||||
|
let mut char_limbs = [0; 4];
|
||||||
|
byteorder::LittleEndian::read_u64_into(Fr::char().as_ref(), &mut char_limbs);
|
||||||
|
|
||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
// Exponentiating by the modulus should have no effect in a prime field.
|
// Exponentiating by the modulus should have no effect in a prime field.
|
||||||
let a = Fr::random(&mut rng);
|
let a = Fr::random(&mut rng);
|
||||||
|
|
||||||
assert_eq!(a, a.pow_vartime(Fr::char()));
|
assert_eq!(a, a.pow_vartime(char_limbs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ pub use self::fr::{Fr, FrRepr};
|
|||||||
|
|
||||||
use super::{Engine, PairingCurveAffine};
|
use super::{Engine, PairingCurveAffine};
|
||||||
|
|
||||||
use ff::{BitIterator, Field, PowVartime, ScalarEngine};
|
use ff::{BitIterator, Field, ScalarEngine};
|
||||||
use group::CurveAffine;
|
use group::CurveAffine;
|
||||||
use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
|
use std::ops::{AddAssign, MulAssign, Neg, SubAssign};
|
||||||
use subtle::CtOption;
|
use subtle::CtOption;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use ff::PowVartime;
|
use ff::{Endianness, Field, PrimeField};
|
||||||
use group::{CurveAffine, CurveProjective};
|
use group::{CurveAffine, CurveProjective};
|
||||||
use rand_core::SeedableRng;
|
use rand_core::SeedableRng;
|
||||||
use rand_xorshift::XorShiftRng;
|
use rand_xorshift::XorShiftRng;
|
||||||
use std::ops::MulAssign;
|
use std::ops::MulAssign;
|
||||||
|
|
||||||
use crate::{Engine, Field, PairingCurveAffine, PrimeField};
|
use crate::{Engine, PairingCurveAffine};
|
||||||
|
|
||||||
pub fn engine_tests<E: Engine>() {
|
pub fn engine_tests<E: Engine>() {
|
||||||
let mut rng = XorShiftRng::from_seed([
|
let mut rng = XorShiftRng::from_seed([
|
||||||
@ -130,8 +130,14 @@ fn random_bilinearity_tests<E: Engine>() {
|
|||||||
|
|
||||||
let mut cd = c;
|
let mut cd = c;
|
||||||
cd.mul_assign(&d);
|
cd.mul_assign(&d);
|
||||||
|
let mut cd = cd.into_repr();
|
||||||
|
<E::Fr as PrimeField>::ReprEndianness::toggle_little_endian(&mut cd);
|
||||||
|
|
||||||
let abcd = E::pairing(a, b).pow_vartime(cd.into_repr());
|
use byteorder::ByteOrder;
|
||||||
|
let mut cd_limbs = [0; 4];
|
||||||
|
byteorder::LittleEndian::read_u64_into(cd.as_ref(), &mut cd_limbs);
|
||||||
|
|
||||||
|
let abcd = E::pairing(a, b).pow_vartime(cd_limbs);
|
||||||
|
|
||||||
assert_eq!(acbd, adbc);
|
assert_eq!(acbd, adbc);
|
||||||
assert_eq!(acbd, abcd);
|
assert_eq!(acbd, abcd);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use ff::{adc, mac_with_carry, sbb, BitIterator, Field, PowVartime, PrimeField};
|
use ff::{adc, mac_with_carry, sbb, BitIterator, Field, PrimeField};
|
||||||
use rand_core::RngCore;
|
use rand_core::RngCore;
|
||||||
use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||||
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
|
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
|
||||||
@ -1051,11 +1051,15 @@ fn test_fs_pow() {
|
|||||||
assert_eq!(c, target);
|
assert_eq!(c, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use byteorder::ByteOrder;
|
||||||
|
let mut char_limbs = [0; 4];
|
||||||
|
byteorder::LittleEndian::read_u64_into(Fs::char().as_ref(), &mut char_limbs);
|
||||||
|
|
||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
// Exponentiating by the modulus should have no effect in a prime field.
|
// Exponentiating by the modulus should have no effect in a prime field.
|
||||||
let a = Fs::random(&mut rng);
|
let a = Fs::random(&mut rng);
|
||||||
|
|
||||||
assert_eq!(a, a.pow_vartime(Fs::char()));
|
assert_eq!(a, a.pow_vartime(char_limbs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user