def dec_recompose(
    enc_wts
):  # function to decrypt the aggregated weight vector received from parameter server
    dec_wts = []
    global_aggregate = {}
    chunks = len(enc_wts)
    for h in range(chunks):
        plain_agg = Plaintext()
        decryptor.decrypt(enc_wts[h], plain_agg)
        crtbuilder.decompose(plain_agg)
        dec_wts += [
            plain_agg.coeff_at(h) for h in range(plain_agg.coeff_count())
        ]
    for h in range(len(dec_wts)):
        if dec_wts[h] > int(parms.plain_modulus().value() - 1) / 2:
            dec_wts[h] = dec_wts[h] - parms.plain_modulus().value()
    for h in range(len(dec_wts)):
        dec_wts[h] = float(dec_wts[h]) / (1000 * m)
    pos_start = 0
    for param_tensor in flattened_lengths:
        pos_end = pos_start + flattened_lengths[param_tensor]
        global_aggregate.update({
            param_tensor:
            torch.tensor(dec_wts[pos_start:pos_end]).reshape(
                shapes[param_tensor])
        })
        pos_start = pos_end
    return global_aggregate
コード例 #2
0
ファイル: decryptors.py プロジェクト: Ysejal/simple-fhe
def decrypt(item):
    decryptor = simplefhe._decryptor

    if simplefhe._private_key is None:
        raise ValueError(
            'Private key has not been set. Decryption not possible.')

    if simplefhe._relin_keys is None:
        raise ValueError(
            'Relinearization keys have not been set. Decryption not possible.')

    result = Plaintext()
    decryptor.decrypt(item._ciphertext, result)

    mode = item._mode
    if mode['type'] == 'int':
        if decryptor.invariant_noise_budget(item._ciphertext) == 0:
            raise ValueError(
                'The noise budget has been exhausted.' +
                ' Try calling `simplefhe.initialize` with a larger `poly_modulus_degree` or a smaller `max_int`.'
            )
        result = result.to_string()
        result = int(result, 16)
        if result > mode['modulus'] // 2:
            result -= mode['modulus']
        return result
    else:
        decoded = DoubleVector()
        item._mode['encoder'].decode(result, decoded)
        return float(decoded[0])
コード例 #3
0
def rotateAdd(ct, length, lowerbound=1):
    res = Plaintext()
    while length > lowerbound:
        length //= 2
        oldCt = copy.deepcopy(ct)
        evaluator.rotate_rows(ct, length, gal_keys)
        evaluator.add(ct, oldCt)
        print(length)
    decryptor.decrypt(ct, res)
    crtbuilder.decompose(res)
    #print_matrix([res.coeff_at(i) for i in range(res.coeff_count())])
    return [res.coeff_at(i) for i in range(lowerbound)]
コード例 #4
0
    def dot_matrix_with_matrix_transpose(self, matrix_a: CipherMatrix,
                                         matrix_b: CipherMatrix):
        result_matrix = CipherMatrix(rows=matrix_a.rows, cols=matrix_a.cols)

        rows_a = matrix_a.rows
        cols_b = matrix_b.rows

        for i in range(rows_a):
            vector_dot_products = []
            zeros = Plaintext()

            for j in range(cols_b):
                vector_dot_products += [
                    self.dot_vector(matrix_a[i], matrix_b[j])
                ]

                if j == 0:
                    zero = DoubleVector()
                    self.encoder.encode(zero, vector_dot_products[j].scale(),
                                        zeros)
                    self.evaluator.mod_switch_to_inplace(
                        zeros, vector_dot_products[j].parms_id())
                    self.evaluator.add_plain(vector_dot_products[j], zeros,
                                             result_matrix[i])
                else:
                    self.evaluator.rotate_vector_inplace(
                        vector_dot_products[j], -j, self.galois_keys)
                    self.evaluator.add_inplace(result_matrix[i],
                                               vector_dot_products[j])

        for vec in result_matrix:
            self.evaluator.relinearize_inplace(vec, self.relin_keys)
            self.evaluator.rescale_to_next_inplace(vec)

        return result_matrix
コード例 #5
0
def print_plain(D):
    # function to print out all elements in a matrix
    for row in D:
        for values in row:
            p = Plaintext()
            decryptor.decrypt(values, p)
            print(encoderF.decode(p))
