Просмотр исходного кода

added VRF(Verifiable Random Function)

mohab 4 лет назад
Родитель
Сommit
3bf1cc4a59
1 измененных файлов с 92 добавлено и 0 удалено
  1. 92 0
      script/research/streamlet/vrf.py

+ 92 - 0
script/research/streamlet/vrf.py

@@ -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)