@@ -34,8 +34,12 @@ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp25
34
34
secp256k1_ge add ;
35
35
secp256k1_fe neg ;
36
36
secp256k1_ge_storage adds ;
37
- secp256k1_scalar recoded ;
38
- int first = 1 ;
37
+ secp256k1_scalar tmp ;
38
+ /* Array of uint32_t values large enough to store COMB_BITS bits. Only the bottom
39
+ * 8 are ever nonzero, but having the zero padding at the end if COMB_BITS>256
40
+ * avoids the need to deal with out-of-bounds reads from a scalar. */
41
+ uint32_t recoded [(COMB_BITS + 31 ) >> 5 ] = {0 };
42
+ int first = 1 , i ;
39
43
40
44
memset (& adds , 0 , sizeof (adds ));
41
45
@@ -44,17 +48,22 @@ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp25
44
48
* To blind the scalar used in the computation, we rewrite this to be R = (gn-b)*G + b*G.
45
49
*
46
50
* Next, we write (gn-b)*G as a sum of values (2*bit_i-1) * 2^i * G, for i=0..COMB_BITS-1.
47
- * The values bit_i can be found as the binary representation of recoded =
48
- * (gn + 2^COMB_BITS - 1 - b)/2 (mod order).
51
+ * The values bit_i can be found as the binary representation of
52
+ * (gn + 2^COMB_BITS - 1 - b)/2 (mod order), stored in recoded .
49
53
*
50
54
* The value (2^COMB_BITS - 1 - b) is precomputed as ctx->scalar_offset, and bG is
51
55
* precomputed as ctx->final_point_add. Thus recoded can be written as
52
56
* recoded = (gn + scalar_offset)/2, and R becomes the sum of (2*bit_i-1)*2^i*G
53
57
* values plus final_point_add. */
54
58
55
- /* Compute the recoded value as a scalar. */
56
- secp256k1_scalar_add (& recoded , gn , & ctx -> scalar_offset );
57
- secp256k1_scalar_half (& recoded , & recoded );
59
+ /* Compute (gn + 2^COMB_BITS - 1 - 1)/2 value as a scalar. */
60
+ secp256k1_scalar_add (& tmp , gn , & ctx -> scalar_offset );
61
+ secp256k1_scalar_half (& tmp , & tmp );
62
+ /* Convert to recoded array. */
63
+ for (i = 0 ; i < 8 ; ++ i ) {
64
+ recoded [i ] = secp256k1_scalar_get_bits (& tmp , 32 * i , 32 );
65
+ }
66
+ secp256k1_scalar_clear (& tmp );
58
67
59
68
/* In secp256k1_ecmult_gen_prec_table we have precomputed sums of the
60
69
* (2*bit_i-1) * 2^i * G points, for various combinations of i positions.
@@ -122,8 +131,8 @@ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp25
122
131
* together: bit (tooth) of bits = bit
123
132
* ((block*COMB_TEETH + tooth)*COMB_SPACING + comb_off) of recoded. */
124
133
uint32_t bits = 0 , sign , abs , index , tooth ;
125
- for (tooth = 0 ; tooth < COMB_TEETH && bit_pos < 256 ; ++ tooth ) {
126
- uint32_t bit = secp256k1_scalar_get_bits ( & recoded , bit_pos , 1 ) ;
134
+ for (tooth = 0 ; tooth < COMB_TEETH ; ++ tooth ) {
135
+ uint32_t bit = ( recoded [ bit_pos >> 5 ] >> ( bit_pos & 0x1f )) & 1 ;
127
136
bits |= bit << tooth ;
128
137
bit_pos += COMB_SPACING ;
129
138
}
@@ -178,7 +187,7 @@ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp25
178
187
secp256k1_fe_clear (& neg );
179
188
secp256k1_ge_clear (& add );
180
189
memset (& adds , 0 , sizeof (adds ));
181
- secp256k1_scalar_clear (& recoded );
190
+ memset (& recoded , 0 , sizeof ( recoded ) );
182
191
}
183
192
184
193
/* Setup blinding values for secp256k1_ecmult_gen. */
0 commit comments