added VRF(Verifiable Random Function)

This commit is contained in:
mohab
2022-01-29 13:34:22 +02:00
parent 9ddd8cb4a1
commit 3bf1cc4a59

View File

@@ -0,0 +1,92 @@
from msilib import type_string
from logger import Logger
import random as rnd
from tate_bilinear_pairing import eta, ecc
def extended_euclidean_algorithm(a, b):
"""
Returns a three-tuple (gcd, x, y) such that
a * x + b * y == gcd, where gcd is the greatest
common divisor of a and b.
This function implements the extended Euclidean
algorithm and runs in O(log b) in the worst case.
"""
s, old_s = 0, 1
t, old_t = 1, 0
r, old_r = b, a
while r != 0:
quotient = old_r // r
old_r, r = r, old_r - quotient * r
old_s, s = s, old_s - quotient * s
old_t, t = t, old_t - quotient * t
return old_r, old_s, old_t
def inverse_of(n, p):
"""
Returns the multiplicative inverse of
n modulo p.
This function returns an integer m such that
(n * m) % p == 1.
"""
gcd, x, y = extended_euclidean_algorithm(n, p)
assert (n * x + p * y) % p == gcd
if gcd != 1:
# Either n is 0, or p is not a prime number.
raise ValueError(
'{} has no multiplicative inverse '
'modulo {}'.format(n, p))
else:
return x % p
class VRF(object):
def __init__(self):
self.pk = None
self.sk = None
self.log = Logger(self)
eta.init(rnd.randint(0,369))
self.g = ecc.gen()
self.password='somepasskey'
self.__gen()
self.order = ecc.order()
def __gen(self):
'''
generate pk/sk
'''
# TODO implement that is simple sk choosing mechanism for poc;
self.sk = rnd.randint(0,1000)
self.pk = ecc.scalar_mult(self.sk, self.g)
def prove(self, x):
pi = ecc.scalar_mult(inverse_of(x+self.sk, self.order), self.g)
y = eta.pairing(*self.g[1:], *pi[1:])
return (y, pi)
'''
@param y: signed output
@param pi: [inf, x, y] proof components
@param pk: [inf, x, y] public key components of the prover
'''
def verify(self, x, y, pi, pk):
gx = ecc.scalar_mult(x, self.g)
pk = ecc.scalar_mult(1, pk)
rhs = eta.pairing(*ecc.scalar_mult(1,self.g)[1:], *pi[1:])
assert(y == rhs)
gxs = ecc.add(gx, pk)
lhs = eta.pairing(*gxs[1:], *pi[1:])
rhs = eta.pairing(*ecc.scalar_mult(1,self.g)[1:], *ecc.scalar_mult(1,self.g)[1:])
assert(lhs==rhs)
vrf = VRF()
x = 2
y, pi = vrf.prove(x)
vrf.verify(x, y, pi, vrf.pk)