def test_paillier_encryption(self):

        # randomly generate a number
        a = random.getrandbits(64)

        # Key Generation
        pub_key, priv_key = paillier.he_key_gen()
        # encrypt the random number
        enc_a = paillier.encrypt(pub_key, a)

        # test if decryption works.
        assert a == paillier.decrypt(priv_key, enc_a)
def enc_tree_node(he_pub_key, prf_hash_key, ope, tree_node, metaData):
    """
    Process the node
    :param metaData:
    :param he_pub_key: the homomorphic key
    :param prf_hash_key: hash key for hmac
    :param ope: ope object for encrypting the comparison value
    :param tree_node: the Interier object (node) in the decision tree.
    :return: ope encrypted tree
    """
    # If it is not leaf, then encode the comp_val using OPE.
    if not isinstance(tree_node, bs.Leaf):

        num = metaData.affine_transform(tree_node.cmp_val)

        if num > MAX_NUM_OPE_ENC or num < 0:
            raise Exception(
                "Invalid input: input is out of range (0, " + MAX_NUM_OPE_ENC +
                "), system cannot encrypt", num)

        tree_node.cmp_val = ope.encrypt(num)

        hmac_code = hmac_msg(prf_hash_key, tree_node.feature_name)
        tree_node.feature_name = hmac_code

        # Recurse to the if true tree_node
        enc_tree_node(he_pub_key, prf_hash_key, ope, tree_node.if_true_child,
                      metaData)
        # Recurse to the if false tree_node
        enc_tree_node(he_pub_key, prf_hash_key, ope, tree_node.if_false_child,
                      metaData)
    # else it is the bs.Leaf
    else:
        # Value....
        tree_node.value = paillier.encrypt(he_pub_key, tree_node.value)
    def test_serialization(self):

        pub_key, priv_key = paillier.he_key_gen()

        # randomly generate 64 bit number
        message = random.getrandbits(64)

        # Encrypt a message
        encrypted_message = paillier.encrypt(pub_key, message)
        # serialize it to json format
        json_str = paillier.ciphertext_serialization(pub_key,
                                                     encrypted_message)

        # deserialize the json format
        pub_key, encrypted_number = paillier.ciphertext_deserialization(
            json_str)
        # decrypted the message using the correct private key.
        check_number = paillier.decrypt(priv_key, encrypted_number)

        assert message == check_number
    def test_paillier_negative_num_test(self):

        pub_key, priv_key = paillier.he_key_gen()

        # Negative number test #
        x = random.randint((-1) * random.getrandbits(64), 0)

        # encrypt negative number x
        enc_x = paillier.encrypt(pub_key, x)
        # encrypted negative number -x (a positive num)
        enc_pos_x = paillier.encrypt(pub_key, (-1) * x)

        paillier.assert_ciphertext(enc_pos_x)
        paillier.assert_ciphertext(enc_x)
        # homomorphic addition (enc_sum <- enc(0))
        enc_sum = enc_pos_x + enc_x

        dec_x = paillier.decrypt(priv_key, enc_x)
        dec_sum = paillier.decrypt(priv_key, enc_sum)
        assert dec_x == x
        assert dec_sum == 0
def client_decrypt_prediction_multiclass(private_key, predictions):
    """
    Client calls this function to compute the multi-class prediction -- i.e. it outputs the most probable class for the
    predicted class.
    This methods first decrypts the aggregated predictions using @private_key@,
    then calls the client_side_multiclass_compute() function.
    :param private_key: the private key to decrypt the values.
    :param predictions: encrypted list of predictions (each entry of the list is a list of encrypted scores.)
    :return: the results as numpy.ndarray()
    """
    decrypted_pred_list = []
    for enc_pred in predictions:
        decrypted_scores = []
        for enc_scores in enc_pred:
            # decrypts the encrypted scores.
            decrypted_scores.append(paillier.decrypt(private_key, enc_scores))
        decrypted_pred_list.append(decrypted_scores)
    result = client_side_multiclass_compute(decrypted_pred_list)
    return np.array(result)