コード例 #6
0
    def masking_output(self):
        spread_mask = generate_random_mask(
            self.modulus, [self.num_output_batch, self.degree])
        self.output_mask_s = torch.zeros(self.num_output_unit).double()

        pod_vector = uIntVector()
        pt = Plaintext()
        for idx_output_batch in range(self.num_output_batch):
            encoding_tensor = torch.zeros(self.degree, dtype=torch.float)
            for idx_piece in range(self.num_piece_in_batch):
                idx_output_unit = self.index_output_batch_to_units(
                    idx_output_batch, idx_piece)
                if idx_output_unit is False:
                    break
                padded_span = self.num_elem_in_piece
                start_piece = idx_piece * padded_span
                arr = spread_mask[idx_output_batch,
                                  start_piece:start_piece + padded_span]
                encoding_tensor[start_piece:start_piece + padded_span] = arr
                self.output_mask_s[idx_output_unit] = arr.double().sum()
            encoding_tensor = pmod(encoding_tensor, self.modulus)
            pod_vector.from_np(encoding_tensor.numpy().astype(np.uint64))
            self.batch_encoder.encode(pod_vector, pt)
            self.evaluator.add_plain_inplace(self.output_cts[idx_output_batch],
                                             pt)

        self.output_mask_s = pmod(self.output_mask_s, self.modulus)
コード例 #7
0
def print_plain(D):
    # function to print out all elements in a matrix
    if (type(D[0]) != list):
        for element in D:
            p = Plaintext()
            decryptor.decrypt(element, p)
            print(encoderF.decode(p), end=" ")
        print()

    else:
        for row in D:
            for values in row:
                p = Plaintext()
                decryptor.decrypt(values, p)
                print(encoderF.decode(p), end=" ")
            print()
コード例 #8
0
    def decrypt_ciphertext(self, cipher):

        plain = Plaintext()
        self.decryptor.decrypt(cipher, plain)
        pl = self.encoder.decode(plain)

        return pl
コード例 #9
0
 def compute_with_weight(self, weight_tensor):
     assert (weight_tensor.shape == self.weight_shape)
     pod_vector = uIntVector()
     pt = Plaintext()
     self.output_cts = encrypt_zeros(self.num_output_batch,
                                     self.batch_encoder, self.encryptor,
                                     self.degree)
     for idx_output_batch, idx_input_batch in product(
             range(self.num_output_batch), range(self.num_input_batch)):
         encoding_tensor = torch.zeros(self.degree)
         is_w_changed = False
         for idx_piece in range(self.num_piece_in_batch):
             idx_row, idx_col_start, idx_col_end = \
                 self.index_weight_batch_to_units(idx_output_batch, idx_input_batch, idx_piece)
             if idx_row is False:
                 continue
             is_w_changed = True
             padded_span = self.num_elem_in_piece
             data_span = idx_col_end - idx_col_start
             start_piece = idx_piece * padded_span
             encoding_tensor[start_piece:start_piece +
                             data_span] = weight_tensor[
                                 idx_row, idx_col_start:idx_col_end]
         if not is_w_changed:
             continue
         encoding_tensor = pmod(encoding_tensor, self.modulus)
         pod_vector.from_np(encoding_tensor.numpy().astype(np.uint64))
         self.batch_encoder.encode(pod_vector, pt)
         sub_dotted = Ciphertext(self.input_cts[idx_input_batch])
         self.evaluator.multiply_plain_inplace(sub_dotted, pt)
         self.evaluator.add_inplace(self.output_cts[idx_output_batch],
                                    sub_dotted)
コード例 #10
0
    def decrypt_new_grid(self, encrypted_new_grid, dim):
        '''
        Decrypts a homomorphic-encrypted grid by looping through every element,
        decrypt it and then applying the decoding rules to get the new board state

        :param encrypted_new_grid:
        :param dim:
        :return:
        '''

        new_grid = numpy.zeros(dim*dim, dtype='i').reshape(dim,dim)
        
        for i in range(dim):
          for j in range(dim):
              plain = Plaintext()
              
              encrypted = encrypted_new_grid[dim*i + j]
                  
              self.decryptor.decrypt(encrypted, plain)
              value = self.encoder.decode_int32(plain)
              
              # transformation / decoding rules
              if(value <= 0):
                  new_grid[i][j] = 0
              elif(value > 0):
                  new_grid[i][j] = 1
              
        return new_grid
