-
Notifications
You must be signed in to change notification settings - Fork 0
/
participant.py
78 lines (68 loc) · 3.59 KB
/
participant.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
#!/usr/bin/python3
from util import *
import math
import random
import hashlib
import itertools
class Participant:
def __init__(self, name, pairing, curve, P, Q, order, S = PointAtInfinity()):
# Pairing that's going to be used to generate shared keys
self.pairing = pairing
# Name from set {'A','B','C'} of the participant
self.name = name
# Elliptic curve
self.curve = curve
# Order of generator points
self.order = order
# Point S used in Miller's Algorithm for the Weil pairing
if pairing == 'Weil':
self.S = S
# Dictionary used to store the public values from different participants
self.publicKeys = {}
# Generate a private key: integer k s.t. 1 < k < order - 1
self.privateKey = random.randint(1,order)
print(name + "'s private key: " + str(self.privateKey))
# Generate public values to broadcast to other 2 participants
self.publicKeys['P_' + name] = doubleAndAdd(P, self.privateKey, curve)
self.publicKeys['Q_' + name] = doubleAndAdd(Q, self.privateKey, curve)
print(name + "'s public keys:\nP: " + self.publicKeys["P_" + name].toString() + "\nQ: " + self.publicKeys["Q_" + name].toString() + "\n")
# Attribute that will store the shared key generated by the protocol
self.sharedKeyHash = ""
""" Generates the shared key of the Tripartite DH protocol """
def generateSharedKey(self):
# Pick the keys (one generated by point P of a participant
# and another generated with point Q by the other participant)
for key in self.publicKeys:
if key.startswith("P") and (key != "P_" + self.name):
P = key
for key in self.publicKeys:
if key.startswith("Q") and (key != "P_" + self.name) and (key[2] != P[2]):
Q = key
# Generate Weil Pairing (using Miller's Algorithm)
if self.pairing == "Weil":
pairing = WeilPairing(self.publicKeys.get(P), self.publicKeys.get(Q), self.S, self.order, self.curve)
else:
pairing = TatePairing(self.publicKeys.get(P), self.publicKeys.get(Q), self.order, self.curve)
# Exponentiate Weil Pairing to private key and get shared key
sharedKey = squareAndMultiply(pairing, self.privateKey)
print(self.name + " computed pairing: " + str(sharedKey))
# Hash shared key so it can be used for symmetric crypto
self.sharedKeyHash = hashlib.sha256(sharedKey.toString().encode()).hexdigest()
""" Sends a tuple with the participant's public values """
def sendPublicKeys(self):
return (self.publicKeys['P_' + self.name], self.publicKeys['Q_' + self.name])
""" Stores public values from another participant """
def getPublicKeys(self, participant, keys):
self.publicKeys['P_' + participant] = keys[0]
self.publicKeys['Q_' + participant] = keys[1]
if len(self.publicKeys) == 6:
self.sharedKey = self.generateSharedKey()
""" Ciphers message and returns it """
def sendMessage(self, message):
xorred = ''.join([chr(ord(x)^ord(y)) for x, y in zip(message, itertools.cycle(self.sharedKeyHash))])
return xorred
""" Deciphers message and prints it """
def receiveMessage(self, message):
print("I am " + self.name + " and I got this ciphered message: " + message)
xorred = ''.join([chr(ord(x)^ord(y)) for x, y in zip(message, itertools.cycle(self.sharedKeyHash))])
print("Deciphering I get: " + xorred)