Пример #1
0
 def test_add_broadcast_reverse(self):
     """Add cyphertext by scalar value broadcast."""
     re = ReArray(plaintext=self.data, **self.reseal_args)
     other = 2
     func = np.add
     re = func(other, re)
     self.arithmetic_evaluator(re, other, func)
Пример #2
0
 def test_add_array_reverse(self):
     """Add cyphertext by (3) numpy array value broadcast."""
     re = ReArray(plaintext=self.data, **self.reseal_args)
     other = np.array([2, 3, 4])
     func = np.add
     re = func(other, re)
     self.arithmetic_evaluator(re, other, func)
Пример #3
0
 def test_multiply_array_reverse(self):
     """Multiply cyphertext by (3) numpy array."""
     re = ReArray(plaintext=self.data, **self.reseal_args)
     other = np.array([2, 3, 4])
     func = np.multiply
     re = func(other, re)
     self.arithmetic_evaluator(re, other, func)
Пример #4
0
 def test_add_re(self):
     """Add cyphertext to cyphertext."""
     re = ReArray(plaintext=self.data, **self.reseal_args)
     other = re
     func = np.add
     re = func(re, other)
     self.arithmetic_evaluator(re, np.array(other), func)
Пример #5
0
 def test_multiply_re(self):
     """Multiply cyphertext by cyphertext."""
     re = ReArray(plaintext=self.data, **self.reseal_args)
     other = re
     func = np.multiply
     re = func(re, other)
     self.arithmetic_evaluator(re, np.array(other), func)
Пример #6
0
 def test_multiply_broadcast(self):
     """Multiply cyphertext by scalar value broadcast."""
     re = ReArray(plaintext=self.data, **self.reseal_args)
     other = 2
     func = np.multiply
     re = func(re, other)
     self.arithmetic_evaluator(re, other, func)
Пример #7
0
 def test_forward(self):
     x = self.data
     cyphertext = ReArray(x, **self.reseal_args)
     node = Decrypt()
     plaintext = node.forward(cyphertext)
     np.testing.assert_array_almost_equal(plaintext,
                                          x,
                                          decimal=4,
                                          verbose=True)
Пример #8
0
 def test_isfinite(self):
     """Check that is finite gives us back results we are expecting."""
     x = self.data
     args = self.reseal_args
     a = ReArray(x, **args)
     f_0 = np.isfinite(a)
     f_1 = np.isfinite(x)
     self.assertIsInstance(f_0, np.ndarray)
     np.testing.assert_array_almost_equal(f_0, f_1, decimal=1, verbose=True)
Пример #9
0
 def test_pickle(self):
     """Ensure that pickling is still possible at this higher dimension."""
     import pickle
     re = ReArray(plaintext=self.data, **self.reseal_args)
     dump = pickle.dumps(re)
     re = pickle.loads(dump)
     self.assertIsInstance(re, ReArray)
     out = np.array(re)
     self.assertIsInstance(out, np.ndarray)
     self.assertEqual(out.shape, self.data.shape)
Пример #10
0
 def test_forward_enc(self):
     """Check encrypted forward pass works as expected."""
     data = self.data
     edata = ReArray(data, **self.reseal_args)
     self.assertTrue(np.array(edata).shape == data.shape)
     self.assertIsInstance(edata, ReArray)
     acti = self.test_forward(data=edata)
     self.assertIsInstance(acti, ReArray)
     plain = np.array(acti)
     self.assertIsInstance(plain, np.ndarray)
Пример #11
0
 def test_forward_decrypt(self):
     """Decrypt forward pass without re-encryption."""
     x = self.data
     cypher = ReArray(x, self.reseal_args)
     node = Rotate()
     plaintext = node.forward(cypher)
     self.assertIsInstance(plaintext, np.ndarray)
     np.testing.assert_array_almost_equal(plaintext,
                                          x,
                                          decimal=4,
                                          verbose=True)
Пример #12
0
 def test_sum(self):
     data = np.array([[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]])
     re = ReArray(plaintext=data, **self.reseal_args)
     sum = np.sum(re, axis=0)  # can only sum first axis
     self.assertIsInstance(sum, ReArray)
     plain_sum = np.array(sum)
     truth = np.sum(data, axis=0)
     np.testing.assert_array_almost_equal(plain_sum,
                                          truth,
                                          decimal=1,
                                          verbose=True)
Пример #13
0
 def test_forward_rotation(self):
     """Check that encryption parameters have been changed, on axis."""
     x = self.data
     encryptor = ReArray(
         np.array([1]),
         {
             "scheme": 2,  # seal.scheme_type.CKK,
             "poly_modulus_degree": 8192 * 2,  # 438
             # "coefficient_modulus": [60, 40, 40, 60],
             "coefficient_modulus": [45, 30, 30, 30, 30, 45
                                     ],  # coefficient mod length of 6
             "scale": pow(2.0, 30),
             "cache": True,
         })
     node = Rotate(encryptor=encryptor)
     cyphertext_in = ReArray(x, **self.reseal_args)
     cyphertext_out = node.forward(cyphertext_in)
     self.assertIsInstance(cyphertext_out, ReArray)
     out_cm = cyphertext_out.cyphertext[0].coefficient_modulus
     in_cm = cyphertext_in.cyphertext[0].coefficient_modulus
     self.assertNotEqual(in_cm, out_cm)
