vrf.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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. gernate vrf keys for stakeholder
  9. @param sk_seed: this is suppoed to be the password of the stakeholder
  10. '''
  11. def generate_vrf_keys(sk_seed):
  12. '''
  13. generate pk/sk
  14. return: list of pk (public key), sk(secret key), base(field base)
  15. '''
  16. #sk = vrf_hash(sk_seed)
  17. sk=2
  18. base = ecc.gen()
  19. pk = ecc.scalar_mult(sk, base)
  20. return (pk, sk, base)
  21. class VRF(object):
  22. '''
  23. verifiable random function implementation
  24. '''
  25. def __init__(self, pk, sk, base):
  26. self.pk = pk
  27. self.sk = sk
  28. self.g=base
  29. self.log = Logger(self)
  30. self.order = ecc.order()
  31. '''
  32. short signature without random oracle
  33. @param x: message to be signed
  34. @return y (the signature), pi (the proof)
  35. '''
  36. def sign(self, x):
  37. pi = ecc.scalar_mult(inverse_of(x+self.sk, self.order), self.g)
  38. y = eta.pairing(*self.g[1:], *pi[1:])
  39. return (y, pi)
  40. def update(self, pk, sk, g):
  41. self.pk = pk
  42. self.sk = sk
  43. self.g = g
  44. '''
  45. verify signature
  46. @param x: signed messaged
  47. @param y: signature
  48. @param pi: [inf, x, y] proof components
  49. @param pk: [inf, x, y] public key components of the prover
  50. @param g: group base
  51. '''
  52. def verify(x, y, pi, pk_raw, g):
  53. gx = ecc.scalar_mult(x, g)
  54. #pk = ecc.scalar_mult(1, pk_raw)
  55. rhs = eta.pairing(*ecc.scalar_mult(1,g)[1:], *pi[1:])
  56. if not y == rhs:
  57. print(f"y: {y}, rhs: {rhs}")
  58. return False
  59. gxs = ecc.add(gx, pk_raw)
  60. lhs = eta.pairing(*gxs[1:], *pi[1:])
  61. rhs = eta.pairing(*ecc.scalar_mult(1, g)[1:], *ecc.scalar_mult(1, g)[1:])
  62. if not lhs==rhs:
  63. print(f"proposed {x}, {y}, {pi}, {pk_raw}, {g}")
  64. print(f"lhs: {lhs},\nrhs: {rhs}")
  65. return False
  66. return True