def __init__(self, p, q): self.p = tf_big.convert_to_tensor(p) self.q = tf_big.convert_to_tensor(q) self.n = self.p * self.q self.nn = self.n * self.n order_of_n = (self.p - 1) * (self.q - 1) self.d1 = order_of_n self.d2 = tf_big.inv(order_of_n, self.n) self.e = tf_big.inv(self.n, order_of_n)
def add( ek: EncryptionKey, lhs: Ciphertext, rhs: Ciphertext, do_refresh: bool = True, ): c0 = tf_big.convert_to_tensor(lhs.raw) c1 = tf_big.convert_to_tensor(rhs.raw) c = (c0 * c1) % ek.nn res = Ciphertext(ek, c) if not do_refresh: return res return refresh(ek, res)
def mul( ek: EncryptionKey, lhs: Ciphertext, rhs: tf.Tensor, do_refresh: bool = True, ): c = lhs.raw k = tf_big.convert_to_tensor(rhs) d = tf_big.pow(c, k) % ek.nn res = Ciphertext(ek, d) if not do_refresh: return res return refresh(ek, res)
def encrypt( ek: EncryptionKey, plaintext: tf.Tensor, randomness: Optional[Randomness] = None, ): x = tf_big.convert_to_tensor(plaintext) randomness = randomness or gen_randomness(ek=ek, shape=x.shape) r = randomness.raw assert r.shape == x.shape gx = 1 + (ek.n * x) % ek.nn rn = tf_big.pow(r, ek.n, ek.nn) c = gx * rn % ek.nn return Ciphertext(ek, c)
def __init__(self, ek: EncryptionKey, raw_ciphertext): self.ek = ek self.raw = tf_big.convert_to_tensor(raw_ciphertext)
def __init__(self, raw_randomness): self.raw = tf_big.convert_to_tensor(raw_randomness)
def __init__(self, n): n = tf_big.convert_to_tensor(n) self.n = n self.nn = n * n