From 94419db7830694baddec0b02df8196faa7b59d14 Mon Sep 17 00:00:00 2001 From: Mamy Ratsimbazafy Date: Sat, 6 Feb 2021 19:32:44 +0100 Subject: [PATCH] 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 --- .../elliptic/ec_shortweierstrass_jacobian.nim | 63 ++++---- .../ec_shortweierstrass_projective.nim | 136 +++++++++--------- 2 files changed, 100 insertions(+), 99 deletions(-) diff --git a/constantine/elliptic/ec_shortweierstrass_jacobian.nim b/constantine/elliptic/ec_shortweierstrass_jacobian.nim index 5883cc6..0febadb 100644 --- a/constantine/elliptic/ec_shortweierstrass_jacobian.nim +++ b/constantine/elliptic/ec_shortweierstrass_jacobian.nim @@ -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]( diff --git a/constantine/elliptic/ec_shortweierstrass_projective.nim b/constantine/elliptic/ec_shortweierstrass_projective.nim index 1d79df6..763a5d7 100644 --- a/constantine/elliptic/ec_shortweierstrass_projective.nim +++ b/constantine/elliptic/ec_shortweierstrass_projective.nim @@ -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](