finished lesson 5

This commit is contained in:
Spekulaas 2023-09-27 10:16:13 +02:00
parent 28917ff865
commit c43218e0e3
4 changed files with 239 additions and 0 deletions

View File

@ -0,0 +1,35 @@
from cryptography.exceptions import *
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
def generate_keys():
private_key = rsa.generate_private_key(public_exponent=65537,key_size=2048)
public_key = private_key.public_key()
return private_key, public_key
def sign(message, private_key):
message = bytes(str(message), 'utf-8')
signature = private_key.sign(
message,
padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH),
hashes.SHA256()
)
return signature
def verify(message, signature, public_key):
message = bytes(str(message), 'utf-8')
try:
public_key.verify(
signature,
message,
padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH),
hashes.SHA256()
)
return True
except InvalidSignature:
return False
except:
print('Error executing public_key.verify')
return False

View File

@ -0,0 +1,92 @@
#!/usr/bin/env python3
"""
Transaction Class
The goal of this exercise is to learn how to complete transaction class.
A transaction is composed of a list of Inputs and a list of outputs, and few methods.
add_input() and add_output(), and sign() are already completed in the previous tutorials and exercise.
In this hoemwork, we will add another method is_valid() to the class. With this method, we can
validate a transaction.
Your task is to:
* locate the TODOs in this file
* complete the missing part from the code
* run the test of this tutorial located in same folder.
To test run 'Transactions_t.py' in your command line
Notes:
* do not change class structure or method signature to not break unit tests
"""
from Signature import *
class Tx:
inputs = None
outputs =None
sigs = None
reqd = None
def __init__(self):
self.inputs = []
self.outputs = []
self.sigs = []
self.reqd = [] # A placeholder for any other extra required signature (e.g. escrow)
def add_input(self, from_addr, amount):
self.inputs.append([from_addr, amount])
def add_output(self, to_addr, amount):
self.outputs.append([to_addr, amount])
# TODO 2: Complete the method
# We would like to have another method to add extra required signature if needded (e.g. escrow)
# with this method, we can specify other required signature to the transaction by adding the
# public key of the required signature
# If this signature is needed, later we can check if the transaction is also signed by that person/party.
def add_reqd(self, addr):
self.reqd.append(addr)
# TODO 3: Complete the method
# This method is also already done in the previous tutorials.
# you can copy and paste the previous codes here
def sign(self, private):
tx_data = self.__gather()
new_sig = sign(tx_data, private)
self.sigs.append(new_sig)
def __gather(self):
data = []
data.append(self.inputs)
data.append(self.outputs)
data.append(self.reqd)
return data
def is_valid(self):
total_in = 0
total_out = 0
for (addr, amount) in self.inputs:
found = False
for s in self.sigs:
if verify(self.__gather(), s, addr):
found = True
if not found:
return False
if amount < 0:
return False
total_in = total_in + amount
for (addr, amount) in self.outputs:
if amount < 0:
return False
total_out = total_out + amount
for sender in self.reqd:
found = False
for s in self.sigs:
if verify(self.__gather(), s, sender):
found = True
if not found:
return False
if total_out > total_in:
return False
return True

View File

@ -0,0 +1,103 @@
"""
This test case will verify if the provided exercise solution by a student for the Transaction.py is correct.
"""
from Signature import *
from Transaction import *
if __name__ == "__main__":
alex_prv, alex_pbc = generate_keys()
mike_prv, mike_pbc = generate_keys()
rose_prv, rose_pbc = generate_keys()
mara_prv, mara_pbc = generate_keys()
# Check Valid Transactions
# Test 1
# --------------------------------------
Tx1 = Tx()
Tx1.add_input(alex_pbc, 1)
Tx1.add_output(mike_pbc, 1)
Tx1.sign(alex_prv)
# Test 2
# --------------------------------------
Tx21 = Tx()
Tx21.add_input(alex_pbc, 2)
Tx21.add_output(mike_pbc, 1)
Tx21.add_output(rose_pbc, 1)
Tx21.sign(alex_prv)
Tx22 = Tx()
Tx22.add_input(rose_pbc, 1.2)
Tx22.add_output(alex_pbc, 1.1)
Tx22.add_reqd(mara_pbc)
Tx22.sign(rose_prv)
Tx22.sign(mara_prv)
for transaction in [Tx1, Tx21, Tx22]:
if transaction.is_valid():
print("SUCCESS! Valid transaction is verified.")
else:
print("ERROR! Valid transaction is not verified.")
# Check Invalid Transactions
# Test 3
# --------------------------------------
# Wrong signatures
Tx3 = Tx()
Tx3.add_input(alex_pbc, 1)
Tx3.add_output(mike_pbc, 1)
Tx3.sign(mike_prv)
# Test 4
# --------------------------------------
# Escrow Tx not signed by the arbiter
Tx4 = Tx()
Tx4.add_input(rose_pbc, 1.2)
Tx4.add_output(mike_pbc, 1.1)
Tx4.add_reqd(mara_pbc)
Tx4.sign(rose_prv)
# Test 5
# --------------------------------------
# Two input addrs, signed by one
Tx5 = Tx()
Tx5.add_input(rose_pbc, 1)
Tx5.add_input(mara_pbc, 0.1)
Tx5.add_output(mike_pbc, 1.1)
Tx5.sign(mara_prv)
# Test 6
# --------------------------------------
# Outputs exceed inputs
Tx6 = Tx()
Tx6.add_input(mara_pbc, 1.2)
Tx6.add_output(alex_pbc, 1)
Tx6.add_output(alex_pbc, 2)
Tx6.sign(mara_prv)
# Test 7
# --------------------------------------
# Negative values
Tx7 = Tx()
Tx7.add_input(mike_pbc, -1)
Tx7.add_output(alex_pbc, -1)
Tx7.sign(mike_prv)
# Test 8
# --------------------------------------
# Modified Tx
Tx8 = Tx()
Tx8.add_input(mike_pbc, 1)
Tx8.add_output(alex_pbc, 1)
Tx8.sign(mike_prv)
# outputs = [(alex_pbc,1)] change to [(rose_pbc,1)]
Tx8.outputs[0] = (rose_pbc, 1)
for transaction in [Tx3, Tx4, Tx5, Tx6, Tx7, Tx8]:
if transaction.is_valid():
print("ERROR! Invalid transaction is verified.")
else:
print("SUCCESS! Invalid transaction is not verified.")

View File

@ -0,0 +1,9 @@
SUCCESS! Valid transaction is verified.
SUCCESS! Valid transaction is verified.
SUCCESS! Valid transaction is verified.
SUCCESS! Invalid transaction is not verified.
SUCCESS! Invalid transaction is not verified.
SUCCESS! Invalid transaction is not verified.
SUCCESS! Invalid transaction is not verified.
SUCCESS! Invalid transaction is not verified.
SUCCESS! Invalid transaction is not verified.