proof.sage 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. # First run div2.sage to generate the function and points which
  2. # are loaded below.
  3. p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
  4. r = 115792089237316195423570985008687907852837564279074904382605163141518161494337
  5. Fp = GF(p) # Base Field
  6. Fr = GF(r) # Scalar Field
  7. A = 0
  8. B = 7
  9. E = EllipticCurve(GF(p), [A, B])
  10. assert(E.cardinality() == r)
  11. K.<x> = PolynomialRing(Fp, implementation="generic")
  12. L.<y> = PolynomialRing(K, implementation="generic")
  13. M.<z> = L[]
  14. eqn = y^2 - x^3 - A * x - B
  15. def slope_intercept(P1, P2):
  16. P1x, P1y = P1.xy()
  17. P2x, P2y = P2.xy()
  18. P3x, P3y = (-(P1 + P2)).xy()
  19. λ = (P2y - P1y) / (P2x - P1x)
  20. μ = P2y - λ*P2x
  21. return λ, μ
  22. A0 = E.random_element()
  23. A1 = E.random_element()
  24. A2 = -(A0 + A1)
  25. [P0, P1, P2, Q, f] = load("div.sobj")
  26. λ, μ = slope_intercept(A0, A1)
  27. g = y - λ*x - μ
  28. class Func:
  29. def __init__(self, func):
  30. self.func = func
  31. def __call__(self, P):
  32. Px, Py = P.xy()
  33. return self.func(x=Px, y=Py)
  34. f = Func(f)
  35. g = Func(g)
  36. # We can actually compute this check in a more efficient way
  37. assert f(A0) * f(A1) * f(A2) == -g(P0) * g(P1)^2 * g(P2)^3 * g(Q)^5
  38. def dlog(D):
  39. Dx = D.differentiate(x)
  40. Dy = D.differentiate(y)
  41. #Dz = Dx + Dy * ((3*x^2 + A) / (2*y))
  42. # Normally we calculate:
  43. # Dz/D
  44. # Due to a bug in sage, we will make the denominator D
  45. # solely an equation in x by taking its norm.
  46. # Denominator = V · V'
  47. V = 2*y * D
  48. # 2y Dz
  49. Dz_numer = ( (2*y*Dx + Dy * (3*x^2 + A)) * V(y=-y) ).mod(eqn)
  50. # Change denominator to the norm
  51. D_denom = (V * V(y=-y)).mod(eqn)
  52. return Dz_numer / D_denom
  53. # Just confirm results from the paper
  54. assert λ^2 == A0[0] + A1[0] + A2[0]
  55. dy_dx = (3*x^2 + A)/(2*y)
  56. dx_dz = 1/(dy_dx - λ)
  57. dx_dz = Func(dx_dz)
  58. assert dx_dz(A0) + dx_dz(A1) + dx_dz(A2) == 0
  59. # These are the actual checks
  60. Dlog = dlog(f.func)
  61. # Another way to calculate dlog:
  62. #D = f.func
  63. #a_X = K(D(y=0))
  64. #b_X = K(D(y=1) - a_X)
  65. #assert D == a_X + y*b_X
  66. #diff_f = a_X.differentiate(x) + dy_dx*b_X + y*b_X.differentiate(x)
  67. #assert diff_f == D.differentiate(x) + D.differentiate(y)*dy_dx
  68. #diff_f = Func(diff_f)
  69. F = Func(Dlog * dx_dz.func)
  70. G = Func(-1/g.func)
  71. # The prover constructs a proof of this relation being true
  72. assert F(A0) + F(A1) + F(A2) == G(P0) + 2*G(P1) + 3*G(P2) + 5*G(Q)