You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
k256: fix wNAF overflow past bit 127 for near-2^128 inputs
`wnaf_128` tracked the residual scalar in two u64 limbs, but a negative
recentered digit adds up to 2^(W-1) − 1 to the value, which can legitimately
overflow past bit 127 when the input is close to 2^128 − 1. The old code
let `hi.wrapping_add(1)` silently wrap, losing the carried bit and
producing a NAF that reconstructs to the wrong value.
The GLV decomposition's `(r1, r2)` each have magnitude strictly less than
2^128, so values in the carry-out window are possible (though
vanishingly rare in random scalars — which is why the existing
randomized tests never caught it).
Fix by carrying the overflow bit into a third limb `top` that is absorbed
back on the next right-shift. Perf impact is in the noise: the `top`
branch is almost never taken and the predictor handles it cleanly.
Add two regression tests:
- `test_wnaf_128_reconstruction_adversarial` — reconstructs the NAF of a
scalar with low 128 bits = 0xFF..FF and asserts it equals 2^128 − 1.
- `test_mul_vartime_adversarial_scalars` — end-to-end check that
`mul_vartime(P, k)` matches the constant-time reference when `k`'s low
128 bits trigger the carry window.
Also add a `debug_assert!` on `idx` in `WnafSlot::apply` to guard the
parallel invariant (`idx < WNAF_TABLE_SIZE`) if `WNAF_WIDTH` is ever
widened without growing the table.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments