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.

87 lines
2.1 KiB

  1. # Implementation of: https://sci-hub.se/10.1109/iccke.2013.6682844
  2. # more details at: https://arnaucube.com/blog/blind-signatures-ec.html#the-scheme
  3. # A Go implementation of this schema can be found at: https://github.com/arnaucube/go-blindsecp256k1
  4. from hashlib import sha256
  5. def hash(m):
  6. h_output = sha256(str(m).encode('utf-8'))
  7. return int(h_output.hexdigest(), 16)
  8. class User:
  9. def __init__(self, F, G):
  10. self.F = F # Z_q
  11. self.G = G # elliptic curve generator
  12. def blind_msg(self, m, R_):
  13. self.a = self.F.random_element()
  14. self.b = self.F.random_element()
  15. self.R = self.a * R_ + self.b * self.G
  16. m_ = self.F(self.a)^(-1) * self.F(self.R.xy()[0]) * self.F(hash(m))
  17. return m_
  18. def unblind_sig(self, s_):
  19. s = self.a * s_ + self.b
  20. return (self.R, s)
  21. class Signer:
  22. def __init__(self, F, G):
  23. self.F = F # Z_q
  24. self.G = G # elliptic curve generator
  25. # gen Signer's key pair
  26. self.d = self.F.random_element()
  27. self.Q = self.G * self.d
  28. def new_request_params(self):
  29. self.k = self.F.random_element()
  30. R_ = self.G * self.k
  31. return R_
  32. def blind_sign(self, m_):
  33. return self.d * m_ + self.k
  34. def verify(G, Q, sig, m):
  35. (R, s) = sig
  36. return s*G == R + (Fq(R.xy()[0]) * Fq(hash(m))) * Q
  37. # ethereum elliptic curve
  38. p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F # base field
  39. a = 0
  40. b = 7
  41. F = GF(p) # base field
  42. E = EllipticCurve(F, [a,b])
  43. GX = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
  44. GY = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
  45. g = E(GX,GY)
  46. n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
  47. q = g.order() # order of Fp
  48. assert is_prime(p)
  49. assert is_prime(q)
  50. Fq = GF(q) # scalar field
  51. # protocol flow:
  52. user = User(Fq, g)
  53. signer = Signer(Fq, g)
  54. R_ = signer.new_request_params()
  55. m = 12345 # user's message
  56. m_ = user.blind_msg(m, R_)
  57. s_ = signer.blind_sign(m_)
  58. sig = user.unblind_sig(s_)
  59. v = verify(g, signer.Q, sig, m)
  60. print(v)
  61. assert v