def send_enc():
    list_params = []
    for param_tensor in model.state_dict():
        list_params += model.state_dict()[param_tensor].flatten().tolist()
    length = len(list_params)
    list_params_int = [0] * length
    for h in range(length):
        # Convert float values to integer so that they can be encrypted
        # length_integer is the maximum number of digits in the integer representation.
        # The returned value min_prec is the min number of dec places before first non-zero digit in float value.
        list_params_int[h] = round(list_params[h], 3) * 1000
        #length_integer = 3
        #list_params_int[h], min_prec = conv_int(list_params[h], length_integer)
    slot_count = int(crtbuilder.slot_count())
    pod_iter = iter(list_params_int)
    pod_sliced = list(
        chunk_pad(pod_iter, slot_count, 0)
    )  # partitions the vector pod_vec into chunks of size equal to the number of batching slots
    for h in range(len(pod_sliced)):
        pod_sliced[h] = [
            int(pod_sliced[h][j]) for j in range(len(pod_sliced[h]))
        ]
        for j in range(len(pod_sliced[h])):
            if pod_sliced[h][j] < 0:
                pod_sliced[h][j] = parms.plain_modulus().value(
                ) + pod_sliced[h][j]
    comm.send(len(pod_sliced), dest=0, tag=1)
    for chunk in range(len(pod_sliced)):
        encrypted_vec = Ciphertext()
        plain_vector = Plaintext()
        crtbuilder.compose(list(pod_sliced[chunk]), plain_vector)
        encryptor.encrypt(plain_vector, encrypted_vec)
        comm.send(encrypted_vec, dest=0, tag=chunk + 2)
コード例 #12
0
    def decrypt(self, encrypted_matrix=None, keygen=None):
        """

        :return:
        """

        if encrypted_matrix is not None:
            self.encrypted_matrix = encrypted_matrix

        assert self._encrypted, "No encrypted matrix"

        del self.matrix
        shape = self.encrypted_matrix.shape

        self.matrix = np.empty(shape)

        if keygen is not None:
            self._update_cryptors(keygen)

        for i in range(shape[0]):
            for j in range(shape[1]):
                plain_text = Plaintext()
                self.decryptor.decrypt(self.encrypted_matrix[i, j], plain_text)
                self.matrix[i, j] = self.encoder.decode(plain_text)

        self._encrypted = False
        return np.copy(self.matrix)
コード例 #13
0
ファイル: encrypt4.py プロジェクト: overgter/CrimeCamera
def search():
    y = np.load('./class_lables.npy')
    X = np.load('all_descriptors.npy')
    centroids = pickle.load('./centroids.npy')
    if len(ENC_CONF) > 0:
        params = ENC_CONF[0]
        context = ENC_CONF[1]
        frac_encoder = ENC_CONF[2]
        encryptor = ENC_CONF[3]
        evaluator = ENC_CONF[4]
        decryptor = ENC_CONF[5]

        encrypted_matrix = Ciphertext()
        e1 = encryptor.encrypt(X[56], encrypted_matrix)
        encrypted_matrix = Ciphertext()
        e2 = encryptor.encrypt(X[128], encrypted_matrix)
        encrypted_matrix = Ciphertext()
        e3 = encryptor.encrypt(X[300], encrypted_matrix)
        test_query = [e1, e2, e3]
        y_test = [y[56], y[128], y[300]]

        encrypted_matrix = Ciphertext()
        c1 = encryptor.encrypt(centroids[0], encrypted_matrix)
        encrypted_matrix = Ciphertext()
        c2 = encryptor.encrypt(centroids[1], encrypted_matrix)
        encrypted_matrix = Ciphertext()
        c3 = encryptor.encrypt(centroids[2], encrypted_matrix)
        encrypted_matrix = Ciphertext()
        c4 = encryptor.encrypt(centroids[3], encrypted_matrix)

        centroids_enc = [c1, c2, c3, c4]

        for i, x in enumerate(test_query):
            print("Received descriptor A for the person")
            for j, c in enumerate(centroids_enc):
                print(
                    "Calculating distance between ciphertext A and Fixed Person from cluster #{}:"
                    .format(j))
                time_start = time.time()
                enc_res = euclidean_dist_enc(evaluator, x, c)
                time_end = time.time()
                print("Done. Time: {} miliseconds".format(
                    (str)(1000 * (time_end - time_start))))
                print("Encrypted distance result is calculated")

                plain_result = Plaintext()
                print("Decrypting result: ")
                time_start = time.time()
                decryptor.decrypt(enc_res, plain_result)
                res = frac_encoder.encode(plain_result)
                time_end = time.time()
                print("Decrypted. Time: {} miliseconds".format(
                    (str)(1000 * (time_end - time_start))))
                print("Distance between Current and Fixed Person #{}: {:.2f}".
                      format(j, res))
                if (res < 0.6):
                    print("🔦Found Match")
                break
                time.sleep(4)  #delay for 20 sec
