ff: Move pow_vartime into a trait that is generic over the limb size

The trait is implemented by default for u8 and u64, allowing pow_vartime
to be used with both the byte encoding and limb representation of field
elements.
This commit is contained in:
Jack Grigg 2020-03-27 22:35:55 +13:00
parent 69c60530d4
commit b6457a905b
14 changed files with 89 additions and 55 deletions

View File

@ -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, PrimeField, ScalarEngine}; use ff::{Field, PowVartime, PrimeField, ScalarEngine};
use group::CurveProjective; use group::CurveProjective;
use std::ops::{AddAssign, MulAssign, SubAssign}; use std::ops::{AddAssign, MulAssign, SubAssign};

View File

@ -1,4 +1,4 @@
use ff::{Field, PrimeField, ScalarEngine}; use ff::{PowVartime, PrimeField, ScalarEngine};
use crate::{ConstraintSystem, LinearCombination, SynthesisError, Variable}; use crate::{ConstraintSystem, LinearCombination, SynthesisError, Variable};

View File

@ -1,6 +1,6 @@
//! Helpers for testing circuit implementations. //! Helpers for testing circuit implementations.
use ff::{Field, PrimeField, PrimeFieldRepr, ScalarEngine}; use ff::{Field, PowVartime, PrimeField, PrimeFieldRepr, ScalarEngine};
use crate::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}; use crate::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable};

View File

@ -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; use ff::{Field, PowVartime};
use group::{CurveAffine, CurveProjective, Wnaf}; use group::{CurveAffine, CurveProjective, Wnaf};
use pairing::Engine; use pairing::Engine;

View File

