Improve Field::pow API and impl

Renamed to Field::pow_vartime to indicate it is still variable time with
respect to the exponent.
This commit is contained in:
Jack Grigg
2019-05-15 11:24:00 +01:00
parent e88e2a9dc2
commit 1c9f5742fa
15 changed files with 75 additions and 72 deletions

View File

@@ -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;

View File

@@ -69,22 +69,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<S: AsRef<[u64]>>(&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<S: AsRef<[u64]>>(&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);
}
}
}