Esempio n. 1
0
    def encrypt(self, plain):
        """Encrypts a message.

        Encrypts the message and returns the corresponding ciphertext.

        Args:
            plain (Plaintext): Plaintext to be encrypted.

        Returns:
            A ciphertext consisting of a pair of polynomials in the ciphertext
            space.
        """
        p0 = self.public_key.p0
        p1 = self.public_key.p1

        random_vec = Polynomial(self.poly_degree,
                                sample_triangle(self.poly_degree))
        error1 = Polynomial(self.poly_degree,
                            sample_triangle(self.poly_degree))
        error2 = Polynomial(self.poly_degree,
                            sample_triangle(self.poly_degree))

        c0 = p0.multiply(random_vec, self.coeff_modulus, crt=self.crt_context)
        c0 = error1.add(c0, self.coeff_modulus)
        c0 = c0.add(plain.poly, self.coeff_modulus)
        c0 = c0.mod_small(self.coeff_modulus)

        c1 = p1.multiply(random_vec, self.coeff_modulus, crt=self.crt_context)
        c1 = error2.add(c1, self.coeff_modulus)
        c1 = c1.mod_small(self.coeff_modulus)

        return Ciphertext(c0, c1, plain.scaling_factor, self.coeff_modulus)
Esempio n. 2
0
    def encrypt_with_secret_key(self, plain):
        """Encrypts a message with secret key encryption.

        Encrypts the message for secret key encryption and returns the corresponding ciphertext.

        Args:
            plain (Plaintext): Plaintext to be encrypted.

        Returns:
            A ciphertext consisting of a pair of polynomials in the ciphertext
            space.
        """
        assert self.secret_key != None, 'Secret key does not exist'

        sk = self.secret_key.s
        random_vec = Polynomial(self.poly_degree,
                                sample_triangle(self.poly_degree))
        error = Polynomial(self.poly_degree, sample_triangle(self.poly_degree))

        c0 = sk.multiply(random_vec, self.coeff_modulus, crt=self.crt_context)
        c0 = error.add(c0, self.coeff_modulus)
        c0 = c0.add(plain.poly, self.coeff_modulus)
        c0 = c0.mod_small(self.coeff_modulus)

        c1 = random_vec.scalar_multiply(-1, self.coeff_modulus)
        c1 = c1.mod_small(self.coeff_modulus)

        return Ciphertext(c0, c1, plain.scaling_factor, self.coeff_modulus)
Esempio n. 3
0
    def encrypt(self, message):
        """Encrypts a message.

        Encrypts the message and returns the corresponding ciphertext.

        Args:
            message (Plaintext): Plaintext to be encrypted.

        Returns:
            A ciphertext consisting of a pair of polynomials in the ciphertext
            space.
        """
        p0 = self.public_key.p0
        p1 = self.public_key.p1
        scaled_message = message.poly.scalar_multiply(self.scaling_factor,
                                                      self.coeff_modulus)

        random_vec = Polynomial(self.poly_degree,
                                sample_triangle(self.poly_degree))
        error1 = Polynomial(self.poly_degree,
                            sample_triangle(self.poly_degree))
        error1 = Polynomial(self.poly_degree, [0] * self.poly_degree)
        error2 = Polynomial(self.poly_degree,
                            sample_triangle(self.poly_degree))
        error2 = Polynomial(self.poly_degree, [0] * self.poly_degree)
        c0 = error1.add(p0.multiply(random_vec, self.coeff_modulus),
                        self.coeff_modulus).add(scaled_message,
                                                self.coeff_modulus)
        c1 = error2.add(p1.multiply(random_vec, self.coeff_modulus),
                        self.coeff_modulus)

        return Ciphertext(c0, c1)
