from secrets import SystemRandom from .week1 import BloodType, blood_cell_compatibility_lookup random = SystemRandom() def enc(m, pk): S = 1000 c = m + sum(random.sample(pk, S)) return c def dec(c, p): m = (c % p) % 2 return m class Alice: def __init__(self, ra, rb, rs): self.ra = ra self.rb = rb self.rs = rs self.p = random.getrandbits(2000) if self.p % 2 == 0: self.p -= 1 n = 2000 big_ints = [random.getrandbits(10**7) for _ in range(n)] small_ints = [random.getrandbits(60) for _ in range(n)] self.pk = [self.p * big_ints[i] + 2 * small_ints[i] for i in range(n)] def send(self): cra = enc(self.ra, self.pk) crb = enc(self.rb, self.pk) crs = enc(self.rs, self.pk) return self.pk, cra, crb, crs def receive(self, result_cipher): return dec(result_cipher, self.p) class Bob: def __init__(self, da, db, ds): self.da = da self.db = db self.ds = ds self.result_cipher = None def receive(self, pk, cra, crb, crs): cda = enc(self.da, pk) cdb = enc(self.db, pk) cds = enc(self.ds, pk) self.result_cipher = (1 + (cda * (1 + cra))) * (1 + (cdb * (1 + crb))) * (1 + (cds * (1 + crs))) def send(self): return self.result_cipher def run(da, db, ds, ra, rb, rs): alice = Alice(ra, rb, rs) bob = Bob(da, db, ds) bob.receive(*alice.send()) z = alice.receive(bob.send()) return z def main(): green = 0 red = 0 for i, recipient in enumerate(BloodType): for j, donor in enumerate(BloodType): z = run(*donor.value, *recipient.value) lookup = blood_cell_compatibility_lookup(recipient, donor) if lookup == z: green += 1 else: print(f"'{BloodType(donor).name} -> {BloodType(recipient).name}' should be {lookup}.") red += 1 print("Green:", green) print("Red :", red)