Пример #14
0
 def test_forward_with_encryptor(self):
     """Check cyphertext is generated from encryptor properly."""
     plaintext = self.data
     encryptor = ReArray(np.array([1]), **self.reseal_args)
     node = Rotate(encryptor=encryptor)
     cyphertext = node.forward(plaintext)
     self.assertIsInstance(cyphertext, ReArray)
     x = np.array(cyphertext)
     np.testing.assert_array_almost_equal(x,
                                          plaintext,
                                          decimal=4,
                                          verbose=True)
Пример #15
0
    def test_equality(self):
        """Check that ReArray param equality is being calculated properly."""
        a_arg = self.reseal_args = {
            "scheme": seal.scheme_type.CKKS,
            "poly_modulus_degree": 8192,
            "coefficient_modulus": [60, 40, 40, 60],
            "scale": pow(2.0, 40),
            "cache": True,
        }
        b_arg = self.reseal_args = {
            "scheme": seal.scheme_type.CKKS,
            "poly_modulus_degree": 8192,
            "coefficient_modulus": [60, 40, 60],  # <-- changed this
            "scale": pow(2.0, 40),
            "cache": True,
        }
        # TODO check changing every attribute of rearray not just coef_mod
        a = ReArray(np.array([1]), **a_arg)
        b = ReArray(np.array([1]), **b_arg)

        self.assertEqual(a, a)
        self.assertNotEqual(a, b)
Пример #16
0
 def test_forward_encrypt_axis(self):
     x = self.data
     axis = 1
     encryptor = ReArray(
         np.array([1]),
         {
             "scheme": 2,  # seal.scheme_type.CKK,
             "poly_modulus_degree": 8192 * 2,  # 438
             # "coefficient_modulus": [60, 40, 40, 60],
             "coefficient_modulus": [45, 30, 30, 30, 30, 45
                                     ],  # coefficient mod length of 6
             "scale": pow(2.0, 30),
             "cache": True,
         })
     node = Rotate(encryptor=encryptor, axis=1)
     cyphertext_in = ReArray(x, **self.reseal_args)
     cyphertext_lst_out = node.forward(cyphertext_in)
     self.assertIsInstance(cyphertext_lst_out, list)
     self.assertIsInstance(cyphertext_lst_out[0], ReArray)
     np.testing.assert_array_almost_equal(cyphertext_lst_out,
                                          cyphertext_in,
                                          decimal=4,
                                          verbose=True)
Пример #17
0
 def test_temp_encryptor_generator(self):
     """Check that FHE parameters are suitable for associated cost."""
     cost = 10
     factor = 1
     parms = ckks_param_heuristic(cost=cost)
     # print(parms)
     x = np.array([0.5, 0.3, 0.7, 0.9, 0.1])
     cyphertxt = ReArray(x, **parms)
     for _ in tqdm(range(cost)):
         cyphertxt = np.multiply(cyphertxt, factor)
         # print("RUN")
     # cyphertext should be at edge of computational chain
     # check by trying to tip it over the edge with one more mult
     with self.assertRaises(ValueError) as context:
         np.multiply(cyphertxt, factor)
     self.assertTrue("scale out of bounds" in str(context.exception))
     # print(x)
     # TODO: generalise next test for all factors
     np.testing.assert_array_almost_equal(cyphertxt, x,
                                          decimal=4,
                                          verbose=True)
Пример #18
0
 def test_add_ndarray(self):
     re = ReArray(plaintext=self.data, **self.reseal_args)
     filter = np.arange(3 * 3 * 3)
     filter.shape = (3, 3, 3)
     with self.assertRaises(ArithmeticError):
         re = re + filter
Пример #19
0
 def test_subtract_array_reverse(self):
     """Subtract cyphertext by (3) numpy array value broadcast."""
     re = ReArray(plaintext=self.data, **self.reseal_args)
     with self.assertRaises(TypeError):
         re = np.array([2, 3, 4]) - re
Пример #20
0
 def test_repr(self):
     re = ReArray(plaintext=self.data, **self.reseal_args)
     self.assertIsInstance(re.__repr__(), str)
Пример #21
0
 def test_numpify(self):
     """Ensure data is intact when decrypted."""
     re = ReArray(plaintext=self.data, **self.reseal_args)
     out = np.array(re)
     self.assertIsInstance(out, np.ndarray)
     self.assertEqual(out.shape, self.data.shape)
