mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 14:48:08 -05:00
added VRF(Verifiable Random Function)
This commit is contained in:
92
script/research/streamlet/vrf.py
Normal file
92
script/research/streamlet/vrf.py
Normal 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)
|
||||
Reference in New Issue
Block a user