-
Notifications
You must be signed in to change notification settings - Fork 0
/
common.py
123 lines (95 loc) · 3.45 KB
/
common.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import socket
import collections
# Security parameters
k_RSA = 2048 # Signatures
k_com = 1024 # Commitment
# Communication parameters
# https://wiki.python.org/moin/TcpCommunication
TCP_IP = '127.0.0.1'
TCP_PORT = 12345
BUFFER_SIZE = 1024
# Protocol messages and flag indicating if the message has already been transmitted
m = collections.OrderedDict()
m['com(a,r) sig'] = {"message": None, "alreadyTransmitted": False} # A -> B
m['b sig'] = {"message": None, "alreadyTransmitted": False} # A <- B
m['a r sig'] = {"message": None, "alreadyTransmitted": False} # A -> B
# Support function to get the key of the next expected message
def get_next_m_key(m):
return ([key for key, value in m.items() if value["alreadyTransmitted"] == False] + [None])[0]
# Commitment
# https://pycryptodome.readthedocs.io/en/latest/src/hash/sha256.html
from Crypto.Hash import SHA256
from Crypto.Random import random
def com(m, r):
h = SHA256.new()
h.update(bytes(m + r, 'utf-8'))
return h.hexdigest()
def verify_com(m, r, c):
return com(m, r) == c
# Generate RSA key pair
# https://pycryptodome.readthedocs.io/en/latest/src/public_key/rsa.html
from Crypto.PublicKey import RSA
#def generateKeyPair(name):
# privatekey = RSA.generate(2048)
# f_private = open('privatekey_' + name + '.pem','wb')
# f_private.write(privatekey.export_key('PEM'))
# f_private.close()
# publickey = privatekey.publickey()
# f_public = open('publickey_' + name + '.pem','wb')
# f_public.write(publickey.export_key('PEM'))
# f_public.close()
# generateKeyPair('Alice')
# generateKeyPair('Bob')
# Signature
# https://www.pycryptodome.org/en/latest/src/signature/pkcs1_v1_5.html
from Crypto.Signature import pkcs1_15
def sig(m, name):
f = open('privatekey_' + name + '.pem','r')
privatekey = RSA.import_key(f.read())
f.close()
m = bytes(m, 'utf-8')
h = SHA256.new(m)
return pkcs1_15.new(privatekey).sign(h)
def verify_sig(m, name, s):
s = s.encode('latin-1')
f = open('publickey_' + name + '.pem','r')
publickey = RSA.import_key(f.read())
f.close()
m = bytes(m, 'utf-8')
h = SHA256.new(m)
try:
pkcs1_15.new(publickey).verify(h, s)
return True
except (ValueError, TypeError):
return False
# Support function to sign and format a message
def sig_m(m, name):
return m + ' ' + sig(m, name).decode('latin-1')
# Support function to print nicely a signed message
def print_sig_m(key, m):
p = '\n\n' + m.split()[0]
if key.count(' ') > 1:
p += '\n\n' + m.split()[1]
s = extract_sig(key, m)
p += '\n\n' + str(s.encode('latin-1')) + '\n\n'
return p
# Support function to extract signature from a signed message
# structured as field1 optional_field2 sig
def extract_sig(key, m):
before_sig = m.split()[0] + ' '
if key.count(' ') > 1:
before_sig = m.split()[0] + ' ' + m.split()[1] + ' '
s = m.replace(before_sig, '', 1)
return s
# Support function to convert a binary string to int
def binary_string_to_int(m):
return sum([int(b)*2**p for b,p in zip(m, range(len(m) - 1, -1, -1))])
# Compute output and print it nicely
def compute_output(a, b):
# Compute
a_xor_b = binary_string_to_int(a) ^ binary_string_to_int(b)
d = a_xor_b % 6 + 1
# Print steps
print('Compute d = (a ^ b) % 6 + 1')
print( a + ' ^ ' + b + ' = ' + ''.join(['1' if i!=j else '0' for i,j in zip(a, b)]) + ' = ' + str(a_xor_b) + ' (base 10)')
print(str(a_xor_b) + ' % 6 + 1 = ' + str(d))