Exemplo n.º 6
0
    def test_get_private_key(self):
        """
        Testing the Client Key Wrapper.
        """

        # Build the ClientKey
        prf_key = token_bytes(16)
        ope_encrypter = OPE(token_bytes(16))
        public_key, private_key = paillier.he_key_gen()
        clientKey = ClientKey(private_key, prf_key, ope_encrypter)

        a = randrange(pow(2, 30))
        b = randrange(pow(2, 30))

        # test the ope key
        ea = clientKey.get_ope_encryptor().encrypt(a)
        eb = clientKey.get_ope_encryptor().encrypt(b)
        assert (a < b) == (ea < eb)

        ea = public_key.encrypt(a)
        eb = public_key.encrypt(b)
        assert clientKey.get_private_key().decrypt(ea + eb) == a + b
    def test_ope_node(self):
        """
        Test vector on evaluating the decision tree based on OPE
        :return:
        """
        t1 = '0:[Pclass<3] yes=1,no=2,missing=1\n\t1:[Fare<13] yes=3,no=4,missing=3\n\t\t3:leaf=323\n\t\t4:[' \
             'Age<42] yes=9,no=10,missing=10\n\t\t\t9:leaf=32434\n\t\t\t10:leaf=43124\n\t2:[Age<6] yes=5,' \
             'no=6,missing=6\n\t\t5:[SibSp<32] yes=11,no=12,' \
             'missing=11\n\t\t\t11:leaf=9473\n\t\t\t12:leaf=836\n\t\t6:leaf=46\n '

        input_vector = pd.read_csv('test_files/test_prediction_input.csv')

        ################################################################################################
        # The folowing is to compute the scores for the decision tree on input vectors in plaintext!
        ################################################################################################
        feature_set = set()

        # As this test just to test the correctness of the encrypt_tree_node method
        # add min_max just to 'fake' some min-max value for this test
        tree = boostparser.parse_tree(t1,
                                      feature_set,
                                      min_max={
                                          'min': 0,
                                          'max': 1
                                      })

        # The score list value in plaintext.
        score_value = list()
        # get each row indexing with input vector's head
        for index, row in input_vector.iterrows():
            score_value.append(tree.eval(row))

        ################################################################################################
        # The folowing is to compute the scores based on the OPE processed decision tree
        ################################################################################################

        # Set up encrytion materials.
        # token bytes calls the os.urandom().
        prf_key = token_bytes(16)
        OPE_key = token_bytes(16)
        encrypter = OPE(OPE_key)

        # create a copy of the input vector and plaintext trees
        test_input_vector = input_vector.copy()
        enc_tree = tree

        public_key, private_key = paillier.he_key_gen()

        # as this only test the enc_tree_node ope, add fake metadata (min and max) for this computation
        # just for testing purposes.
        metaDataMinMax = MetaData({'min': 0, 'max': 1000})

        # 1. Encrypts the input vector for prediction (using prf_key_hash and ope-encrypter) based on the feature set.
        ppbooster.enc_input_vector(prf_key, encrypter, feature_set,
                                   test_input_vector, metaDataMinMax)

        # 2. process the tree into ope_enc_tree
        ppbooster.enc_tree_node(public_key, prf_key, encrypter, enc_tree,
                                metaDataMinMax)

        # 3. OPE evaluation based on OPE encrypted values in the tree nodes.
        encrypted_value = list()
        for index, row in test_input_vector.iterrows():
            score = enc_tree.eval(row)
            encrypted_value.append(score)

        dec_value = list()
        for c in encrypted_value:
            dec_value.append(paillier.decrypt(private_key, c))

        # 4. compare
        assert dec_value == score_value
    def test_paillier_api(self):

        pub_key, priv_key = paillier.he_key_gen()

        # randomly generate the a and b from [0, sixty_four_bit_num)
        a = random.getrandbits(64)
        b = random.getrandbits(64)

        # encrypt a & b
        enc_a = paillier.encrypt(pub_key, a)
        enc_b = paillier.encrypt(pub_key, b)

        # homomorphically evaluate a + b
        # enc_a_b = enc(a+b)
        paillier.assert_ciphertext(enc_a)
        paillier.assert_ciphertext(enc_b)
        enc_a_b = enc_a + enc_b

        # try to catch the exception if the input is NOT a ciphertext
        try:
            paillier.assert_ciphertext(a)
        except ValueError:
            print("Input was not a ciphertext")
            assert True

        scalar = random.getrandbits(64)

        # encrypted_c_scalar = enc(scalar * a)
        encrypted_c_scalar = scalar * enc_a

        # perform all decryptions
        dec_a_b = paillier.decrypt(priv_key, enc_a_b)
        dec_c_scalar = paillier.decrypt(priv_key, encrypted_c_scalar)

        assert dec_a_b == a + b
        assert dec_c_scalar == scalar * a