Esempio n. 4
0
    def generate_relin_key(self, params):
        """Generates a relinearization key for BFV scheme.

        Args:
            params (Parameters): Parameters including polynomial degree,
                plaintext, and ciphertext modulus.
        """
        base = ceil(sqrt(params.ciph_modulus))
        num_levels = floor(log(params.ciph_modulus, base)) + 1

        keys = [0] * num_levels
        power = 1
        sk_squared = self.secret_key.s.multiply(self.secret_key.s,
                                                params.ciph_modulus)

        for i in range(num_levels):
            k1 = Polynomial(
                params.poly_degree,
                sample_uniform(0, params.ciph_modulus, params.poly_degree))
            error = Polynomial(params.poly_degree,
                               sample_triangle(params.poly_degree))
            k0 = self.secret_key.s.multiply(k1, params.ciph_modulus).add(
                error, params.ciph_modulus).scalar_multiply(-1).add(
                    sk_squared.scalar_multiply(power),
                    params.ciph_modulus).mod(params.ciph_modulus)
            keys[i] = (k0, k1)
            power *= base
            power %= params.ciph_modulus

        self.relin_key = BFVRelinKey(base, keys)
    def generate_switching_key(self, new_key):
        """Generates a switching key for CKKS scheme.

        Generates a switching key as described in KSGen in the CKKS paper.

        Args:
            new_key (Polynomial): New key to generate switching key.

        Returns:
            A switching key.
        """
        mod = self.params.big_modulus
        mod_squared = mod**2

        swk_coeff = Polynomial(
            self.params.poly_degree,
            sample_uniform(0, mod_squared, self.params.poly_degree))
        swk_error = Polynomial(self.params.poly_degree,
                               sample_triangle(self.params.poly_degree))

        sw0 = swk_coeff.multiply(self.secret_key.s, mod_squared)
        sw0 = sw0.scalar_multiply(-1, mod_squared)
        sw0 = sw0.add(swk_error, mod_squared)
        temp = new_key.scalar_multiply(mod, mod_squared)
        sw0 = sw0.add(temp, mod_squared)
        sw1 = swk_coeff
        return PublicKey(sw0, sw1)
Esempio n. 6
0
    def encrypt(self, plain):
        p0 = self.public_key[0]
        p1 = self.public_key[1]
        random_vec = Poly(self.poly_degree, sample_triangle(self.poly_degree))
        error1 = Poly(self.poly_degree, sample_triangle(self.poly_degree))
        error2 = Poly(self.poly_degree, sample_triangle(self.poly_degree))
        c0 = p0.multiply(random_vec, self.coeff_modulus, crt=self.crt_context)
        c0 = error1.add(c0, self.coeff_modulus)
        c0 = c0.add(plain.poly, self.coeff_modulus)
        c0 = c0.mod_small(self.coeff_modulus)

        c1 = p1.multiply(random_vec, self.coeff_modulus, crt=self.crt_context)
        c1 = error2.add(c1, self.coeff_modulus)
        c1 = c1.mod_small(self.coeff_modulus)

        return Ciphertext(c0, c1, plain.scaling_factor, self.coeff_modulus)
Esempio n. 7
0
    def generate_secret_key(self, params):
        """Generates a secret key for BFV scheme.

        Args:
            params (Parameters): Parameters including polynomial degree,
                plaintext, and ciphertext modulus.
        """
        self.secret_key = SecretKey(
            Polynomial(params.poly_degree,
                       sample_triangle(params.poly_degree)))
Esempio n. 8
0
    def generate_public_key(self, params):
        """Generates a public key for BFV scheme.

        Args:
            params (Parameters): Parameters including polynomial degree,
                plaintext, and ciphertext modulus.
        """
        pk_coeff = Polynomial(
            params.poly_degree,
            sample_uniform(0, params.ciph_modulus, params.poly_degree))
        pk_error = Polynomial(params.poly_degree,
                              sample_triangle(params.poly_degree))
        p0 = pk_error.add(
            pk_coeff.multiply(self.secret_key.s, params.ciph_modulus),
            params.ciph_modulus).scalar_multiply(-1, params.ciph_modulus)
        p1 = pk_coeff
        self.public_key = PublicKey(p0, p1)