예제 #1
0
    def test_multiply_01(self):
        poly1 = Polynomial(4, sample_uniform(0, 30, 4))
        poly2 = Polynomial(4, sample_uniform(0, 30, 4))

        poly_prod = poly1.multiply_fft(poly2)
        poly_prod2 = poly1.multiply_naive(poly2)

        self.assertEqual(poly_prod.coeffs, poly_prod2.coeffs)
예제 #2
0
    def test_multiply_time(self):
        self.params.print_parameters()
        num_iterations = 1
        print("Number of multiplications: %d" % (num_iterations))
        total_time = 0

        for _ in range(num_iterations):
            vec1 = sample_uniform(0, self.plain_modulus, self.degree)
            vec2 = sample_uniform(0, self.plain_modulus, self.degree)
            total_time += self.run_test_multiply(vec1, vec2)

        print("Average time per multiply operation: %f seconds" %
              (total_time / num_iterations))
예제 #3
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)
예제 #4
0
    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)
예제 #5
0
    def test_fft_inverses(self):
        """Checks that fft_fwd and fft_inv are inverses.

        Performs the FFT on the input vector, performs the inverse FFT on the result,
        and checks that they match.

        Raises:
            ValueError: An error if test fails.
        """
        vec = sample_uniform(0, 7, self.num_slots)
        fft_vec = self.fft.fft_fwd(vec)
        to_check = self.fft.fft_inv(fft_vec)

        check_complex_vector_approx_eq(vec, to_check, 0.000001,
                                       "fft_inv is not the inverse of fft_fwd")
예제 #6
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)
예제 #7
0
    def test_embedding_inverses(self):
        """Checks that embedding and embedding_inv are inverses.

        Computes the canonical embedding on the input vector, performs the inverse embedding on the
        result, and checks that they match.

        Raises:
            ValueError: An error if test fails.
        """
        n = 1 << 5
        context = FFTContext(fft_length=4 * n)

        vec = sample_uniform(0, 7, n)
        fft_vec = context.embedding(vec)
        to_check = context.embedding_inv(fft_vec)

        check_complex_vector_approx_eq(vec, to_check, 0.000001,
                                       "embedding_inv is not the inverse of embedding")
 def test_large_encrypt_decrypt_01(self):
     vec = sample_uniform(0, self.large_plain_modulus, self.large_degree)
     self.run_test_large_encrypt_decrypt(vec)
예제 #9
0
 def test_multiply_01(self):
     vec1 = sample_uniform(0, self.plain_modulus, self.degree)
     vec2 = sample_uniform(0, self.plain_modulus, self.degree)
     self.run_test_multiply(vec1, vec2)
예제 #10
0
 def test_encode_decode_01(self):
     vec = sample_uniform(0, self.plain_modulus, self.degree)
     self.run_test_encode_decode(vec)