vrf.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. from ouroboros.logger import Logger
  2. import random as rnd
  3. from tate_bilinear_pairing import eta, ecc
  4. from ouroboros.utils import inverse_of
  5. from ouroboros.utils import vrf_hash
  6. eta.init(369)
  7. '''
  8. verify signature
  9. @param x: signed messaged
  10. @param y: signature
  11. @param pi: [inf, x, y] proof components
  12. @param pk: [inf, x, y] public key components of the prover
  13. @param g: group base
  14. '''
  15. def verify(x, y, pi, pk_raw, g):
  16. gx = ecc.scalar_mult(x, g)
  17. rhs = eta.pairing(*ecc.scalar_mult(1,g)[1:], *pi[1:])
  18. if not y == rhs:
  19. print(f"y: {y}, rhs: {rhs}")
  20. return False
  21. gxs = ecc.add(gx, pk_raw)
  22. lhs = eta.pairing(*gxs[1:], *pi[1:])
  23. rhs = eta.pairing(*ecc.scalar_mult(1, g)[1:], *ecc.scalar_mult(1, g)[1:])
  24. if not lhs==rhs:
  25. print(f"proposed {x}, {y}, {pi}, {pk_raw}, {g}")
  26. print(f"lhs: {lhs},\nrhs: {rhs}")
  27. return False
  28. return True
  29. class VRF(object):
  30. '''
  31. verifiable random function implementation
  32. '''
  33. def __init__(self, seed):
  34. self.log = Logger(self)
  35. self.order = ecc.order()
  36. #TODO use ecc to gen sk
  37. sk = vrf_hash(seed) % self.order
  38. g = ecc.gen()
  39. pk = ecc.scalar_mult(sk, g)
  40. #
  41. self.pk = pk
  42. self.sk = sk
  43. self.g=g
  44. '''
  45. short signature without random oracle
  46. @param x: message to be signed
  47. @return y (the signature), pi (the proof)
  48. '''
  49. def sign(self, x):
  50. pi = ecc.scalar_mult(inverse_of(x+self.sk, self.order), self.g)
  51. y = eta.pairing(*self.g[1:], *pi[1:])
  52. return (y, pi)
  53. def update(self, pk, sk, g):
  54. self.pk = pk
  55. self.sk = sk
  56. self.g = g
  57. '''
  58. verify signature
  59. @param x: signed messaged
  60. @param y: signature
  61. @param pi: [inf, x, y] proof components
  62. '''
  63. def verify(self, x, y, pi):
  64. gx = ecc.scalar_mult(x, self.g)
  65. rhs = eta.pairing(*ecc.scalar_mult(1,self.g)[1:], *pi[1:])
  66. if not y == rhs:
  67. print(f"y: {y}, rhs: {rhs}")
  68. return False
  69. gxs = ecc.add(gx, self.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. if not lhs==rhs:
  73. print(f"proposed {x}, {y}, {pi}, {self.pk}, {self.g}")
  74. print(f"lhs: {lhs},\nrhs: {rhs}")
  75. return False
  76. return True