diff --git a/bellman/src/domain.rs b/bellman/src/domain.rs index 455a4c0f5..0e9192e44 100644 --- a/bellman/src/domain.rs +++ b/bellman/src/domain.rs @@ -106,7 +106,7 @@ impl> EvaluationDomain { worker.scope(self.coeffs.len(), |scope, chunk| { for (i, v) in self.coeffs.chunks_mut(chunk).enumerate() { scope.spawn(move |_scope| { - let mut u = g.pow(&[(i * chunk) as u64]); + let mut u = g.pow_vartime(&[(i * chunk) as u64]); for v in v.iter_mut() { v.group_mul_assign(&u); u.mul_assign(&g); @@ -131,7 +131,7 @@ impl> EvaluationDomain { /// This evaluates t(tau) for this domain, which is /// tau^m - 1 for these radix-2 domains. pub fn z(&self, tau: &E::Fr) -> E::Fr { - let mut tmp = tau.pow(&[self.coeffs.len() as u64]); + let mut tmp = tau.pow_vartime(&[self.coeffs.len() as u64]); tmp.sub_assign(&E::Fr::one()); tmp @@ -294,7 +294,7 @@ fn serial_fft>(a: &mut [T], omega: &E::Fr, log_n: u let mut m = 1; for _ in 0..log_n { - let w_m = omega.pow(&[u64::from(n / (2 * m))]); + let w_m = omega.pow_vartime(&[u64::from(n / (2 * m))]); let mut k = 0; while k < n { @@ -328,7 +328,7 @@ fn parallel_fft>( let num_cpus = 1 << log_cpus; let log_new_n = log_n - log_cpus; let mut tmp = vec![vec![T::group_zero(); 1 << log_new_n]; num_cpus]; - let new_omega = omega.pow(&[num_cpus as u64]); + let new_omega = omega.pow_vartime(&[num_cpus as u64]); worker.scope(0, |scope, _| { let a = &*a; @@ -336,8 +336,8 @@ fn parallel_fft>( for (j, tmp) in tmp.iter_mut().enumerate() { scope.spawn(move |_scope| { // Shuffle into a sub-FFT - let omega_j = omega.pow(&[j as u64]); - let omega_step = omega.pow(&[(j as u64) << log_new_n]); + let omega_j = omega.pow_vartime(&[j as u64]); + let omega_step = omega.pow_vartime(&[(j as u64) << log_new_n]); let mut elt = E::Fr::one(); for (i, tmp) in tmp.iter_mut().enumerate() { diff --git a/bellman/src/gadgets/multieq.rs b/bellman/src/gadgets/multieq.rs index d05282270..37b2d9429 100644 --- a/bellman/src/gadgets/multieq.rs +++ b/bellman/src/gadgets/multieq.rs @@ -50,7 +50,9 @@ impl> MultiEq { assert!((E::Fr::CAPACITY as usize) > (self.bits_used + num_bits)); - let coeff = E::Fr::from_str("2").unwrap().pow(&[self.bits_used as u64]); + let coeff = E::Fr::from_str("2") + .unwrap() + .pow_vartime(&[self.bits_used as u64]); self.lhs = self.lhs.clone() + (coeff, lhs); self.rhs = self.rhs.clone() + (coeff, rhs); self.bits_used += num_bits; diff --git a/bellman/src/gadgets/test/mod.rs b/bellman/src/gadgets/test/mod.rs index f4cc92744..0a37cd16f 100644 --- a/bellman/src/gadgets/test/mod.rs +++ b/bellman/src/gadgets/test/mod.rs @@ -155,7 +155,7 @@ impl TestConstraintSystem { let negone = E::Fr::one().neg(); let powers_of_two = (0..E::Fr::NUM_BITS) - .map(|i| E::Fr::from_str("2").unwrap().pow(&[u64::from(i)])) + .map(|i| E::Fr::from_str("2").unwrap().pow_vartime(&[u64::from(i)])) .collect::>(); let pp = |s: &mut String, lc: &LinearCombination| { diff --git a/bellman/src/groth16/generator.rs b/bellman/src/groth16/generator.rs index 32c9d0765..d99383555 100644 --- a/bellman/src/groth16/generator.rs +++ b/bellman/src/groth16/generator.rs @@ -242,7 +242,7 @@ where worker.scope(powers_of_tau.len(), |scope, chunk| { for (i, powers_of_tau) in powers_of_tau.chunks_mut(chunk).enumerate() { scope.spawn(move |_scope| { - let mut current_tau_power = tau.pow(&[(i * chunk) as u64]); + let mut current_tau_power = tau.pow_vartime(&[(i * chunk) as u64]); for p in powers_of_tau { p.0 = current_tau_power; diff --git a/bellman/src/groth16/tests/dummy_engine.rs b/bellman/src/groth16/tests/dummy_engine.rs index d9040049a..63aca12f9 100644 --- a/bellman/src/groth16/tests/dummy_engine.rs +++ b/bellman/src/groth16/tests/dummy_engine.rs @@ -172,7 +172,10 @@ impl Field for Fr { if ::is_zero(self) { CtOption::new(::zero(), Choice::from(0)) } else { - CtOption::new(self.pow(&[(MODULUS_R.0 as u64) - 2]), Choice::from(1)) + CtOption::new( + self.pow_vartime(&[(MODULUS_R.0 as u64) - 2]), + Choice::from(1), + ) } } @@ -187,9 +190,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([32]); + let mut r = self.pow_vartime([32]); // t = self^t - let mut t = self.pow([63]); + let mut t = self.pow_vartime([63]); let mut m = Fr::S; while t != ::one() { @@ -311,7 +314,7 @@ impl PrimeField for Fr { fn from_repr(repr: FrRepr) -> Result { if repr.0[0] >= (MODULUS_R.0 as u64) { - Err(PrimeFieldDecodingError::NotInField(format!("{}", repr))) + Err(PrimeFieldDecodingError::NotInField) } else { Ok(Fr(Wrapping(repr.0[0] as u32))) } diff --git a/bellman/src/groth16/tests/mod.rs b/bellman/src/groth16/tests/mod.rs index f3349a421..5c2f02dbb 100644 --- a/bellman/src/groth16/tests/mod.rs +++ b/bellman/src/groth16/tests/mod.rs @@ -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(&[1 << 10])); + assert_eq!(Fr::one(), root_of_unity.pow_vartime(&[1 << 10])); // Let's turn it into a 2^3 root of unity. - root_of_unity = root_of_unity.pow(&[1 << 7]); - assert_eq!(Fr::one(), root_of_unity.pow(&[1 << 3])); + root_of_unity = root_of_unity.pow_vartime(&[1 << 7]); + assert_eq!(Fr::one(), root_of_unity.pow_vartime(&[1 << 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 { - points.push(root_of_unity.pow(&[i])); + 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(&[8]); + let mut t_at_tau = tau.pow_vartime(&[8]); t_at_tau.sub_assign(&Fr::one()); { let mut tmp = Fr::one(); diff --git a/ff/Cargo.toml b/ff/Cargo.toml index 907fcb2d9..3b4b486bd 100644 --- a/ff/Cargo.toml +++ b/ff/Cargo.toml @@ -11,14 +11,15 @@ repository = "https://github.com/ebfull/ff" edition = "2018" [dependencies] -byteorder = "1" +byteorder = { version = "1", default-features = false } ff_derive = { version = "0.4.0", path = "ff_derive", optional = true } -rand_core = "0.5" -subtle = "2.2.1" +rand_core = { version = "0.5", default-features = false } +subtle = { version = "2.2.1", default-features = false, features = ["i128"] } [features] -default = [] +default = ["std"] derive = ["ff_derive"] +std = [] [badges] maintenance = { status = "actively-developed" } diff --git a/ff/ff_derive/src/lib.rs b/ff/ff_derive/src/lib.rs index e3f8ca3e2..7b19d9664 100644 --- a/ff/ff_derive/src/lib.rs +++ b/ff/ff_derive/src/lib.rs @@ -113,9 +113,9 @@ fn prime_field_repr_impl(repr: &syn::Ident, limbs: usize) -> proc_macro2::TokenS #[derive(Copy, Clone, PartialEq, Eq, Default)] pub struct #repr(pub [u64; #limbs]); - impl ::std::fmt::Debug for #repr + impl ::core::fmt::Debug for #repr { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { write!(f, "0x")?; for i in self.0.iter().rev() { write!(f, "{:016x}", *i)?; @@ -125,8 +125,8 @@ fn prime_field_repr_impl(repr: &syn::Ident, limbs: usize) -> proc_macro2::TokenS } } - impl ::std::fmt::Display for #repr { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + impl ::core::fmt::Display for #repr { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { write!(f, "0x")?; for i in self.0.iter().rev() { write!(f, "{:016x}", *i)?; @@ -153,7 +153,7 @@ fn prime_field_repr_impl(repr: &syn::Ident, limbs: usize) -> proc_macro2::TokenS impl From for #repr { #[inline(always)] fn from(val: u64) -> #repr { - use std::default::Default; + use core::default::Default; let mut repr = Self::default(); repr.0[0] = val; @@ -163,22 +163,22 @@ fn prime_field_repr_impl(repr: &syn::Ident, limbs: usize) -> proc_macro2::TokenS impl Ord for #repr { #[inline(always)] - fn cmp(&self, other: &#repr) -> ::std::cmp::Ordering { + fn cmp(&self, other: &#repr) -> ::core::cmp::Ordering { for (a, b) in self.0.iter().rev().zip(other.0.iter().rev()) { if a < b { - return ::std::cmp::Ordering::Less + return ::core::cmp::Ordering::Less } else if a > b { - return ::std::cmp::Ordering::Greater + return ::core::cmp::Ordering::Greater } } - ::std::cmp::Ordering::Equal + ::core::cmp::Ordering::Equal } } impl PartialOrd for #repr { #[inline(always)] - fn partial_cmp(&self, other: &#repr) -> Option<::std::cmp::Ordering> { + fn partial_cmp(&self, other: &#repr) -> Option<::core::cmp::Ordering> { Some(self.cmp(other)) } } @@ -209,7 +209,7 @@ fn prime_field_repr_impl(repr: &syn::Ident, limbs: usize) -> proc_macro2::TokenS while n >= 64 { let mut t = 0; for i in self.0.iter_mut().rev() { - ::std::mem::swap(&mut t, i); + ::core::mem::swap(&mut t, i); } n -= 64; } @@ -257,7 +257,7 @@ fn prime_field_repr_impl(repr: &syn::Ident, limbs: usize) -> proc_macro2::TokenS while n >= 64 { let mut t = 0; for i in &mut self.0 { - ::std::mem::swap(&mut t, i); + ::core::mem::swap(&mut t, i); } n -= 64; } @@ -427,7 +427,7 @@ fn prime_field_constants_and_sqrt( // Because r = 3 (mod 4) // sqrt can be done with only one exponentiation, // via the computation of self^((r + 1) // 4) (mod r) - let sqrt = self.pow(#mod_plus_1_over_4); + let sqrt = self.pow_vartime(#mod_plus_1_over_4); ::subtle::CtOption::new( sqrt, @@ -447,7 +447,7 @@ fn prime_field_constants_and_sqrt( use ::subtle::{ConditionallySelectable, ConstantTimeEq}; // w = self^((t - 1) // 2) - let w = self.pow(#t_minus_1_over_2); + let w = self.pow_vartime(#t_minus_1_over_2); let mut v = S; let mut x = *self * &w; @@ -767,15 +767,15 @@ fn prime_field_impl( let top_limb_index = limbs - 1; quote! { - impl ::std::marker::Copy for #name { } + impl ::core::marker::Copy for #name { } - impl ::std::clone::Clone for #name { + impl ::core::clone::Clone for #name { fn clone(&self) -> #name { *self } } - impl ::std::default::Default for #name { + impl ::core::default::Default for #name { fn default() -> #name { #name::zero() } @@ -787,17 +787,17 @@ fn prime_field_impl( } } - impl ::std::cmp::PartialEq for #name { + impl ::core::cmp::PartialEq for #name { fn eq(&self, other: &#name) -> bool { self.0 == other.0 } } - impl ::std::cmp::Eq for #name { } + impl ::core::cmp::Eq for #name { } - impl ::std::fmt::Debug for #name + impl ::core::fmt::Debug for #name { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { write!(f, "{}({:?})", stringify!(#name), self.into_repr()) } } @@ -805,20 +805,20 @@ fn prime_field_impl( /// Elements are ordered lexicographically. impl Ord for #name { #[inline(always)] - fn cmp(&self, other: &#name) -> ::std::cmp::Ordering { + fn cmp(&self, other: &#name) -> ::core::cmp::Ordering { self.into_repr().cmp(&other.into_repr()) } } impl PartialOrd for #name { #[inline(always)] - fn partial_cmp(&self, other: &#name) -> Option<::std::cmp::Ordering> { + fn partial_cmp(&self, other: &#name) -> Option<::core::cmp::Ordering> { Some(self.cmp(other)) } } - impl ::std::fmt::Display for #name { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + impl ::core::fmt::Display for #name { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { write!(f, "{}({})", stringify!(#name), self.into_repr()) } } @@ -839,7 +839,7 @@ fn prime_field_impl( } } - impl ::std::ops::Neg for #name { + impl ::core::ops::Neg for #name { type Output = #name; #[inline] @@ -854,7 +854,7 @@ fn prime_field_impl( } } - impl<'r> ::std::ops::Add<&'r #name> for #name { + impl<'r> ::core::ops::Add<&'r #name> for #name { type Output = #name; #[inline] @@ -865,7 +865,7 @@ fn prime_field_impl( } } - impl ::std::ops::Add for #name { + impl ::core::ops::Add for #name { type Output = #name; #[inline] @@ -874,7 +874,7 @@ fn prime_field_impl( } } - impl<'r> ::std::ops::AddAssign<&'r #name> for #name { + impl<'r> ::core::ops::AddAssign<&'r #name> for #name { #[inline] fn add_assign(&mut self, other: &#name) { // This cannot exceed the backing capacity. @@ -885,14 +885,14 @@ fn prime_field_impl( } } - impl ::std::ops::AddAssign for #name { + impl ::core::ops::AddAssign for #name { #[inline] fn add_assign(&mut self, other: #name) { self.add_assign(&other); } } - impl<'r> ::std::ops::Sub<&'r #name> for #name { + impl<'r> ::core::ops::Sub<&'r #name> for #name { type Output = #name; #[inline] @@ -903,7 +903,7 @@ fn prime_field_impl( } } - impl ::std::ops::Sub for #name { + impl ::core::ops::Sub for #name { type Output = #name; #[inline] @@ -912,7 +912,7 @@ fn prime_field_impl( } } - impl<'r> ::std::ops::SubAssign<&'r #name> for #name { + impl<'r> ::core::ops::SubAssign<&'r #name> for #name { #[inline] fn sub_assign(&mut self, other: &#name) { // If `other` is larger than `self`, we'll need to add the modulus to self first. @@ -924,14 +924,14 @@ fn prime_field_impl( } } - impl ::std::ops::SubAssign for #name { + impl ::core::ops::SubAssign for #name { #[inline] fn sub_assign(&mut self, other: #name) { self.sub_assign(&other); } } - impl<'r> ::std::ops::Mul<&'r #name> for #name { + impl<'r> ::core::ops::Mul<&'r #name> for #name { type Output = #name; #[inline] @@ -942,7 +942,7 @@ fn prime_field_impl( } } - impl ::std::ops::Mul for #name { + impl ::core::ops::Mul for #name { type Output = #name; #[inline] @@ -951,7 +951,7 @@ fn prime_field_impl( } } - impl<'r> ::std::ops::MulAssign<&'r #name> for #name { + impl<'r> ::core::ops::MulAssign<&'r #name> for #name { #[inline] fn mul_assign(&mut self, other: &#name) { @@ -959,7 +959,7 @@ fn prime_field_impl( } } - impl ::std::ops::MulAssign for #name { + impl ::core::ops::MulAssign for #name { #[inline] fn mul_assign(&mut self, other: #name) { @@ -977,7 +977,7 @@ fn prime_field_impl( Ok(r) } else { - Err(PrimeFieldDecodingError::NotInField(format!("{}", r.0))) + Err(PrimeFieldDecodingError::NotInField) } } diff --git a/ff/src/lib.rs b/ff/src/lib.rs index d4602ba41..ebec847c7 100644 --- a/ff/src/lib.rs +++ b/ff/src/lib.rs @@ -1,17 +1,22 @@ //! This crate provides traits for working with finite fields. // Catch documentation errors caused by code changes. +#![no_std] #![deny(intra_doc_link_resolution_failure)] #![allow(unused_imports)] +#[cfg(feature = "std")] +#[macro_use] +extern crate std; + #[cfg(feature = "derive")] pub use ff_derive::*; +use core::fmt; +use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use rand_core::RngCore; -use std::error::Error; -use std::fmt; +#[cfg(feature = "std")] use std::io::{self, Read, Write}; -use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use subtle::{ConditionallySelectable, CtOption}; /// This trait represents an element of a field. @@ -69,22 +74,20 @@ pub trait Field: /// the Frobenius automorphism. fn frobenius_map(&mut self, power: usize); - /// Exponentiates this element by a number represented with `u64` limbs, - /// least significant digit first. - fn pow>(&self, exp: S) -> Self { + /// 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>(&self, exp: S) -> Self { let mut res = Self::one(); - - let mut found_one = false; - - for i in BitIterator::new(exp) { - if found_one { + for e in exp.as_ref().iter().rev() { + for i in (0..64).rev() { res = res.square(); - } else { - found_one = i; - } - if i { - res.mul_assign(self); + if ((*e >> i) & 1) == 1 { + res.mul_assign(self); + } } } @@ -152,6 +155,7 @@ pub trait PrimeFieldRepr: fn shl(&mut self, amt: u32); /// Writes this `PrimeFieldRepr` as a big endian integer. + #[cfg(feature = "std")] fn write_be(&self, mut writer: W) -> io::Result<()> { use byteorder::{BigEndian, WriteBytesExt}; @@ -163,6 +167,7 @@ pub trait PrimeFieldRepr: } /// Reads a big endian integer into this representation. + #[cfg(feature = "std")] fn read_be(&mut self, mut reader: R) -> io::Result<()> { use byteorder::{BigEndian, ReadBytesExt}; @@ -174,6 +179,7 @@ pub trait PrimeFieldRepr: } /// Writes this `PrimeFieldRepr` as a little endian integer. + #[cfg(feature = "std")] fn write_le(&self, mut writer: W) -> io::Result<()> { use byteorder::{LittleEndian, WriteBytesExt}; @@ -185,6 +191,7 @@ pub trait PrimeFieldRepr: } /// Reads a little endian integer into this representation. + #[cfg(feature = "std")] fn read_le(&mut self, mut reader: R) -> io::Result<()> { use byteorder::{LittleEndian, ReadBytesExt}; @@ -201,13 +208,14 @@ pub trait PrimeFieldRepr: #[derive(Debug)] pub enum PrimeFieldDecodingError { /// The encoded value is not in the field - NotInField(String), + NotInField, } -impl Error for PrimeFieldDecodingError { +#[cfg(feature = "std")] +impl std::error::Error for PrimeFieldDecodingError { fn description(&self) -> &str { match *self { - PrimeFieldDecodingError::NotInField(..) => "not an element of the field", + PrimeFieldDecodingError::NotInField => "not an element of the field", } } } @@ -215,9 +223,7 @@ impl Error for PrimeFieldDecodingError { impl fmt::Display for PrimeFieldDecodingError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match *self { - PrimeFieldDecodingError::NotInField(ref repr) => { - write!(f, "{} is not an element of the field", repr) - } + PrimeFieldDecodingError::NotInField => write!(f, "not an element of the field"), } } } diff --git a/pairing/src/bls12_381/fq.rs b/pairing/src/bls12_381/fq.rs index 509008361..4acd5a508 100644 --- a/pairing/src/bls12_381/fq.rs +++ b/pairing/src/bls12_381/fq.rs @@ -464,7 +464,7 @@ fn test_frob_coeffs() { assert_eq!(FROBENIUS_COEFF_FQ2_C1[0], Fq::one()); assert_eq!( FROBENIUS_COEFF_FQ2_C1[1], - nqr.pow([ + nqr.pow_vartime([ 0xdcff7fffffffd555, 0xf55ffff58a9ffff, 0xb39869507b587b12, @@ -482,7 +482,7 @@ fn test_frob_coeffs() { assert_eq!(FROBENIUS_COEFF_FQ6_C1[0], Fq2::one()); assert_eq!( FROBENIUS_COEFF_FQ6_C1[1], - nqr.pow([ + nqr.pow_vartime([ 0x9354ffffffffe38e, 0xa395554e5c6aaaa, 0xcd104635a790520c, @@ -493,7 +493,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ6_C1[2], - nqr.pow([ + nqr.pow_vartime([ 0xb78e0000097b2f68, 0xd44f23b47cbd64e3, 0x5cb9668120b069a9, @@ -510,7 +510,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ6_C1[3], - nqr.pow([ + nqr.pow_vartime([ 0xdbc6fcd6f35b9e06, 0x997dead10becd6aa, 0x9dbbd24c17206460, @@ -533,7 +533,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ6_C1[4], - nqr.pow([ + nqr.pow_vartime([ 0x4649add3c71c6d90, 0x43caa6528972a865, 0xcda8445bbaaa0fbb, @@ -562,7 +562,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ6_C1[5], - nqr.pow([ + nqr.pow_vartime([ 0xf896f792732eb2be, 0x49c86a6d1dc593a1, 0xe5b31e94581f91c3, @@ -599,7 +599,7 @@ fn test_frob_coeffs() { assert_eq!(FROBENIUS_COEFF_FQ6_C2[0], Fq2::one()); assert_eq!( FROBENIUS_COEFF_FQ6_C2[1], - nqr.pow([ + nqr.pow_vartime([ 0x26a9ffffffffc71c, 0x1472aaa9cb8d5555, 0x9a208c6b4f20a418, @@ -610,7 +610,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ6_C2[2], - nqr.pow([ + nqr.pow_vartime([ 0x6f1c000012f65ed0, 0xa89e4768f97ac9c7, 0xb972cd024160d353, @@ -627,7 +627,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ6_C2[3], - nqr.pow([ + nqr.pow_vartime([ 0xb78df9ade6b73c0c, 0x32fbd5a217d9ad55, 0x3b77a4982e40c8c1, @@ -650,7 +650,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ6_C2[4], - nqr.pow([ + nqr.pow_vartime([ 0x8c935ba78e38db20, 0x87954ca512e550ca, 0x9b5088b775541f76, @@ -679,7 +679,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ6_C2[5], - nqr.pow([ + nqr.pow_vartime([ 0xf12def24e65d657c, 0x9390d4da3b8b2743, 0xcb663d28b03f2386, @@ -716,7 +716,7 @@ fn test_frob_coeffs() { assert_eq!(FROBENIUS_COEFF_FQ12_C1[0], Fq2::one()); assert_eq!( FROBENIUS_COEFF_FQ12_C1[1], - nqr.pow([ + nqr.pow_vartime([ 0x49aa7ffffffff1c7, 0x51caaaa72e35555, 0xe688231ad3c82906, @@ -727,7 +727,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ12_C1[2], - nqr.pow([ + nqr.pow_vartime([ 0xdbc7000004bd97b4, 0xea2791da3e5eb271, 0x2e5cb340905834d4, @@ -744,7 +744,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ12_C1[3], - nqr.pow(vec![ + nqr.pow_vartime(vec![ 0x6de37e6b79adcf03, 0x4cbef56885f66b55, 0x4edde9260b903230, @@ -767,7 +767,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ12_C1[4], - nqr.pow(vec![ + nqr.pow_vartime(vec![ 0xa324d6e9e38e36c8, 0xa1e5532944b95432, 0x66d4222ddd5507dd, @@ -796,7 +796,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ12_C1[5], - nqr.pow(vec![ + nqr.pow_vartime(vec![ 0xfc4b7bc93997595f, 0xa4e435368ee2c9d0, 0xf2d98f4a2c0fc8e1, @@ -831,7 +831,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ12_C1[6], - nqr.pow(vec![ + nqr.pow_vartime(vec![ 0x21219610a012ba3c, 0xa5c19ad35375325, 0x4e9df1e497674396, @@ -872,7 +872,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ12_C1[7], - nqr.pow(vec![ + nqr.pow_vartime(vec![ 0x742754a1f22fdb, 0x2a1955c2dec3a702, 0x9747b28c796d134e, @@ -919,7 +919,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ12_C1[8], - nqr.pow(vec![ + nqr.pow_vartime(vec![ 0x802f5720d0b25710, 0x6714f0a258b85c7c, 0x31394c90afdf16e, @@ -972,7 +972,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ12_C1[9], - nqr.pow(vec![ + nqr.pow_vartime(vec![ 0x4af4accf7de0b977, 0x742485e21805b4ee, 0xee388fbc4ac36dec, @@ -1031,7 +1031,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ12_C1[10], - nqr.pow(vec![ + nqr.pow_vartime(vec![ 0xe5953a4f96cdda44, 0x336b2d734cbc32bb, 0x3f79bfe3cd7410e, @@ -1096,7 +1096,7 @@ fn test_frob_coeffs() { ); assert_eq!( FROBENIUS_COEFF_FQ12_C1[11], - nqr.pow(vec![ + nqr.pow_vartime(vec![ 0x107db680942de533, 0x6262b24d2052393b, 0x6136df824159ebc, @@ -2032,7 +2032,7 @@ fn test_fq_pow() { // Exponentiate by various small numbers and ensure it consists with repeated // multiplication. let a = Fq::random(&mut rng); - let target = a.pow(&[i]); + let target = a.pow_vartime(&[i]); let mut c = Fq::one(); for _ in 0..i { c.mul_assign(&a); @@ -2044,7 +2044,7 @@ fn test_fq_pow() { // Exponentiating by the modulus should have no effect in a prime field. let a = Fq::random(&mut rng); - assert_eq!(a, a.pow(Fq::char())); + assert_eq!(a, a.pow_vartime(Fq::char())); } } @@ -2195,7 +2195,7 @@ fn test_fq_root_of_unity() { Fq::from_repr(FqRepr::from(2)).unwrap() ); assert_eq!( - Fq::multiplicative_generator().pow([ + Fq::multiplicative_generator().pow_vartime([ 0xdcff7fffffffd555, 0xf55ffff58a9ffff, 0xb39869507b587b12, @@ -2205,7 +2205,7 @@ fn test_fq_root_of_unity() { ]), Fq::root_of_unity() ); - assert_eq!(Fq::root_of_unity().pow([1 << Fq::S]), Fq::one()); + assert_eq!(Fq::root_of_unity().pow_vartime([1 << Fq::S]), Fq::one()); assert!(bool::from(Fq::multiplicative_generator().sqrt().is_none())); } diff --git a/pairing/src/bls12_381/fq2.rs b/pairing/src/bls12_381/fq2.rs index 8f7cbb2d8..3fb0de3be 100644 --- a/pairing/src/bls12_381/fq2.rs +++ b/pairing/src/bls12_381/fq2.rs @@ -253,7 +253,7 @@ impl SqrtField for Fq2 { CtOption::new(Self::zero(), Choice::from(1)) } else { // a1 = self^((q - 3) / 4) - let mut a1 = self.pow([ + let mut a1 = self.pow_vartime([ 0xee7fbfffffffeaaa, 0x7aaffffac54ffff, 0xd9cc34a83dac3d89, @@ -285,7 +285,7 @@ impl SqrtField for Fq2 { } else { alpha.add_assign(&Fq2::one()); // alpha = alpha^((q - 1) / 2) - alpha = alpha.pow([ + alpha = alpha.pow_vartime([ 0xdcff7fffffffd555, 0xf55ffff58a9ffff, 0xb39869507b587b12, diff --git a/pairing/src/bls12_381/fr.rs b/pairing/src/bls12_381/fr.rs index b2fa4e1df..4c30e49cb 100644 --- a/pairing/src/bls12_381/fr.rs +++ b/pairing/src/bls12_381/fr.rs @@ -767,7 +767,7 @@ fn test_fr_pow() { // Exponentiate by various small numbers and ensure it consists with repeated // multiplication. let a = Fr::random(&mut rng); - let target = a.pow(&[i]); + let target = a.pow_vartime(&[i]); let mut c = Fr::one(); for _ in 0..i { c.mul_assign(&a); @@ -779,7 +779,7 @@ fn test_fr_pow() { // Exponentiating by the modulus should have no effect in a prime field. let a = Fr::random(&mut rng); - assert_eq!(a, a.pow(Fr::char())); + assert_eq!(a, a.pow_vartime(Fr::char())); } } @@ -964,7 +964,7 @@ fn test_fr_root_of_unity() { Fr::from_repr(FrRepr::from(7)).unwrap() ); assert_eq!( - Fr::multiplicative_generator().pow([ + Fr::multiplicative_generator().pow_vartime([ 0xfffe5bfeffffffff, 0x9a1d80553bda402, 0x299d7d483339d808, @@ -972,7 +972,7 @@ fn test_fr_root_of_unity() { ]), Fr::root_of_unity() ); - assert_eq!(Fr::root_of_unity().pow([1 << Fr::S]), Fr::one()); + assert_eq!(Fr::root_of_unity().pow_vartime([1 << Fr::S]), Fr::one()); assert!(bool::from(Fr::multiplicative_generator().sqrt().is_none())); } diff --git a/pairing/src/bls12_381/mod.rs b/pairing/src/bls12_381/mod.rs index ad66cbde5..80848e12d 100644 --- a/pairing/src/bls12_381/mod.rs +++ b/pairing/src/bls12_381/mod.rs @@ -124,7 +124,7 @@ impl Engine for Bls12 { r.mul_assign(&f2); fn exp_by_x(f: &mut Fq12, x: u64) { - *f = f.pow(&[x]); + *f = f.pow_vartime(&[x]); if BLS_X_IS_NEGATIVE { f.conjugate(); } diff --git a/pairing/src/tests/engine.rs b/pairing/src/tests/engine.rs index 6b6a43003..0776e5d4b 100644 --- a/pairing/src/tests/engine.rs +++ b/pairing/src/tests/engine.rs @@ -130,7 +130,7 @@ fn random_bilinearity_tests() { let mut cd = c; cd.mul_assign(&d); - let abcd = E::pairing(a, b).pow(cd.into_repr()); + let abcd = E::pairing(a, b).pow_vartime(cd.into_repr()); assert_eq!(acbd, adbc); assert_eq!(acbd, abcd); diff --git a/pairing/src/tests/field.rs b/pairing/src/tests/field.rs index a07360433..cd352a9ae 100644 --- a/pairing/src/tests/field.rs +++ b/pairing/src/tests/field.rs @@ -14,7 +14,7 @@ pub fn random_frobenius_tests>(characteristic: C, maxp let mut b = a; for _ in 0..i { - a = a.pow(&characteristic); + a = a.pow_vartime(&characteristic); } b.frobenius_map(i); diff --git a/zcash_primitives/src/jubjub/fs.rs b/zcash_primitives/src/jubjub/fs.rs index a493e7a3a..332e49682 100644 --- a/zcash_primitives/src/jubjub/fs.rs +++ b/zcash_primitives/src/jubjub/fs.rs @@ -454,7 +454,7 @@ impl PrimeField for Fs { Ok(r) } else { - Err(PrimeFieldDecodingError::NotInField(format!("{}", r.0))) + Err(PrimeFieldDecodingError::NotInField) } } @@ -744,7 +744,7 @@ impl SqrtField for Fs { // https://eprint.iacr.org/2012/685.pdf (page 9, algorithm 2) // a1 = self^((s - 3) // 4) - let mut a1 = self.pow([ + let mut a1 = self.pow_vartime([ 0xb425c397b5bdcb2d, 0x299a0824f3320420, 0x4199cec0404d0ec0, @@ -1495,7 +1495,7 @@ fn test_fs_pow() { // Exponentiate by various small numbers and ensure it consists with repeated // multiplication. let a = Fs::random(&mut rng); - let target = a.pow(&[i]); + let target = a.pow_vartime(&[i]); let mut c = Fs::one(); for _ in 0..i { c.mul_assign(&a); @@ -1507,7 +1507,7 @@ fn test_fs_pow() { // Exponentiating by the modulus should have no effect in a prime field. let a = Fs::random(&mut rng); - assert_eq!(a, a.pow(Fs::char())); + assert_eq!(a, a.pow_vartime(Fs::char())); } } @@ -1688,7 +1688,7 @@ fn test_fs_root_of_unity() { Fs::from_repr(FsRepr::from(6)).unwrap() ); assert_eq!( - Fs::multiplicative_generator().pow([ + Fs::multiplicative_generator().pow_vartime([ 0x684b872f6b7b965b, 0x53341049e6640841, 0x83339d80809a1d80, @@ -1696,6 +1696,6 @@ fn test_fs_root_of_unity() { ]), Fs::root_of_unity() ); - assert_eq!(Fs::root_of_unity().pow([1 << Fs::S]), Fs::one()); + assert_eq!(Fs::root_of_unity().pow_vartime([1 << Fs::S]), Fs::one()); assert!(bool::from(Fs::multiplicative_generator().sqrt().is_none())); }