コード例 #14
0
def learn(y_data, x_data, evaluator, m_data, b_data, encoder, encryptor,
          learningRate_e, decryptor):
    y_data_encoded = encoder.encode(y_data)
    x_data_encoded = encoder.encode(x_data)
    m_data_encoded = encoder.encode(m_data)
    b_data_encoded = encoder.encode(b_data)

    # Encrypting the values is easy.
    y_e_data = Ciphertext()
    x_e_data = Ciphertext()
    encryptor.encrypt(y_data_encoded, y_e_data)
    encryptor.encrypt(x_data_encoded, x_e_data)

    m_e_current = Ciphertext()
    b_e_current = Ciphertext()

    encryptor.encrypt(m_data_encoded, m_e_current)
    encryptor.encrypt(b_data_encoded, b_e_current)

    # Calculate y_e_predicted = m_e_c*x_e_data _ b_e_c
    ypred_data = 1.0
    ypred_data_encoded = encoder.encode(ypred_data)
    ypred_e_data = Ciphertext()
    encryptor.encrypt(ypred_data_encoded, ypred_e_data)
    evaluator.multiply(ypred_e_data, x_e_data)
    evaluator.multiply(ypred_e_data, m_e_current)
    evaluator.add(ypred_e_data, b_e_current)

    # delta = ypred_e - y_e
    evaluator.negate(y_e_data)
    evaluator.add(ypred_e_data, y_e_data)

    # Update m and b
    m_e_current = updateM(evaluator, m_e_current, x_e_data, learningRate_e,
                          ypred_e_data)
    b_e_current = updateB(evaluator, b_e_current, learningRate_e, ypred_e_data)

    retVals = []
    m_learnt = Plaintext()
    decryptor.decrypt(m_e_current, m_learnt)
    retVals.append(encoder.decode(m_learnt))
    b_learnt = Plaintext()
    decryptor.decrypt(b_e_current, b_learnt)
    retVals.append(encoder.decode(b_learnt))

    return retVals
コード例 #15
0
 def dec(self, cipher_arr):
     n = len(cipher_arr)
     arr = np.empty(n, int)
     for i in range(n):
         p = Plaintext()
         self._decryptor.decrypt(cipher_arr[i], p)
         arr[i] = self._encoder.decode_int64(p)
     return arr
コード例 #16
0
def encode_float(item: float) -> Plaintext:
    """Encodes the given float into a plaintext."""
    mode = simplefhe._mode
    encoder = mode['encoder']
    scale = mode['default_scale']

    output = Plaintext()
    encoder.encode(item, scale, output)
    return output
コード例 #17
0
 def multiplyDeterminant(M, determinant):
     p=Plaintext()
     # need to send user D so that user can send back -1/D either in encrypted form or decrypted form
     decryptor.decrypt(determinant, p)
     d= (-1/encoderF.decode(p))
     delta=encoderF.encode(d)
     for i in range(len(M)):
         for j in range(len(M[0])):
             evaluator.multiply_plain(M[i][j], delta)
コード例 #18
0
def mat_decrypt(matrix, decryption, encoding):
	result=np.zeros((matrix.shape[0], matrix.shape[1])).tolist()
	for i in range(matrix.shape[0]):
		for j in range(matrix.shape[1]):
			plain_result = Plaintext()
			decryption.decrypt(matrix[i][j], plain_result)
			result[i][j] = (str)(encoding.decode_int32(plain_result))
	
	return np.asarray(result)
コード例 #19
0
def encrypt_zeros(num_batch, batch_encoder, encryptor, degree):
    cts = [Ciphertext() for i in range(num_batch)]
    pod_vector = uIntVector()
    pt = Plaintext()
    zeros_tensor = np.zeros(degree).astype(np.int64)
    pod_vector.from_np(zeros_tensor)
    batch_encoder.encode(pod_vector, pt)
    for i in range(num_batch):
        encryptor.encrypt(pt, cts[i])
    return cts
