Пример #1
0
    def Enc_localData(self):
        """
        Protocol-Vertical Step2(local computation)

        :param self.X, self.Y: training dataset. X = (n,d) matrix, Y = n vector
        :param magnitude: parameter for data representation(if we use at most "l" fractional digits, then magnitude = 10**l)
        :return self.enc_A, self.enc_b: Enc(A), Enc(b) 
        :return self.labEnc_Xi, self.labEnc_Yi : labEnc(X), labEnc(Y)
        """

        # convert a data representation domain(real -> Integer)
        # R => Z<l+r> => Z<N>
        Xi = (self.Xi * self.magnitude).astype(int)

        # compute Enc(Ai)
        Xi_trans = np.transpose(Xi)
        Ai = np.matmul(Xi_trans, Xi).astype(int).tolist()
        enc_Ai = []
        for index, line in enumerate(Ai):
            enc_Ai.append([0] * index + [
                self.mpk.encrypt(space_mapping(item, self.mpk.n))
                for item in line[index:]
            ])

        # compute labEnc(Xi)
        Xi = Xi.tolist()
        labEnc_Xi = [[
            self.mpk.labEncrypt(self.seed,
                                (h_index + w_index * self.num_instances),
                                Xi_item)
            for Xi_item, w_index in zip(Xi_line, range(self.num_features))
        ] for Xi_line, h_index in zip(Xi, range(self.num_instances))]

        # Enc()
        if self.Yi is None:
            enc_bi = None
            labEnc_Yi = None
        else:
            #Enc(bi) = Enc(Xi_trans, Yi)
            Yi = (self.Yi * self.magnitude).astype(int)
            bi = np.matmul(Xi_trans, Yi).astype(int).tolist()
            enc_bi = [
                self.mpk.encrypt(space_mapping(item, self.mpk.n))
                for item in bi
            ]

            Yi = Yi.tolist()
            labEnc_Yi = [
                self.mpk.labEncrypt(self.seed, index, Yi_item)
                for Yi_item, index in zip(Yi, range(self.num_instances))
            ]

        # return
        self.enc_Ai = enc_Ai
        self.enc_bi = enc_bi
        self.labEnc_Xi = labEnc_Xi
        self.labEnc_Yi = labEnc_Yi
Пример #2
0
    def compute_merged_mask(self, enc_seed_i, num_instances, num_features):
        """
        Protocol-Vertical Step1(set up)
        - receive upk_i[Enc(seed_i)], label information[num_instances, num_features] from DataOweners
        - compute B'=Enc(sum(b_i*b_j), c'=Enc(sum(bi*b_0))
        
        :param enc_seed_i : upk_i
        :param num_instances, num_features : label information
        :return enc_mask_A, enc_mask_b: B', c' denoted in the paper
        """
        seed_i = self.msk.decrypt(enc_seed_i)

        mask_X_i = [[
            PRF(seed_i, h_index + w_index * num_instances, self.mpk.n)
            for w_index in range(num_features)
        ] for h_index in range(num_instances)]

        # compute B'[i,j]
        enc_mask_A = None
        t_mask_X_i = transpose(mask_X_i)
        if len(self.list_mask_X) != 0:
            for mask_X_j in self.list_mask_X:
                submask = [[
                    self.mpk.encrypt(
                        space_mapping(sum(map(operator.mul, vector1, vector2)),
                                      self.mpk.n)) for vector1 in t_mask_X_i
                ] for vector2 in transpose(mask_X_j)]

                if enc_mask_A is None:
                    enc_mask_A = submask
                else:
                    enc_mask_A += submask

        self.list_mask_X.append(mask_X_i)

        # compute c'[i]
        enc_mask_b = None
        if self.mask_Y is None:
            #self.mask_Y = [PRF(seed_i, index, self.mpk.n) for index in range(num_instances)]
            self.mask_Y = t_mask_X_i[0]
        else:
            enc_mask_b = [
                self.mpk.encrypt(
                    space_mapping(sum(map(operator.mul, vector1, self.mask_Y)),
                                  self.mpk.n)) for vector1 in t_mask_X_i
            ]

        return enc_mask_A, enc_mask_b
