Skip to content

Commit

Permalink
Verify func28 (#5)
Browse files Browse the repository at this point in the history
* flat_shamir_hash

* functioning low numbers verifier

* verify function

* add test with higher delay
  • Loading branch information
programmingAthlete authored Dec 2, 2023
1 parent bf6c27d commit 2e43d73
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 11 deletions.
28 changes: 26 additions & 2 deletions src/crypto_VDF/clis/pietrzak.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,35 @@
app = typer.Typer(pretty_exceptions_show_locals=False, no_args_is_help=True)


# out 16384 delay 6 modulus 21
@app.command(name='proof')
def cmd_proof(x: int = 10, y: int = 16, delay: int = 1, modulus: int = 21, log: bool = False):
pp = PublicParams(modulus=modulus, delay=delay)
out = PietrzakVDF.compute_proof(public_params=pp, input_param=x, output_param=y, log=log)
print(out)


# x 13
@app.command(name='output')
def cmd_sol(x: int = 13, delay: int = 1, modulus: int = 21):
pp = PublicParams(modulus=modulus, delay=delay)
out = PietrzakVDF.sol(input_param=x, public_params=pp)
print(out)


@app.command(name='verify')
def cmd_verif(x: int = 16384, y: int = 6, delay: int = 1, modulus: int = 21, log: bool = False):
pp = PublicParams(modulus=modulus, delay=delay)
proof = [16]
out = PietrzakVDF.verify(public_params=pp, input_param=x, output_param=y, proof=proof, log=log)
print(out)


@app.command(name="eval")
def cmd_eval(security_parameter: int = 100, delay: int = 100):
def cmd_eval(security_parameter: int = 8, delay: int = 6):
pp = PietrzakVDF.setup(security_param=security_parameter, delay=delay)
x = PietrzakVDF.gen(pp)
y = PietrzakVDF.eval_function(public_params=pp, input_param=x)
y = PietrzakVDF.eval(public_params=pp, input_param=x)
print("Output of Eval:", y)


Expand Down
4 changes: 4 additions & 0 deletions src/crypto_VDF/utils/number_theory.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,7 @@ def generate_quadratic_residue(cls, modulus: int, max_iters: int = 1000000000) -
i += 1
raise QuadraticResidueFailed(
f"Failed to create a quadratic residue + of modulus {modulus} in {max_iters} iterations")

@staticmethod
def modular_abs(x, n):
return min(x, n - x)
38 changes: 36 additions & 2 deletions src/crypto_VDF/utils/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import hashlib


def square_sequences(a: int, steps: int, n: int) -> int:
"""
Modular exponentiation
Expand All @@ -10,9 +13,9 @@ def square_sequences(a: int, steps: int, n: int) -> int:
Returns:
a^exponent (mod n)
"""
c = abs((a * a) % n)
c = a % n
for _ in range(steps):
c *= abs((a * a) % n)
c = abs((c * c) % n)
return c


Expand Down Expand Up @@ -72,3 +75,34 @@ def base_to_10(numb: [int], base: int) -> int:
for i in range(len(numb)):
base_10 += numb[::-1][i] * base ** i
return base_10


def pad_zeros(func):
def wrapper(x):
f = func(x)
if len(f) % 2 == 0:
return f
else:
return '0' + f

return wrapper

@pad_zeros
def get_hex(x):
return '{:02x}'.format(x)


def concat_hexs(*args):
# hexs = [bytes.fromhex(get_hex(item)) for item in args]
# hex_string = b''.join(hexs).hex()
# a = int(hex_string, 16)
hexs2 = [get_hex(item) for item in args]
hex_string2 = ''.join(hexs2)
# assert a == int(hex_string2, 16)
return int(hex_string2, 16)


def flat_shamir_hash(x: int, y: int) -> int:
i = bytes.fromhex(get_hex(x)) + bytes.fromhex(get_hex(y))
h = hashlib.sha256(i).hexdigest()
return int(h, 16)
80 changes: 77 additions & 3 deletions src/crypto_VDF/verifiable_delay_functions/pietrzak.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import logging
from typing import List

from crypto_VDF.custom_errors.custom_exceptions import PrimeNumberNotFound
from crypto_VDF.data_transfer_objects.dto import PublicParams
from crypto_VDF.utils.number_theory import NumberTheory
from crypto_VDF.utils.prime_numbers import PrimNumbers
from crypto_VDF.utils.utils import concat_hexs, flat_shamir_hash, exp_modular
from crypto_VDF.verifiable_delay_functions.vdf import VDF

logging.basicConfig(level=logging.INFO)

_log = logging.getLogger(__name__)
_log.setLevel(logging.INFO)


class PietrzakVDF(VDF):

Expand All @@ -21,12 +30,77 @@ def gen(cls, public_params):
return NumberTheory.generate_quadratic_residue(public_params.modulus)

@classmethod
def eval(cls, public_params, input_param):
def sol(cls, public_params, input_param):
return cls.eval_function(public_params=public_params, input_param=input_param)

@classmethod
def verify(cls, public_params, input_param, output_param, proof=None):
pass
def eval(cls, public_params, input_param):
output = cls.eval_function(public_params=public_params, input_param=input_param)
proof = cls.compute_proof(public_params=public_params, input_param=input_param, output_param=output)
return output, proof

@classmethod
def verify(cls, public_params, input_param, output_param, proof=None, log: bool = False) -> bool:
if log is True:
_log.setLevel(logging.DEBUG)
if any(NumberTheory.check_quadratic_residue(modulus=public_params.modulus, x=item) is False for item in
[input_param, output_param]):
_log.error("Not Quadratic residues")
return False
x_i = input_param
y_i = output_param
if len(proof) == 0:
return y_i == (x_i ** 2) % public_params.modulus
for i in range(len(proof)):
t = public_params.delay / (2 ** i)
_log.debug(f"2 to t: {2 ** t}")
h_in = concat_hexs(x_i, int(2 ** t), y_i)
_log.debug(f"Hash input: {h_in}")
r_i = flat_shamir_hash(x=h_in, y=proof[i])
_log.debug(f"r_i = {r_i}")
x_i = (exp_modular(a=x_i, exponent=r_i, n=public_params.modulus) * proof[i]) % public_params.modulus
_log.info(NumberTheory.modular_abs(x_i, public_params.modulus))
y_i = (exp_modular(a=proof[i], exponent=r_i, n=public_params.modulus) * y_i) % public_params.modulus
_log.info(NumberTheory.modular_abs(y_i, public_params.modulus))
_log.debug(f"x = {x_i} and y = {y_i}")
_log.debug(f"x = {x_i} and y = {y_i}")
return y_i == exp_modular(a=x_i, exponent=2, n=public_params.modulus)

@staticmethod
def compute_proof(public_params: PublicParams, input_param, output_param, log: bool = False) -> List[int]:
if log is True:
_log.setLevel(logging.DEBUG)
x_i = input_param
y_i = output_param
_log.info(f"Initial: {(x_i ** 2) % public_params.modulus}")
mu = []
i = 1
while public_params.delay != i:
t = public_params.delay / (2 ** i)
exp = int(2 ** t)
_log.debug(f"x = {x_i}, y={y_i}, exp = {exp}")
mu_i = exp_modular(a=x_i, n=public_params.modulus, exponent=exp)
assert NumberTheory.check_quadratic_residue(modulus=public_params.modulus, x=mu_i)
_log.debug(f"mu_i = {mu_i}")

t_step = public_params.delay / (int(2 ** (i - 1)))
_log.debug(f"2 to t: {int(t_step)}")
h_in = concat_hexs(int(x_i), int(2 ** t_step), int(y_i))
_log.debug(f"Hash input: {h_in}")
r_i = flat_shamir_hash(x=h_in, y=int(mu_i))
_log.debug(f"r_i = {r_i}")

# Update x_i any y_i
x_i = (exp_modular(a=x_i, exponent=r_i, n=public_params.modulus) * mu_i) % public_params.modulus
y_i = (exp_modular(a=mu_i, exponent=r_i, n=public_params.modulus) * y_i) % public_params.modulus
_log.debug(f"x = {x_i} and y = {y_i}")
a = (x_i ** 2) % public_params.modulus
_log.debug(f"check: {a}")
a = (y_i ** (int(2 ** t))) % public_params.modulus
_log.debug(f"check: {a}")
mu.append(mu_i)
i += 1
return mu


if __name__ == '__main__':
Expand Down
54 changes: 53 additions & 1 deletion tests/test_pietraz.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,56 @@ def test_setup(self):
sec_param = 100
delay = 4
pp = PietrzakVDF.setup(security_param=sec_param, delay=delay)
self.assertTrue(isinstance(pp, PublicParams))
self.assertTrue(isinstance(pp, PublicParams))

def test_compute_verify(self):
x = 10
modulus = 21

pp = PublicParams(delay=2, modulus=modulus)
out = PietrzakVDF.sol(public_params=pp, input_param=x)
proof = PietrzakVDF.compute_proof(public_params=pp, input_param=x, output_param=out)
verification = PietrzakVDF.verify(public_params=pp, input_param=x, output_param=out, proof=proof)
self.assertTrue(verification)

pp = PublicParams(delay=4, modulus=modulus)
out = PietrzakVDF.sol(public_params=pp, input_param=x)
proof = PietrzakVDF.compute_proof(public_params=pp, input_param=x, output_param=out)
verification = PietrzakVDF.verify(public_params=pp, input_param=x, output_param=out, proof=proof)
self.assertTrue(verification)

pp = PublicParams(delay=6, modulus=modulus)
out = PietrzakVDF.sol(public_params=pp, input_param=x)
proof = PietrzakVDF.compute_proof(public_params=pp, input_param=x, output_param=out)
verification = PietrzakVDF.verify(public_params=pp, input_param=x, output_param=out, proof=proof)

self.assertTrue(verification)
pp = PublicParams(delay=8, modulus=modulus)
out = PietrzakVDF.sol(public_params=pp, input_param=x)
proof = PietrzakVDF.compute_proof(public_params=pp, input_param=x, output_param=out)
verification = PietrzakVDF.verify(public_params=pp, input_param=x, output_param=out, proof=proof)
self.assertTrue(verification)

pp = PublicParams(delay=22, modulus=modulus)
out = PietrzakVDF.sol(public_params=pp, input_param=x)
proof = PietrzakVDF.compute_proof(public_params=pp, input_param=x, output_param=out)
verification = PietrzakVDF.verify(public_params=pp, input_param=x, output_param=out, proof=proof)
self.assertTrue(verification)

pp = PublicParams(delay=102, modulus=modulus)
out = PietrzakVDF.sol(public_params=pp, input_param=x)
proof = PietrzakVDF.compute_proof(public_params=pp, input_param=x, output_param=out)
verification = PietrzakVDF.verify(public_params=pp, input_param=x, output_param=out, proof=proof)
self.assertTrue(verification)

pp = PublicParams(delay=402, modulus=modulus)
out = PietrzakVDF.sol(public_params=pp, input_param=x)
proof = PietrzakVDF.compute_proof(public_params=pp, input_param=x, output_param=out)
verification = PietrzakVDF.verify(public_params=pp, input_param=x, output_param=out, proof=proof)
self.assertTrue(verification)

pp = PublicParams(delay=602, modulus=modulus)
out = PietrzakVDF.sol(public_params=pp, input_param=x)
proof = PietrzakVDF.compute_proof(public_params=pp, input_param=x, output_param=out)
verification = PietrzakVDF.verify(public_params=pp, input_param=x, output_param=out, proof=proof)
self.assertTrue(verification)
14 changes: 11 additions & 3 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import unittest

from crypto_VDF.utils.utils import exp_modular, square_sequences
from crypto_VDF.utils.number_theory import NumberTheory
from crypto_VDF.utils.utils import exp_modular, square_sequences, concat_hexs


class TestUtils(unittest.TestCase):
Expand All @@ -18,5 +19,12 @@ def test_exp_modular(self):
def test_squaring_sequence(self):
res = square_sequences(2, 4, 3)
self.assertEqual(res, 1)


res = square_sequences(10, 1, 21)
self.assertEqual(res, 16)

def test_concat_hexs(self):
x1 = 1
x2 = 2
res = concat_hexs(1, 2)
h1, h2 = '{:02x}'.format(x1), '{:02x}'.format(x2)
self.assertEqual(int(h1 + h2, 16), res)

0 comments on commit 2e43d73

Please sign in to comment.