vrf.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. from streamlet.logger import Logger
  2. import random as rnd
  3. from tate_bilinear_pairing import eta, ecc
  4. from ouroboros.utils import inverse_of
  5. eta.init(369)
  6. class VRF(object):
  7. '''
  8. verifiable random function implementation
  9. '''
  10. def __init__(self):
  11. self.pk = None
  12. self.sk = None
  13. self.log = Logger(self)
  14. #TODO (res) adhoc temporary
  15. self.g = ecc.gen()
  16. self.__gen()
  17. self.order = ecc.order()
  18. def __gen(self):
  19. '''
  20. generate pk/sk
  21. '''
  22. # TODO implement that is simple sk choosing mechanism for poc;
  23. self.sk = rnd.randint(0,1000)
  24. self.pk = ecc.scalar_mult(self.sk, self.g)
  25. '''
  26. short signature without random oracle
  27. @param x: message to be signed
  28. '''
  29. def sign(self, x):
  30. pi = ecc.scalar_mult(inverse_of(x+self.sk, self.order), self.g)
  31. y = eta.pairing(*self.g[1:], *pi[1:])
  32. return (y, pi, self.g)
  33. '''
  34. verify signature
  35. @param x: signed messaged
  36. @param y: signature
  37. @param pi: [inf, x, y] proof components
  38. @param pk: [inf, x, y] public key components of the prover
  39. @param g: group base
  40. '''
  41. def verify(x, y, pi, pk_raw, g):
  42. gx = ecc.scalar_mult(x, g)
  43. #pk = ecc.scalar_mult(1, pk_raw)
  44. rhs = eta.pairing(*ecc.scalar_mult(1,g)[1:], *pi[1:])
  45. if not y == rhs:
  46. print(f"y: {y}, rhs: {rhs}")
  47. return False
  48. gxs = ecc.add(gx, pk_raw)
  49. lhs = eta.pairing(*gxs[1:], *pi[1:])
  50. rhs = eta.pairing(*ecc.scalar_mult(1, g)[1:], *ecc.scalar_mult(1, g)[1:])
  51. if not lhs==rhs:
  52. print(f"proposed {x}, {y}, {pi}, {pk_raw}, {g}")
  53. print(f"lhs: {lhs},\nrhs: {rhs}")
  54. return False
  55. return True