Пример #3
0
    def protocol_ridge_step2(self, enc_C, enc_d):
        """
        Protocol-ridge_version1 Step2(masked model computation)
        - receive Enc(C), Enc(d) from MLE and decrypt them
        - compute w_tilda and determinant of C(=A*R)
        
        :param enc_C: Enc(C) = Enc(A*R) received from MLE
        :param enc_d: Enc(d) = Enc(b + Ar) received from MLE
        :return w_tilda: inverse(C)*d mod N
        """
        # decrypt Enc(C) and Enc(d)
        dec_C = []
        for line in enc_C:
            dec_C.append([self.msk.decrypt(x) for x in line])

        dec_d = [self.msk.decrypt(y) for y in enc_d]

        # compute w_tilda( = inverse(C)*d) using gaussian Elimination algorithm
        temp = [dec_C[index] + [dec_d[index]] for index in range(len(dec_C))]
        w_tilda = gaussElimination(temp, self.mpk.n)

        for index, item in enumerate(w_tilda):
            w_tilda[index] = space_mapping(item, self.mpk.n)

        return w_tilda
Пример #4
0
 def labDecrypt(self, cipher):
     if isinstance(cipher, LabEncDataType1):
         return space_mapping(cipher.hm + self.decrypt(cipher.enc_mask),
                              self.public_key.n)
     else:
         print("cipher data type error in labDecrypt()")
         assert False
Пример #5
0
 def __mul__(self, other):
     # other should be one of (int, type1)LabEncDataType1
     if isinstance(other, LabEncDataType1):
         return other.enc_mask * self.hm + self.enc_mask * other.hm + space_mapping(
             self.hm * other.hm, self.enc_mask.public_key.n)
     elif isinstance(other, int):
         return LabEncDataType1(self.hm * other, self.enc_mask * other)
     else:
         print("type(other) :", type(other))
         assert False, "Datatype(other) error during LabEncData multiplication"
Пример #6
0
    def labEncrypt(self, seed, label, plain):
        # compute mask[b](b belong to Z(n))
        mask = PRF(seed, label, self.n)

        # hidden message = plain - b mod pk.n,
        hidden_message = space_mapping(plain - mask, self.n)

        # enc_mask = Enc(b)
        enc_mask = self.encrypt(mask)

        return LabEncDataType1(hidden_message, enc_mask)
Пример #7
0
    def computeEnc_Ab(self):
        """
        Protocol-Horizontal Step2(local computation)

        :param X, Y: training dataset. X = (n,d) matrix, Y = n vector
        :param magnitude: parameter for data representation(if we use at most "l" fractional digits, then magnitude = 10**l)
        :return enc_A: encrypted trans(X)*X 
        :return enc_b: encrypted trans(X)*Y 
        """
        # convert a data representation domain(real -> Integer)
        # R => Z<l+r> => Z<N>
        X = (self.X * self.magnitude).astype(int)
        Y = (self.Y * self.magnitude).astype(int).tolist()
        X_trans = np.transpose(X).tolist()
        num_instances = self.X.shape[0]
        num_features = self.X.shape[1]

        # compute A = trans(X)*X, encrypt A
        self.enc_A = []
        for index in range(num_features):
            # To improve efficiency, compute a triangular matrix of A
            # Because A_ij = A_ji
            self.enc_A.append([0] * index + [
                self.pk.encrypt(x) for x in [
                    space_mapping(sum(map(mul, X_trans[index], X_trans[j])),
                                  self.pk.n)
                    for j in range(index, num_features)
                ]
            ])

        # compute b = trans(X)*Y, encrypt b
        self.enc_b = [
            self.pk.encrypt(b) for b in [
                space_mapping(sum(map(mul, X_trans[i], Y)), self.pk.n)
                for i in range(num_features)
            ]
        ]
Пример #8
0
    def protocol_ridge_step3(self, w_tilda):
        """
        Protocol-ridge Step3(model reconstruction)
        - receive w_tilda and det(C)  and compute w*

        :param w_tilda: inverse(C)*d mod N
        :return w_star: Estimated coefficients for the linear regression problem computed by the suggested protocol(version1)
        """

        # compute w_dash = R*w_tilda - r
        w_dash = []
        for index in range(len(w_tilda)):
            w_dash.append(space_mapping((sum(map(mul, self.R[index], w_tilda)) - self.r[index]) , self.mpk.n))

        # rational reconstruction
        w_star = rationalRecon(w_dash, self.mpk.n)
        w_star = np.asarray(w_star)

        return w_star