From e81b8da855499c4902dff34780b2e196c57bc45a Mon Sep 17 00:00:00 2001 From: Benjamin Loison Date: Sun, 16 Apr 2023 20:19:33 +0200 Subject: [PATCH] Add difficulty verification to the verifier one --- common.py | 9 ++++++++- prover.py | 11 +++++------ verifier.py | 9 ++++++--- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/common.py b/common.py index 0fa6fe7..0f4cd0a 100644 --- a/common.py +++ b/common.py @@ -8,6 +8,8 @@ MAXIMUM_HASH_DIFFICULTY = 1 / 16 # The following space is a minimum. SPACE_TO_PROVE_IN_BITS = 1_000 +LEAST_DIFFICULT_HASH = int('F' * (SECURITY_PARAMETER // 4), 16) + NUMBER_OF_BITS_IN_AVERAGE_FOR_SOLVING_PUZZLE = int(math.log2(1 / MAXIMUM_HASH_DIFFICULTY)) ENTRIES_NUMBER = math.ceil(SPACE_TO_PROVE_IN_BITS // NUMBER_OF_BITS_IN_AVERAGE_FOR_SOLVING_PUZZLE) # To ease Merkle tree implementation use a power of 2 number of leafs. @@ -24,4 +26,9 @@ def numberOfBitsOf(n): return math.floor(math.log2(n)) + 1 def otherIndex(n): - return n + (1 if n % 2 == 0 else -1) \ No newline at end of file + return n + (1 if n % 2 == 0 else -1) + +def doesHashMatchDifficulty(hashed): + hashedInteger = int(hashed, 16) + hashedDifficulty = hashedInteger / LEAST_DIFFICULT_HASH + return hashedDifficulty <= MAXIMUM_HASH_DIFFICULTY \ No newline at end of file diff --git a/prover.py b/prover.py index cb88ee2..6247131 100755 --- a/prover.py +++ b/prover.py @@ -19,14 +19,10 @@ STORED_NONCES = [] counter = 0 lastCounter = 0 -LEAST_DIFFICULT_HASH = int('F' * (common.SECURITY_PARAMETER // 4), 16) - # We enforce `STORED_NONCES` to have its length being a power of 2, to ease Merkle tree implementation. while len(STORED_NONCES) < common.ENTRIES_NUMBER: hashed = common.hash(protocolInitializationPhaseId + str(counter)) - hashedInteger = int(hashed, 16) - hashedDifficulty = hashedInteger / LEAST_DIFFICULT_HASH - if hashedDifficulty <= common.MAXIMUM_HASH_DIFFICULTY: + if common.doesHashMatchDifficulty(hashed): deltaCounter = counter - lastCounter STORED_NONCES += [deltaCounter] lastCounter = counter @@ -90,6 +86,7 @@ for indexRequest in indexesRequest: for index in [indexRequest, otherIndex]: verificationMerkleTreeLevels[0][index] = merkleTreeLevels[0][index] +# Should rename `entries`, as they aren't *entries* for higher levels. entries = [] for verificationMerkleTreeLevelsIndex, verificationMerkleTreeLevel in enumerate(verificationMerkleTreeLevels[:-1]): for index in verificationMerkleTreeLevel: @@ -100,7 +97,9 @@ for verificationMerkleTreeLevelsIndex, verificationMerkleTreeLevel in enumerate( verificationMerkleTreeLevels[verificationMerkleTreeLevelsIndex + 1][leftIndex // 2] = common.hash(leftHash + rightHash) if verificationMerkleTreeLevelsIndex > 0 or leftIndex == index: if verificationMerkleTreeLevelsIndex == 0: - entries += [leftHash, rightHash] + leftNonce = sum(STORED_NONCES[:leftIndex + 1]) + rightNonce = leftNonce + STORED_NONCES[rightIndex] + entries += [leftNonce, rightNonce] else: entries += [otherHash] diff --git a/verifier.py b/verifier.py index 0a1f7ee..078931d 100755 --- a/verifier.py +++ b/verifier.py @@ -46,7 +46,6 @@ print(f'{indexesRequest=}') # Add mentions of rationality and code its factor? or/and precise when to run initialization and execution phases # TODO: precising `entries` size could be interesting. -# TODO: verify hash difficulty - requires to send actual nonces # Proceeding in a minimum number of passes could be interesting but this can be left for future work. entries = ast.literal_eval(input('entries: ')) @@ -56,8 +55,12 @@ merkleTreeLevels = [{} for _ in range(common.LEVELS)] for index in indexesRequest: otherIndex = common.otherIndex(index) leftIndex, rightIndex = sorted([index, otherIndex]) - for i, hash in zip([leftIndex, rightIndex], [entries.pop(0) for _ in range(2)]): - merkleTreeLevels[0][i] = hash + for i, nonce in zip([leftIndex, rightIndex], [entries.pop(0) for _ in range(2)]): + hashed = common.hash(protocolInitializationPhaseId + str(nonce)) + if not common.doesHashMatchDifficulty(hashed): + print("The received difficulty doesn't match the claimed one!'") + exit(1) + merkleTreeLevels[0][i] = common.hash(protocolInitializationPhaseId + protocolExecutionPhaseId + str(nonce)) for merkleTreeLevelsIndex, merkleTreeLevel in enumerate(merkleTreeLevels[:-1]): for index in merkleTreeLevel.copy():