@@ -304,7 +304,7 @@ export class wNAF<PC extends PC_ANY> {
304304 * https://github.com/paulmillr/noble-secp256k1/blob/47cb1669b6e506ad66b35fe7d76132ae97465da2/index.ts#L502-L541
305305 * @returns real and fake (for const-time) points
306306 */
307- private wNAF ( W : number , precomputes : PC_P < PC > [ ] , n : bigint ) : { p : PC_P < PC > ; f : PC_P < PC > } {
307+ private wNAF ( W : number , precomputes : PC_P < PC > [ ] [ ] , n : bigint ) : { p : PC_P < PC > ; f : PC_P < PC > } {
308308 // Scalar should be smaller than field order
309309 if ( ! this . Fn . isValid ( n ) ) throw new Error ( 'invalid scalar' ) ;
310310 // Accumulators
@@ -323,10 +323,10 @@ export class wNAF<PC extends PC_ANY> {
323323 if ( isZero ) {
324324 // bits are 0: add garbage to fake point
325325 // Important part for const-time getPublicKey: add random "noise" point to f.
326- f = f . add ( negateCt ( isNegF , precomputes [ offsetF ] ) ) ;
326+ f = f . add ( precomputes [ offsetF ] [ isNegF ? 1 : 0 ] ) ;
327327 } else {
328328 // bits are 1: add to result point
329- p = p . add ( negateCt ( isNeg , precomputes [ offset ] ) ) ;
329+ p = p . add ( precomputes [ offset ] [ isNeg ? 1 : 0 ] ) ;
330330 }
331331 }
332332 assert0 ( n ) ;
@@ -343,7 +343,7 @@ export class wNAF<PC extends PC_ANY> {
343343 */
344344 private wNAFUnsafe (
345345 W : number ,
346- precomputes : PC_P < PC > [ ] ,
346+ precomputes : PC_P < PC > [ ] [ ] ,
347347 n : bigint ,
348348 acc : PC_P < PC > = this . ZERO
349349 ) : PC_P < PC > {
@@ -358,22 +358,25 @@ export class wNAF<PC extends PC_ANY> {
358358 continue ;
359359 } else {
360360 const item = precomputes [ offset ] ;
361- acc = acc . add ( isNeg ? item . negate ( ) : item ) ; // Re-using acc allows to save adds in MSM
361+ acc = acc . add ( item [ isNeg ? 1 : 0 ] ) ; // Re-using acc allows to save adds in MSM
362362 }
363363 }
364364 assert0 ( n ) ;
365365 return acc ;
366366 }
367367
368- private getPrecomputes ( W : number , point : PC_P < PC > , transform ?: Mapper < PC_P < PC > > ) : PC_P < PC > [ ] {
368+ private getPrecomputes ( W : number , point : PC_P < PC > , transform ?: Mapper < PC_P < PC > > ) : PC_P < PC > [ ] [ ] {
369369 // Calculate precomputes on a first run, reuse them after
370370 let comp = pointPrecomputes . get ( point ) ;
371371 if ( ! comp ) {
372372 comp = this . precomputeWindow ( point , W ) as PC_P < PC > [ ] ;
373373 if ( W !== 1 ) {
374374 // Doing transform outside of if brings 15% perf hit
375375 if ( typeof transform === 'function' ) comp = transform ( comp ) ;
376+ comp = comp . map ( ( p ) => [ p , p . negate ( ) ] ) ;
376377 pointPrecomputes . set ( point , comp ) ;
378+ } else {
379+ comp = comp . map ( ( p ) => [ p , p . negate ( ) ] ) ;
377380 }
378381 }
379382 return comp ;
0 commit comments