mirror of
https://github.com/codex-storage/constantine.git
synced 2025-02-05 15:33:55 +00:00
Arg aliasing in elliptic curves (#150)
* Jacobian addition can handle aliasing fine * handle aliasing and use less mem for Jacobian double * Handle aliasing for Projective EC
This commit is contained in:
parent
5710a961a1
commit
94419db783
@ -56,7 +56,7 @@ func `==`*(P, Q: ECP_ShortW_Jac): SecretBool =
|
||||
b *= z1z1
|
||||
result = result and a == b
|
||||
|
||||
func isInf*(P: ECP_ShortW_Jac): SecretBool =
|
||||
func isInf*(P: ECP_ShortW_Jac): SecretBool {.inline.} =
|
||||
## Returns true if P is an infinity point
|
||||
## and false otherwise
|
||||
##
|
||||
@ -66,13 +66,13 @@ func isInf*(P: ECP_ShortW_Jac): SecretBool =
|
||||
## Y can be anything
|
||||
result = P.z.isZero()
|
||||
|
||||
func setInf*(P: var ECP_ShortW_Jac) =
|
||||
func setInf*(P: var ECP_ShortW_Jac) {.inline.} =
|
||||
## Set ``P`` to infinity
|
||||
P.x.setOne()
|
||||
P.y.setOne()
|
||||
P.z.setZero()
|
||||
|
||||
func ccopy*(P: var ECP_ShortW_Jac, Q: ECP_ShortW_Jac, ctl: SecretBool) =
|
||||
func ccopy*(P: var ECP_ShortW_Jac, Q: ECP_ShortW_Jac, ctl: SecretBool) {.inline.} =
|
||||
## Constant-time conditional copy
|
||||
## If ctl is true: Q is copied into P
|
||||
## if ctl is false: Q is not copied and P is unmodified
|
||||
@ -119,17 +119,17 @@ func trySetFromCoordX*[F; Tw](
|
||||
P.x = x
|
||||
P.z.setOne()
|
||||
|
||||
func neg*(P: var ECP_ShortW_Jac, Q: ECP_ShortW_Jac) =
|
||||
func neg*(P: var ECP_ShortW_Jac, Q: ECP_ShortW_Jac) {.inline.} =
|
||||
## Negate ``P``
|
||||
P.x = Q.x
|
||||
P.y.neg(Q.y)
|
||||
P.z = Q.z
|
||||
|
||||
func neg*(P: var ECP_ShortW_Jac) =
|
||||
func neg*(P: var ECP_ShortW_Jac) {.inline.} =
|
||||
## Negate ``P``
|
||||
P.y.neg()
|
||||
|
||||
func cneg*(P: var ECP_ShortW_Jac, ctl: CTBool) =
|
||||
func cneg*(P: var ECP_ShortW_Jac, ctl: CTBool) {.inline.} =
|
||||
## Conditional negation.
|
||||
## Negate if ``ctl`` is true
|
||||
P.y.cneg(ctl)
|
||||
@ -267,6 +267,7 @@ func sum*[F; Tw: static Twisted](
|
||||
# - HHH_or_Mpre contains HHH (add) or garbage precomputation (dbl)
|
||||
# - V_or_S is set with V = U₁*HH (add) or S = X₁*YY (dbl)
|
||||
block: # Finishing line
|
||||
# we can start using r, while carefully handling r and P or Q aliasing
|
||||
var t {.noInit.}: F
|
||||
t.double(V_or_S)
|
||||
r.x.square(R_or_M)
|
||||
@ -403,50 +404,50 @@ func double*[F; Tw: static Twisted](
|
||||
# Y₃ = E*(D-X₃)-8*C
|
||||
# Z₃ = 2*Y₁*Z₁
|
||||
#
|
||||
var A {.noInit.}, B{.noInit.}, C {.noInit.}, D{.noInit.}: F
|
||||
var A {.noInit.}, B{.noInit.}, C {.noInit.}: F
|
||||
A.square(P.x)
|
||||
B.square(P.y)
|
||||
C.square(B)
|
||||
D.sum(P.x, B)
|
||||
D.square()
|
||||
D -= A
|
||||
D -= C
|
||||
D *= 2 # D = 2*((X₁+B)²-A-C)
|
||||
B += P.x
|
||||
# aliasing: we don't use P.x anymore
|
||||
|
||||
B.square()
|
||||
B -= A
|
||||
B -= C
|
||||
B.double() # D = 2*((X₁+B)²-A-C)
|
||||
A *= 3 # E = 3*A
|
||||
r.x.square(A) # F = E²
|
||||
|
||||
B.double(D)
|
||||
r.x -= B
|
||||
r.x -= B # X₃ = F-2*D
|
||||
|
||||
B.diff(D, r.x) # (D-X₃)
|
||||
r.y.prod(A, B) # E*(D-X₃)
|
||||
B -= r.x # (D-X₃)
|
||||
A *= B # E*(D-X₃)
|
||||
C *= 8
|
||||
r.y -= C # Y₃ = E*(D-X₃)-8*C
|
||||
|
||||
r.z.prod(P.y, P.z)
|
||||
r.z *= 2 # Z₃ = 2*Y₁*Z₁
|
||||
r.z.prod(P.z, P.y)
|
||||
r.z.double() # Z₃ = 2*Y₁*Z₁
|
||||
# aliasing: we don't use P.y, P.z anymore
|
||||
|
||||
r.y.diff(A, C) # Y₃ = E*(D-X₃)-8*C
|
||||
|
||||
else:
|
||||
{.error: "Not implemented.".}
|
||||
|
||||
func `+=`*(P: var ECP_ShortW_Jac, Q: ECP_ShortW_Jac) =
|
||||
func `+=`*(P: var ECP_ShortW_Jac, Q: ECP_ShortW_Jac) {.inline.} =
|
||||
## In-place point addition
|
||||
# TODO test for aliasing support
|
||||
var tmp {.noInit.}: ECP_ShortW_Jac
|
||||
tmp.sum(P, Q)
|
||||
P = tmp
|
||||
P.sum(P, Q)
|
||||
|
||||
func double*(P: var ECP_ShortW_Jac) =
|
||||
var tmp {.noInit.}: ECP_ShortW_Jac
|
||||
tmp.double(P)
|
||||
P = tmp
|
||||
func double*(P: var ECP_ShortW_Jac) {.inline.} =
|
||||
## In-place point doubling
|
||||
P.double(P)
|
||||
|
||||
func diff*(r: var ECP_ShortW_Jac,
|
||||
P, Q: ECP_ShortW_Jac
|
||||
) =
|
||||
) {.inline.} =
|
||||
## r = P - Q
|
||||
## Can handle r and Q aliasing
|
||||
var nQ = Q
|
||||
nQ.neg()
|
||||
var nQ {.noInit.}: typeof(Q)
|
||||
nQ.neg(Q)
|
||||
r.sum(P, nQ)
|
||||
|
||||
func affineFromJacobian*[F; Tw](
|
||||
|
@ -50,7 +50,7 @@ func `==`*(P, Q: ECP_ShortW_Prj): SecretBool =
|
||||
b.prod(Q.y, P.z)
|
||||
result = result and a == b
|
||||
|
||||
func isInf*(P: ECP_ShortW_Prj): SecretBool =
|
||||
func isInf*(P: ECP_ShortW_Prj): SecretBool {.inline.} =
|
||||
## Returns true if P is an infinity point
|
||||
## and false otherwise
|
||||
##
|
||||
@ -60,13 +60,13 @@ func isInf*(P: ECP_ShortW_Prj): SecretBool =
|
||||
## Y can be anything
|
||||
result = P.x.isZero() and P.z.isZero()
|
||||
|
||||
func setInf*(P: var ECP_ShortW_Prj) =
|
||||
func setInf*(P: var ECP_ShortW_Prj) {.inline.} =
|
||||
## Set ``P`` to infinity
|
||||
P.x.setZero()
|
||||
P.y.setOne()
|
||||
P.z.setZero()
|
||||
|
||||
func ccopy*(P: var ECP_ShortW_Prj, Q: ECP_ShortW_Prj, ctl: SecretBool) =
|
||||
func ccopy*(P: var ECP_ShortW_Prj, Q: ECP_ShortW_Prj, ctl: SecretBool) {.inline.} =
|
||||
## Constant-time conditional copy
|
||||
## If ctl is true: Q is copied into P
|
||||
## if ctl is false: Q is not copied and P is unmodified
|
||||
@ -110,17 +110,17 @@ func trySetFromCoordX*[F; Tw](
|
||||
P.x = x
|
||||
P.z.setOne()
|
||||
|
||||
func neg*(P: var ECP_ShortW_Prj, Q: ECP_ShortW_Prj) =
|
||||
func neg*(P: var ECP_ShortW_Prj, Q: ECP_ShortW_Prj) {.inline.} =
|
||||
## Negate ``P``
|
||||
P.x = Q.x
|
||||
P.y.neg(Q.y)
|
||||
P.z = Q.z
|
||||
|
||||
func neg*(P: var ECP_ShortW_Prj) =
|
||||
func neg*(P: var ECP_ShortW_Prj) {.inline.} =
|
||||
## Negate ``P``
|
||||
P.y.neg()
|
||||
|
||||
func cneg*(P: var ECP_ShortW_Prj, ctl: CTBool) =
|
||||
func cneg*(P: var ECP_ShortW_Prj, ctl: CTBool) {.inline.} =
|
||||
## Conditional negation.
|
||||
## Negate if ``ctl`` is true
|
||||
P.y.cneg(ctl)
|
||||
@ -167,6 +167,7 @@ func sum*[F; Tw: static Twisted](
|
||||
|
||||
when F.C.getCoefA() == 0:
|
||||
var t0 {.noInit.}, t1 {.noInit.}, t2 {.noInit.}, t3 {.noInit.}, t4 {.noInit.}: F
|
||||
var x3 {.noInit.}, y3 {.noInit.}, z3 {.noInit.}: F
|
||||
const b3 = 3 * F.C.getCoefB()
|
||||
|
||||
# Algorithm 7 for curves: y² = x³ + b
|
||||
@ -188,39 +189,39 @@ func sum*[F; Tw: static Twisted](
|
||||
when Tw == OnTwist and F.C.getSexticTwist() == D_Twist:
|
||||
t3 *= SexticNonResidue
|
||||
t4.sum(P.y, P.z) # 9. t₄ <- Y₁ + Z₁
|
||||
r.x.sum(Q.y, Q.z) # 10. X₃ <- Y₂ + Z₂
|
||||
t4 *= r.x # 11. t₄ <- t₄ X₃
|
||||
r.x.sum(t1, t2) # 12. X₃ <- t₁ + t₂ X₃ = Y₁Y₂ + Z₁Z₂
|
||||
t4 -= r.x # 13. t₄ <- t₄ - X₃ t₄ = (Y₁ + Z₁)(Y₂ + Z₂) - (Y₁Y₂ + Z₁Z₂) = Y₁Z₂ + Y₂Z₁
|
||||
x3.sum(Q.y, Q.z) # 10. X₃ <- Y₂ + Z₂
|
||||
t4 *= x3 # 11. t₄ <- t₄ X₃
|
||||
x3.sum(t1, t2) # 12. X₃ <- t₁ + t₂ X₃ = Y₁Y₂ + Z₁Z₂
|
||||
t4 -= x3 # 13. t₄ <- t₄ - X₃ t₄ = (Y₁ + Z₁)(Y₂ + Z₂) - (Y₁Y₂ + Z₁Z₂) = Y₁Z₂ + Y₂Z₁
|
||||
when Tw == OnTwist and F.C.getSexticTwist() == D_Twist:
|
||||
t4 *= SexticNonResidue
|
||||
r.x.sum(P.x, P.z) # 14. X₃ <- X₁ + Z₁
|
||||
r.y.sum(Q.x, Q.z) # 15. Y₃ <- X₂ + Z₂
|
||||
r.x *= r.y # 16. X₃ <- X₃ Y₃ X₃ = (X₁Z₁)(X₂Z₂)
|
||||
r.y.sum(t0, t2) # 17. Y₃ <- t₀ + t₂ Y₃ = X₁ X₂ + Z₁ Z₂
|
||||
r.y.diff(r.x, r.y) # 18. Y₃ <- X₃ - Y₃ Y₃ = (X₁ + Z₁)(X₂ + Z₂) - (X₁ X₂ + Z₁ Z₂) = X₁Z₂ + X₂Z₁
|
||||
x3.sum(P.x, P.z) # 14. X₃ <- X₁ + Z₁
|
||||
y3.sum(Q.x, Q.z) # 15. Y₃ <- X₂ + Z₂
|
||||
x3 *= y3 # 16. X₃ <- X₃ Y₃ X₃ = (X₁Z₁)(X₂Z₂)
|
||||
y3.sum(t0, t2) # 17. Y₃ <- t₀ + t₂ Y₃ = X₁ X₂ + Z₁ Z₂
|
||||
y3.diff(x3, y3) # 18. Y₃ <- X₃ - Y₃ Y₃ = (X₁ + Z₁)(X₂ + Z₂) - (X₁ X₂ + Z₁ Z₂) = X₁Z₂ + X₂Z₁
|
||||
when Tw == OnTwist and F.C.getSexticTwist() == D_Twist:
|
||||
t0 *= SexticNonResidue
|
||||
t1 *= SexticNonResidue
|
||||
r.x.double(t0) # 19. X₃ <- t₀ + t₀ X₃ = 2 X₁X₂
|
||||
t0 += r.x # 20. t₀ <- X₃ + t₀ t₀ = 3 X₁X₂
|
||||
x3.double(t0) # 19. X₃ <- t₀ + t₀ X₃ = 2 X₁X₂
|
||||
t0 += x3 # 20. t₀ <- X₃ + t₀ t₀ = 3 X₁X₂
|
||||
t2 *= b3 # 21. t₂ <- 3b t₂ t₂ = 3bZ₁Z₂
|
||||
when Tw == OnTwist and F.C.getSexticTwist() == M_Twist:
|
||||
t2 *= SexticNonResidue
|
||||
r.z.sum(t1, t2) # 22. Z₃ <- t₁ + t₂ Z₃ = Y₁Y₂ + 3bZ₁Z₂
|
||||
z3.sum(t1, t2) # 22. Z₃ <- t₁ + t₂ Z₃ = Y₁Y₂ + 3bZ₁Z₂
|
||||
t1 -= t2 # 23. t₁ <- t₁ - t₂ t₁ = Y₁Y₂ - 3bZ₁Z₂
|
||||
r.y *= b3 # 24. Y₃ <- 3b Y₃ Y₃ = 3b(X₁Z₂ + X₂Z₁)
|
||||
y3 *= b3 # 24. Y₃ <- 3b Y₃ Y₃ = 3b(X₁Z₂ + X₂Z₁)
|
||||
when Tw == OnTwist and F.C.getSexticTwist() == M_Twist:
|
||||
r.y *= SexticNonResidue
|
||||
r.x.prod(t4, r.y) # 25. X₃ <- t₄ Y₃ X₃ = 3b(Y₁Z₂ + Y₂Z₁)(X₁Z₂ + X₂Z₁)
|
||||
y3 *= SexticNonResidue
|
||||
x3.prod(t4, y3) # 25. X₃ <- t₄ Y₃ X₃ = 3b(Y₁Z₂ + Y₂Z₁)(X₁Z₂ + X₂Z₁)
|
||||
t2.prod(t3, t1) # 26. t₂ <- t₃ t₁ t₂ = (X₁Y₂ + X₂Y₁) (Y₁Y₂ - 3bZ₁Z₂)
|
||||
r.x.diff(t2, r.x) # 27. X₃ <- t₂ - X₃ X₃ = (X₁Y₂ + X₂Y₁) (Y₁Y₂ - 3bZ₁Z₂) - 3b(Y₁Z₂ + Y₂Z₁)(X₁Z₂ + X₂Z₁)
|
||||
r.y *= t0 # 28. Y₃ <- Y₃ t₀ Y₃ = 9bX₁X₂ (X₁Z₂ + X₂Z₁)
|
||||
t1 *= r.z # 29. t₁ <- t₁ Z₃ t₁ = (Y₁Y₂ - 3bZ₁Z₂)(Y₁Y₂ + 3bZ₁Z₂)
|
||||
r.y += t1 # 30. Y₃ <- t₁ + Y₃ Y₃ = (Y₁Y₂ + 3bZ₁Z₂)(Y₁Y₂ - 3bZ₁Z₂) + 9bX₁X₂ (X₁Z₂ + X₂Z₁)
|
||||
r.x.diff(t2, x3) # 27. X₃ <- t₂ - X₃ X₃ = (X₁Y₂ + X₂Y₁) (Y₁Y₂ - 3bZ₁Z₂) - 3b(Y₁Z₂ + Y₂Z₁)(X₁Z₂ + X₂Z₁)
|
||||
y3 *= t0 # 28. Y₃ <- Y₃ t₀ Y₃ = 9bX₁X₂ (X₁Z₂ + X₂Z₁)
|
||||
t1 *= z3 # 29. t₁ <- t₁ Z₃ t₁ = (Y₁Y₂ - 3bZ₁Z₂)(Y₁Y₂ + 3bZ₁Z₂)
|
||||
r.y.sum(y3, t1) # 30. Y₃ <- t₁ + Y₃ Y₃ = (Y₁Y₂ + 3bZ₁Z₂)(Y₁Y₂ - 3bZ₁Z₂) + 9bX₁X₂ (X₁Z₂ + X₂Z₁)
|
||||
t0 *= t3 # 31. t₀ <- t₀ t₃ t₀ = 3X₁X₂ (X₁Y₂ + X₂Y₁)
|
||||
r.z *= t4 # 32. Z₃ <- Z₃ t₄ Z₃ = (Y₁Y₂ + 3bZ₁Z₂)(Y₁Z₂ + Y₂Z₁)
|
||||
r.z += t0 # 33. Z₃ <- Z₃ + t₀ Z₃ = (Y₁Z₂ + Y₂Z₁)(Y₁Y₂ + 3bZ₁Z₂) + 3X₁X₂ (X₁Y₂ + X₂Y₁)
|
||||
z3 *= t4 # 32. Z₃ <- Z₃ t₄ Z₃ = (Y₁Y₂ + 3bZ₁Z₂)(Y₁Z₂ + Y₂Z₁)
|
||||
r.z.sum(z3, t0) # 33. Z₃ <- Z₃ + t₀ Z₃ = (Y₁Z₂ + Y₂Z₁)(Y₁Y₂ + 3bZ₁Z₂) + 3X₁X₂ (X₁Y₂ + X₂Y₁)
|
||||
else:
|
||||
{.error: "Not implemented.".}
|
||||
|
||||
@ -238,6 +239,7 @@ func madd*[F; Tw: static Twisted](
|
||||
|
||||
when F.C.getCoefA() == 0:
|
||||
var t0 {.noInit.}, t1 {.noInit.}, t2 {.noInit.}, t3 {.noInit.}, t4 {.noInit.}: F
|
||||
var x3 {.noInit.}, y3 {.noInit.}, z3 {.noInit.}: F
|
||||
const b3 = 3 * F.C.getCoefB()
|
||||
|
||||
# Algorithm 8 for curves: y² = x³ + b
|
||||
@ -259,31 +261,31 @@ func madd*[F; Tw: static Twisted](
|
||||
t4 += P.y # 9. t₄ <- t₄ + Y₁, t₄ = Y₁+Y₂Z₁
|
||||
when Tw == OnTwist and F.C.getSexticTwist() == D_Twist:
|
||||
t4 *= SexticNonResidue
|
||||
r.y.prod(Q.x, P.z) # 10. Y₃ <- X₂ Z₁
|
||||
r.y += P.x # 11. Y₃ <- Y₃ + X₁, Y₃ = X₁ + X₂Z₁
|
||||
y3.prod(Q.x, P.z) # 10. Y₃ <- X₂ Z₁
|
||||
y3 += P.x # 11. Y₃ <- Y₃ + X₁, Y₃ = X₁ + X₂Z₁
|
||||
when Tw == OnTwist and F.C.getSexticTwist() == D_Twist:
|
||||
t0 *= SexticNonResidue
|
||||
t1 *= SexticNonResidue
|
||||
r.x.double(t0) # 12. X₃ <- t₀ + t₀
|
||||
t0 += r.x # 13. t₀ <- X₃ + t₀, t₀ = 3X₁X₂
|
||||
x3.double(t0) # 12. X₃ <- t₀ + t₀
|
||||
t0 += x3 # 13. t₀ <- X₃ + t₀, t₀ = 3X₁X₂
|
||||
t2 = P.z
|
||||
t2 *= b3 # 14. t₂ <- 3bZ₁
|
||||
when Tw == OnTwist and F.C.getSexticTwist() == M_Twist:
|
||||
t2 *= SexticNonResidue
|
||||
r.z.sum(t1, t2) # 15. Z₃ <- t₁ + t₂, Z₃ = Y₁Y₂ + 3bZ₁
|
||||
z3.sum(t1, t2) # 15. Z₃ <- t₁ + t₂, Z₃ = Y₁Y₂ + 3bZ₁
|
||||
t1 -= t2 # 16. t₁ <- t₁ - t₂, t₁ = Y₁Y₂ - 3bZ₁
|
||||
r.y *= b3 # 17. Y₃ <- 3bY₃, Y₃ = 3b(X₁ + X₂Z₁)
|
||||
y3 *= b3 # 17. Y₃ <- 3bY₃, Y₃ = 3b(X₁ + X₂Z₁)
|
||||
when Tw == OnTwist and F.C.getSexticTwist() == M_Twist:
|
||||
r.y *= SexticNonResidue
|
||||
r.x.prod(t4, r.y) # 18. X₃ <- t₄ Y₃, X₃ = (Y₁ + Y₂Z₁) 3b(X₁ + X₂Z₁)
|
||||
y3 *= SexticNonResidue
|
||||
x3.prod(t4, y3) # 18. X₃ <- t₄ Y₃, X₃ = (Y₁ + Y₂Z₁) 3b(X₁ + X₂Z₁)
|
||||
t2.prod(t3, t1) # 19. t₂ <- t₃ t₁, t₂ = (X₁Y₂ + X₂Y₁)(Y₁Y₂ - 3bZ₁)
|
||||
r.x.diff(t2, r.x) # 20. X₃ <- t₂ - X₃, X₃ = (X₁Y₂ + X₂Y₁)(Y₁Y₂ - 3bZ₁) - 3b(Y₁ + Y₂Z₁)(X₁ + X₂Z₁)
|
||||
r.y *= t0 # 21. Y₃ <- Y₃ t₀, Y₃ = 9bX₁X₂ (X₁ + X₂Z₁)
|
||||
t1 *= r.z # 22. t₁ <- t₁ Z₃, t₁ = (Y₁Y₂ - 3bZ₁)(Y₁Y₂ + 3bZ₁)
|
||||
r.y += t1 # 23. Y₃ <- t₁ + Y₃, Y₃ = (Y₁Y₂ + 3bZ₁)(Y₁Y₂ - 3bZ₁) + 9bX₁X₂ (X₁ + X₂Z₁)
|
||||
r.x.diff(t2, x3) # 20. X₃ <- t₂ - X₃, X₃ = (X₁Y₂ + X₂Y₁)(Y₁Y₂ - 3bZ₁) - 3b(Y₁ + Y₂Z₁)(X₁ + X₂Z₁)
|
||||
y3 *= t0 # 21. Y₃ <- Y₃ t₀, Y₃ = 9bX₁X₂ (X₁ + X₂Z₁)
|
||||
t1 *= z3 # 22. t₁ <- t₁ Z₃, t₁ = (Y₁Y₂ - 3bZ₁)(Y₁Y₂ + 3bZ₁)
|
||||
r.y.sum(y3, t1) # 23. Y₃ <- t₁ + Y₃, Y₃ = (Y₁Y₂ + 3bZ₁)(Y₁Y₂ - 3bZ₁) + 9bX₁X₂ (X₁ + X₂Z₁)
|
||||
t0 *= t3 # 31. t₀ <- t₀ t₃, t₀ = 3X₁X₂ (X₁Y₂ + X₂Y₁)
|
||||
r.z *= t4 # 32. Z₃ <- Z₃ t₄, Z₃ = (Y₁Y₂ + 3bZ₁)(Y₁ + Y₂Z₁)
|
||||
r.z += t0 # 33. Z₃ <- Z₃ + t₀, Z₃ = (Y₁ + Y₂Z₁)(Y₁Y₂ + 3bZ₁) + 3X₁X₂ (X₁Y₂ + X₂Y₁)
|
||||
z3 *= t4 # 32. Z₃ <- Z₃ t₄, Z₃ = (Y₁Y₂ + 3bZ₁)(Y₁ + Y₂Z₁)
|
||||
r.z.sum(z3, t0) # 33. Z₃ <- Z₃ + t₀, Z₃ = (Y₁ + Y₂Z₁)(Y₁Y₂ + 3bZ₁) + 3X₁X₂ (X₁Y₂ + X₂Y₁)
|
||||
else:
|
||||
{.error: "Not implemented.".}
|
||||
|
||||
@ -323,7 +325,8 @@ func double*[F; Tw: static Twisted](
|
||||
# Cost: 8M + 3S + 3 mul(a) + 2 mul(3b) + 15a
|
||||
|
||||
when F.C.getCoefA() == 0:
|
||||
var t0 {.noInit.}, t1 {.noInit.}, t2 {.noInit.}, snrY {.noInit.}: F
|
||||
var t0 {.noInit.}, t1 {.noInit.}, t2 {.noInit.}: F
|
||||
var x3 {.noInit.}, y3 {.noInit.}, z3 {.noInit.}: F
|
||||
const b3 = 3 * F.C.getCoefB()
|
||||
|
||||
# Algorithm 9 for curves:
|
||||
@ -332,59 +335,56 @@ func double*[F; Tw: static Twisted](
|
||||
# X₃ = 2XY(Y² - 9bZ²)
|
||||
# Y₃ = (Y² - 9bZ²)(Y² + 3bZ²) + 24bY²Z²
|
||||
# Z₃ = 8Y³Z
|
||||
snrY = P.y
|
||||
when Tw == OnTwist and F.C.getSexticTwist() == D_Twist:
|
||||
snrY *= SexticNonResidue
|
||||
var snrY {.noInit.}: F
|
||||
snrY.prod(P.y, SexticNonResidue)
|
||||
t0.square(P.y)
|
||||
t0 *= SexticNonResidue
|
||||
else:
|
||||
template snrY: untyped = P.y
|
||||
t0.square(P.y) # 1. t₀ <- Y Y
|
||||
r.z.double(t0) # 2. Z₃ <- t₀ + t₀
|
||||
r.z.double() # 3. Z₃ <- Z₃ + Z₃
|
||||
r.z.double() # 4. Z₃ <- Z₃ + Z₃ Z₃ = 8Y²
|
||||
z3.double(t0) # 2. Z₃ <- t₀ + t₀
|
||||
z3.double() # 3. Z₃ <- Z₃ + Z₃
|
||||
z3.double() # 4. Z₃ <- Z₃ + Z₃ Z₃ = 8Y²
|
||||
t1.prod(snrY, P.z) # 5. t₁ <- Y Z
|
||||
t2.square(P.z) # 6. t₂ <- Z Z
|
||||
t2 *= b3 # 7. t₂ <- 3b t₂
|
||||
when Tw == OnTwist and F.C.getSexticTwist() == M_Twist:
|
||||
t2 *= SexticNonResidue
|
||||
r.x.prod(t2, r.z) # 8. X₃ <- t₂ Z₃
|
||||
r.y.sum(t0, t2) # 9. Y₃ <- t₀ + t₂
|
||||
r.z *= t1 # 10. Z₃ <- t₁ Z₃
|
||||
x3.prod(t2, z3) # 8. X₃ <- t₂ Z₃
|
||||
y3.sum(t0, t2) # 9. Y₃ <- t₀ + t₂
|
||||
r.z.prod(z3, t1) # 10. Z₃ <- t₁ Z₃
|
||||
t1.double(t2) # 11. t₁ <- t₂ + t₂
|
||||
t2 += t1 # 12. t₂ <- t₁ + t₂
|
||||
t0 -= t2 # 13. t₀ <- t₀ - t₂
|
||||
r.y *= t0 # 14. Y₃ <- t₀ Y₃
|
||||
r.y += r.x # 15. Y₃ <- X₃ + Y₃
|
||||
t1.prod(P.x, snrY) # 16. t₁ <- X Y
|
||||
r.x.prod(t0, t1) # 17. X₃ <- t₀ t₁
|
||||
r.x.double() # 18. X₃ <- X₃ + X₃
|
||||
y3 *= t0 # 14. Y₃ <- t₀ Y₃
|
||||
t1.prod(P.x, snrY) # 16. t₁ <- X Y - snrY aliases P.y on Fp
|
||||
r.y.sum(y3, x3) # 15. Y₃ <- X₃ + Y₃
|
||||
x3.prod(t0, t1) # 17. X₃ <- t₀ t₁
|
||||
r.x.double(x3) # 18. X₃ <- X₃ + X₃
|
||||
else:
|
||||
{.error: "Not implemented.".}
|
||||
|
||||
func `+=`*(P: var ECP_ShortW_Prj, Q: ECP_ShortW_Prj) =
|
||||
func `+=`*(P: var ECP_ShortW_Prj, Q: ECP_ShortW_Prj) {.inline.} =
|
||||
## In-place point addition
|
||||
# TODO test for aliasing support
|
||||
var tmp {.noInit.}: ECP_ShortW_Prj
|
||||
tmp.sum(P, Q)
|
||||
P = tmp
|
||||
P.sum(P, Q)
|
||||
|
||||
func `+=`*(P: var ECP_ShortW_Prj, Q: ECP_ShortW_Aff) =
|
||||
func `+=`*(P: var ECP_ShortW_Prj, Q: ECP_ShortW_Aff) {.inline.} =
|
||||
## In-place mixed point addition
|
||||
# used in line_addition
|
||||
P.madd(P, Q)
|
||||
|
||||
func double*(P: var ECP_ShortW_Prj) =
|
||||
var tmp {.noInit.}: ECP_ShortW_Prj
|
||||
tmp.double(P)
|
||||
P = tmp
|
||||
func double*(P: var ECP_ShortW_Prj) {.inline.} =
|
||||
## In-place EC doubling
|
||||
P.double(P)
|
||||
|
||||
func diff*(r: var ECP_ShortW_Prj,
|
||||
P, Q: ECP_ShortW_Prj
|
||||
) =
|
||||
) {.inline.} =
|
||||
## r = P - Q
|
||||
## Can handle r and Q aliasing
|
||||
var nQ = Q
|
||||
nQ.neg()
|
||||
var nQ {.noInit.}: typeof(Q)
|
||||
nQ.neg(Q)
|
||||
r.sum(P, nQ)
|
||||
|
||||
func affineFromProjective*[F, Tw](
|
||||
|
Loading…
x
Reference in New Issue
Block a user