@@ -561,6 +561,36 @@ func mixedSum*[F; G: static Subgroup](
561
561
562
562
r = o
563
563
564
+ func dbl_1998_cmo_rescaled_a0_impl [F; G: static Subgroup ](r: var EC_ShortW_Jac[F, G], P: EC_ShortW_Jac[F, G]) {.inline .} =
565
+ static : doAssert F.Name .getCoefA () == 0
566
+ # "dbl-1998-cmo" doubling formula - https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-1998-cmo
567
+ # rescaled by 1/2, 1/4, 1/8 (inspiration from Bos et al https://eprint.iacr.org/2014/130.pdf)
568
+ # See [./ec_shortweierstrass_jacobian.md](./ec_shortweierstrass_jacobian.md)
569
+ #
570
+ # Cost: 3M + 4S + 3add + 1*2 + 1*3 + 1half
571
+ #
572
+ # YY = Y₁²
573
+ # M = 3X₁²/2
574
+ # S = X₁*YY
575
+ # X₃ = M²-2*S
576
+ # Y₃ = M*(S-X₃)-YY²
577
+ # Z₃ = Y₁*Z₁
578
+ var Y {.noInit .}, M {.noInit .}, S {.noInit .}: F
579
+ Y.square (P.y)
580
+ M.square (P.x)
581
+ M *= 3
582
+ M.div2 ()
583
+ S.prod (P.x, Y)
584
+ Y.square ()
585
+
586
+ r.z.prod (P.z, P.y) # Z₃ = Y₁*Z₁, no aliasing
587
+ r.x.square (M) # X₃ = M²
588
+ r.x -= S # X₃ = M²-S
589
+ r.x -= S # X₃ = M²-2*S
590
+ r.y.diff (S, r.x) # Y₃ = S-X₃
591
+ r.y *= M # Y₃ = M*(S-X₃)
592
+ r.y -= Y # Y₃ = M*(S-X₃)-YY²
593
+
564
594
func double * [F; G: static Subgroup ](r: var EC_ShortW_Jac[F, G], P: EC_ShortW_Jac[F, G]) {.meter .} =
565
595
# # Elliptic curve point doubling for Short Weierstrass curves in projective coordinate
566
596
# #
@@ -575,49 +605,7 @@ func double*[F; G: static Subgroup](r: var EC_ShortW_Jac[F, G], P: EC_ShortW_Jac
575
605
# #
576
606
# # Implementation is constant-time.
577
607
when F.Name .getCoefA () == 0 :
578
- # "dbl-2009-l" doubling formula - https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
579
- #
580
- # Cost: 2M + 5S + 6add + 3*2 + 1*3 + 1*8.
581
- # Source: 2009.04.01 Lange.
582
- # Explicit formulas:
583
- #
584
- # A = X₁²
585
- # B = Y₁²
586
- # C = B²
587
- # D = 2*((X₁+B)²-A-C)
588
- # E = 3*A
589
- # F = E²
590
- # X₃ = F-2*D
591
- # Y₃ = E*(D-X₃)-8*C
592
- # Z₃ = 2*Y₁*Z₁
593
- #
594
- var A {.noInit .}, B{.noInit .}, C {.noInit .}: F
595
- A.square (P.x)
596
- B.square (P.y)
597
- C.square (B)
598
- B += P.x
599
- # aliasing: we don't use P.x anymore
600
-
601
- B.square ()
602
- B -= A
603
- B -= C
604
- B.double () # D = 2*((X₁+B)²-A-C)
605
- A *= 3 # E = 3*A
606
- r.x.square (A) # F = E²
607
-
608
- r.x -= B
609
- r.x -= B # X₃ = F-2*D
610
-
611
- B -= r.x # (D-X₃)
612
- A *= B # E*(D-X₃)
613
- C *= 8
614
-
615
- r.z.prod (P.z, P.y)
616
- r.z.double () # Z₃ = 2*Y₁*Z₁
617
- # aliasing: we don't use P.y, P.z anymore
618
-
619
- r.y.diff (A, C) # Y₃ = E*(D-X₃)-8*C
620
-
608
+ dbl_1998_cmo_rescaled_a0_impl (r, P)
621
609
else :
622
610
{.error : " Not implemented." .}
623
611
@@ -741,7 +729,7 @@ func sum_vartime*[F; G: static Subgroup](
741
729
var U {.noInit .}, S{.noInit .}, H{.noInit .}, R{.noInit .}: F
742
730
743
731
if not isPz1: # case Z₁ != 1
744
- R.square (p.z, lazyReduce = true ) # Z₁Z₁ = Z₁²
732
+ R.square (p.z, lazyReduce = true ) # Z₁Z₁ = Z₁²
745
733
if isQz1: # case Z₂ = 1
746
734
U = p.x # U₁ = X₁*Z₂Z₂
747
735
if isPz1: # case Z₁ = Z₂ = 1
0 commit comments