vrf.py 2.0 KB

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