Add difficulty verification to the verifier one

This commit is contained in:
Benjamin Loison 2023-04-16 20:19:33 +02:00
parent d6b26fa7a0
commit e81b8da855
Signed by: Benjamin_Loison
SSH Key Fingerprint: SHA256:BtnEgYTlHdOg1u+RmYcDE0mnfz1rhv5dSbQ2gyxW8B8
3 changed files with 19 additions and 10 deletions

View File

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

View File

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

View File

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