@@ -492,7 +492,7 @@ static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a,
492
492
493
493
494
494
static void secp256k1_gej_add_ge (secp256k1_gej * r , const secp256k1_gej * a , const secp256k1_ge * b ) {
495
- /* Operations: 7 mul, 5 sqr, 4 normalize, 21 mul_int/ add/negate/cmov */
495
+ /* Operations: 7 mul, 5 sqr, 24 add/cmov/half/mul_int/ negate/normalize_weak/normalizes_to_zero */
496
496
secp256k1_fe zz , u1 , u2 , s1 , s2 , t , tt , m , n , q , rr ;
497
497
secp256k1_fe m_alt , rr_alt ;
498
498
int infinity , degenerate ;
@@ -513,11 +513,11 @@ static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const
513
513
* Z = Z1*Z2
514
514
* T = U1+U2
515
515
* M = S1+S2
516
- * Q = T*M^2
516
+ * Q = - T*M^2
517
517
* R = T^2-U1*U2
518
- * X3 = 4*( R^2-Q)
519
- * Y3 = 4* (R*(3*Q-2*R^2)- M^4)
520
- * Z3 = 2* M*Z
518
+ * X3 = R^2+Q
519
+ * Y3 = - (R*(2*X3+Q)+ M^4)/2
520
+ * Z3 = M*Z
521
521
* (Note that the paper uses xi = Xi / Zi and yi = Yi / Zi instead.)
522
522
*
523
523
* This formula has the benefit of being the same for both addition
@@ -581,29 +581,25 @@ static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const
581
581
* and denominator of lambda; R and M represent the explicit
582
582
* expressions x1^2 + x2^2 + x1x2 and y1 + y2. */
583
583
secp256k1_fe_sqr (& n , & m_alt ); /* n = Malt^2 (1) */
584
- secp256k1_fe_mul (& q , & n , & t ); /* q = Q = T*Malt^2 (1) */
584
+ secp256k1_fe_negate (& q , & t , 2 ); /* q = -T (3) */
585
+ secp256k1_fe_mul (& q , & q , & n ); /* q = Q = -T*Malt^2 (1) */
585
586
/* These two lines use the observation that either M == Malt or M == 0,
586
587
* so M^3 * Malt is either Malt^4 (which is computed by squaring), or
587
588
* zero (which is "computed" by cmov). So the cost is one squaring
588
589
* versus two multiplications. */
589
590
secp256k1_fe_sqr (& n , & n );
590
591
secp256k1_fe_cmov (& n , & m , degenerate ); /* n = M^3 * Malt (2) */
591
592
secp256k1_fe_sqr (& t , & rr_alt ); /* t = Ralt^2 (1) */
592
- secp256k1_fe_mul (& r -> z , & a -> z , & m_alt ); /* r->z = Malt*Z (1) */
593
+ secp256k1_fe_mul (& r -> z , & a -> z , & m_alt ); /* r->z = Z3 = Malt*Z (1) */
593
594
infinity = secp256k1_fe_normalizes_to_zero (& r -> z ) & ~a -> infinity ;
594
- secp256k1_fe_mul_int (& r -> z , 2 ); /* r->z = Z3 = 2*Malt*Z (2) */
595
- secp256k1_fe_negate (& q , & q , 1 ); /* q = -Q (2) */
596
- secp256k1_fe_add (& t , & q ); /* t = Ralt^2-Q (3) */
597
- secp256k1_fe_normalize_weak (& t );
598
- r -> x = t ; /* r->x = Ralt^2-Q (1) */
599
- secp256k1_fe_mul_int (& t , 2 ); /* t = 2*x3 (2) */
600
- secp256k1_fe_add (& t , & q ); /* t = 2*x3 - Q: (4) */
601
- secp256k1_fe_mul (& t , & t , & rr_alt ); /* t = Ralt*(2*x3 - Q) (1) */
602
- secp256k1_fe_add (& t , & n ); /* t = Ralt*(2*x3 - Q) + M^3*Malt (3) */
603
- secp256k1_fe_negate (& r -> y , & t , 3 ); /* r->y = Ralt*(Q - 2x3) - M^3*Malt (4) */
604
- secp256k1_fe_normalize_weak (& r -> y );
605
- secp256k1_fe_mul_int (& r -> x , 4 ); /* r->x = X3 = 4*(Ralt^2-Q) */
606
- secp256k1_fe_mul_int (& r -> y , 4 ); /* r->y = Y3 = 4*Ralt*(Q - 2x3) - 4*M^3*Malt (4) */
595
+ secp256k1_fe_add (& t , & q ); /* t = Ralt^2 + Q (2) */
596
+ r -> x = t ; /* r->x = X3 = Ralt^2 + Q (2) */
597
+ secp256k1_fe_mul_int (& t , 2 ); /* t = 2*X3 (4) */
598
+ secp256k1_fe_add (& t , & q ); /* t = 2*X3 + Q (5) */
599
+ secp256k1_fe_mul (& t , & t , & rr_alt ); /* t = Ralt*(2*X3 + Q) (1) */
600
+ secp256k1_fe_add (& t , & n ); /* t = Ralt*(2*X3 + Q) + M^3*Malt (3) */
601
+ secp256k1_fe_negate (& r -> y , & t , 3 ); /* r->y = -(Ralt*(2*X3 + Q) + M^3*Malt) (4) */
602
+ secp256k1_fe_half (& r -> y ); /* r->y = Y3 = -(Ralt*(2*X3 + Q) + M^3*Malt)/2 (3) */
607
603
608
604
/** In case a->infinity == 1, replace r with (b->x, b->y, 1). */
609
605
secp256k1_fe_cmov (& r -> x , & b -> x , a -> infinity );
0 commit comments