-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwallet.py
99 lines (81 loc) · 3.54 KB
/
wallet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
'''
Here in this file we are working with the wallets and the major part of the hashing and
ssecurity consideration is done is here we are also working with SHA256 and PKCS1_v1_5 algorithm to
genrate the Signature of the transaction
use case = "Major use"
made: 22/5
no_of updated = 127
last_update: 18/6
******THERE WILL ALWAYS BE ONE ERROR IN LAST LINE*******
******CAN'T DO ANYTHING ABOUT THAT********
'''
from Crypto.PublicKey import RSA
#this will generate the unique public key
from Crypto.Signature import PKCS1_v1_5
#this will generate the signature (special algorithm)
from Crypto.Hash import SHA256
#security
import Crypto.Random
import binascii
class Wallet:
"""Creates, loads and holds private and public keys. Manages transaction signing and verification."""
def __init__(self, node_id):
self.private_key = None
self.public_key = None
self.node_id = node_id
def create_keys(self):
"""Create a new pair of private and public keys."""
private_key, public_key = self.generate_keys()
self.private_key = private_key
self.public_key = public_key
def save_keys(self):
"""Saves the keys to a file (wallet.txt)."""
if self.public_key != None and self.private_key != None:
try:
with open('wallet-{}.txt'.format(self.node_id), mode='w') as f:
f.write(self.public_key)
f.write('\n')
f.write(self.private_key)
return True
except (IOError, IndexError):
print('Saving wallet failed...')
return False
def load_keys(self):
"""Loads the keys from the wallet.txt file into memory."""
try:
with open('wallet-{}.txt'.format(self.node_id), mode='r') as f:
keys = f.readlines()
public_key = keys[0][:-1]
private_key = keys[1]
self.public_key = public_key
self.private_key = private_key
return True
except (IOError, IndexError):
print('Loading wallet failed...')
return False
def generate_keys(self):
"""Generate a new pair of private and public key."""
private_key = RSA.generate(1024, Crypto.Random.new().read)
public_key = private_key.publickey()
return (binascii.hexlify(private_key.exportKey(format='DER')).decode('ascii'), binascii.hexlify(public_key.exportKey(format='DER')).decode('ascii'))
def sign_transaction(self, sender, recipient, amount):
"""Sign a transaction and return the signature.
Arguments:
:sender: The sender of the transaction.
:recipient: The recipient of the transaction.
:amount: The amount of the transaction.
"""
signer = PKCS1_v1_5.new(RSA.importKey(binascii.unhexlify(self.private_key)))
h = SHA256.new((str(sender) + str(recipient) + str(amount)).encode('utf8'))
signature = signer.sign(h)
return binascii.hexlify(signature).decode('ascii')
@staticmethod
def verify_transaction(transaction):
"""Verify the signature of a transaction.
Arguments:
:transaction: The transaction that should be verified.
"""
public_key = RSA.importKey(binascii.unhexlify(transaction.sender))
verifier = PKCS1_v1_5.new(public_key)
h = SHA256.new((str(transaction.sender) + str(transaction.recipient) + str(transaction.amount)).encode('utf8'))
return verifier.verify(h, binascii.unhexlify(transaction.signature))