Skip to content
This repository was archived by the owner on Jun 7, 2026. It is now read-only.

Commit a40270e

Browse files
authored
Honor PrimeField::BYTE_ORDER in wNAF implementation (#21)
When the byte order is `ff::ByteOrder::BigEndian`, processes the individual bytes of the buffer in reverse order. This is a replacement for #12 which is hopefully closer to something which can land upstream.
1 parent 4dd7b16 commit a40270e

2 files changed

Lines changed: 20 additions & 3 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/wnaf.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,12 @@ pub(crate) fn wnaf_form<S: AsRef<[u8]>>(wnaf: &mut Vec<i64>, c: S, window: usize
144144
pos += window;
145145
}
146146
}
147+
148+
// If there is a remaining carry (the scalar used all `bit_len` bit and the last wNAF digit was
149+
// negative), emit it so the representation is exact.
150+
if carry != 0 {
151+
wnaf.push(carry as i64);
152+
}
147153
}
148154

149155
/// Performs w-NAF exponentiation with the provided window table and w-NAF form scalar.
@@ -315,7 +321,7 @@ impl<G: WnafGroup> Wnaf<(), Vec<G>, Vec<i64>> {
315321
let window_size = 4;
316322

317323
// Compute the wNAF form of the scalar.
318-
wnaf_form(&mut self.scalar, scalar.to_repr(), window_size);
324+
wnaf_form(&mut self.scalar, le_repr(scalar), window_size);
319325

320326
// Return a Wnaf object that mutably borrows the base storage location, but
321327
// immutably borrows the computed wNAF form scalar location.
@@ -393,7 +399,7 @@ impl<B, S: AsMut<Vec<i64>>> Wnaf<usize, B, S> {
393399
where
394400
B: AsRef<[G]>,
395401
{
396-
wnaf_form(self.scalar.as_mut(), scalar.to_repr(), self.window_size);
402+
wnaf_form(self.scalar.as_mut(), le_repr(scalar), self.window_size);
397403
wnaf_exp(self.base.as_ref(), self.scalar.as_mut())
398404
}
399405
}
@@ -510,3 +516,14 @@ impl<G: Group, const WINDOW_SIZE: usize> Mul<&WnafScalar<G::Scalar, WINDOW_SIZE>
510516
wnaf_exp(&self.table, &rhs.wnaf)
511517
}
512518
}
519+
520+
/// Get the little endian representation of a field, namely a scalar.
521+
fn le_repr<F: PrimeField>(fe: &F) -> F::Repr {
522+
let mut ret = fe.to_repr();
523+
524+
if F::BYTE_ORDER == ff::ByteOrder::BigEndian {
525+
ret.as_mut().reverse();
526+
}
527+
528+
ret
529+
}

0 commit comments

Comments
 (0)