Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions src/ecmult_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,24 @@ static int secp256k1_ecmult_wnaf(int *wnaf, int len, const secp256k1_scalar *a,
return last_set_bit + 1;
}

/* Same as secp256k1_ecmult_wnaf, but stores to int8_t array. Requires w <= 8. */
static int secp256k1_ecmult_wnaf_small(int8_t *wnaf, int len, const secp256k1_scalar *a, int w) {
int wnaf_tmp[256];
int ret, i;

VERIFY_CHECK(2 <= w && w <= 8);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
VERIFY_CHECK(2 <= w && w <= 8);
VERIFY_CHECK(2 <= w && w <= 7);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why w = 8 wouldn't work. The documentation of wnaf says

 *  - each wnaf[i] is either 0, or an odd integer between -(1<<(w-1) - 1) and (1<<(w-1) - 1)

So for w = 8, wnaf[i] is in [-127, 127] which fits in an int8_t.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, yes, you're right. I was getting confused. secp256k1_ecmult_wnaf itself needs w <= 31 (and not 32), if only because it performs a carry << w shift (for int carry) which is certainly UB if int is 32 bits. (In fact, if carry == 1, then even 1 << 31 is UB. This is another edge case that we should fix! Let me add this to the other issue.)

But since your function only copies the results, everything is fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, if carry == 1, then even 1 << 31 is UB. This is another edge case that we should fix! Let me add this to the other issue

Oh, great catch!

ret = secp256k1_ecmult_wnaf(wnaf_tmp, len, a, w);

for (i = 0; i < len; i++) {
wnaf[i] = (int8_t)wnaf_tmp[i];
}

return ret;
}

struct secp256k1_strauss_point_state {
int wnaf_na_1[129];
int wnaf_na_lam[129];
int8_t wnaf_na_1[129];
int8_t wnaf_na_lam[129];
int bits_na_1;
int bits_na_lam;
};
Expand Down Expand Up @@ -259,8 +274,8 @@ static void secp256k1_ecmult_strauss_wnaf(const struct secp256k1_strauss_state *
secp256k1_scalar_split_lambda(&na_1, &na_lam, &na[np]);

/* build wnaf representation for na_1 and na_lam. */
state->ps[no].bits_na_1 = secp256k1_ecmult_wnaf(state->ps[no].wnaf_na_1, 129, &na_1, WINDOW_A);
state->ps[no].bits_na_lam = secp256k1_ecmult_wnaf(state->ps[no].wnaf_na_lam, 129, &na_lam, WINDOW_A);
state->ps[no].bits_na_1 = secp256k1_ecmult_wnaf_small(state->ps[no].wnaf_na_1, 129, &na_1, WINDOW_A);
state->ps[no].bits_na_lam = secp256k1_ecmult_wnaf_small(state->ps[no].wnaf_na_lam, 129, &na_lam, WINDOW_A);
VERIFY_CHECK(state->ps[no].bits_na_1 <= 129);
VERIFY_CHECK(state->ps[no].bits_na_lam <= 129);
if (state->ps[no].bits_na_1 > bits) {
Expand Down