ex and hw of week 4

This commit is contained in:
“Spekulaas” 2023-09-20 16:40:44 +02:00
parent 7185389683
commit e3e587a74e
5 changed files with 318 additions and 0 deletions

View File

@ -0,0 +1,58 @@
#!/usr/bin/env python3
"""Block Integrity -> Blockchain Data Structure: Exercise 1
The goal of this exercise is to learn how a simple blockchain can be created and securely linked
together using cryptography. In general, each block is used to hold a batch of transactions. In addition a cryptographic
hash of the previous block in the chain and some other needed values for computation.
For the simplicity of this exercise each block will hold a string message (data) and hash of the previous block (previousBlock).
The computeHash() method should compute the cryptographic hash of the current block.
Be sure which values must be considered to compute the hash properly.
Your task is to:
* locate the TODOs in this file
* complete the missing part from the code
* run the test of this exercise located in same folder.
To test run 'Blockchain_t.py' in your command line
Notes:
* do not change class structure or method signature to not break unit tests
* visit this url for more information on this topic:
https://cryptography.io/en/latest/hazmat/primitives/cryptographic-hashes/
"""
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
class CBlock:
previousHash = None
previousBlock = None
data = None
# TODO 1: Initialize a block
# Make sure you initialize the genesis block and transaction blocks differently
def __init__(self, data, previousBlock):
if previousBlock == None :
self.previousHash = None
self.previousBlock = None
self.data = data
else:
self.previousBlock = previousBlock
self.previousHash = self.previousBlock.computeHash()
self.data = data
pass
# TODO 2: Compute the hash of a the current block
# Make sure you include all required data
def computeHash(self):
digest = hashes.Hash(hashes.SHA256())
if self.previousHash != None:
digest.update(self.previousHash)
try:
digest.update(str(self.data).encode())
except:
digest.update(self.data)
return digest.finalize()

View File

@ -0,0 +1,58 @@
#!/usr/bin/env python3
"""
This test case will verify if the provided exercise solution by a student for Blockchain.py is correct.
"""
from Blockchain import *
class anotherClass:
string = None
num = 1264378
def __init__(self, mystring):
self.string = mystring
def __repr__(self):
return self.string + str(self.num)
if __name__ == '__main__':
# Instantiate the genesis block
root = CBlock(b'I am root', None)
# Instantiate another block
B1 = CBlock('I am a child!', root)
# Check if blocks are correctly linked
if root.computeHash() == B1.previousHash:
print("Success! B1 hash matches")
else:
print("Fail! B1 hash does not match")
if B1.previousBlock.computeHash() == B1.previousHash:
print("Success! B1 hash matches")
else:
print("Fail! B1 hash does not match")
# Add more blocks to the chain
B2 = CBlock('I am a brother', root)
B3 = CBlock(b'I contiain bytes', B1)
B4 = CBlock(12354, B3)
B5 = CBlock(anotherClass('Hi there!'), B4)
B6 = CBlock("child of B5", B5)
for b, name in [(B1, 'B1'), (B2, 'B2'), (B3, 'B3'), (B4, 'B4'), (B5, 'B5')]:
if b.previousBlock.computeHash() == b.previousHash:
print("Success! "+name+" hash matches")
else:
print("Fail! " +name+" hash does not match")
#Check if tampered blocks can be detected
B4.data = 12345
if B5.previousBlock.computeHash() == B5.previousHash:
print("Fail! Couldn't detect a tamper")
else:
print("Success! Tampering is detected")
B5.data.num = 23678
if B6.previousBlock.computeHash() == B6.previousHash:
print("Fail! Couldn't detect a tamper")
else:
print("Success! Tampering is detected")

View File

@ -0,0 +1,86 @@
#!/usr/bin/env python3
"""Block Integrity -> Tamper Proof Chain: Homework
The goal of this homework is to extend the behavior of a block to created a chain and securely link
them together using cryptography. In general, each block is used to hold a batch of transactions. In addition a cryptographic
hash of the previous block in the chain and some other needed values for computation.
In this homework each block will hold:
* a string message (data)
* its own block hash value
* hash value of the previous block
* nonce value which will be incremented when a block is mined
Your task is to:
* locate the TODOs in this file
* complete the missing part from the code
* run the test of this exercise located in same folder.
To test run 'Blockchain_t.py' in your command line
Notes:
* do not change class structure or method signature to not break unit tests
* visit this url for more information on this topic:
https://cryptography.io/en/latest/hazmat/primitives/cryptographic-hashes/
"""
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
class CBlock:
# TODO 1: Initialize the values of a block
# Make sure you distinguish between the genesis block and other blocks
def __init__(self, data, previousBlock):
if previousBlock == None :
self.previousHash = None
self.previousBlock = None
self.data = data
else:
self.previousBlock = previousBlock
self.previousHash = self.previousBlock.computeHash()
self.data = data
self.blockHash = None
self.nonce = 0
# TODO 2: Compute the cryptographic hash of the current block.
# Be sure which values must be considered to compute the hash properly.
# return the digest value
def computeHash(self):
digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
if self.previousHash != None:
digest.update(self.previousHash)
try:
digest.update(str(self.data).encode())
except:
digest.update(self.data)
digest.update(str(self.nonce).encode())
return digest.finalize()
# TODO 3: Mine the current value of a block
# Calculates a digest based on required values from the block, such as:
# data, previousHash, nonce
# Make sure to compute the hash value of the current block and store it properly
def mine(self, leading_zeros):
self.nonce = 0
while True:
digest = self.computeHash()
if digest[:leading_zeros] == b'\x00' * leading_zeros:
self.blockHash = digest
print(self.nonce) # Output.txt file has printed nonce values
break
self.nonce += 1
# TODO 4: Check if the current block contains valid hash digest values
# Make sure to distinguish between the genesis block and other blocks
# Make sure to compare both hash digest values:
# The computed digest of the current block
# The stored digest of the previous block
# return the result of all comparisons as a boolean value
def is_valid_hash(self):
if self.previousBlock == None:
return True
return self.computeHash() == self.blockHash

