diff --git a/week4.py b/week4.py new file mode 100644 index 0000000..5d16dd1 --- /dev/null +++ b/week4.py @@ -0,0 +1,119 @@ +# Concept: Create 8 PKs where each represent a bloodtype. Let 7 of them be created by OGen and 1 of them by KeyGen. +# The one represents our bloodtype. Bob will then encrypt 8 values using these PKs, where each value repredents +# A truth value, thus either true or false, s.t. each cipher is an entry in the bloodtype comptability matrix. + +import secrets +import numpy as np +from crypto.week1 import BloodType, convert_from_string_to_enum, blood_cell_compatibility_lookup + +convert_bloodtype_to_index = { + BloodType.O_NEGATIVE: 0, + BloodType.O_POSITIVE: 1, + BloodType.A_NEGATIVE: 2, + BloodType.A_POSITIVE: 3, + BloodType.B_NEGATIVE: 4, + BloodType.B_POSITIVE: 5, + BloodType.AB_NEGATIVE: 6, + BloodType.AB_POSITIVE: 7, +} + + +class Group: + def __init__(self, q): + self.order = q + + def gen_group_stuff(self): + my_group = [] + for i in range(1, self.order): + if np.gcd(i, self.order) == 1: + my_group.append(i) + for group_ele in my_group: + if group_ele**self.order == 1 % self.order: + gen = group_ele + return gen, self.order, my_group + +class ElGamal: + def __init__(self, G, g, q): + self.group = G + self.gen_ = g + self.order = q + self.pk = None + self.sk = None + + def gen(self, sk): + h = self.gen_**sk + self.sk = sk + self.pk = (self.gen_, h) + return self.pk + + def enc(self, m, pk): + # sample random r \in Zq + r = secrets.SystemRandom().randint(1, self.order-1) + g, h = pk + c = (g ** r, m * h**r) + return c + + def dec(self, c): + c1, c2 = c + m = c2 * c1**(-self.sk) # % self.order + return m + + def ogen(self, r): + # Here, q = 2p+1, thus we actually need to use the p here, instead of + # self.order, but as we do not know p yet, .e we + # TODO: Use p instead of self.order, s.t. self.order = 2p+1 + s = secrets.SystemRandom().randint(1, self.order) + h = s**2 % self.order + return self.gen_, h + + +class Alice: + def __init__(self, bloodtype, elgamal): + self.elgamal = elgamal + self.gen_ = 9 + self.order = 453 + self.b = convert_bloodtype_to_index[convert_from_string_to_enum[bloodtype]] + self.sk = secrets.SystemRandom().randint(1, self.order) + + self.pk = self.elgamal.gen(self.sk) + self.fake_pks = [self.elgamal.ogen(secrets.SystemRandom().randint(0, self.order)) + for _ in range(7)] + + def send_pks(self): + all_pks = self.fake_pks + all_pks.insert(self.b, self.pk) + return all_pks + + def retrieve(self, ciphers): + mb = self.elgamal.dec(ciphers[self.b]) + return mb + + +class Bob: + def __init__(self, bloodtype, elgamal): + self.bloodtype = convert_from_string_to_enum[bloodtype] + self.truth_vals = [] + self.elgamal = elgamal + self.pks = None + for donor in BloodType: + truth_val = blood_cell_compatibility_lookup(self.bloodtype, donor) + self.truth_vals.append(truth_val) + + def receive_pks(self, pks): + self.pks = pks + + def transfer_messages(self): + ciphers = [] + for idx, truth_val in enumerate(self.truth_vals): + pk = self.pks[idx] + c = self.elgamal.enc(truth_val, pk) + ciphers.append(c) + return ciphers + + +if __name__ == "__main__": + group = Group(11) + gen, order, my_group = group.gen_group_stuff() + + print(gen, order, my_group) +