diff --git a/README.md b/README.md index bda2210..43a63a7 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,30 @@

mimcvdf ⏲️

-

Simple Verifiable Delay Function using MiMC

+

Simple Verifiable Delay Function using MiMC

## Applications This module was created for use in reducing spam in a similar manner to [HashCash](https://en.wikipedia.org/wiki/Hashcash). However, some potential uses for VDFs include blockchains and verifiable lotteries. +## Usage + +``` +from mimchash import vdf_create, vdf_verify + + +# Get a mimc hash of a byte sequence + +vdf_create(byte_data, round_count) # Returns hex string + + +# Verify a mimc hash (must use same round count) + +vdf_verify(same_bytes_data, vdf_create_result, rounds) + +``` + + ## Security diff --git a/mimcvdf/__init__.py b/mimcvdf/__init__.py index 1ec393f..ac7bde0 100644 --- a/mimcvdf/__init__.py +++ b/mimcvdf/__init__.py @@ -32,7 +32,7 @@ def _sha3_256_hash(data: bytes) -> str: def vdf_create(data: bytes, rounds: int = DEFAULT_ROUNDS) -> str: - assert rounds > 0 + assert rounds > 1 input_hash = int(_sha3_256_hash(data), 16) return hex(forward_mimc(input_hash, rounds)).replace('0x', '') @@ -42,22 +42,33 @@ def vdf_verify( test_hash: Union[str, bytes], rounds: int = DEFAULT_ROUNDS) -> bool: """Verify data for test_hash generated by vdf_create.""" - assert rounds > 0 + assert rounds > 1 return _sha3_256_hash(data) == \ hex(reverse_mimc(int(test_hash, 16), rounds)).replace('0x', '') -def profile_cpu_speed(rounds=1000, seconds=1) -> float: - time_results = [] - for _ in range(10000): - start = time.time() - vdf_create(b"t", rounds) - end = time.time() - time_results.append(end - start) - return (seconds / mean(time_results) * 1000) +def profile_cpu_speed(seconds=1) -> float: + n = 2 + start = time.time() + done = False + results = [] + try: + for _ in range(20): + done = False + n = 2 + start = time.time() + while not done: + vdf_create(b't', n) + if time.time() - start >= seconds: + break + n += 1 + results.append(n) + except KeyboardInterrupt: + pass + return ceil(mean(results)) if __name__ == "__main__": print("Calculate how may rounds are needed for X seconds (influenced by system processes): ") seconds = int(input("Seconds: ")) - print("Rounds:", ceil(profile_cpu_speed())) + print("Rounds:", profile_cpu_speed(seconds)) diff --git a/tests/test_mimc.py b/tests/test_mimc.py new file mode 100644 index 0000000..a076525 --- /dev/null +++ b/tests/test_mimc.py @@ -0,0 +1,27 @@ +import sys +import os +sys.path.append('..') +import unittest +import time +from hashlib import sha3_256 + +import mimcvdf.mimc + +class TestMimc(unittest.TestCase): + + def test_bytes(self): + start = time.time() + data = b"a" * 6000000 + h = sha3_256() + h.update(data) + data = int(h.hexdigest(), 16) + + forw = mimcvdf.forward_mimc(data, 2000) + + rev = mimcvdf.reverse_mimc(forw, 2000) + + print(data) + print(forw, rev) + self.assertEqual(rev, data) + +unittest.main() \ No newline at end of file diff --git a/tests/test_vdf.py b/tests/test_vdf.py index d7b257e..e3d1d4a 100644 --- a/tests/test_vdf.py +++ b/tests/test_vdf.py @@ -2,7 +2,7 @@ import sys import os sys.path.append('..') import unittest -import timeit +from time import time import mimcvdf @@ -19,11 +19,8 @@ class TestVDF(unittest.TestCase): def test_above_zero_rounds(self): self.assertRaises(AssertionError, mimcvdf.vdf_create, b"test", 0) self.assertRaises(AssertionError, mimcvdf.vdf_create, b"test", -1) + self.assertRaises(AssertionError, mimcvdf.vdf_create, b"test", 1) self.assertRaises(AssertionError, mimcvdf.vdf_create, b"test", -10000) - def test_profile(self): - rand = os.urandom(1000) - self.assertAlmostEqual(timeit.timeit(lambda: mimcvdf.vdf_create(b"test", 1000), number=100), mimcvdf.profile_cpu_speed(1000), places=2) - self.assertAlmostEqual(timeit.timeit(lambda: mimcvdf.vdf_create(rand, 1000), number=100), mimcvdf.profile_cpu_speed(1000), places=2) unittest.main() \ No newline at end of file