Skip to content

Commit 145cc6e

Browse files
committed
Improve performance of _ecmult_wnaf
- Track carry explicitly instead of adding to scalar - Branch-free code for carry calculations
1 parent 0cbc860 commit 145cc6e

File tree

1 file changed

+14
-11
lines changed

1 file changed

+14
-11
lines changed

src/ecmult_impl.h

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_scalar_t *a, int w)
220220
int set_bits = 0;
221221
int bit = 0;
222222
int sign = 1;
223+
int carry = 0;
223224

224225
if (secp256k1_scalar_get_bits(&s, 255, 1)) {
225226
secp256k1_scalar_negate(&s, &s);
@@ -229,26 +230,28 @@ static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_scalar_t *a, int w)
229230
while (bit < 256) {
230231
int now;
231232
int word;
232-
if (secp256k1_scalar_get_bits(&s, bit, 1) == 0) {
233+
if (secp256k1_scalar_get_bits(&s, bit, 1) == (unsigned int)carry) {
233234
bit++;
234235
continue;
235236
}
236-
while (set_bits < bit) {
237-
wnaf[set_bits++] = 0;
238-
}
237+
239238
now = w;
240-
if (bit + now > 256) {
239+
if (now > 256 - bit) {
241240
now = 256 - bit;
242241
}
243-
word = secp256k1_scalar_get_bits_var(&s, bit, now);
244-
if (word & (1 << (w-1))) {
245-
secp256k1_scalar_add_bit(&s, bit + w);
246-
wnaf[set_bits++] = sign * (word - (1 << w));
247-
} else {
248-
wnaf[set_bits++] = sign * word;
242+
243+
word = secp256k1_scalar_get_bits_var(&s, bit, now) + carry;
244+
245+
carry = (word >> (w-1)) & 1;
246+
word -= carry << w;
247+
248+
while (set_bits < bit) {
249+
wnaf[set_bits++] = 0;
249250
}
251+
wnaf[set_bits++] = sign * word;
250252
bit += now;
251253
}
254+
VERIFY_CHECK(carry == 0);
252255
return set_bits;
253256
}
254257

0 commit comments

Comments
 (0)