99
1010#include "num.h"
1111#include "group.h"
12+ #include "scalar.h"
1213#include "ecmult.h"
1314
1415/* optimal for 128-bit and 256-bit exponents. */
@@ -121,38 +122,51 @@ static void secp256k1_ecmult_stop(void) {
121122 * with the following guarantees:
122123 * - each wnaf[i] is either 0, or an odd integer between -(1<<(w-1) - 1) and (1<<(w-1) - 1)
123124 * - two non-zero entries in wnaf are separated by at least w-1 zeroes.
124- * - the index of the highest non-zero entry in wnaf (=return value-1) is at most bits, where
125- * bits is the number of bits necessary to represent the absolute value of the input.
125+ * - the number of set values in wnaf is returned. This number is at most 256, and at most one more
126+ * - than the number of bits in the ( absolute value) of the input.
126127 */
127128static int secp256k1_ecmult_wnaf (int * wnaf , const secp256k1_num_t * a , int w ) {
128- int ret = 0 ;
129- int zeroes = 0 ;
130129 secp256k1_num_t x ;
131130 secp256k1_num_copy (& x , a );
132131 int sign = 1 ;
133132 if (secp256k1_num_is_neg (& x )) {
134133 sign = -1 ;
135134 secp256k1_num_negate (& x );
136135 }
137- while (!secp256k1_num_is_zero (& x )) {
138- while (!secp256k1_num_is_odd (& x )) {
139- zeroes ++ ;
140- secp256k1_num_shift (& x , 1 );
136+ unsigned char cr [32 ];
137+ secp256k1_num_get_bin (cr , 32 , & x );
138+ secp256k1_scalar_t s ;
139+ secp256k1_scalar_set_b32 (& s , cr , NULL );
140+
141+ if (secp256k1_scalar_get_bits (& s , 255 , 1 )) {
142+ secp256k1_scalar_negate (& s , & s );
143+ sign *= -1 ;
144+ }
145+
146+ int set_bits = 0 ;
147+ int bit = 0 ;
148+ while (bit < 256 ) {
149+ if (secp256k1_scalar_get_bits (& s , bit , 1 ) == 0 ) {
150+ bit ++ ;
151+ continue ;
152+ }
153+ while (set_bits < bit ) {
154+ wnaf [set_bits ++ ] = 0 ;
141155 }
142- int word = secp256k1_num_shift (& x , w );
143- while (zeroes ) {
144- wnaf [ret ++ ] = 0 ;
145- zeroes -- ;
156+ int now = w ;
157+ if (bit + now > 256 ) {
158+ now = 256 - bit ;
146159 }
160+ int word = secp256k1_scalar_get_bits_var (& s , bit , now );
147161 if (word & (1 << (w - 1 ))) {
148- secp256k1_num_inc ( & x );
149- wnaf [ret ++ ] = sign * (word - (1 << w ));
162+ secp256k1_scalar_add_bit ( & s , bit + w );
163+ wnaf [set_bits ++ ] = sign * (word - (1 << w ));
150164 } else {
151- wnaf [ret ++ ] = sign * word ;
165+ wnaf [set_bits ++ ] = sign * word ;
152166 }
153- zeroes = w - 1 ;
167+ bit += now ;
154168 }
155- return ret ;
169+ return set_bits ;
156170}
157171
158172static void secp256k1_ecmult (secp256k1_gej_t * r , const secp256k1_gej_t * a , const secp256k1_num_t * na , const secp256k1_num_t * ng ) {
@@ -170,7 +184,7 @@ static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const
170184 if (bits_na_lam > bits ) bits = bits_na_lam ;
171185#else
172186 /* build wnaf representation for na. */
173- int wnaf_na [257 ]; int bits_na = secp256k1_ecmult_wnaf (wnaf_na , na , WINDOW_A );
187+ int wnaf_na [256 ]; int bits_na = secp256k1_ecmult_wnaf (wnaf_na , na , WINDOW_A );
174188 int bits = bits_na ;
175189#endif
176190
0 commit comments