Skip to content

Commit 55daf2d

Browse files
author
mx
committed
wip(transaction signature & verification)
1 parent 39e8f64 commit 55daf2d

File tree

3 files changed

+88
-10
lines changed

3 files changed

+88
-10
lines changed

test_wallet.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from wallet import Wallet
2+
from transaction import Transaction
3+
from mx_crypto import MxCrypto
4+
5+
wallet = Wallet(1024, True)
6+
guy_wallet = Wallet(1024, True)
7+
8+
my_address = wallet.address
9+
guy_address = guy_wallet.address
10+
11+
value = 10
12+
13+
14+
def test_signature():
15+
# creation of a transaction with my wallet.
16+
transaction = Transaction(
17+
sender_address=my_address, recipient_address=guy_address, value=value)
18+
19+
signature = wallet.sign_transaction(transaction)
20+
21+
assert transaction.verify_signature(signature) == True
22+
23+
# guy sign my transaction...
24+
fake_signature = guy_wallet.sign_transaction(transaction)
25+
is_valid = transaction.verify_signature(fake_signature)
26+
27+
assert is_valid == False

transaction.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from collections import OrderedDict
2+
import hashlib
3+
4+
from Crypto.PublicKey import RSA
5+
from Crypto.Cipher import PKCS1_OAEP
6+
from Crypto.Signature import PKCS1_v1_5
7+
from Crypto import Random
8+
from base64 import b64encode, b64decode
9+
from Crypto.Hash import SHA256
10+
from mx_crypto import MxCrypto
11+
import json
12+
13+
14+
class Transaction:
15+
16+
def __init__(self, sender_address, recipient_address, value):
17+
# @ = public keys
18+
self.sender_address = sender_address
19+
self.recipient_address = recipient_address
20+
21+
self.value = value
22+
23+
def to_dict(self):
24+
return OrderedDict({'sender_address': self.sender_address,
25+
'recipient_address': self.recipient_address,
26+
'value': self.value})
27+
28+
def toJSON(self):
29+
# return json.dumps({
30+
# 'sender_address': self.sender_address,
31+
# 'recipient_address': self.recipient_address,
32+
# 'value': self.value
33+
# }, sort_keys=True)
34+
return json.dumps(self, default=lambda o: o.__dict__,
35+
sort_keys=True, indent=4)
36+
37+
def verify_signature(self, signature):
38+
"""
39+
Check that the provided signature corresponds to transaction
40+
signed by the public key (sender_address)
41+
"""
42+
43+
# sender_address = string. I need RSA Object.
44+
pubkey = RSA.import_key(self.sender_address)
45+
return MxCrypto.verify(pubkey, self.toJSON(), signature)

wallet.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,31 @@
66
import hashlib
77
from Crypto.Hash import SHA256
88
from mx_crypto import MxCrypto
9+
from transaction import Transaction
910

1011

1112
class Wallet:
1213
"""
1314
Manage my priv/pub key.
1415
"""
1516

16-
def __init__(self):
17-
try:
18-
public_key, private_key, str_public_key = Wallet._import_keys()
19-
except FileNotFoundError:
20-
# to handle!
21-
public_key, private_key = MxCrypto.generate_keys()
17+
def __init__(self, key_length=4096, regenerate=False):
18+
if regenerate is True:
19+
public_key, private_key = MxCrypto.generate_keys(key_length)
20+
else:
21+
try:
22+
public_key, private_key = Wallet._import_keys()
23+
except FileNotFoundError:
24+
# to handle!
25+
public_key, private_key = MxCrypto.generate_keys(key_length)
2226

23-
Wallet._save_key(public_key, private_key)
27+
Wallet._save_key(public_key, private_key)
2428

2529
self.public_key = public_key
2630
self.private_key = private_key
2731

32+
self.address = self.public_key.export_key().decode()
33+
2834
# self.address = hashlib.sha256(
2935
# str_public_key.encode('utf-8')).hexdigest()
3036

@@ -50,14 +56,14 @@ def _import_keys():
5056
str_public_key = open('./keys/public.pem', 'r').read()
5157
public_key = RSA.import_key(str_public_key)
5258

53-
return public_key, private_key, str_public_key
59+
return public_key, private_key
5460

5561
def sign_transaction(self, transaction):
5662
"""
5763
Sign transaction with private key
5864
"""
5965

60-
if not isinstance(transaction):
66+
if not isinstance(transaction, Transaction):
6167
raise ValueError('transaction should be Transation instance.')
6268

63-
return Wallet.sign(str(transaction.to_dict()), self.private_key)
69+
return MxCrypto.sign(self.private_key, transaction.toJSON())

0 commit comments

Comments
 (0)