mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-06 20:20:34 +00:00
patch: index-based pow_vartime loops (Aeneas/Charon compatibility)
iter().rev() / (0..64).rev() double-ended range iterators have no Aeneas model. Iteration order and arithmetic identical to upstream: limbs most- to least-significant, bits high to low. Crate tests: 11/11 fp tests pass (incl. test_inv, test_inv_2, test_pow_by_t_minus1_over2). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
7f3278863b
commit
ea23c12d6a
1 changed files with 14 additions and 3 deletions
|
|
@ -588,15 +588,26 @@ impl ff::Field for Fp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pow_vartime<S: AsRef<[u64]>>(&self, exp: S) -> Self {
|
fn pow_vartime<S: AsRef<[u64]>>(&self, exp: S) -> Self {
|
||||||
|
// PATCH (Aeneas compatibility): index-based loops instead of
|
||||||
|
// `iter().rev()` / `(0..64).rev()` (double-ended range iterators have
|
||||||
|
// no Aeneas model). Iteration order and arithmetic are IDENTICAL to
|
||||||
|
// upstream: limbs from most- to least-significant, bits from high to
|
||||||
|
// low, square-then-conditionally-multiply.
|
||||||
let mut res = Self::one();
|
let mut res = Self::one();
|
||||||
let mut found_one = false;
|
let mut found_one = false;
|
||||||
for e in exp.as_ref().iter().rev() {
|
let exp = exp.as_ref();
|
||||||
for i in (0..64).rev() {
|
let mut j = exp.len();
|
||||||
|
while j > 0 {
|
||||||
|
j -= 1;
|
||||||
|
let e = exp[j];
|
||||||
|
let mut i = 64u32;
|
||||||
|
while i > 0 {
|
||||||
|
i -= 1;
|
||||||
if found_one {
|
if found_one {
|
||||||
res = res.square();
|
res = res.square();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*e >> i) & 1) == 1 {
|
if ((e >> i) & 1) == 1 {
|
||||||
found_one = true;
|
found_one = true;
|
||||||
res *= self;
|
res *= self;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue