You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

88 lines
2.5 KiB

  1. F = GF(2^255-19)
  2. dM = F(-121665)
  3. d = F(-121665/121666)
  4. ii = sqrt(F(-1))
  5. def lobit(x): return int(x) & 1
  6. def hibit(x): return lobit(2*x)
  7. magic = sqrt(F(-121666))
  8. if lobit(magic): magic = -magic
  9. def eddsa_to_decaf(x,y):
  10. """
  11. Converts an EdDSA point to a Decaf representation, in a manner compatible
  12. with libdecaf.
  13. The input point must be even.
  14. Note well! Decaf does not represent the cofactor information of a point.
  15. So e2d(d2e(s)) = s, but d2e(e2d(x,y)) might not be (x,y).
  16. """
  17. if x*y == 0: return 0 # This will happen anyway with straightforward square root trick
  18. if not is_square((1-y)/(1+y)): raise Exception("Unimplemented: odd point in eddsa_to_decaf")
  19. if hibit(magic/(x*y)): (x,y) = (ii*y,ii*x)
  20. if hibit(2*magic/x): y = -y
  21. s = sqrt((1-y)/(1+y))
  22. if hibit(s): s = -s
  23. return s
  24. def isqrt_trick(to_isr,to_inv):
  25. to_sqrt = to_isr*to_inv^2
  26. if to_sqrt == 0: return 0,0 # This happens automatically in C; just to avoid problems in SAGE
  27. if not is_square(to_sqrt): raise Exception("Not square in isqrt_trick!")
  28. tmp = 1/sqrt(to_sqrt)
  29. isr = tmp * to_inv
  30. inv = tmp * isr * to_isr
  31. assert isr^2 == 1/to_isr
  32. assert inv == 1/to_inv
  33. return isr, inv
  34. def eddsa_to_decaf_opt(x,y,z=None):
  35. """
  36. Optimized version of eddsa_to_decaf.
  37. Uses only one isqrt.
  38. """
  39. if z is None:
  40. # Pretend that we're in projective
  41. z = F.random_element()
  42. x *= z
  43. y *= z
  44. isr,inv = isqrt_trick(z^2-y^2,x*y)
  45. inv *= magic
  46. rotate = hibit(inv*z^2)
  47. if rotate:
  48. isr *= (z^2-y^2)*inv
  49. y = ii*x
  50. if hibit(2*inv*y*z) != rotate: y = -y
  51. s = (z-y) * isr
  52. if hibit(s): s = -s
  53. return s
  54. print [eddsa_to_decaf_opt(x,y) == eddsa_to_decaf(x,y) for _,_,_,_,y1,y2 in points for x,y in [decode(y1,y2)]]
  55. def decaf_to_eddsa(s):
  56. """
  57. Convert a Decaf representation to an EdDSA point, in a manner compatible
  58. with libdecaf.
  59. Note well! The Decaf representation of a point is canonical, but the EdDSA one
  60. is not, in that
  61. """
  62. if s == 0: return (0,1)
  63. if hibit(s): raise Exception("invalid: s has high bit")
  64. if not is_square(s^4 + (2-4*dM)*s^2 + 1): raise Exception("invalid: not on curve")
  65. t = sqrt(s^4 + (2-4*dM)*s^2 + 1)/s
  66. if hibit(t): t = -t
  67. y = (1-s^2)/(1+s^2)
  68. x = 2*magic/t
  69. if y == 0 or lobit(t/y): raise Exception("invalid: t/y has high bit")
  70. assert y^2 - x^2 == 1+d*x^2*y^2
  71. return (x,y)