コード例 #20
0
    def encrypt(self, matrix: np.array):
        matrix = Matrix.from_numpy_array(array=matrix)
        cipher_matrix = CipherMatrix(rows=matrix.rows, cols=matrix.cols)

        for i in range(matrix.rows):
            encoded_row = Plaintext()
            self.encoder.encode(matrix[i], self.scale, encoded_row)
            self.encryptor.encrypt(encoded_row, cipher_matrix[i])

        return cipher_matrix
コード例 #21
0
ファイル: seal_tests.py プロジェクト: uriariel/ppsvm
def test_seal_env_running():
    n = np.ones((3, 3))
    s = SealOps.with_env()
    m = s.encrypt(n)
    x = s.get_vector_range(m[0], 1, 2)
    p = Plaintext()
    p1 = DoubleVector()
    s.decryptor.decrypt(x, p)
    s.encoder.decode(p, p1)
    print(p1)
コード例 #22
0
def decrypt_matrix(M):
    M_dec = []
    for x in M:
        m = []
        for y in x:
            p = Plaintext()
            decryptor.decrypt(y, p)
            m.append(encoderF.decode(p))
        M.append(m)
    return (M)
コード例 #23
0
def encode_int(item: int) -> Plaintext:
    """Encodes the given integer into a plaintext."""
    modulus = simplefhe._mode['modulus']

    if item <= -modulus // 2 or item > modulus // 2:
        raise ValueError(f'Integer {item} is too large to be represented.' +
                         ' Try increasing `max_int` during initialization.')

    item = item % modulus
    item_str = hex(item)[2:]
    return Plaintext(item_str)
コード例 #24
0
    def decrypt(self, cipher_matrix: CipherMatrix) -> Matrix:
        matrix = Matrix(rows=cipher_matrix.rows, cols=cipher_matrix.cols)

        for i in range(matrix.rows):
            row = Vector()
            encoded_row = Plaintext()
            self.decryptor.decrypt(cipher_matrix[i], encoded_row)
            self.encoder.decode(encoded_row, row)
            matrix[i] = row

        return matrix
コード例 #25
0
ファイル: encrypt4.py プロジェクト: overgter/CrimeCamera
def decompose_plain(slot_count, x, crtbuilder):
    if type(x) is np.ndarray:
        DESC_SIZE = x.shape[0]
    x = x.reshape(1, DESC_SIZE)
    zeros = np.zeros((1, slot_count), dtype=np.int32)
    zeros[:x.shape[0], :x.shape[1]] = x
    pad_matrix = zeros.flatten()
    print("Decomposed flattened vector", pad_matrix)
    plain_matrix = Plaintext()
    crtbuilder.compose(pad_matrix, plain_matrix)
    return plain_matrix
コード例 #26
0
    def get_vector_range(self, vector_a: Ciphertext, i: int,
                         j: int) -> Ciphertext:
        cipher_range = Ciphertext()

        one_and_zeros = DoubleVector([0.0 if x < i else 1.0 for x in range(j)])
        plain = Plaintext()
        self.encoder.encode(one_and_zeros, self.scale, plain)
        self.evaluator.mod_switch_to_inplace(plain, vector_a.parms_id())
        self.evaluator.multiply_plain(vector_a, plain, cipher_range)

        return cipher_range
コード例 #27
0
def encryption(value):
    # IntegerEncoder with base 2
    encoder = IntegerEncoder(context.plain_modulus())

    # generate public/private keys
    keygen = KeyGenerator(context)
    public_key = keygen.public_key()
    secret_key = keygen.secret_key()

    # encrypts public key
    encryptor = Encryptor(context, public_key)

    # perform computations on ciphertexts
    evaluator = Evaluator(context)

    # decrypts secret key
    decryptor = Decryptor(context, secret_key)

    # perform encryptions
    plaintext = encoder.encode(value)

    # convert into encrypted ciphertext
    encrypt = Ciphertext()
    encryptor.encrypt(plaintext, encrypt)
    print("Encryption successful!")
    print("Encrypted ciphertext: " + (str)(value) + " as " +
          plaintext.to_string())

    # noise budget of fresh encryptions
    print("Noise budget: " + (str)(decryptor.invariant_noise_budget(encrypt)) +
          " bits")

    # decrypts result
    result = Plaintext()
    decryptor.decrypt(encrypt, result)
    print("Decryption successful!")

    print("Plaintext: " + result.to_string())

    # decode for original integer
    print("Original node: " + (str)(encoder.decode_int32(result)) + "\n")
