def test_encode_decode(self): for i in range(100): en_i = FixedPointNumber.encode(i) de_en_i = en_i.decode() self.assertEqual(de_en_i, i) en_i = FixedPointNumber.encode(-i) de_en_i = en_i.decode() self.assertEqual(de_en_i, -i) for i in range(100): x = i * 0.6 en_x = FixedPointNumber.encode(x) de_en_x = en_x.decode() self.assertAlmostEqual(de_en_x, x) elem = np.ones(100) * np.random.rand() for x in elem: en_x = FixedPointNumber.encode(x) de_en_x = en_x.decode() self.assertAlmostEqual(de_en_x, x) elem = np.ones(100) * np.random.randint(100) for x in elem: en_x = FixedPointNumber.encode(x) de_en_x = en_x.decode() self.assertAlmostEqual(de_en_x, x)
def test_mul(self): x_li = np.ones(100) * np.random.randint(100) y_li = np.ones(100) * np.random.randint(1000) * -1 z_li = np.ones(100) * np.random.rand() t_li = range(0, 100) for i in range(x_li.shape[0]): x = x_li[i] y = y_li[i] z = z_li[i] t = t_li[i] en_x = FixedPointNumber.encode(x) en_res = (en_x * y + z) * t res = (x * y + z) * t de_en_res = en_res.decode() self.assertAlmostEqual(de_en_res, res) x = 9 en_x = FixedPointNumber.encode(x) for i in range(100): en_x = en_x + 5000 - 0.2 x = x + 5000 - 0.2 de_en_x = en_x.decode() self.assertAlmostEqual(de_en_x, x)
def test_eq(self): for i in range(100): x = np.random.randint(10) y = np.random.randint(10) en_x = FixedPointNumber.encode(x) en_y = FixedPointNumber.encode(y) z = x == y en_z = en_x == en_y self.assertEqual(en_z, z)
def test_gt(self): for i in range(100): x = np.random.randn() * 100 y = np.random.randn() * 100 en_x = FixedPointNumber.encode(x) en_y = FixedPointNumber.encode(y) z = x > y en_z = en_x > en_y self.assertEqual(en_z, z)
def test_div(self): for i in range(100): x = np.random.randn() * 100 y = np.random.randn() * 100 en_x = FixedPointNumber.encode(x) en_y = FixedPointNumber.encode(y) z = x / y en_z = en_x / en_y de_en_z = en_z.decode() self.assertAlmostEqual(de_en_z, z)
def __mul__(self, scalar): """return Multiply by an scalar(such as int, float) """ encode = FixedPointNumber.encode(scalar, self.public_key.n, self.public_key.max_int) plaintext = encode.encoding if plaintext < 0 or plaintext >= self.public_key.n: raise ValueError("Scalar out of bounds: %i" % plaintext) if plaintext >= self.public_key.n - self.public_key.max_int: # Very large plaintext, play a sneaky trick using inverses neg_c = gmpy_math.invert(self.ciphertext(False), self.public_key.nsquare) neg_scalar = self.public_key.n - plaintext ciphertext = gmpy_math.powmod(neg_c, neg_scalar, self.public_key.nsquare) else: ciphertext = gmpy_math.powmod(self.ciphertext(False), plaintext, self.public_key.nsquare) exponent = self.exponent + encode.exponent return PaillierEncryptedNumber(self.public_key, ciphertext, exponent)
def __add_scalar(self, scalar): """return PaillierEncryptedNumber: z = E(x) + y """ encoded = FixedPointNumber.encode(scalar, self.public_key.n, self.public_key.max_int, max_exponent=self.exponent) return self.__add_fixpointnumber(encoded)
def encrypt(self, value, precision=None, random_value=None): """Encode and Paillier encrypt a real number value. """ encoding = FixedPointNumber.encode(value, self.n, self.max_int, precision) obfuscator = random_value or 1 ciphertext = self.raw_encrypt(encoding.encoding, random_value=obfuscator) encryptednumber = PaillierEncryptedNumber(self, ciphertext, encoding.exponent) if random_value is None: encryptednumber.apply_obfuscator() return encryptednumber
def test_sub(self): x_li = np.ones(100) * np.random.randint(100) y_li = np.ones(100) * np.random.randint(1000) z_li = np.ones(100) * np.random.rand() t_li = range(100) for i in range(x_li.shape[0]): x = x_li[i] y = y_li[i] z = z_li[i] t = t_li[i] en_x = FixedPointNumber.encode(x) en_y = FixedPointNumber.encode(y) en_z = FixedPointNumber.encode(z) en_t = FixedPointNumber.encode(t) en_res = en_x - en_y - en_z - en_t res = x - y - z - t de_en_res = en_res.decode() self.assertAlmostEqual(de_en_res, res)
def test_add(self): x_li = np.ones(100) * np.random.randint(100) y_li = np.ones(100) * np.random.randint(1000) z_li = np.ones(100) * np.random.rand() t_li = range(100) for i in range(x_li.shape[0]): x = x_li[i] y = y_li[i] z = z_li[i] t = t_li[i] en_x = FixedPointNumber.encode(x) en_y = FixedPointNumber.encode(y) en_z = FixedPointNumber.encode(-z) en_t = FixedPointNumber.encode(-t) en_res = en_x + en_y + en_z + en_t res = x + y + (-z) + (-t) de_en_res = en_res.decode() self.assertAlmostEqual(de_en_res, res)
def __init__(self, sample_num: int, encrypter: PaillierEncrypt, precision=fix_point_precision, max_sample_weight=1.0, task_type=consts.CLASSIFICATION, g_min=None, g_max=None, class_num=1, mo_mode=False, sync_para=True): if task_type == consts.CLASSIFICATION: g_max = 1.0 g_min = -1.0 h_max = 1.0 elif task_type == consts.REGRESSION: if g_min is None and g_max is None: g_max = REGRESSION_MAX_GRADIENT # assign a large value for regression gradients g_min = -g_max else: g_max = g_max g_min = g_min h_max = 2.0 else: raise ValueError('unknown task type {}'.format(task_type)) self.g_max, self.g_min, self.h_max = g_max * max_sample_weight, g_min * max_sample_weight, h_max * max_sample_weight self.g_offset = abs(self.g_min) self.g_max_int, self.h_max_int = self._compute_packing_parameter( sample_num, precision) self.exponent = FixedPointNumber.encode(0, precision=precision).exponent self.precision = precision self.class_num = class_num self.mo_mode = mo_mode self.packer = GuestIntegerPacker( class_num * 2, [self.g_max_int, self.h_max_int] * class_num, encrypter=encrypter, sync_para=sync_para)
def encode(self, value, precision=None): return FixedPointNumber.encode(value, self.n, self.max_int, precision)
def __mul__(self, scalar): """return Multiply by an scalar(such as int, float) """ C1=sm2_crypt._kg(int(scalar,self.C1) C2=sm2_crypt._kg(int(scalar,self.C2) return ECCEncryptedNumber(self.public_key, C1,C2) def increase_exponent_to(self, new_exponent): """return ECCEncryptedNumber: new ECCEncryptedNumber with same value but having great exponent. """ if new_exponent < self.exponent: raise ValueError("New exponent %i should be great than old exponent %i" % (new_exponent, self.exponent)) factor = pow(FixedPointNumber.BASE, new_exponent - self.exponent) new_encryptednumber = self.__mul__(factor) new_encryptednumber.exponent = new_exponent return new_encryptednumber def __align_exponent(self, x, y): """return x,y with same exponet """ if x.exponent < y.exponent: x = x.increase_exponent_to(y.exponent) elif x.exponent > y.exponent: y = y.increase_exponent_to(x.exponent) return x, y def __add_scalar(self, scalar): """return ECCEncryptedNumber: z = E(x) + y """ encoded = FixedPointNumber.encode(scalar, self.public_key.n, self.public_key.max_int, max_exponent=self.exponent) return self.__add_fixpointnumber(encoded) def __add_fixpointnumber(self, encoded): """return ECCEncryptedNumber: z = E(x) + FixedPointNumber(y) """ if self.public_key.n != encoded.n: raise ValueError("Attempted to add numbers encoded against different public keys!") # their exponents must match, and align. x, y = self.__align_exponent(self, encoded) encrypted_scalar = x.public_key.raw_encrypt(y.encoding, 1) encryptednumber = self.__raw_add(x.ciphertext(False), encrypted_scalar, x.exponent) return encryptednumber def __add_encryptednumber(self, other): """return ECCEncryptedNumber: z = E(x) + E(y) """ C_x_plus_y_1=self.sm2_crypt._add_point(e_x.C1,e_y.C1) C_x_plus_y_2=self.sm2_crypt._add_point(e_x.C2,e_y.C2) return ECCEncryptedNumber(self.public_key, ciphertext, exponent) return encryptednumber def __raw_add(self, e_x, e_y, exponent): """return the integer E(x + y) given ints E(x) and E(y). """ C_x_plus_y_1=self.sm2_crypt._add_point(e_x.C1,e_y.C1) C_x_plus_y_2=self.sm2_crypt._add_point(e_x.C2,e_y.C2) return ECCEncryptedNumber(self.public_key, ciphertext, exponent) return encryptednumber
def fate_encode(value,precision=None): if precision == None: return FixedPointNumber.encode(value,None,None,PRECISION) else: return FixedPointNumber.encode(value,None,None,precision)