@@ -139,8 +139,7 @@ static void secp256k1_ecmult_odd_multiples_table_globalz_windowa(secp256k1_ge *p
139
139
140
140
static void secp256k1_ecmult_odd_multiples_table_storage_var (const int n , secp256k1_ge_storage * pre , const secp256k1_gej * a ) {
141
141
secp256k1_gej d ;
142
- secp256k1_ge a_ge , d_ge , p_ge ;
143
- secp256k1_ge last_ge ;
142
+ secp256k1_ge d_ge , p_ge ;
144
143
secp256k1_gej pj ;
145
144
secp256k1_fe zi ;
146
145
secp256k1_fe zr ;
@@ -162,51 +161,48 @@ static void secp256k1_ecmult_odd_multiples_table_storage_var(const int n, secp25
162
161
d_ge .y = d .y ;
163
162
d_ge .infinity = 0 ;
164
163
165
- secp256k1_ge_set_gej_zinv (& a_ge , a , & d .z );
166
- pj .x = a_ge .x ;
167
- pj .y = a_ge .y ;
164
+ secp256k1_ge_set_gej_zinv (& p_ge , a , & d .z );
165
+ pj .x = p_ge .x ;
166
+ pj .y = p_ge .y ;
168
167
pj .z = a -> z ;
169
168
pj .infinity = 0 ;
170
169
171
- zr = d .z ;
172
- secp256k1_fe_normalize_var (& zr );
173
- secp256k1_fe_to_storage (& pre [0 ].x , & zr );
174
- secp256k1_fe_normalize_var (& pj .y );
175
- secp256k1_fe_to_storage (& pre [0 ].y , & pj .y );
176
-
177
- for (i = 1 ; i < n ; i ++ ) {
170
+ for (i = 0 ; i < (n - 1 ); i ++ ) {
171
+ secp256k1_fe_normalize_var (& pj .y );
172
+ secp256k1_fe_to_storage (& pre [i ].y , & pj .y );
178
173
secp256k1_gej_add_ge_var (& pj , & pj , & d_ge , & zr );
179
174
secp256k1_fe_normalize_var (& zr );
180
175
secp256k1_fe_to_storage (& pre [i ].x , & zr );
181
- secp256k1_fe_normalize_var (& pj .y );
182
- secp256k1_fe_to_storage (& pre [i ].y , & pj .y );
183
176
}
184
177
185
- /* Map `pj` back to our curve by multiplying its z-coordinate by `d.z`. */
186
- zr = pj .z ; /* save pj.z so we can use it to extract (d.z)^-1 from zi */
187
- secp256k1_fe_mul (& pj .z , & pj .z , & d .z );
178
+ /* Invert d.z in the same batch, preserving pj.z so we can extract 1/d.z */
179
+ secp256k1_fe_mul (& zi , & pj .z , & d .z );
180
+ secp256k1_fe_inv_var (& zi , & zi );
181
+
188
182
/* Directly set `pre[n - 1]` to `pj`, saving the inverted z-coordinate so
189
183
* that we can combine it with the saved z-ratios to compute the other zs
190
184
* without any more inversions. */
191
- secp256k1_fe_inv_var (& zi , & pj .z );
192
185
secp256k1_ge_set_gej_zinv (& p_ge , & pj , & zi );
193
- secp256k1_ge_from_storage (& last_ge , & pre [n - 1 ]);
194
186
secp256k1_ge_to_storage (& pre [n - 1 ], & p_ge );
195
187
196
188
/* Compute the actual x-coordinate of D, which will be needed below. */
197
- secp256k1_fe_mul (& d .z , & zi , & zr ); /* d.z = 1/d.z */
189
+ secp256k1_fe_mul (& d .z , & zi , & pj . z ); /* d.z = 1/d.z */
198
190
secp256k1_fe_sqr (& dx_over_dz_squared , & d .z );
199
191
secp256k1_fe_mul (& dx_over_dz_squared , & dx_over_dz_squared , & d .x );
200
192
201
193
i = n - 1 ;
202
194
while (i > 0 ) {
203
195
secp256k1_fe zi2 , zi3 ;
196
+ const secp256k1_fe * rzr ;
204
197
i -- ;
198
+
199
+ secp256k1_ge_from_storage (& p_ge , & pre [i ]);
200
+
205
201
/* For the remaining points, we extract the z-ratio from the stored
206
202
* x-coordinate, compute its z^-1 from that, and compute the full
207
- * point from that. The z-ratio for the next iteration is stored in
208
- * the x-coordinate at the end of the loop. */
209
- secp256k1_fe_mul (& zi , & zi , & last_ge . x );
203
+ * point from that. */
204
+ rzr = & p_ge . x ;
205
+ secp256k1_fe_mul (& zi , & zi , rzr );
210
206
secp256k1_fe_sqr (& zi2 , & zi );
211
207
secp256k1_fe_mul (& zi3 , & zi2 , & zi );
212
208
/* To compute the actual x-coordinate, we use the stored z ratio and
@@ -217,7 +213,7 @@ static void secp256k1_ecmult_odd_multiples_table_storage_var(const int n, secp25
217
213
* multiplying by each z-ratio in turn.
218
214
*
219
215
* Denoting the z-ratio as `rzr` (though the actual variable binding
220
- * is `last_ge .x`), we observe that it equal to `h` from the inside
216
+ * is `p_ge .x`), we observe that it equal to `h` from the inside
221
217
* of the above `gej_add_ge_var` call. This satisfies
222
218
*
223
219
* rzr = d_x * z^2 - x
@@ -230,12 +226,11 @@ static void secp256k1_ecmult_odd_multiples_table_storage_var(const int n, secp25
230
226
* x = d_x - rzr / z^2
231
227
* = d_x - rzr * zi2
232
228
*/
233
- secp256k1_fe_mul (& p_ge .x , & last_ge . x , & zi2 );
229
+ secp256k1_fe_mul (& p_ge .x , rzr , & zi2 );
234
230
secp256k1_fe_negate (& p_ge .x , & p_ge .x , 1 );
235
231
secp256k1_fe_add (& p_ge .x , & dx_over_dz_squared );
236
232
/* y is stored_y/z^3, as we expect */
237
- secp256k1_ge_from_storage (& last_ge , & pre [i ]);
238
- secp256k1_fe_mul (& p_ge .y , & last_ge .y , & zi3 );
233
+ secp256k1_fe_mul (& p_ge .y , & p_ge .y , & zi3 );
239
234
/* Store */
240
235
secp256k1_ge_to_storage (& pre [i ], & p_ge );
241
236
}
0 commit comments