This commit is contained in:
parent
e81b8da855
commit
2196afc414
20
common.py
20
common.py
@ -2,20 +2,34 @@ import math
|
||||
from hashlib import sha256
|
||||
|
||||
SECURITY_PARAMETER = 256
|
||||
# Note that `MAXIMUM_HASH_DIFFICULTY` and `SPACE_TO_PROVE_IN_BITS` should be sent from the prover to the verifier before the second verifier initialization step. However to ease this prototype this communication isn't performed.
|
||||
# Note that notably `MAXIMUM_HASH_DIFFICULTY` and `SPACE_TO_PROVE_IN_BITS` should be sent from the prover to the verifier before the second verifier initialization step. However to ease this prototype this communication isn't performed.
|
||||
# For the ease of this prototype only 1 / (2 ** n) values are supported for `MAXIMUM_HASH_DIFFICULTY`.
|
||||
MAXIMUM_HASH_DIFFICULTY = 1 / 16
|
||||
# The following space is a minimum.
|
||||
SPACE_TO_PROVE_IN_BITS = 1_000
|
||||
INITIAL_SPACE_TO_PROVE_IN_BITS = 10_000
|
||||
SPACE_TO_PROVE_IN_BITS = 10_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)
|
||||
|
||||
PROBABILITY_TO_CATCH_MALICIOUS = 1 - 2 ** -1
|
||||
# Let's hardcode that we dedicate 1% of extra storage for the proof probability.
|
||||
SPACE_UPPER_BOUND_IN_BITS_POTENTIALLY_MALICIOUS = math.ceil(SPACE_TO_PROVE_IN_BITS / 100)
|
||||
|
||||
PROBABILITY_NOT_TO_CATCH_MALICIOUS_WITH_ONE_QUERY = (SPACE_TO_PROVE_IN_BITS - SPACE_UPPER_BOUND_IN_BITS_POTENTIALLY_MALICIOUS) / SPACE_TO_PROVE_IN_BITS
|
||||
|
||||
NUMBER_OF_BITS_TO_VERIFY = math.ceil(math.log(1 - PROBABILITY_TO_CATCH_MALICIOUS) / math.log(PROBABILITY_NOT_TO_CATCH_MALICIOUS_WITH_ONE_QUERY))
|
||||
NUMBER_OF_ENTRIES_TO_VERIFY = math.ceil(NUMBER_OF_BITS_TO_VERIFY / NUMBER_OF_BITS_IN_AVERAGE_FOR_SOLVING_PUZZLE)
|
||||
|
||||
SPACE_TO_PROVE_IN_BITS = math.ceil(SPACE_TO_PROVE_IN_BITS + SPACE_UPPER_BOUND_IN_BITS_POTENTIALLY_MALICIOUS)
|
||||
|
||||
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.
|
||||
ENTRIES_NUMBER = 2 ** math.ceil(math.log2(ENTRIES_NUMBER))
|
||||
LEVELS = int(math.log2(ENTRIES_NUMBER)) + 1
|
||||
|
||||
# Do we have a problem due to length extension attacks? If so, could sha256 one more time as in Bitcoin.
|
||||
def hash(x):
|
||||
return sha256(x.encode('ascii')).hexdigest()
|
||||
|
||||
|
10
prover.py
10
prover.py
@ -62,7 +62,8 @@ print(f'{merkleTreeRoot=}')
|
||||
|
||||
## Execution phase: 3. Receive a random set of indexes from the verifier.
|
||||
|
||||
indexesRequest = ast.literal_eval(input('indexesRequest: '))
|
||||
with open(input('indexesRequest: ')) as f:
|
||||
indexesRequest = ast.literal_eval(f.read())
|
||||
|
||||
## Execution phase: 4. Respond with the corresponding table entries and commitment openings.
|
||||
|
||||
@ -103,5 +104,10 @@ for verificationMerkleTreeLevelsIndex, verificationMerkleTreeLevel in enumerate(
|
||||
else:
|
||||
entries += [otherHash]
|
||||
|
||||
print(f'{entries=}')
|
||||
entriesFilePath = 'entries.txt'
|
||||
|
||||
with open(entriesFilePath, 'w') as f:
|
||||
f.write(str(entries))
|
||||
|
||||
print(f'entries: {entriesFilePath}')
|
||||
|
||||
|
22
verifier.py
22
verifier.py
@ -4,11 +4,6 @@
|
||||
|
||||
import secrets, common, ast
|
||||
|
||||
# Propose a probability of confidence setting is left for future work.
|
||||
# Is actually a fraction giving a constant probability of confidence no matter the number of entries? I mean doesn't a constant number of entries to verify doesn't provide such a constant probability even for various number of entries?
|
||||
# Have to address this scalability issue.
|
||||
FRACTION_OF_SPACE_TO_VERIFY = 10 ** -2
|
||||
|
||||
## Initialization phase: Generate a random bitstring to send to the prover.
|
||||
# To make sure that the following protocol execution can't be used partially or totally by the prover to reduce the cost of another protocol execution.
|
||||
|
||||
@ -35,11 +30,16 @@ merkleTreeRoot = input('merkleTreeRoot: ')
|
||||
|
||||
indexesRequest = set()
|
||||
|
||||
while len(indexesRequest) < common.ENTRIES_NUMBER * FRACTION_OF_SPACE_TO_VERIFY:
|
||||
while len(indexesRequest) < common.NUMBER_OF_ENTRIES_TO_VERIFY:
|
||||
index = secrets.randbelow(common.ENTRIES_NUMBER)
|
||||
indexesRequest.add(index)
|
||||
|
||||
print(f'{indexesRequest=}')
|
||||
indexesRequestFilePath = 'indexesRequest.txt'
|
||||
|
||||
with open(indexesRequestFilePath, 'w') as f:
|
||||
f.write(str(indexesRequest))
|
||||
|
||||
print(f'indexesRequest: {indexesRequestFilePath}')
|
||||
|
||||
## Execution phase: 4. Receive and verify corresponding table entries and commitment openings.
|
||||
|
||||
@ -48,7 +48,8 @@ print(f'{indexesRequest=}')
|
||||
|
||||
# Proceeding in a minimum number of passes could be interesting but this can be left for future work.
|
||||
|
||||
entries = ast.literal_eval(input('entries: '))
|
||||
with open(input('entries: ')) as f:
|
||||
entries = ast.literal_eval(f.read())
|
||||
|
||||
merkleTreeLevels = [{} for _ in range(common.LEVELS)]
|
||||
|
||||
@ -58,7 +59,7 @@ for index in indexesRequest:
|
||||
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!'")
|
||||
print("The received difficulty doesn't match the claimed one!")
|
||||
exit(1)
|
||||
merkleTreeLevels[0][i] = common.hash(protocolInitializationPhaseId + protocolExecutionPhaseId + str(nonce))
|
||||
|
||||
@ -76,8 +77,7 @@ for merkleTreeLevelsIndex, merkleTreeLevel in enumerate(merkleTreeLevels[:-1]):
|
||||
actualStorage = common.ENTRIES_NUMBER * common.NUMBER_OF_BITS_IN_AVERAGE_FOR_SOLVING_PUZZLE
|
||||
|
||||
if merkleTreeRoot == merkleTreeLevels[-1][0] and actualStorage >= common.SPACE_TO_PROVE_IN_BITS:
|
||||
# Could precise the probability.
|
||||
print(f'Verified with some probability that the prover is storing in average {common.SPACE_TO_PROVE_IN_BITS} (actually the prover is storing in average {actualStorage} bits)')
|
||||
print(f'Verified with probability {common.PROBABILITY_TO_CATCH_MALICIOUS} that the prover is storing in average {common.INITIAL_SPACE_TO_PROVE_IN_BITS} (actually the prover is storing in average {actualStorage} bits)')
|
||||
else:
|
||||
print("The prover hasn't provided a correct proof!")
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user