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.

94 lines
2.5 KiB

  1. from hashlib import sha256
  2. # Ring Signatures
  3. # bLSAG: Back’s Linkable Spontaneous Anonymous Group signatures
  4. def hashToPoint(a):
  5. # TODO use a proper hash-to-point
  6. h = sha256((str(a)).encode('utf-8'))
  7. r = int(h.hexdigest(), 16) * g
  8. return r
  9. def hash(R, m, A, B, q):
  10. h = sha256((
  11. str(R) + str(m) + str(A) + str(B)
  12. ).encode('utf-8'))
  13. r = int(h.hexdigest(), 16)
  14. return int(mod(r, q))
  15. def print_ring(a):
  16. print("ring of c's:")
  17. for i in range(len(a)):
  18. print(i, a[i])
  19. print("")
  20. class Prover(object):
  21. def __init__(self, F, g):
  22. self.F = F # Z_p
  23. self.g = g # elliptic curve generator
  24. self.q = self.g.order() # order of group
  25. def new_key(self):
  26. self.w = int(self.F.random_element())
  27. self.K = self.g * self.w
  28. return self.K
  29. def sign(self, m, R):
  30. # determine pi (the position of signer's public key in R
  31. pi = -1
  32. for i in range(len(R)):
  33. if self.K == R[i]:
  34. pi = i
  35. break
  36. assert pi>=0
  37. a = int(self.F.random_element())
  38. r = [None] * len(R)
  39. # for i \in {1, 2, ..., n} \ {i=pi}
  40. for i in range(0, len(R)):
  41. if i==pi:
  42. continue
  43. r[i] = int(mod(int(self.F.random_element()), self.q))
  44. c = [None] * len(R)
  45. # c_{pi+1}
  46. pi1 = mod(pi + 1, len(R))
  47. c[pi1] = hash(R, m, a * self.g, a * hashToPoint(R[pi]), self.q)
  48. key_image = self.w * hashToPoint(self.K)
  49. # do c_{i+1} from i=pi+1 to pi-1:
  50. # for j in range(0, len(R)-1):
  51. for j in range(0, len(R)-1):
  52. i = mod(pi1+j, len(R))
  53. i1 = mod(pi1+j +1, len(R))
  54. c[i1] = hash(R, m, r[i] * self.g + c[i] * R[i], r[i] * hashToPoint(R[i]) + c[i] * key_image, self.q)
  55. # compute r_pi
  56. r[pi] = int(mod(a - c[pi] * self.w, self.q))
  57. print_ring(c)
  58. return [c[0], r]
  59. def verify(g, R, m, key_image, sig):
  60. q = g.order()
  61. c1 = sig[0]
  62. r = sig[1]
  63. assert len(R) == len(r)
  64. # check that key_image \in G (EC), by l * key_image == 0
  65. assert q * key_image == 0 # in sage 0 EC point is interpreted as (0:1:0)
  66. # for i \in 1,2,...,n
  67. c = [None] * len(R)
  68. c[0] = c1
  69. for j in range(0, len(R)):
  70. i = mod(j, len(R))
  71. i1 = mod(j+1, len(R))
  72. c[i1] = hash(R, m, r[i] * g + c[i] * R[i], r[i] * hashToPoint(R[i]) + c[i] * key_image, q)
  73. print_ring(c)
  74. assert c1 == c[0]