@ -1,4 +1,6 @@
use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, ScalarEngine, SqrtField}; use ff::{
Field, PowVartime, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, ScalarEngine, SqrtField,
};
use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError}; use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError};
use pairing::{Engine, PairingCurveAffine}; use pairing::{Engine, PairingCurveAffine};
@ -190,9 +192,9 @@ impl SqrtField for Fr {
// https://eprint.iacr.org/2012/685.pdf (page 12, algorithm 5) // https://eprint.iacr.org/2012/685.pdf (page 12, algorithm 5)
let mut c = Fr::root_of_unity(); let mut c = Fr::root_of_unity();
// r = self^((t + 1) // 2) // r = self^((t + 1) // 2)
let mut r = self.pow_vartime([32]); let mut r = self.pow_vartime([32u64]);
// t = self^t // t = self^t
let mut t = self.pow_vartime([63]); let mut t = self.pow_vartime([63u64]);
let mut m = Fr::S; let mut m = Fr::S;
while t != <Fr as Field>::one() { while t != <Fr as Field>::one() {

View File

@ -1,4 +1,4 @@
use ff::{Field, PrimeField}; use ff::{Field, PowVartime, PrimeField};
use pairing::Engine; use pairing::Engine;
mod dummy_engine; mod dummy_engine;
@ -127,22 +127,22 @@ fn test_xordemo() {
let mut root_of_unity = Fr::root_of_unity(); let mut root_of_unity = Fr::root_of_unity();
// We expect this to be a 2^10 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. // Let's turn it into a 2^3 root of unity.
root_of_unity = root_of_unity.pow_vartime(&[1 << 7]); root_of_unity = root_of_unity.pow_vartime(&[1u64 << 7]);
assert_eq!(Fr::one(), root_of_unity.pow_vartime(&[1 << 3])); assert_eq!(Fr::one(), root_of_unity.pow_vartime(&[1u64 << 3]));
assert_eq!(Fr::from_str("20201").unwrap(), root_of_unity); assert_eq!(Fr::from_str("20201").unwrap(), root_of_unity);
// Let's compute all the points in our evaluation domain. // Let's compute all the points in our evaluation domain.
let mut points = Vec::with_capacity(8); 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])); points.push(root_of_unity.pow_vartime(&[i]));
} }
// Let's compute t(tau) = (tau - p_0)(tau - p_1)... // Let's compute t(tau) = (tau - p_0)(tau - p_1)...
// = tau^8 - 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()); t_at_tau.sub_assign(&Fr::one());
{ {
let mut tmp = Fr::one(); let mut tmp = Fr::one();

View File

@ -13,7 +13,7 @@ extern crate std;
pub use ff_derive::*; pub use ff_derive::*;
use core::fmt; use core::fmt;
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use core::ops::{Add, AddAssign, BitAnd, Mul, MulAssign, Neg, Shr, Sub, SubAssign};
use rand_core::RngCore; use rand_core::RngCore;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
@ -73,21 +73,36 @@ pub trait Field:
/// Exponentiates this element by a power of the base prime modulus via /// Exponentiates this element by a power of the base prime modulus via
/// the Frobenius automorphism. /// the Frobenius automorphism.
fn frobenius_map(&mut self, power: usize); 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 /// 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<[u64]>>(&self, exp: S) -> Self { fn pow_vartime<S: AsRef<[L]>>(&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() {
for i in (0..64).rev() { let mut i = Self::ZERO;
while i < Self::LIMB_SIZE {
res = res.square(); res = res.square();
if ((*e >> i) & 1) == 1 { if ((*e >> (Self::LIMB_SIZE - Self::ONE - i)) & Self::ONE) == Self::ONE {
res.mul_assign(self); res.mul_assign(self);
} }
i += Self::ONE;
} }
} }
@ -95,6 +110,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. /// This trait represents an element of a field that has a square root operation described for it.
pub trait SqrtField: Field { pub trait SqrtField: Field {
/// Returns the square root of the field element, if it is /// Returns the square root of the field element, if it is

View File

@ -2,6 +2,8 @@ use super::fq2::Fq2;
use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr}; use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr};
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;
@ -466,7 +468,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ2_C1[1], FROBENIUS_COEFF_FQ2_C1[1],
nqr.pow_vartime([ nqr.pow_vartime([
0xdcff7fffffffd555, 0xdcff7fffffffd555u64,
0xf55ffff58a9ffff, 0xf55ffff58a9ffff,
0xb39869507b587b12, 0xb39869507b587b12,
0xb23ba5c279c2895f, 0xb23ba5c279c2895f,
@ -484,7 +486,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ6_C1[1], FROBENIUS_COEFF_FQ6_C1[1],
nqr.pow_vartime([ nqr.pow_vartime([
0x9354ffffffffe38e, 0x9354ffffffffe38eu64,
0xa395554e5c6aaaa, 0xa395554e5c6aaaa,
0xcd104635a790520c, 0xcd104635a790520c,
0xcc27c3d6fbd7063f, 0xcc27c3d6fbd7063f,
@ -495,7 +497,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ6_C1[2], FROBENIUS_COEFF_FQ6_C1[2],
nqr.pow_vartime([ nqr.pow_vartime([
0xb78e0000097b2f68, 0xb78e0000097b2f68u64,
0xd44f23b47cbd64e3, 0xd44f23b47cbd64e3,
0x5cb9668120b069a9, 0x5cb9668120b069a9,
0xccea85f9bf7b3d16, 0xccea85f9bf7b3d16,
@ -512,7 +514,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ6_C1[3], FROBENIUS_COEFF_FQ6_C1[3],
nqr.pow_vartime([ nqr.pow_vartime([
0xdbc6fcd6f35b9e06, 0xdbc6fcd6f35b9e06u64,
0x997dead10becd6aa, 0x997dead10becd6aa,
0x9dbbd24c17206460, 0x9dbbd24c17206460,
0x72b97acc6057c45e, 0x72b97acc6057c45e,
@ -535,7 +537,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ6_C1[4], FROBENIUS_COEFF_FQ6_C1[4],
nqr.pow_vartime([ nqr.pow_vartime([
0x4649add3c71c6d90, 0x4649add3c71c6d90u64,
0x43caa6528972a865, 0x43caa6528972a865,
0xcda8445bbaaa0fbb, 0xcda8445bbaaa0fbb,
0xc93dea665662aa66, 0xc93dea665662aa66,
@ -564,7 +566,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ6_C1[5], FROBENIUS_COEFF_FQ6_C1[5],
nqr.pow_vartime([ nqr.pow_vartime([
0xf896f792732eb2be, 0xf896f792732eb2beu64,
0x49c86a6d1dc593a1, 0x49c86a6d1dc593a1,
0xe5b31e94581f91c3, 0xe5b31e94581f91c3,
0xe3da5cc0a6b20d7f, 0xe3da5cc0a6b20d7f,
@ -601,7 +603,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ6_C2[1], FROBENIUS_COEFF_FQ6_C2[1],
nqr.pow_vartime([ nqr.pow_vartime([
0x26a9ffffffffc71c, 0x26a9ffffffffc71cu64,
0x1472aaa9cb8d5555, 0x1472aaa9cb8d5555,
0x9a208c6b4f20a418, 0x9a208c6b4f20a418,
0x984f87adf7ae0c7f, 0x984f87adf7ae0c7f,
@ -612,7 +614,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ6_C2[2], FROBENIUS_COEFF_FQ6_C2[2],
nqr.pow_vartime([ nqr.pow_vartime([
0x6f1c000012f65ed0, 0x6f1c000012f65ed0u64,
0xa89e4768f97ac9c7, 0xa89e4768f97ac9c7,
0xb972cd024160d353, 0xb972cd024160d353,
0x99d50bf37ef67a2c, 0x99d50bf37ef67a2c,
@ -629,7 +631,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ6_C2[3], FROBENIUS_COEFF_FQ6_C2[3],
nqr.pow_vartime([ nqr.pow_vartime([
0xb78df9ade6b73c0c, 0xb78df9ade6b73c0cu64,
0x32fbd5a217d9ad55, 0x32fbd5a217d9ad55,
0x3b77a4982e40c8c1, 0x3b77a4982e40c8c1,
0xe572f598c0af88bd, 0xe572f598c0af88bd,
@ -652,7 +654,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ6_C2[4], FROBENIUS_COEFF_FQ6_C2[4],
nqr.pow_vartime([ nqr.pow_vartime([
0x8c935ba78e38db20, 0x8c935ba78e38db20u64,
0x87954ca512e550ca, 0x87954ca512e550ca,
0x9b5088b775541f76, 0x9b5088b775541f76,
0x927bd4ccacc554cd, 0x927bd4ccacc554cd,
@ -681,7 +683,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ6_C2[5], FROBENIUS_COEFF_FQ6_C2[5],
nqr.pow_vartime([ nqr.pow_vartime([
0xf12def24e65d657c, 0xf12def24e65d657cu64,
0x9390d4da3b8b2743, 0x9390d4da3b8b2743,
0xcb663d28b03f2386, 0xcb663d28b03f2386,
0xc7b4b9814d641aff, 0xc7b4b9814d641aff,
@ -718,7 +720,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ12_C1[1], FROBENIUS_COEFF_FQ12_C1[1],
nqr.pow_vartime([ nqr.pow_vartime([
0x49aa7ffffffff1c7, 0x49aa7ffffffff1c7u64,
0x51caaaa72e35555, 0x51caaaa72e35555,
0xe688231ad3c82906, 0xe688231ad3c82906,
0xe613e1eb7deb831f, 0xe613e1eb7deb831f,
@ -729,7 +731,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ12_C1[2], FROBENIUS_COEFF_FQ12_C1[2],
nqr.pow_vartime([ nqr.pow_vartime([
0xdbc7000004bd97b4, 0xdbc7000004bd97b4u64,
0xea2791da3e5eb271, 0xea2791da3e5eb271,
0x2e5cb340905834d4, 0x2e5cb340905834d4,
0xe67542fcdfbd9e8b, 0xe67542fcdfbd9e8b,
@ -746,7 +748,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ12_C1[3], FROBENIUS_COEFF_FQ12_C1[3],
nqr.pow_vartime(vec![ nqr.pow_vartime(vec![
0x6de37e6b79adcf03, 0x6de37e6b79adcf03u64,
0x4cbef56885f66b55, 0x4cbef56885f66b55,
0x4edde9260b903230, 0x4edde9260b903230,
0x395cbd66302be22f, 0x395cbd66302be22f,
@ -769,7 +771,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ12_C1[4], FROBENIUS_COEFF_FQ12_C1[4],
nqr.pow_vartime(vec![ nqr.pow_vartime(vec![
0xa324d6e9e38e36c8, 0xa324d6e9e38e36c8u64,
0xa1e5532944b95432, 0xa1e5532944b95432,
0x66d4222ddd5507dd, 0x66d4222ddd5507dd,
0xe49ef5332b315533, 0xe49ef5332b315533,
@ -798,7 +800,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ12_C1[5], FROBENIUS_COEFF_FQ12_C1[5],
nqr.pow_vartime(vec![ nqr.pow_vartime(vec![
0xfc4b7bc93997595f, 0xfc4b7bc93997595fu64,
0xa4e435368ee2c9d0, 0xa4e435368ee2c9d0,
0xf2d98f4a2c0fc8e1, 0xf2d98f4a2c0fc8e1,
0xf1ed2e60535906bf, 0xf1ed2e60535906bf,
@ -833,7 +835,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ12_C1[6], FROBENIUS_COEFF_FQ12_C1[6],
nqr.pow_vartime(vec![ nqr.pow_vartime(vec![
0x21219610a012ba3c, 0x21219610a012ba3cu64,
0xa5c19ad35375325, 0xa5c19ad35375325,
0x4e9df1e497674396, 0x4e9df1e497674396,
0xfb05b717c991c6ef, 0xfb05b717c991c6ef,
@ -874,7 +876,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ12_C1[7], FROBENIUS_COEFF_FQ12_C1[7],
nqr.pow_vartime(vec![ nqr.pow_vartime(vec![
0x742754a1f22fdb, 0x742754a1f22fdbu64,
0x2a1955c2dec3a702, 0x2a1955c2dec3a702,
0x9747b28c796d134e, 0x9747b28c796d134e,
0xc113a0411f59db79, 0xc113a0411f59db79,
@ -921,7 +923,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ12_C1[8], FROBENIUS_COEFF_FQ12_C1[8],
nqr.pow_vartime(vec![ nqr.pow_vartime(vec![
0x802f5720d0b25710, 0x802f5720d0b25710u64,
0x6714f0a258b85c7c, 0x6714f0a258b85c7c,
0x31394c90afdf16e, 0x31394c90afdf16e,
0xe9d2b0c64f957b19, 0xe9d2b0c64f957b19,
@ -974,7 +976,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ12_C1[9], FROBENIUS_COEFF_FQ12_C1[9],
nqr.pow_vartime(vec![ nqr.pow_vartime(vec![
0x4af4accf7de0b977, 0x4af4accf7de0b977u64,
0x742485e21805b4ee, 0x742485e21805b4ee,
0xee388fbc4ac36dec, 0xee388fbc4ac36dec,
0x1e199da57ad178a, 0x1e199da57ad178a,
@ -1033,7 +1035,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ12_C1[10], FROBENIUS_COEFF_FQ12_C1[10],
nqr.pow_vartime(vec![ nqr.pow_vartime(vec![
0xe5953a4f96cdda44, 0xe5953a4f96cdda44u64,
0x336b2d734cbc32bb, 0x336b2d734cbc32bb,
0x3f79bfe3cd7410e, 0x3f79bfe3cd7410e,
0x267ae19aaa0f0332, 0x267ae19aaa0f0332,
@ -1098,7 +1100,7 @@ fn test_frob_coeffs() {
assert_eq!( assert_eq!(
FROBENIUS_COEFF_FQ12_C1[11], FROBENIUS_COEFF_FQ12_C1[11],
nqr.pow_vartime(vec![ nqr.pow_vartime(vec![
0x107db680942de533, 0x107db680942de533u64,
0x6262b24d2052393b, 0x6262b24d2052393b,
0x6136df824159ebc, 0x6136df824159ebc,
0xedb052c9970c5deb, 0xedb052c9970c5deb,
@ -2029,7 +2031,7 @@ fn test_fq_pow() {
0xe5, 0xe5,
]); ]);
for i in 0..1000 { for i in 0u64..1000 {
// Exponentiate by various small numbers and ensure it consists with repeated // Exponentiate by various small numbers and ensure it consists with repeated
// multiplication. // multiplication.
let a = Fq::random(&mut rng); let a = Fq::random(&mut rng);
@ -2197,7 +2199,7 @@ fn test_fq_root_of_unity() {
); );
assert_eq!( assert_eq!(
Fq::multiplicative_generator().pow_vartime([ Fq::multiplicative_generator().pow_vartime([
0xdcff7fffffffd555, 0xdcff7fffffffd555u64,
0xf55ffff58a9ffff, 0xf55ffff58a9ffff,
0xb39869507b587b12, 0xb39869507b587b12,
0xb23ba5c279c2895f, 0xb23ba5c279c2895f,
@ -2206,7 +2208,7 @@ fn test_fq_root_of_unity() {
]), ]),
Fq::root_of_unity() Fq::root_of_unity()
); );
assert_eq!(Fq::root_of_unity().pow_vartime([1 << Fq::S]), Fq::one()); assert_eq!(Fq::root_of_unity().pow_vartime([1u64 << Fq::S]), Fq::one());
assert!(bool::from(Fq::multiplicative_generator().sqrt().is_none())); assert!(bool::from(Fq::multiplicative_generator().sqrt().is_none()));
} }

View File

@ -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, SqrtField}; use ff::{Field, PowVartime, SqrtField};
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};
@ -254,7 +254,7 @@ impl SqrtField for Fq2 {
} else { } else {
// a1 = self^((q - 3) / 4) // a1 = self^((q - 3) / 4)
let mut a1 = self.pow_vartime([ let mut a1 = self.pow_vartime([
0xee7fbfffffffeaaa, 0xee7fbfffffffeaaau64,
0x7aaffffac54ffff, 0x7aaffffac54ffff,
0xd9cc34a83dac3d89, 0xd9cc34a83dac3d89,
0xd91dd2e13ce144af, 0xd91dd2e13ce144af,
@ -286,7 +286,7 @@ impl SqrtField for Fq2 {
alpha.add_assign(&Fq2::one()); alpha.add_assign(&Fq2::one());
// alpha = alpha^((q - 1) / 2) // alpha = alpha^((q - 1) / 2)
alpha = alpha.pow_vartime([ alpha = alpha.pow_vartime([
0xdcff7fffffffd555, 0xdcff7fffffffd555u64,
0xf55ffff58a9ffff, 0xf55ffff58a9ffff,
0xb39869507b587b12, 0xb39869507b587b12,
0xb23ba5c279c2895f, 0xb23ba5c279c2895f,

View File

@ -6,6 +6,8 @@ use std::ops::{AddAssign, MulAssign, SubAssign};
#[PrimeFieldGenerator = "7"] #[PrimeFieldGenerator = "7"]
pub struct Fr(FrRepr); pub struct Fr(FrRepr);
#[cfg(test)]
use ff::PowVartime;
#[cfg(test)] #[cfg(test)]
use rand_core::SeedableRng; use rand_core::SeedableRng;
#[cfg(test)] #[cfg(test)]
@ -763,7 +765,7 @@ fn test_fr_pow() {
0xe5, 0xe5,
]); ]);
for i in 0..1000 { for i in 0u64..1000 {
// Exponentiate by various small numbers and ensure it consists with repeated // Exponentiate by various small numbers and ensure it consists with repeated
// multiplication. // multiplication.
let a = Fr::random(&mut rng); let a = Fr::random(&mut rng);
@ -965,14 +967,14 @@ fn test_fr_root_of_unity() {
); );
assert_eq!( assert_eq!(
Fr::multiplicative_generator().pow_vartime([ Fr::multiplicative_generator().pow_vartime([
0xfffe5bfeffffffff, 0xfffe5bfeffffffffu64,
0x9a1d80553bda402, 0x9a1d80553bda402,
0x299d7d483339d808, 0x299d7d483339d808,
0x73eda753 0x73eda753
]), ]),
Fr::root_of_unity() 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())); assert!(bool::from(Fr::multiplicative_generator().sqrt().is_none()));
} }

View File

@ -23,7 +23,7 @@ pub use self::fr::{Fr, FrRepr};
use super::{Engine, PairingCurveAffine}; use super::{Engine, PairingCurveAffine};
use ff::{BitIterator, Field, ScalarEngine}; use ff::{BitIterator, Field, PowVartime, 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;

View File

@ -1,3 +1,4 @@
use ff::PowVartime;
use group::{CurveAffine, CurveProjective}; use group::{CurveAffine, CurveProjective};
use rand_core::SeedableRng; use rand_core::SeedableRng;
use rand_xorshift::XorShiftRng; use rand_xorshift::XorShiftRng;

View File

@ -1,4 +1,4 @@
use ff::{Field, PrimeField, SqrtField}; use ff::{Field, PowVartime, PrimeField, SqrtField};
use rand_core::{RngCore, SeedableRng}; use rand_core::{RngCore, SeedableRng};
use rand_xorshift::XorShiftRng; use rand_xorshift::XorShiftRng;

View File

@ -1,6 +1,6 @@
use byteorder::{ByteOrder, LittleEndian}; use byteorder::{ByteOrder, LittleEndian};
use ff::{ use ff::{
adc, mac_with_carry, sbb, BitIterator, Field, PrimeField, PrimeFieldDecodingError, adc, mac_with_carry, sbb, BitIterator, Field, PowVartime, PrimeField, PrimeFieldDecodingError,
PrimeFieldRepr, SqrtField, PrimeFieldRepr, SqrtField,
}; };
use rand_core::RngCore; use rand_core::RngCore;
@ -745,7 +745,7 @@ impl SqrtField for Fs {
// a1 = self^((s - 3) // 4) // a1 = self^((s - 3) // 4)
let mut a1 = self.pow_vartime([ let mut a1 = self.pow_vartime([
0xb425c397b5bdcb2d, 0xb425c397b5bdcb2du64,
0x299a0824f3320420, 0x299a0824f3320420,
0x4199cec0404d0ec0, 0x4199cec0404d0ec0,
0x39f6d3a994cebea, 0x39f6d3a994cebea,
@ -1491,7 +1491,7 @@ fn test_fs_pow() {
0xe5, 0xe5,
]); ]);
for i in 0..1000 { for i in 0u64..1000 {
// Exponentiate by various small numbers and ensure it consists with repeated // Exponentiate by various small numbers and ensure it consists with repeated
// multiplication. // multiplication.
let a = Fs::random(&mut rng); let a = Fs::random(&mut rng);
@ -1689,13 +1689,13 @@ fn test_fs_root_of_unity() {
); );
assert_eq!( assert_eq!(
Fs::multiplicative_generator().pow_vartime([ Fs::multiplicative_generator().pow_vartime([
0x684b872f6b7b965b, 0x684b872f6b7b965bu64,
0x53341049e6640841, 0x53341049e6640841,
0x83339d80809a1d80, 0x83339d80809a1d80,
0x73eda753299d7d4 0x73eda753299d7d4
]), ]),
Fs::root_of_unity() Fs::root_of_unity()
); );
assert_eq!(Fs::root_of_unity().pow_vartime([1 << Fs::S]), Fs::one()); assert_eq!(Fs::root_of_unity().pow_vartime([1u64 << Fs::S]), Fs::one());
assert!(bool::from(Fs::multiplicative_generator().sqrt().is_none())); assert!(bool::from(Fs::multiplicative_generator().sqrt().is_none()));
} }