def mine(self): # Create hash of transactions with a Merkle Tree tree = MerkleTree() for t in self.transactions: tree.encryptRecord(t.id.encode()) # make bytestring merkle_hash = tree.rootHash # 32-bit sized nonce for nonce in range(2 << 32): # header consists ofev_hash, nonce, merkle of transactions # and the block timestamps. # see: https://en.bitcoin.it/wiki/Block_hashing_algorithm nonce = hex(nonce).encode() timestamp = str(time()).encode() header = self.previous_hash + nonce + merkle_hash + timestamp h = SHA256.new() # apply hashing 2 times hash_value = h.new(h.new(header).digest()).hexdigest() hash_value = str(hash_value[::-1]) # reverse, little endian if int(hash_value[0:config.DIFFICULTY], 16) == 0: solved = True break if solved: self.hash = hash_value.encode() self.nonce = nonce self.timestamp = timestamp else: self.mine()
def test_UndecodableRecord_with_encryptRecord(byte, encoding, security): tree = MerkleTree('a', 'b', 'c', encoding=encoding, raw_bytes=False, security=security) with pytest.raises(UndecodableRecord): tree.encryptRecord(byte)
def validate_hash(self): # validate block hash value tree = MerkleTree() for t in self.transactions: tree.encryptRecord(t.id.encode()) # make bytestring merkle_hash = tree.rootHash header = self.previous_hash + self.nonce+\ merkle_hash + self.timestamp h = SHA256.new() hash_value = str(h.new(h.new(header).digest()).hexdigest()[::-1]) return (int(hash_value[0:config.DIFFICULTY], 16) == 0)
def test_UndecodableRecordError_with_encryptRecord(_byte, _encoding, _security): _tree = MerkleTree('a', 'b', 'c', encoding=_encoding, security=_security) _output = _tree.encryptRecord(_byte) assert _output == 1 and _tree.length == 3
"""pymerkle demo""" from pymerkle import MerkleTree, validateProof if __name__ == '__main__': tree = MerkleTree(hash_type='sha256', encoding='utf-8', raw_bytes=True, security=True) for i in range(7): tree.encryptRecord('%d-th record' % i) print(repr(tree)) challenge = { 'checksum': '45c44059cf0f5a447933f57d851a6024ac78b44a41603738f563bcbf83f35d20' } proof = tree.merkleProof(challenge) print(proof) assert validateProof(proof) receipt = validateProof(proof, get_receipt=True) print(receipt)
def consistency_proofs_benchmark(): # Generate states global TREE TREE = MerkleTree('0-th record', encoding=ENCODING, hash_type=HASH_TYPE) STATES = [] for _ in range(1, LENGTH + 3 * ADDITIONAL): #): STATES.append((TREE.rootHash, TREE.length)) TREE.encryptRecord(bytes('%d-th record' % _, encoding=ENCODING)) STATES.append((TREE.rootHash, TREE.length)) # Generate proofs global PROOFS sys.stdout.write('\nConsistency proofs') START = datetime.now() MAX = None MIN = None TOTAL = 0.0 elapsed = [] for _ in range(TREE.length): # print(_) _oldhash = STATES[_][0] _sublength = STATES[_][1] _cycle = datetime.now() _proof = TREE.consistencyProof(oldhash=_oldhash, sublength=_sublength) _elapsed = _time_elapsed(_cycle) # print(_proof) # print(_) if MAX is None: MIN = MAX = _elapsed else: MAX = max(_elapsed, MAX) MIN = min(_elapsed, MIN) PROOFS.append(_proof) TOTAL += _elapsed elapsed.append(_elapsed) mean, stdev = _mean_value(elapsed, precision_2, with_stdev=True) _show_stats(message='Consistency proofs', total=_quantize(TOTAL, precision_2), min=MIN, max=MAX, mean=mean, stdev=stdev)
def tree_benchmark(): global TREE sys.stdout.write('\n') sys.stdout.write('\nTree size with 0 nodes (bytes): %d' % _size(TREE)) START = datetime.now() TREE = MerkleTree(*['%d-th record' % _ for _ in range(LENGTH)], hash_type=HASH_TYPE, encoding=ENCODING) time_needed = _time_elapsed(START) sys.stdout.write('\n') sys.stdout.write( '\nTime needed to generate a Merkle-tree with %d leaves (secs): %s' % (LENGTH, time_needed)) sys.stdout.write('\nSize of tree with %d leaves (bytes): %d' % (TREE.length, _size(TREE))) START = datetime.now() for _ in range(LENGTH, LENGTH + ADDITIONAL): TREE.encryptRecord('%d-th record' % _) time_needed = _time_elapsed(START) sys.stdout.write('\n') sys.stdout.write( '\nTime needed to update the tree with %d leaves (secs): %f' % (ADDITIONAL, time_needed)) sys.stdout.write('\nSize of tree with %d leaves (bytes): %d' % (TREE.length, _size(TREE))) # START = datetime.now() MAX = None MIN = None TOTAL = 0.0 elapsed = [] for _ in range(TREE.length, TREE.length + ADDITIONAL): _cycle = datetime.now() TREE.update(record='%d-th record' % _) _elapsed = _time_elapsed(_cycle) if MAX is None: MAX = _elapsed MIN = _elapsed else: MAX = max(_elapsed, MAX) MIN = min(_elapsed, MIN) TOTAL += _elapsed elapsed.append(_elapsed) mean, stdev = _mean_value(elapsed, precision_2, with_stdev=True) _show_stats(message='Tree update', total=_quantize(TOTAL, precision_2), min=MIN, max=MAX, mean=mean, stdev=stdev)
trees_and_subtrees = [] for security in (True, False): for hash_type in hashing.HASH_TYPES: for encoding in ENCODINGS: tree = MerkleTree('a', 'b', 'c', 'd', 'e', hash_type=hash_type, encoding=encoding, security=security) subhash = tree.rootHash for record in ('f', 'g', 'h', 'k'): tree.encryptRecord(record) trees_and_subtrees.append((tree, subhash)) # Exception cases @pytest.mark.parametrize("subhash", [100, 'no bytes']) def test_inclusion_test_InvalidTypes(subhash): with pytest.raises(InvalidTypes): MerkleTree().inclusionTest(subhash) # Success edge case with standard Merkle-Tree def test_inclusion_test_failure_for_zero_leaves_case():
audit_challenge_2 = {'checksum': hash_func(b'anything non recorded...')} @pytest.mark.parametrize('challenge', [audit_challenge_1, audit_challenge_2]) def test_audit_merkleProof(challenge): merkle_proof = tree.merkleProof(challenge) commitment = merkle_proof.header['commitment'] audit_proof = tree.auditProof(challenge['checksum']) assert commitment == tree.rootHash and merkle_proof.body == audit_proof.body cons_challenge_1 = {'subhash': tree.rootHash} cons_challenge_2 = {'subhash': b'anything else...'} for i in range(1000): tree.encryptRecord(f'{i}-th record') @pytest.mark.parametrize('challenge', [cons_challenge_1, cons_challenge_2]) def test_consistency_merkleProof(challenge): subhash = challenge['subhash'] consistency_proof = tree.consistencyProof(subhash) merkle_proof = tree.merkleProof(challenge) commitment = merkle_proof.header['commitment'] assert commitment == tree.rootHash and merkle_proof.body == consistency_proof.body __invalid_challenges = [ {}, {