View File

@ -0,0 +1,73 @@
#!/usr/bin/env python3
"""
This test case will verify if the provided homework solution by a student for Blockchain.py is correct.
"""
from BlockChain import *
leading_zero = 2
dataG = 'Root'
data1 = 'It is B1'
data2 = 'It is B2'
data3 = 'It is B3'
data4 = 'It is B4'
data5 = 'It is B5'
if __name__ == '__main__':
# Instantiate different blocks to be added to the chain
Gn = CBlock(dataG, None)
B1 = CBlock(data1, Gn)
B2 = CBlock(data2, B1)
B3 = CBlock(data3, B2)
B4 = CBlock(data4, B3)
print('\n--- Blocks are created --- Hashes and Nonces should not match!')
# Check if hashes and nonces of each block are valid
for b, name in [(B1, 'B1'), (B2, 'B2'), (B3, 'B3'), (B4, 'B4')]:
if b.is_valid_hash():
print("Success! "+name+" hash matches")
else:
print("Fail! " +name+" hash does not match")
# Mine each block
for b, name in [(Gn, 'Gn'), (B1, 'B1'), (B2, 'B2'), (B3, 'B3'), (B4, 'B4')]:
print(f'\nMining {name} ...')
b.mine(leading_zero)
print('\n--- Blocks are mined --- Hashes and Nonces must match!')
# Check if hashes and nonces of each block are valid
# Check if block are linked correctly
for b, name in [(B1, 'B1'), (B2, 'B2'), (B3, 'B3'), (B4, 'B4')]:
if b.is_valid_hash():
print("Success! "+name+" hash matches")
else:
print("Fail! " +name+" hash does not match")
# Temper the value of a blok
data3t = 'It is B3t'
B3.data = data3t
print('\n--- Block3 is tampered --- Hashes and Nonces of blocks after B3 should not match!')
# Check if tempering of block B3 can be detected.
# Hashes and Nonces of its block must not match
for b, name in [(B1, 'B1'), (B2, 'B2'), (B3, 'B3'), (B4, 'B4')]:
if b.is_valid_hash():
print("Success! "+name+" hash matches")
else:
print("Fail! " +name+" hash does not match")
# Mine the blockchain again
for b, name in [(Gn, 'Gn'), (B1, 'B1'), (B2, 'B2'), (B3, 'B3'), (B4, 'B4')]:
print(f'\nMining {name} ...')
b.mine(leading_zero)
print('\n--- Blocks are mined again --- Hashes and Nonces must match again!')
# Mine the blockchain again
# Hashes and Nonces must match again
for b, name in [(B1, 'B1'), (B2, 'B2'), (B3, 'B3'), (B4, 'B4')]:
if b.is_valid_hash():
print("Success! "+name+" hash matches")
else:
print("Fail! " +name+" hash does not match")

View File

@ -0,0 +1,43 @@
--- Blocks are created --- Hashes and Nonces should not match!
Fail! B1 hash does not match
Fail! B2 hash does not match
Fail! B3 hash does not match
Fail! B4 hash does not match
Mining Gn ...
11724
Mining B1 ...
21751
Mining B2 ...
83579
Mining B3 ...
209059
Mining B4 ...
67743
--- Blocks are mined --- Hashes and Nonces must match!
Success! B1 hash matches
Success! B2 hash matches
Success! B3 hash matches
Success! B4 hash matches
--- Block3 is tampered --- Hashes and Nonces of blocks after B3 should not match!
Success! B1 hash matches
Success! B2 hash matches
Fail! B3 hash does not match
Fail! B4 hash does not match
Mining Gn ...
11724
Mining B1 ...
21751
Mining B2 ...
83579
Mining B3 ...
143719
Mining B4 ...
67743
--- Blocks are mined again --- Hashes and Nonces must match again!
Success! B1 hash matches
Success! B2 hash matches
Success! B3 hash matches
Success! B4 hash matches