from random import randrange
from itertools import combinations
# Dining cryptographers
class Cryptographer(object):
"Dining cryptographer"
def __init__(self, name):
self.name = name
self.partners = dict()
self.pubBit = 0
def __repr__(self):
return self.name
def AddPartner(self, otherCryptographer):
randBit = randrange(2)
print(
"Negotiating secret bit: "
+ self.name
+ "->"
+ otherCryptographer.name
)
print(" value:" + repr(randBit))
otherCryptographer.partners.update(
[[self.name, randBit]]
)
self.partners.update(
[[otherCryptographer.name, randBit]]
)
def Prepare(self):
self.pubBit = (sum(self.partners.values())) % 2
def SendBit(self, bt):
self.Prepare()
self.pubBit = (self.pubBit + bt) % 2
class DiningCryptographers(object):
"Dining Cryptographers 1-bit channel"
def __init__(self, Cryptographers):
if type(Cryptographers) == int:
Cr = []
for i in range(0, Cryptographers):
Cr.append(
Cryptographer(
"Cryptographer #" + repr(i + 1)
)
)
Cryptographers = Cr
self.Cryptographers = Cryptographers
def __getitem__(self, i):
return self.Cryptographers[i]
def negotiate(self):
for [A, B] in combinations(self.Cryptographers, 2):
A.AddPartner(B)
for A in self.Cryptographers:
A.Prepare()
def reveal(self):
res = 0
for A in self.Cryptographers:
print(repr(A) + " sends:" + repr(A.pubBit))
res = (res + A.pubBit) % 2
return res
DiningCryptographers(13)