Пример #22
0
 def test_error_slot_overflow(self):
     """Testing that correctly errors when the data overflows encryption."""
     data = np.arange(64 * 320 * 320 * 3)
     data.shape = (64, 320, 320, 3)  # making it waay to big
     with self.assertRaises(OverflowError):
         ReArray(plaintext=data, **self.reseal_args)
Пример #23
0
 def test__error_data_type(self):
     """Testing that correctly errors when the data overflows encryption."""
     data = np.arange(64 * 32 * 32 * 3)
     data.shape = (64, 32, 32, 3)
     with self.assertRaises(TypeError):
         ReArray(plaintext=data.tolist(), **self.reseal_args)
Пример #24
0
 def test_object_creation(self):
     """Checking that the object creation is completed properly."""
     re = ReArray(plaintext=self.data, **self.reseal_args)
     self.assertIsInstance(re, ReArray)
Пример #25
0
 def test_subtract_re(self):
     """Subtract cyphertext by cyphertext."""
     re = ReArray(plaintext=self.data, **self.reseal_args)
     with self.assertRaises(TypeError):
         re = re - re
Пример #26
0
 def test_subtract_broadcast_reverse(self):
     """Subtract cyphertext by scalar value broadcast."""
     re = ReArray(plaintext=self.data, **self.reseal_args)
     with self.assertRaises(TypeError):
         re = 2 - re
Пример #27
0
 def test_floor_divide_broadcast_reverse(self):
     """Divide cyphertext by scalar value broadcast."""
     re = ReArray(plaintext=self.data, **self.reseal_args)
     with self.assertRaises(TypeError):
         re = 2 // re
Пример #28
0
 def test_floor_divide_array_reverse(self):
     """Divide cyphertext by (3) numpy array value broadcast."""
     re = ReArray(plaintext=self.data, **self.reseal_args)
     with self.assertRaises(TypeError):
         re = np.array([2, 3, 4]) // re
Пример #29
0
    def test_ann_shapes(self):
        """Test both numpy and ReArray input result in desired ann output."""
        import copy

        x_dummy = ReArray(self.data, **self.reseal_args)
        x = []
        num_inputs = 5
        for i in range(num_inputs):
            r = ReArray(clone=x_dummy, plaintext=self.data)
            x.append(r)
        self.assertIsInstance(x[i], ReArray)

        ann = Layer_ANN(weights=(num_inputs, ), bias=self.bias)
        np_ann = copy.deepcopy(ann)
        previous_activation = None

        for i in range(10):
            debug = {}
            print("ANN ITERATION:", i)
            debug["iteration"] = i
            # FORWARD PASS TEST
            activations = ann.forward(x)
            np_activations = np_ann.forward(np.array(x))
            # check that output is equal in shape to any single input ndarray
            # also check that ReArray and numpy produce the same results
            self.assertEqual(activations.shape, x_dummy.shape)
            self.assertEqual(np_activations.shape, x_dummy.shape)
            # self.assertListEqual(
            #     np.around(np.array(activations),
            #               decimals=2).flatten().tolist(),
            #     np.around(np.array(np_activations),
            #               decimals=2).flatten().tolist(),
            # )
            a = np.array(np_activations)
            # print(a, "\n", a.shape)
            for _ in range(1, a.ndim):
                a = a.sum(axis=-1)
                # print(a, "\n", a.shape)
            a = np.around(a.mean(axis=0), decimals=5)
            debug["activation-np"] = a

            # CHECK IF MORE ACCURATE PREDICTION
            # print(a)
            current_loss = 1 - a
            debug["target"] = 1
            debug["loss-np"] = current_loss
            if previous_activation is not None:
                previous_loss = 1 - previous_activation
                txt = "loss somehow more inacurate activations".format()
                # print("current:", abs(current_loss),
                #       "previous:", abs(previous_loss))
                # self.assertLess(abs(current_loss), abs(previous_loss), txt)
            previous_activation = a

            # BACKWARD PASS TEST
            gradient = ann.backward(1 - a)
            # print("GRADIENT", gradient)
            np_gradient = np_ann.backward(1 - a)
            debug["gradient-np"] = np_gradient
            print(debug)
            # we desire the resultant gradient to be of shape
            # (num_inputs, num_batches)
            desired_shape = (num_inputs, ) + (len(x_dummy), )
            self.assertEqual(gradient.shape, desired_shape)
            self.assertEqual(np_gradient.shape, desired_shape)
            # self.assertListEqual(
            #     np.around(np.array(gradient),
            #               decimals=2).flatten().tolist(),
            #     np.around(np.array(np_gradient),
            #               decimals=2).flatten().tolist(),
            # )

            # UPDATE ANN
            ann.update()
            np_ann.update()
Пример #30
0
 def test_floor_divide_re(self):
     """Floor divide cyphertext by cyphertext."""
     re = ReArray(plaintext=self.data, **self.reseal_args)
     with self.assertRaises(TypeError):
         re = re // re