@@ -73,6 +73,23 @@ impl<Fq: FqTrait> Curve<Fq> {
73
73
* ZQ = * XPQ * ( V1 - V2 ) . square ( ) ;
74
74
}
75
75
76
+ /// x-only differential addition with PointX type, sets `R` to x(P + Q) given x(P)
77
+ /// x(Q) and x(P - Q) as `PointX<Fq>`.
78
+ #[ inline]
79
+ fn xadd_aff_add_into ( R : & mut PointX < Fq > , xP : & PointX < Fq > , xQ : & PointX < Fq > , xPmQ : & Fq ) {
80
+ R . X = xQ. X ;
81
+ R . Z = xQ. Z ;
82
+ Self :: xadd_aff ( & xPmQ, & xP. X , & xP. Z , & mut R . X , & mut R . Z ) ;
83
+ }
84
+
85
+ /// Return x(P + Q) given x(P), x(Q) and x(P - Q) as `PointX<Fq>`.
86
+ #[ inline]
87
+ fn xdiff_add_add ( xP : & PointX < Fq > , xQ : & PointX < Fq > , xPmQ : & Fq ) -> PointX < Fq > {
88
+ let mut R = PointX :: INFINITY ;
89
+ Self :: xadd_aff_add_into ( & mut R , xP, xQ, xPmQ) ;
90
+ R
91
+ }
92
+
76
93
/// P3 <- n*P, x-only variant.
77
94
/// Integer n is encoded as unsigned little-endian, with length
78
95
/// nbitlen bits. Bits beyond that length are ignored.
@@ -326,11 +343,23 @@ impl<Fq: FqTrait> Curve<Fq> {
326
343
R [ 2 ] = T [ s1] ;
327
344
328
345
// Compute the difference points for T, R
329
- let mut D1 = R [ 1 ] ;
330
- let mut D2 = R [ 2 ] ;
346
+ let D1 = R [ 1 ] ;
347
+ let D2 = R [ 2 ] ;
331
348
R [ 2 ] = Self :: xdiff_add ( & R [ 1 ] , & R [ 2 ] , & B . PQ ) ;
332
- let mut F1 = R [ 2 ] ;
333
- let mut F2 = B . PQ ;
349
+ let F1 = R [ 2 ] ;
350
+ let F2 = B . PQ ;
351
+
352
+ // The cost for the main loop is k doubles and 2*k differential adds.
353
+ // If we normalise D1, D2, F1, F2 then we can save one mul per diff.
354
+ // add, saving 2*k multiplications in total. As this function is usually
355
+ // called with scalars of size log(p)/2 > 30, then it's worth normalising
356
+ // the points.
357
+ let mut inverses: [ Fq ; 4 ] = [ D1 . Z , D2 . Z , F1 . Z , F2 . Z ] ;
358
+ Fq :: batch_invert ( & mut inverses) ;
359
+ let mut xD1 = D1 . X * inverses[ 0 ] ;
360
+ let mut xD2 = D2 . X * inverses[ 1 ] ;
361
+ let mut xF1 = F1 . X * inverses[ 2 ] ;
362
+ let mut xF2 = F2 . X * inverses[ 3 ] ;
334
363
335
364
// Main ladder loop, compute [a]P + [b]Q
336
365
for i in ( 0 ..k) . rev ( ) {
@@ -345,10 +374,10 @@ impl<Fq: FqTrait> Curve<Fq> {
345
374
T [ 0 ] = self . xdouble ( & T [ h >> 1 ] ) ;
346
375
T [ 1 ] = R [ r2] ;
347
376
T [ 2 ] = R [ r2 + 1 ] ;
348
- PointX :: condswap ( & mut D1 , & mut D2 , ( r2 as u32 ) . wrapping_neg ( ) ) ;
349
- T [ 1 ] = Self :: xdiff_add ( & T [ 1 ] , & T [ 2 ] , & D1 ) ;
350
- T [ 2 ] = Self :: xdiff_add ( & R [ 0 ] , & R [ 2 ] , & F1 ) ;
351
- PointX :: condswap ( & mut F1 , & mut F2 , ( ( h & 1 ) as u32 ) . wrapping_neg ( ) ) ;
377
+ Fq :: condswap ( & mut xD1 , & mut xD2 , ( r2 as u32 ) . wrapping_neg ( ) ) ;
378
+ T [ 1 ] = Self :: xdiff_add_add ( & T [ 1 ] , & T [ 2 ] , & xD1 ) ;
379
+ T [ 2 ] = Self :: xdiff_add_add ( & R [ 0 ] , & R [ 2 ] , & xF1 ) ;
380
+ Fq :: condswap ( & mut xF1 , & mut xF2 , ( ( h & 1 ) as u32 ) . wrapping_neg ( ) ) ;
352
381
353
382
// Update R values from T values.
354
383
R = T ;
0 commit comments