vrf.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. from msilib import type_string
  2. from logger import Logger
  3. import random as rnd
  4. from tate_bilinear_pairing import eta, ecc
  5. def extended_euclidean_algorithm(a, b):
  6. """
  7. Returns a three-tuple (gcd, x, y) such that
  8. a * x + b * y == gcd, where gcd is the greatest
  9. common divisor of a and b.
  10. This function implements the extended Euclidean
  11. algorithm and runs in O(log b) in the worst case.
  12. """
  13. s, old_s = 0, 1
  14. t, old_t = 1, 0
  15. r, old_r = b, a
  16. while r != 0:
  17. quotient = old_r // r
  18. old_r, r = r, old_r - quotient * r
  19. old_s, s = s, old_s - quotient * s
  20. old_t, t = t, old_t - quotient * t
  21. return old_r, old_s, old_t
  22. def inverse_of(n, p):
  23. """
  24. Returns the multiplicative inverse of
  25. n modulo p.
  26. This function returns an integer m such that
  27. (n * m) % p == 1.
  28. """
  29. gcd, x, y = extended_euclidean_algorithm(n, p)
  30. assert (n * x + p * y) % p == gcd
  31. if gcd != 1:
  32. # Either n is 0, or p is not a prime number.
  33. raise ValueError(
  34. '{} has no multiplicative inverse '
  35. 'modulo {}'.format(n, p))
  36. else:
  37. return x % p
  38. class VRF(object):
  39. def __init__(self):
  40. self.pk = None
  41. self.sk = None
  42. self.log = Logger(self)
  43. eta.init(rnd.randint(0,369))
  44. self.g = ecc.gen()
  45. self.password='somepasskey'
  46. self.__gen()
  47. self.order = ecc.order()
  48. def __gen(self):
  49. '''
  50. generate pk/sk
  51. '''
  52. # TODO implement that is simple sk choosing mechanism for poc;
  53. self.sk = rnd.randint(0,1000)
  54. self.pk = ecc.scalar_mult(self.sk, self.g)
  55. def prove(self, x):
  56. pi = ecc.scalar_mult(inverse_of(x+self.sk, self.order), self.g)
  57. y = eta.pairing(*self.g[1:], *pi[1:])
  58. return (y, pi)
  59. '''
  60. @param y: signed output
  61. @param pi: [inf, x, y] proof components
  62. @param pk: [inf, x, y] public key components of the prover
  63. '''
  64. def verify(self, x, y, pi, pk):
  65. gx = ecc.scalar_mult(x, self.g)
  66. pk = ecc.scalar_mult(1, pk)
  67. rhs = eta.pairing(*ecc.scalar_mult(1,self.g)[1:], *pi[1:])
  68. assert(y == rhs)
  69. gxs = ecc.add(gx, pk)
  70. lhs = eta.pairing(*gxs[1:], *pi[1:])
  71. rhs = eta.pairing(*ecc.scalar_mult(1,self.g)[1:], *ecc.scalar_mult(1,self.g)[1:])
  72. assert(lhs==rhs)
  73. vrf = VRF()
  74. x = 2
  75. y, pi = vrf.prove(x)
  76. vrf.verify(x, y, pi, vrf.pk)