Changeset View
Changeset View
Standalone View
Standalone View
src/secp256k1/src/ecmult_const_impl.h
Show First 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | static int secp256k1_wnaf_const(int *wnaf, const secp256k1_scalar *scalar, int w, int size) { | ||||
/* 1 2 3 */ | /* 1 2 3 */ | ||||
int u_last; | int u_last; | ||||
int u; | int u; | ||||
int flip; | int flip; | ||||
int bit; | int bit; | ||||
secp256k1_scalar s; | secp256k1_scalar s; | ||||
int not_neg_one; | int not_neg_one; | ||||
VERIFY_CHECK(w > 0); | |||||
VERIFY_CHECK(size > 0); | |||||
/* Note that we cannot handle even numbers by negating them to be odd, as is | /* Note that we cannot handle even numbers by negating them to be odd, as is | ||||
* done in other implementations, since if our scalars were specified to have | * done in other implementations, since if our scalars were specified to have | ||||
* width < 256 for performance reasons, their negations would have width 256 | * width < 256 for performance reasons, their negations would have width 256 | ||||
* and we'd lose any performance benefit. Instead, we use a technique from | * and we'd lose any performance benefit. Instead, we use a technique from | ||||
* Section 4.2 of the Okeya/Tagaki paper, which is to add either 1 (for even) | * Section 4.2 of the Okeya/Tagaki paper, which is to add either 1 (for even) | ||||
* or 2 (for odd) to the number we are encoding, returning a skew value indicating | * or 2 (for odd) to the number we are encoding, returning a skew value indicating | ||||
* this, and having the caller compensate after doing the multiplication. | * this, and having the caller compensate after doing the multiplication. | ||||
* | * | ||||
Show All 17 Lines | static int secp256k1_wnaf_const(int *wnaf, const secp256k1_scalar *scalar, int w, int size) { | ||||
* the skew must be 1 or 2, never zero) and flipping is not, we need to change | * the skew must be 1 or 2, never zero) and flipping is not, we need to change | ||||
* our flags to claim that we only skewed. */ | * our flags to claim that we only skewed. */ | ||||
global_sign = secp256k1_scalar_cond_negate(&s, flip); | global_sign = secp256k1_scalar_cond_negate(&s, flip); | ||||
global_sign *= not_neg_one * 2 - 1; | global_sign *= not_neg_one * 2 - 1; | ||||
skew = 1 << bit; | skew = 1 << bit; | ||||
/* 4 */ | /* 4 */ | ||||
u_last = secp256k1_scalar_shr_int(&s, w); | u_last = secp256k1_scalar_shr_int(&s, w); | ||||
while (word * w < size) { | do { | ||||
int sign; | int sign; | ||||
int even; | int even; | ||||
/* 4.1 4.4 */ | /* 4.1 4.4 */ | ||||
u = secp256k1_scalar_shr_int(&s, w); | u = secp256k1_scalar_shr_int(&s, w); | ||||
/* 4.2 */ | /* 4.2 */ | ||||
even = ((u & 1) == 0); | even = ((u & 1) == 0); | ||||
sign = 2 * (u_last > 0) - 1; | sign = 2 * (u_last > 0) - 1; | ||||
u += sign * even; | u += sign * even; | ||||
u_last -= sign * even * (1 << w); | u_last -= sign * even * (1 << w); | ||||
/* 4.3, adapted for global sign change */ | /* 4.3, adapted for global sign change */ | ||||
wnaf[word++] = u_last * global_sign; | wnaf[word++] = u_last * global_sign; | ||||
u_last = u; | u_last = u; | ||||
} | } while (word * w < size); | ||||
wnaf[word] = u * global_sign; | wnaf[word] = u * global_sign; | ||||
VERIFY_CHECK(secp256k1_scalar_is_zero(&s)); | VERIFY_CHECK(secp256k1_scalar_is_zero(&s)); | ||||
VERIFY_CHECK(word == WNAF_SIZE_BITS(size, w)); | VERIFY_CHECK(word == WNAF_SIZE_BITS(size, w)); | ||||
return skew; | return skew; | ||||
} | } | ||||
static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *scalar, int size) { | static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *scalar, int size) { | ||||
▲ Show 20 Lines • Show All 136 Lines • Show Last 20 Lines |