コード例 #28
0
def sumDiagProducts(diagMatrix, ct_vector):
    template = [0] * len(diagMatrix[0])
    plain_matrix = Plaintext()
    crtbuilder.compose(template, plain_matrix)
    accumulated = Ciphertext()
    encryptor.encrypt(plain_matrix, accumulated)
    for i, row in enumerate(diagMatrix):
        print("_____________________________")
        print(i, row)
        temp = copy.deepcopy(ct_vector)
        # the last number needs to wrap around! 
        evaluator.rotate_rows(temp, i, gal_keys)

        decryptor.decrypt(temp, plain_matrix)
        crtbuilder.decompose(plain_matrix)
        print_matrix([plain_matrix.coeff_at(i) for i in range(plain_matrix.coeff_count())])

        encodedRow = Plaintext()
        crtbuilder.compose(row, encodedRow)
        evaluator.multiply_plain(temp, encodedRow)
        evaluator.add(accumulated, temp)
        decryptor.decrypt(accumulated, plain_matrix)
        crtbuilder.decompose(plain_matrix)
        print([plain_matrix.coeff_at(i) for i in range(4)])
    return accumulated
コード例 #29
0
ファイル: encrypt4.py プロジェクト: overgter/CrimeCamera
def test2():
    img_path = '00001.jpg'
    img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
    print("Original image dimensions {}".format(img.shape))
    sift = cv2.xfeatures2d.SIFT_create()
    (kps, desc) = sift.detectAndCompute(img, None)

    desc = preprocessing.normalize(np.array(
        desc.flatten()[:DESC_SIZE]).reshape(1, DESC_SIZE),
                                   norm='l2')
    descriptor_vec1 = desc
    descriptor_vec2 = descriptor_vec1
    context = config()
    public_key, secret_key = keygen(context)

    encoder = IntegerEncoder(context.plain_modulus())
    encryptor = Encryptor(context, public_key)
    crtbuilder = PolyCRTBuilder(context)
    evaluator = Evaluator(context)
    decryptor = Decryptor(context, secret_key)

    slot_count = (int)(crtbuilder.slot_count())
    print("slot count {}".format(slot_count))
    print("Plaintext shape", descriptor_vec1.shape)
    plain_matrix = decompose_plain(slot_count, descriptor_vec1, crtbuilder)

    for i in range(10000):
        encrypted_matrix = Ciphertext()
        print("Encrypting: ")
        time_start = time.time()
        encryptor.encrypt(plain_matrix, encrypted_matrix)
        time_end = time.time()
        print("Done in time {}".format((str)(1000 * (time_end - time_start))))

        print("Square:")
        time_start = time.time()
        evaluator.square(encrypted_matrix)
        time_end = time.time()
        print("Square is done in {} miliseconds".format(
            (str)(1000 * (time_end - time_start))))

        plain_result = Plaintext()
        print("Decryption plain: ")
        time_start = time.time()
        decryptor.decrypt(encrypted_matrix, plain_result)
        time_end = time.time()
        print("Decryption is done in {} miliseconds".format(
            (str)(1000 * (time_end - time_start))))
        # print("Plaintext polynomial: {}".format(plain_result.to_string()))
        # print("Decoded integer: {}".format(encoder.decode_int32(plain_result)))
        print("Noise budget {} bits".format(
            decryptor.invariant_noise_budget(encrypted_matrix)))
コード例 #30
0
def multiplyDeterminant(M, determinant):
	p=Plaintext()
	plainMul_pool = multiprocessing.Pool(processes=num_cores)
	# need to send user D so that user can send back -1/D either in encrypted form or decrypted form
	decryptor.decrypt(determinant, p)
	d= (-1/encoderF.decode(p))
	delta=encoderF.encode(d)
	del(p)
	X=[]
	for i in range(len(M)):
		X.append(plainMul_pool.starmap(parallel_plainMultiplication, zip(M[i],itertools.repeat(delta))))
	plainMul_pool.close()
	return(X)