@@ -139,8 +139,7 @@ static void secp256k1_ecmult_odd_multiples_table_globalz_windowa(secp256k1_ge *p
139139
140140static void secp256k1_ecmult_odd_multiples_table_storage_var (const int n , secp256k1_ge_storage * pre , const secp256k1_gej * a ) {
141141 secp256k1_gej d ;
142- secp256k1_ge a_ge , d_ge , p_ge ;
143- secp256k1_ge last_ge ;
142+ secp256k1_ge d_ge , p_ge ;
144143 secp256k1_gej pj ;
145144 secp256k1_fe zi ;
146145 secp256k1_fe zr ;
@@ -162,51 +161,48 @@ static void secp256k1_ecmult_odd_multiples_table_storage_var(const int n, secp25
162161 d_ge .y = d .y ;
163162 d_ge .infinity = 0 ;
164163
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 ;
168167 pj .z = a -> z ;
169168 pj .infinity = 0 ;
170169
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 );
178173 secp256k1_gej_add_ge_var (& pj , & pj , & d_ge , & zr );
179174 secp256k1_fe_normalize_var (& zr );
180175 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 );
183176 }
184177
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+
188182 /* Directly set `pre[n - 1]` to `pj`, saving the inverted z-coordinate so
189183 * that we can combine it with the saved z-ratios to compute the other zs
190184 * without any more inversions. */
191- secp256k1_fe_inv_var (& zi , & pj .z );
192185 secp256k1_ge_set_gej_zinv (& p_ge , & pj , & zi );
193- secp256k1_ge_from_storage (& last_ge , & pre [n - 1 ]);
194186 secp256k1_ge_to_storage (& pre [n - 1 ], & p_ge );
195187
196188 /* 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 */
198190 secp256k1_fe_sqr (& dx_over_dz_squared , & d .z );
199191 secp256k1_fe_mul (& dx_over_dz_squared , & dx_over_dz_squared , & d .x );
200192
201193 i = n - 1 ;
202194 while (i > 0 ) {
203195 secp256k1_fe zi2 , zi3 ;
196+ const secp256k1_fe * rzr ;
204197 i -- ;
198+
199+ secp256k1_ge_from_storage (& p_ge , & pre [i ]);
200+
205201 /* For the remaining points, we extract the z-ratio from the stored
206202 * 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 );
210206 secp256k1_fe_sqr (& zi2 , & zi );
211207 secp256k1_fe_mul (& zi3 , & zi2 , & zi );
212208 /* 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
217213 * multiplying by each z-ratio in turn.
218214 *
219215 * 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
221217 * of the above `gej_add_ge_var` call. This satisfies
222218 *
223219 * rzr = d_x * z^2 - x
@@ -230,12 +226,11 @@ static void secp256k1_ecmult_odd_multiples_table_storage_var(const int n, secp25
230226 * x = d_x - rzr / z^2
231227 * = d_x - rzr * zi2
232228 */
233- secp256k1_fe_mul (& p_ge .x , & last_ge . x , & zi2 );
229+ secp256k1_fe_mul (& p_ge .x , rzr , & zi2 );
234230 secp256k1_fe_negate (& p_ge .x , & p_ge .x , 1 );
235231 secp256k1_fe_add (& p_ge .x , & dx_over_dz_squared );
236232 /* 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 );
239234 /* Store */
240235 secp256k1_ge_to_storage (& pre [i ], & p_ge );
241236 }
0 commit comments