def test_convert(self): secint = mpc.SecInt() secint8 = mpc.SecInt(8) secint16 = mpc.SecInt(16) secfld257 = mpc.SecFld(257) secfld263 = mpc.SecFld(263) secfxp = mpc.SecFxp() secfxp16 = mpc.SecFxp(16) x = [secint8(-100), secint8(100)] y = mpc.convert(x, secint) self.assertEqual(mpc.run(mpc.output(y)), [-100, 100]) y = mpc.convert(y, secint8) self.assertEqual(mpc.run(mpc.output(y)), [-100, 100]) x = [secint16(i) for i in range(10)] y = mpc.convert(x, secfld257) self.assertEqual(mpc.run(mpc.output(y)), list(range(10))) x = [secfld257(i) for i in range(10)] y = mpc.convert(x, secfld263) self.assertEqual(mpc.run(mpc.output(y)), list(range(10))) x = [secint(-100), secint(100)] y = mpc.convert(x, secfxp) self.assertEqual(mpc.run(mpc.output(y)), [-100, 100]) y = mpc.convert(y, secint) self.assertEqual(mpc.run(mpc.output(y)), [-100, 100]) x = [secfxp16(-100.25), secfxp16(100.875)] y = mpc.convert(x, secfxp) self.assertEqual(mpc.run(mpc.output(y)), [-100.25, 100.875]) y = mpc.convert(y, secfxp16) self.assertEqual(mpc.run(mpc.output(y)), [-100.25, 100.875])
def transmit_sample(host, port): """ Transmits random JSON-encoded data sample to a given IP address and port number. host : IP address of host (string) port : Port number (int) """ #read samples and split to secrets living_data = np.loadtxt('living_data.csv', delimiter=",") temperature = living_data[:, 0].tolist() airco_status = living_data[:, 1].tolist() secnum = mpc.SecFxp() #secnum = mpc.SecInt() temperature_sec_ = [secnum(a) for a in temperature] airco_status_sec_ = [secnum(a) for a in airco_status] stype = type(temperature_sec_[0]) field = stype.field temperature_sec = [a.df for a in temperature_sec_] airco_status_sec = [a.df for a in airco_status_sec_] m = len(host) t = 1 N = len(temperature) for i in np.arange(N): # Generate shares for each data sample in temperature and airco_status temperature_shares = [None] * m aircostatus_shares = [None] * m temperature_shares = thresha.random_split([temperature_sec[i]], t, m) aircostatus_shares = thresha.random_split([airco_status_sec[i]], t, m) temperature_shares_str = [] for other_pid, data in enumerate(temperature_shares): data = field.to_bytes(data) temperature_shares_str.append(base64.b64encode(data).decode()) aircostatus_shares_str = [] for other_pid, data in enumerate(aircostatus_shares): data = field.to_bytes(data) aircostatus_shares_str.append(base64.b64encode(data).decode()) print(temperature_shares_str) #send shares to MPC servers for j in np.arange(m): sample = { "timestamp": datetime.datetime.now().isoformat(), "temperature": temperature_shares_str[j], "airco": aircostatus_shares_str[j] } sample_json = json.dumps(sample) l.debug(f"Sample: {sample_json}") r = requests.put(f"http://{host[j]}:{port[j]}/store", json=sample_json) #verify=os.getenv("CERT_PATH")) l.debug(f"HTTP response code: {r.status_code}")
async def main(): if sys.argv[1:]: n = int(sys.argv[1]) else: n = 5 print('Setting input to default =', n) s = [(-1)**i * (i + n//2)**2 for i in range(n)] secnum = mpc.SecInt() print('Using secure integers:', secnum) x = list(map(secnum, s)) async with mpc: mpc.random.shuffle(secnum, x) # secret in-place random shuffle print('Randomly shuffled input:', await mpc.output(x)) x = mpc.sorted(x, key=lambda a: a**2) # sort on absolute value print('Sorted by absolute value:', await mpc.output(x)) secnum = mpc.SecFxp() print('Using secure fixed-point numbers:', secnum) x = list(map(secnum, s)) async with mpc: mpc.random.shuffle(secnum, x) # secret in-place random shuffle print('Randomly shuffled input:', await mpc.output(x)) x = mpc.seclist(x) x.sort(reverse=True) # in-place sort in descending order print('Sorted by descending value:', await mpc.output(list(x)))
async def main(): if sys.argv[1:]: N = int(sys.argv[1]) else: N = 8 print('Setting input to default =', N) await mpc.start() secint = mpc.SecInt() print('Using secure integers:', secint) for n in range(2, N + 1): print(n, await mpc.output(random_derangement(n, secint))) secfxp = mpc.SecFxp() print('Using secure fixed-point numbers:', secfxp) for n in range(2, N + 1): print(n, await mpc.output(random_derangement(n, secfxp))) secpfld = mpc.SecFld(l=max(len(mpc.parties), (N - 1)).bit_length()) print('Using secure prime fields:', secpfld) for n in range(2, N + 1): print(n, await mpc.output(random_derangement(n, secpfld))) secbfld = mpc.SecFld(char2=True, l=max(len(mpc.parties), (N - 1)).bit_length()) print('Using secure binary fields:', secbfld) for n in range(2, N + 1): print(n, await mpc.output(random_derangement(n, secbfld))) await mpc.shutdown()
def test_secfxp(self): secfxp = mpc.SecFxp() a = getrandbits(secfxp, 10) self.assertTrue(a.integral) a = mpc.run(mpc.output(a)) self.assertGreaterEqual(int(a), 0) self.assertLessEqual(int(a), 2**10 - 1) x = mpc.run(mpc.output(random_unit_vector(secfxp, 6))) self.assertEqual(int(sum(x)), 1) x = mpc.run(mpc.output(random_permutation(secfxp, range(1, 9)))) self.assertSetEqual({a for a in range(1, 9)}, {int(a) for a in x}) x = mpc.run(mpc.output(random_derangement(secfxp, range(2)))) self.assertListEqual([1, 0], [int(a) for a in x]) a = mpc.run(mpc.output(choice(secfxp, [0.8, 0.9, 1.0, 1.1, 1.2]))) self.assertAlmostEqual(float(a), 1.0, 0) a = mpc.run(mpc.output(choice(secfxp, [0.08, 0.09, 0.1, 0.11, 0.12]))) self.assertAlmostEqual(float(a), 0.1, 1) a = mpc.run(mpc.output(random(secfxp))) self.assertGreaterEqual(float(a), 0) self.assertLessEqual(float(a), 1) a = mpc.run(mpc.output(uniform(secfxp, 13.13, 13.17))) self.assertGreaterEqual(float(a), 13.13) self.assertLessEqual(float(a), 13.17) a = mpc.run(mpc.output(uniform(secfxp, -13.13, -13.17))) self.assertGreaterEqual(float(a), -13.17) self.assertLessEqual(float(a), -13.13)
def test_misc(self): secint = mpc.SecInt() secfxp = mpc.SecFxp() secfld = mpc.SecFld() for secnum in (secint, secfxp, secfld): self.assertEqual(type(mpc.run(mpc.output(secnum(0), raw=True))), secnum.field) self.assertEqual(mpc.run(mpc.output(mpc._reshare([secnum(0)]))), [0]) self.assertEqual(mpc.run(mpc.output(mpc.all(secnum(1) for _ in range(5)))), True) self.assertEqual(mpc.run(mpc.output(mpc.all([secnum(1), secnum(1), secnum(0)]))), False) self.assertEqual(mpc.run(mpc.output(mpc.any(secnum(0) for _ in range(5)))), False) self.assertEqual(mpc.run(mpc.output(mpc.any([secnum(0), secnum(1), secnum(1)]))), True) self.assertEqual(mpc.run(mpc.output(mpc.sum([secnum(1)], start=1))), 2) self.assertEqual(mpc.run(mpc.output(mpc.prod([secnum(1)], start=1))), 1) self.assertEqual(mpc.run(mpc.output(mpc.sum([secnum(1)], start=secnum(1)))), 2) self.assertEqual(mpc.run(mpc.output(mpc.min(secint(i) for i in range(-1, 2, 1)))), -1) self.assertEqual(mpc.run(mpc.output(mpc.argmin(secint(i) for i in range(-1, 2, 1))[0])), 0) self.assertEqual(mpc.run(mpc.output(mpc.max(secfxp(i) for i in range(-1, 2, 1)))), 1) self.assertEqual(mpc.run(mpc.output(mpc.argmax(secfxp(i) for i in range(-1, 2, 1))[0])), 2) self.assertEqual(mpc.run(mpc.output(list(mpc.min_max(map(secfxp, range(5)))))), [0, 4]) x = (secint(i) for i in range(-3, 3)) s = [0, -1, 1, -2, 2, -3] self.assertEqual(mpc.run(mpc.output(mpc.sorted(x, key=lambda a: a*(2*a+1)))), s) x = (secfxp(i) for i in range(5)) self.assertEqual(mpc.run(mpc.output(mpc.sorted(x, reverse=True))), [4, 3, 2, 1, 0]) self.assertEqual(mpc.run(mpc.output(mpc.sum(map(secint, range(5))))), 10) self.assertEqual(mpc.run(mpc.output(mpc.sum([secfxp(2.75)], start=3.125))), 5.875) self.assertEqual(int(mpc.run(mpc.output(mpc.prod(map(secfxp, range(1, 5)))))), 24) self.assertEqual(int(mpc.run(mpc.output(mpc.prod([secfxp(1.414214)]*4)))), 4)
def test_if_else_if_swap(self): secfld = mpc.SecFld() a = secfld(0) b = secfld(1) c = secfld(1) self.assertEqual(mpc.run(mpc.output(c.if_else(a, b))), 0) self.assertEqual(mpc.run(mpc.output(mpc.if_swap(1 - c, a, b))), [0, 1]) self.assertEqual(mpc.run(mpc.output(mpc.if_else(c, [a, b], [b, a]))), [0, 1]) self.assertEqual(mpc.run(mpc.output((1 - c).if_swap(a, b))), [0, 1]) secint = mpc.SecInt() a = secint(-1) b = secint(1) c = secint(1) self.assertEqual(mpc.run(mpc.output(c.if_swap([a, b], [b, a])[0])), [1, -1]) self.assertEqual(mpc.run(mpc.output(mpc.if_else(1 - c, b, b))), 1) self.assertEqual(mpc.run(mpc.output(mpc.if_swap(c, a, b))), [1, -1]) self.assertEqual(mpc.run(mpc.output((1 - c).if_else([a, b], [b, a]))), [1, -1]) secfxp = mpc.SecFxp() a = secfxp(-1.0) b = secfxp(1.0) c = secfxp(1) self.assertEqual(mpc.run(mpc.output(c.if_else([a, a], [b, b]))), [-1.0, -1.0]) self.assertEqual(mpc.run(mpc.output(mpc.if_swap(1 - c, a, b))), [-1.0, 1.0]) self.assertEqual(mpc.run(mpc.output(mpc.if_swap(c, 0.0, 1.0))), [1.0, 0.0]) self.assertEqual(mpc.run(mpc.output((1 - c).if_else(0.0, 1.0))), 1.0)
def main(): if not mpc.args: m = 8 print('Setting input to default =', m) else: m = int(mpc.args[0]) mpc.start() secfld = mpc.SecFld(l=max(len(mpc.parties), (m - 1)).bit_length() + 1) print('Using secure fields:', secfld) for n in range(2, m + 1): print(n, mpc.run(mpc.output(random_derangement(n, secfld)))) secint = mpc.SecInt() print('Using secure integers:', secint) for n in range(2, m + 1): print(n, mpc.run(mpc.output(random_derangement(n, secint)))) secfxp = mpc.SecFxp() print('Using secure fixed-point numbers:', secfxp) for n in range(2, m + 1): print(n, mpc.run(mpc.output(random_derangement(n, secfxp)))) mpc.shutdown()
def test_secfxp(self): secfxp = mpc.SecFxp() a = getrandbits(secfxp, 10) self.assertTrue(a.integral) a = mpc.run(mpc.output(a)) self.assertGreaterEqual(int(a), 0) self.assertLessEqual(int(a), 2**10 - 1) x = mpc.run(mpc.output(random_unit_vector(secfxp, 3))) self.assertEqual(int(sum(x)), 1) x = mpc.run(mpc.output(random_permutation(secfxp, range(1, 9)))) self.assertSetEqual(set(map(int, x)), set(range(1, 9))) x = mpc.run(mpc.output(random_derangement(secfxp, [0.0, 1.0]))) self.assertListEqual(list(map(int, x)), [1, 0]) a = mpc.run(mpc.output(choice(secfxp, [0.08, 0.09, 0.1, 0.11, 0.12]))) self.assertAlmostEqual(a, 0.1, 1) a = mpc.run(mpc.output(random(secfxp))) self.assertGreaterEqual(a, 0) self.assertLessEqual(a, 1) a = mpc.run(mpc.output(uniform(secfxp, 13.13, 13.17))) self.assertGreaterEqual(a, 13.13) self.assertLessEqual(a, 13.17) a = mpc.run(mpc.output(uniform(secfxp, -13.13, -13.17))) self.assertGreaterEqual(a, -13.17) self.assertLessEqual(a, -13.13)
def test_if_else(self): secfld = mpc.SecFld() a = secfld(0) b = secfld(1) c = secfld(1) self.assertEqual(mpc.run(mpc.output(mpc.if_else(c, a, b))), 0) self.assertEqual(mpc.run(mpc.output(mpc.if_else(1 - c, a, b))), 1) self.assertEqual(mpc.run(mpc.output(mpc.if_else(c, [a, b], [b, a]))), [0, 1]) self.assertEqual( mpc.run(mpc.output(mpc.if_else(1 - c, [a, b], [b, a]))), [1, 0]) secint = mpc.SecInt() a = secint(-1) b = secint(1) c = secint(1) self.assertEqual(mpc.run(mpc.output(mpc.if_else(c, a, b))), -1) self.assertEqual(mpc.run(mpc.output(mpc.if_else(1 - c, a, b))), 1) self.assertEqual(mpc.run(mpc.output(mpc.if_else(c, [a, b], [b, a]))), [-1, 1]) self.assertEqual( mpc.run(mpc.output(mpc.if_else(1 - c, [a, b], [b, a]))), [1, -1]) secfxp = mpc.SecFxp() a = secfxp(-1.0) b = secfxp(1.0) c = secfxp(1) self.assertEqual(mpc.run(mpc.output(mpc.if_else(c, a, b))), -1.0) self.assertEqual(mpc.run(mpc.output(mpc.if_else(1 - c, a, b))), 1.0) self.assertEqual(mpc.run(mpc.output(mpc.if_else(c, 0.0, 1.0))), 0.0) self.assertEqual(mpc.run(mpc.output(mpc.if_else(1 - c, 0.0, 1.0))), 1.0)
async def main(): if sys.argv[1:]: n = int(sys.argv[1]) else: n = 5 print('Setting input to default =', n) s = [(-1)**i * (i + (n // 2))**2 for i in range(n)] await mpc.start() global secnum secnum = mpc.SecInt() print('Using secure integers:', secnum) x = list(map(secnum, s)) print('Array:', await mpc.output(x)) print('Sorted array:', await mpc.output(bsort(x))) secnum = mpc.SecFxp() print('Using secure fixed-point numbers:', secnum) x = list(map(secnum, s)) print('Input array:', await mpc.output(x)) print('Sorted array:', await mpc.output(bsort(x))) await mpc.shutdown()
def test_secfxp(self): secfxp = mpc.SecFxp() x = [1, 1, 2, 2, 3, 4, 4, 4, 6] * 5 random.shuffle(x) x = list(map(secfxp, x)) self.assertAlmostEqual(mpc.run(mpc.output(mean(x))), 3, delta=1) self.assertAlmostEqual(mpc.run(mpc.output(median(x))), 3) self.assertAlmostEqual(mpc.run(mpc.output(mode(x))), 4) x = [1, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 6, 6] * 100 random.shuffle(x) x = list(map(lambda a: a * 2**-4, x)) x = list(map(secfxp, x)) self.assertAlmostEqual(mpc.run(mpc.output(mean(x))), (2**-4) * 10/3, delta=1) y = [1.75, 1.25, -0.25, 0.5, 1.25, -3.5] * 5 random.shuffle(y) x = list(map(secfxp, y)) self.assertAlmostEqual(mpc.run(mpc.output(mean(x))), statistics.mean(y), 4) self.assertAlmostEqual(mpc.run(mpc.output(variance(x))), statistics.variance(y), 2) self.assertAlmostEqual(mpc.run(mpc.output(stdev(x))), statistics.stdev(y), 3) self.assertAlmostEqual(mpc.run(mpc.output(pvariance(x))), statistics.pvariance(y), 2) self.assertAlmostEqual(mpc.run(mpc.output(pstdev(x))), statistics.pstdev(y), 3) self.assertAlmostEqual(mpc.run(mpc.output(median(x))), statistics.median(y), 4) self.assertAlmostEqual(mpc.run(mpc.output(quantiles(x))), statistics.quantiles(y), 4) self.assertAlmostEqual(mpc.run(mpc.output(quantiles(x, method='inclusive'))), statistics.quantiles(y, method='inclusive'), 4) x = list(map(secfxp, [1.0]*10)) self.assertAlmostEqual(mpc.run(mpc.output(mode(x))), 1) k = mpc.options.sec_param mpc.options.sec_param = 1 # force no privacy case self.assertAlmostEqual(mpc.run(mpc.output(mode(x))), 1) mpc.options.sec_param = k x[0] = secfxp(1.5) self.assertRaises(ValueError, mode, x) x = [1, 2, 3, 4, 5, 6, 7, 8, 9] y = [1, 2, 3, 1, 2, 3, 1, 2, 3] self.assertEqual(covariance(x, y), 0.75) self.assertEqual(correlation(x, x), 1.0) self.assertAlmostEqual(correlation(x, y), 0.316, 3) self.assertEqual(linear_regression(x, y)[1], 1.5) x = list(map(secfxp, x)) y = list(map(secfxp, y)) self.assertEqual(mpc.run(mpc.output(covariance(x, y))), 0.75) self.assertAlmostEqual(mpc.run(mpc.output(correlation(x, x))), 1.0, 2) self.assertAlmostEqual(mpc.run(mpc.output(correlation(x, y))), 0.32, 2) self.assertAlmostEqual(mpc.run(mpc.output(linear_regression(x, y)[1])), 1.5, 2) x = [1, 2, 3, 4, 5, 6, 7, 8, 9] y = [9, 8, 7, 6, 5, 4, 3, 2, 1] self.assertEqual(covariance(x, y), -7.5) self.assertEqual(correlation(x, y), -1.0) self.assertEqual(linear_regression(x, y)[1], 10.0) x = list(map(secfxp, x)) y = list(map(secfxp, y)) self.assertAlmostEqual(mpc.run(mpc.output(covariance(x, y))), -7.5, 2) self.assertAlmostEqual(mpc.run(mpc.output(correlation(x, y))), -1.0, 2) self.assertAlmostEqual(mpc.run(mpc.output(linear_regression(x, y)[1])), 10.0, 2)
def test_errors(self): secfxp = mpc.SecFxp() self.assertRaises(ValueError, mpc.all, [secfxp(0.5)]) self.assertRaises(ValueError, mpc.any, [secfxp(0.5)]) self.assertRaises(ValueError, mpc.min, []) self.assertRaises(ValueError, mpc.max, []) self.assertRaises(ValueError, mpc.min_max, []) self.assertRaises(ValueError, mpc.unit_vector, secfxp(1.5), 2)
def test_secfxp(self): secfxp = mpc.SecFxp() s = seclist([5, -3, 2, 5, 5], secfxp) self.assertFalse(mpc.run(mpc.output(s < s))) t = s[:] t[-1] += 1 self.assertTrue(mpc.run(mpc.output(s < t))) s = [[1, 0], [0, 1], [0, 0], [1, 1]] ss = mpc.sorted([[secfxp(a) for a in _] for _ in s], key=seclist) self.assertEqual([mpc.run(mpc.output(_)) for _ in ss], sorted(s))
def test_pickle(self): xsecfld = mpc.SecFld(256) psecfld = mpc.SecFld(257) secint = mpc.SecInt() secfxp = mpc.SecFxp() secflt = mpc.SecFlt() seccl = mpc.SecClassGroup(-23) a = seccl.group((2, 1)) # NB: mpc.transfer() calls pickle.dumps() and pickle.loads() self.assertEqual( mpc.run(mpc.output(mpc.run(mpc.transfer(xsecfld(12), senders=0)))), 12) self.assertEqual( mpc.run(mpc.output(mpc.run(mpc.transfer(psecfld(12), senders=0)))), 12) self.assertEqual( mpc.run(mpc.output(mpc.run(mpc.transfer(secint(12), senders=0)))), 12) self.assertEqual( mpc.run(mpc.output(mpc.run(mpc.transfer(secfxp(12.5), senders=0)))), 12.5) self.assertEqual( mpc.run(mpc.output(mpc.run(mpc.transfer(secflt(12.5), senders=0)))), 12.5) self.assertEqual( mpc.run( mpc.output(mpc.run(mpc.transfer(seccl((2, 1, 3)), senders=0)))), a) self.assertEqual(mpc.run(mpc.transfer(xsecfld.field(12), senders=0)), 12) self.assertEqual(mpc.run(mpc.transfer(psecfld.field(12), senders=0)), 12) self.assertEqual(mpc.run(mpc.transfer(secint.field(12), senders=0)), 12) self.assertEqual(mpc.run(mpc.transfer(secfxp.field(13), senders=0)), 13) self.assertEqual(mpc.run(mpc.transfer(xsecfld.field.modulus, 0)), xsecfld.field.modulus) x = [(xsecfld(12), psecfld(12), secint(12), secfxp(12.5), secflt(12.5), seccl((2, 1, 3))), [ xsecfld.field(12), psecfld.field(12), secint.field(12), secfxp.field(13), a ], xsecfld.field.modulus] y = mpc.run(mpc.transfer(x, senders=0)) self.assertTrue( all(mpc.run(mpc.output(a == b)) for a, b in zip(y[0], x[0]))) self.assertEqual(y[1], x[1]) self.assertEqual(y[2], x[2])
def receive_computed_shares_mpc(function, hosts, ports): #start mpc servers results = mp_compute_functions_mpc(function, hosts, ports) print(f'response length: {len(results)}') secnum = mpc.SecFxp() data_sample = secnum(10) stype = type(data_sample) field = stype.field print(f'party 0: {results[0].text}') print(f'party 1: {results[1].text}') print(f'party 2: {results[2].text}')
def send_shares_mpc_single(data, dataname, datapart, hosts, ports): #print(f'Sending each data sample...') if data.ndim == 1: cols = data.shape[0] rows = 1 name_cols = len(dataname) elif data.ndim == 2: rows, cols = data.shape name_cols = len(dataname) if cols != name_cols: raise ValueError('Data and dataname columns do no match %d and %d' % (cols,name_cols)) secnum = mpc.SecFxp() test_sample = secnum(10) stype = type(test_sample) field = stype.field data_sec = np.vectorize(secnum)(data) print(data_sec.shape) m = len(hosts) t = 1 N = rows #N = 3 for k in np.arange(cols): for i in np.arange(N): # Generate shares for each data sample data_shares = [None]*m data_shares = thresha.random_split([data_sec[k, i].df], t, m) data_shares_str = [] for other_pid, data in enumerate(data_shares): data = field.to_bytes(data) data_shares_str.append(base64.b64encode(data).decode()) #print(data_shares_str) timestamp = datetime.datetime.now().isoformat() for j in np.arange(m): sample = { "timestamp" : timestamp, dataname[k] : data_shares_str[j] } sample_json = json.dumps(sample) send_data(sample_json, datapart, hosts[j], ports[j])
async def main(): if sys.argv[1:]: n = int(sys.argv[1]) else: n = 10 print('Setting input to default =', n) secfld = mpc.SecFld(min_order=max(len(mpc.parties) + 1, n)) secint = mpc.SecInt() secfxp = mpc.SecFxp() await xprint(n, mpc.unit_vector, secfld) # NB: secret_index does not work with secfld await xprint(n, mpc.unit_vector, secint) await xprint(n, secret_index, secint) await xprint(n, mpc.unit_vector, secfxp) await xprint(n, secret_index, secfxp)
def test_misc(self): secint = mpc.SecInt() secfxp = mpc.SecFxp() secfld = mpc.SecFld() for secnum in (secint, secfxp, secfld): self.assertEqual(mpc.run(mpc.output(mpc._reshare([secnum(0)]))), [0]) self.assertEqual( mpc.run(mpc.output(mpc.all(secnum(1) for _ in range(5)))), True) self.assertEqual( mpc.run(mpc.output(mpc.all([secnum(1), secnum(1), secnum(0)]))), False) self.assertEqual( mpc.run(mpc.output(mpc.any(secnum(0) for _ in range(5)))), False) self.assertEqual( mpc.run(mpc.output(mpc.any([secnum(0), secnum(1), secnum(1)]))), True) self.assertEqual( mpc.run(mpc.output(mpc.sum([secnum(1)], start=1))), 2) self.assertEqual( mpc.run(mpc.output(mpc.prod([secnum(1)], start=1))), 1) self.assertEqual( mpc.run(mpc.output(mpc.sum([secnum(1)], start=secnum(1)))), 2) self.assertEqual( mpc.run(mpc.output(mpc.min(secint(i) for i in range(-1, 2, 1)))), -1) self.assertEqual( mpc.run(mpc.output(mpc.max(secfxp(i) for i in range(-1, 2, 1)))), 1) self.assertEqual( mpc.run(mpc.output(list(mpc.min_max(map(secfxp, range(5)))))), [0, 4]) self.assertEqual(mpc.run(mpc.output(mpc.sum(map(secint, range(5))))), 10) self.assertEqual( mpc.run(mpc.output(mpc.sum([secfxp(2.72)], start=3.14))), 5.86) self.assertEqual( int(mpc.run(mpc.output(mpc.prod(map(secfxp, range(1, 5)))))), 24) self.assertEqual( int(mpc.run(mpc.output(mpc.prod([secfxp(1.414214)] * 4)))), 4)
async def main(): if sys.argv[1:]: N = int(sys.argv[1]) else: N = 8 print('Setting input to default =', N) await mpc.start() await xprint(N, 'integers', mpc.SecInt()) await xprint(N, 'fixed-point numbers:', mpc.SecFxp()) bound = max(len(mpc.parties) + 1, N) await xprint(N, 'prime fields', mpc.SecFld(min_order=bound)) await xprint(N, 'binary fields', mpc.SecFld(char=2, min_order=bound)) await xprint(N, 'quinary fields', mpc.SecFld(char=5, min_order=bound)) await xprint(N, 'extension fields (medium prime)', mpc.SecFld(order=11**7)) await xprint(N, 'extension fields (larger prime)', mpc.SecFld(order=1031**3)) await mpc.shutdown()
def test_secfxp(self): secfxp = mpc.SecFxp() x = [1, 1, 2, 2, 3, 4, 4, 4, 6] * 5 random.shuffle(x) x = list(map(secfxp, x)) self.assertAlmostEqual(mpc.run(mpc.output(mean(x))).signed(), 3, delta=1) self.assertAlmostEqual(mpc.run(mpc.output(median(x))).signed(), 3) self.assertAlmostEqual(mpc.run(mpc.output(mode(x))).signed(), 4) x = [1, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 6, 6] * 100 random.shuffle(x) x = list(map(lambda a: a * 2**-4, x)) x = list(map(secfxp, x)) self.assertAlmostEqual(mpc.run(mpc.output(mean(x))).signed(), (2**-4) * 10 / 3, delta=1) y = [1.75, 1.25, -0.25, 0.5, 1.25, -3.5] * 5 random.shuffle(y) x = list(map(secfxp, y)) self.assertAlmostEqual(float(mpc.run(mpc.output(mean(x)))), statistics.mean(y), 4) self.assertAlmostEqual(float(mpc.run(mpc.output(variance(x)))), statistics.variance(y), 2) self.assertAlmostEqual(float(mpc.run(mpc.output(stdev(x)))), statistics.stdev(y), 3) self.assertAlmostEqual(float(mpc.run(mpc.output(pvariance(x)))), statistics.pvariance(y), 2) self.assertAlmostEqual(float(mpc.run(mpc.output(pstdev(x)))), statistics.pstdev(y), 3) self.assertAlmostEqual(float(mpc.run(mpc.output(median(x)))), statistics.median(y), 4) x = list(map(secfxp, [1.0] * 10)) self.assertAlmostEqual(mpc.run(mpc.output(mode(x))).signed(), 1) k = mpc.options.sec_param mpc.options.sec_param = 1 # force no privacy case self.assertAlmostEqual(mpc.run(mpc.output(mode(x))).signed(), 1) mpc.options.sec_param = k
async def main(): global secnum k = 1 if len(sys.argv) == 1 else float(sys.argv[1]) if k - int(k) == 0.5: secnum = mpc.SecFxp(10, 4) else: secnum = mpc.SecInt(37) batch_size = round(k - 0.01) await mpc.start() if len(sys.argv) <= 2: import mpyc.random as secrnd offset = await mpc.output(secrnd.randrange(secnum, 10001 - batch_size)) else: offset = sys.argv[2] offset = int(offset) f = 6 logging.info('--------------- INPUT -------------') print( f'Type = {secnum.__name__}, range = ({offset}, {offset + batch_size})') # read batch_size labels and images at given offset df = gzip.open(os.path.join('data', 'cnn', 't10k-labels-idx1-ubyte.gz')) d = df.read()[8 + offset:8 + offset + batch_size] labels = list(map(int, d)) print('Labels:', labels) df = gzip.open(os.path.join('data', 'cnn', 't10k-images-idx3-ubyte.gz')) d = df.read()[16 + offset * 28**2:16 + (offset + batch_size) * 28**2] x = list(map(lambda a: a / 255, d)) x = np.array(x).reshape(batch_size, 1, 28, 28) if batch_size == 1: print(np.vectorize(lambda a: int(bool(a)))(x[0, 0])) x = scale_to_int(1 << f)(x) logging.info('--------------- LAYER 1 -------------') W, b = load('conv1', f) x = convolvetensor(x, W, b) await mpc.barrier() if secnum.__name__.startswith('SecInt'): secnum.bit_length = 16 x = maxpool(x) await mpc.barrier() x = ReLU(x) await mpc.barrier() logging.info('--------------- LAYER 2 -------------') W, b = load('conv2', f, 3) x = convolvetensor(x, W, b) await mpc.barrier() if secnum.__name__.startswith('SecInt'): secnum.bit_length = 23 x = maxpool(x) await mpc.barrier() x = ReLU(x) await mpc.barrier() logging.info('--------------- LAYER 3 -------------') x = x.reshape(batch_size, 64 * 7**2) W, b = load('fc1', f, 4) x = tensormatrix_prod(x, W, b) if secnum.__name__.startswith('SecInt'): secnum.bit_length = 30 x = ReLU(x) await mpc.barrier() logging.info('--------------- LAYER 4 -------------') W, b = load('fc2', f, 5) x = tensormatrix_prod(x, W, b) logging.info('--------------- OUTPUT -------------') if secnum.__name__.startswith('SecInt'): secnum.bit_length = 37 for i in range(batch_size): prediction = int(await mpc.output(argmax(x[i]))) error = '******* ERROR *******' if prediction != labels[i] else '' print( f'Image #{offset+i} with label {labels[i]}: {prediction} predicted. {error}' ) print(await mpc.output(x[i])) await mpc.shutdown()
async def main(): parser = argparse.ArgumentParser() parser.add_argument( '-i', '--dataset', type=int, metavar='I', help=('dataset 0=uvlp (default), 1=wiki, 2=tb2x2, 3=woody, ' '4=LPExample_R20, 5=sc50b, 6=kb2, 7=LPExample')) parser.add_argument('-l', '--bit-length', type=int, metavar='L', help='override preset bit length for dataset') parser.set_defaults(dataset=0, bit_length=0) args = parser.parse_args() settings = [('uvlp', 24, 37 / 3), ('wiki', 24, 20), ('tb2x2', 18, 10.5), ('woody', 36, 540), ('LPExample_R20', 52, 3.441176), ('sc50b', 52, 70), ('kb2', 96, 1749.9204734889486), ('LPExample', 96, 1188806595)] name, bit_length, exact_max = settings[args.dataset] if args.bit_length: bit_length = args.bit_length with open(os.path.join('data', 'lp', name + '.csv')) as file: T = list(csv.reader(file)) m = len(T) - 1 n = len(T[0]) - 1 secfxp = mpc.SecFxp(bit_length) print( f'Using secure {bit_length}-bit fixed-point numbers: {secfxp.__name__}' ) print(f'dataset: {name} with {m} constraints and {n} variables') T[0][-1] = '0' # initialize optimal value for i in range(m + 1): for j in range(n + 1): T[i][j] = secfxp(float(T[i][j]), integral=False) c = T[0][:-1] # maximize c.x subject to A.x <= b, x >= 0 A = [T[i + 1][:-1] for i in range(m)] b = [T[i + 1][-1] for i in range(m)] await mpc.start() cobasis = [secfxp(j) for j in range(n)] basis = [secfxp(n + i) for i in range(m)] iteration = 0 while True: # find index of pivot column p_col_index, minimum = argmin_int(T[0][:-1]) if await mpc.output(minimum >= 0): break # maximum reached # find index of pivot row p_col = mpc.matrix_prod([p_col_index], T, True)[0] constraints = [[T[i][-1], p_col[i], p_col[i] > 0.0001] for i in range(1, m + 1)] p_row_index, (_, pivot, _) = argmin_rat(constraints) # reveal progress a bit iteration += 1 mx = await mpc.output(T[0][-1]) p = await mpc.output(pivot) logging.info(f'Iteration {iteration}: {mx} pivot={p}') # swap basis entries delta = mpc.in_prod(basis, p_row_index) - mpc.in_prod( cobasis, p_col_index) cobasis = mpc.vector_add(cobasis, mpc.scalar_mul(delta, p_col_index)) basis = mpc.vector_sub(basis, mpc.scalar_mul(delta, p_row_index)) # update tableau Tij = Tij - (Til - bool(i==k))/Tkl * (Tkj + bool(j==l)) p_col_index.append(secfxp(0)) p_row_index.insert(0, secfxp(0)) p_col = mpc.vector_sub(p_col, p_row_index) p_col = mpc.scalar_mul(1 / pivot, p_col) p_row = mpc.matrix_prod([p_row_index], T)[0] p_row = mpc.vector_add(p_row, p_col_index) T = mpc.gauss(T, secfxp(1), p_col, p_row) mx = await mpc.output(T[0][-1]) rel_error = (mx - exact_max) / exact_max print(f'max = {mx} (error {rel_error:.3%}) in {iteration} iterations') logging.info('Solution x') x = [secfxp(0) for _ in range(n)] for i in range(m): u = mpc.unit_vector(basis[i], m + n)[:n] v = mpc.scalar_mul(T[i + 1][-1], u) x = mpc.vector_add(x, v) cx = mpc.in_prod(c, x) Ax = mpc.matrix_prod([x], A, True)[0] approx = lambda a: 1.01 * a + 0.0001 Ax_bounded_by_b = mpc.all(Ax[i] <= approx(b[i]) for i in range(m)) x_nonnegative = mpc.all(x[j] >= 0 for j in range(n)) logging.info('Dual solution y') y = [secfxp(0) for _ in range(m)] for j in range(n): u = mpc.unit_vector(cobasis[j], m + n)[n:] v = mpc.scalar_mul(T[0][j], u) y = mpc.vector_sub(y, v) yb = mpc.in_prod(y, b) yA = mpc.matrix_prod([y], A)[0] approx = lambda a: mpc.if_else(a < 0, 1 / 1.01, 1.01) * a + 0.0001 yA_bounded_by_c = mpc.all(yA[j] <= approx(c[j]) for j in range(n)) y_nonpositive = mpc.all(y[i] <= 0 for i in range(m)) cx_eq_yb = abs(cx - yb) <= 0.01 * abs(cx) check = mpc.all([ cx_eq_yb, Ax_bounded_by_b, x_nonnegative, yA_bounded_by_c, y_nonpositive ]) check = bool(await mpc.output(check)) print( f'verification c.x == y.b, A.x <= b, x >= 0, y.A <= c, y <= 0: {check}' ) x = await mpc.output(x) print(f'solution = {x}') await mpc.shutdown()
def test_misc(self): secint = mpc.SecInt() secfxp = mpc.SecFxp() secfld = mpc.SecFld() for secnum in (secint, secfxp, secfld): self.assertEqual(type(mpc.run(mpc.output(secnum(0), raw=True))), secnum.field) self.assertEqual(mpc.run(mpc.output(mpc._reshare([secnum(0)]))), [0]) self.assertEqual( mpc.run(mpc.output(mpc.all(secnum(1) for _ in range(5)))), True) self.assertEqual( mpc.run(mpc.output(mpc.all([secnum(1), secnum(1), secnum(0)]))), False) self.assertEqual( mpc.run(mpc.output(mpc.any(secnum(0) for _ in range(5)))), False) self.assertEqual( mpc.run(mpc.output(mpc.any([secnum(0), secnum(1), secnum(1)]))), True) self.assertEqual( mpc.run(mpc.output(mpc.sum([secnum(1)], start=1))), 2) self.assertEqual( mpc.run(mpc.output(mpc.prod([secnum(1)], start=1))), 1) self.assertEqual( mpc.run(mpc.output(mpc.sum([secnum(1)], start=secnum(1)))), 2) self.assertEqual( mpc.run(mpc.output(mpc.find([secnum(1)], 0, e=-1))), -1) self.assertEqual(mpc.run(mpc.output(mpc.find([secnum(1)], 1))), 0) self.assertEqual( mpc.run(mpc.output(mpc.find([secnum(1)], 1, f=lambda i: i))), 0) self.assertEqual( mpc.run(mpc.output(mpc.min(secint(i) for i in range(-1, 2, 1)))), -1) self.assertEqual( mpc.run( mpc.output(mpc.argmin(secint(i) for i in range(-1, 2, 1))[0])), 0) self.assertEqual( mpc.run(mpc.output(mpc.max(secfxp(i) for i in range(-1, 2, 1)))), 1) self.assertEqual( mpc.run( mpc.output(mpc.argmax(secfxp(i) for i in range(-1, 2, 1))[0])), 2) self.assertEqual( mpc.run(mpc.output(list(mpc.min_max(map(secfxp, range(5)))))), [0, 4]) x = (secint(i) for i in range(-3, 3)) s = [0, -1, 1, -2, 2, -3] self.assertEqual( mpc.run(mpc.output(mpc.sorted(x, key=lambda a: a * (2 * a + 1)))), s) x = (secfxp(i) for i in range(5)) self.assertEqual(mpc.run(mpc.output(mpc.sorted(x, reverse=True))), [4, 3, 2, 1, 0]) self.assertEqual(mpc.run(mpc.output(mpc.sum(map(secint, range(5))))), 10) self.assertEqual( mpc.run(mpc.output(mpc.sum([secfxp(2.75)], start=3.125))), 5.875) self.assertEqual( int(mpc.run(mpc.output(mpc.prod(map(secfxp, range(1, 5)))))), 24) self.assertEqual( int(mpc.run(mpc.output(mpc.prod([secfxp(1.414214)] * 4)))), 4) self.assertEqual(mpc.find([], 0), 0) self.assertEqual(mpc.find([], 0, e=None), (1, 0)) self.assertEqual( mpc.run(mpc.output(list(mpc.find([secfld(1)], 1, e=None)))), [0, 0]) self.assertEqual( mpc.run(mpc.output(mpc.find([secfld(2)], 2, bits=False))), 0) x = [secint(i) for i in range(5)] f = lambda i: [i**2, 3**i] self.assertEqual(mpc.run(mpc.output(mpc.find(x, 2, bits=False, f=f))), [4, 9]) cs_f = lambda b, i: [b * (2 * i + 1) + i**2, (b * 2 + 1) * 3**i] self.assertEqual( mpc.run(mpc.output(mpc.find(x, 2, bits=False, cs_f=cs_f))), [4, 9])
def test_secfxp(self): secfxp = mpc.SecFxp() self.assertEqual( mpc.run(mpc.output(mpc.input(secfxp(7.75), senders=0))), 7.75) c = mpc.to_bits(secfxp(0), 0) # mpc.output() only works for nonempty lists self.assertEqual(c, []) c = mpc.run(mpc.output(mpc.to_bits(secfxp(0)))) self.assertEqual(c, [0.0] * 32) c = mpc.run(mpc.output(mpc.to_bits(secfxp(1)))) self.assertEqual(c, [0.0] * 16 + [1.0] + [0.0] * 15) c = mpc.run(mpc.output(mpc.to_bits(secfxp(0.5)))) self.assertEqual(c, [0.0] * 15 + [1.0] + [0.0] * 16) c = mpc.run(mpc.output(mpc.to_bits(secfxp(8113)))) self.assertEqual(c, [0.0] * 16 + [1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0]) c = mpc.run(mpc.output(mpc.to_bits(secfxp(2**15 - 1)))) self.assertEqual(c, [0] * 16 + [1] * 15 + [0]) c = mpc.run(mpc.output(mpc.to_bits(secfxp(-1)))) self.assertEqual(c, [0] * 16 + [1] * 16) c = mpc.run(mpc.output(mpc.to_bits(secfxp(-2**15)))) self.assertEqual(c, [0] * 31 + [1]) for f in [8, 16, 32, 64]: secfxp = mpc.SecFxp(2 * f) c = mpc.run(mpc.output(secfxp(1) + secfxp(1))) self.assertEqual(c, 2) c = mpc.run(mpc.output(secfxp(2**-f) + secfxp(1))) if f != 64: # NB: 1 + 2**-64 == 1 in Python self.assertEqual(c, 1 + 2**-f) self.assertEqual(mpc.run(mpc.output(secfxp(0.5) * secfxp(2.0))), 1) self.assertEqual(mpc.run(mpc.output(secfxp(2.0) * secfxp(0.5))), 1) c = mpc.run( mpc.output( secfxp(2**(f // 2 - 1) - 0.5) * secfxp(-2**(f // 2) + 0.5))) self.assertEqual(c, -2**(f - 1) + 1.5 * 2**(f // 2 - 1) - 0.25) s = [10.75, -3.375, 0.125, -0.125] self.assertEqual(mpc.run(mpc.output(list(map(secfxp, s)))), s) s = [10.5, -3.25, 0.125, -0.125] a, b, c, d = list(map(secfxp, s)) t = [v * v for v in s] self.assertEqual(mpc.run(mpc.output([a * a, b * b, c * c, d * d])), t) x = [a, b, c, d] self.assertEqual(mpc.run(mpc.output(mpc.schur_prod(x, x))), t) self.assertEqual(mpc.run(mpc.output(mpc.schur_prod(x, x[:]))), t) t = sum(t) self.assertEqual(mpc.run(mpc.output(mpc.in_prod(x, x))), t) self.assertEqual(mpc.run(mpc.output(mpc.in_prod(x, x[:]))), t) self.assertEqual( mpc.run(mpc.output(mpc.matrix_prod([x], [x], True)[0])), [t]) u = mpc.unit_vector(secfxp(3), 4) self.assertEqual( mpc.run(mpc.output(mpc.matrix_prod([x], [u], True)[0])), [s[3]]) self.assertEqual( mpc.run(mpc.output(mpc.matrix_prod([u], [x], True)[0])), [s[3]]) self.assertEqual( mpc.run(mpc.output(mpc.gauss([[a]], b, [a], [b])[0])), [0]) t = [_ for a, b, c, d in [s] for _ in [a + b, a * b, a - b]] self.assertEqual(mpc.run(mpc.output([a + b, a * b, a - b])), t) t = [ _ for a, b, c, d in [s] for _ in [(a + b)**2, (a + b)**2 + 3 * c] ] self.assertEqual( mpc.run(mpc.output([(a + b)**2, (a + b)**2 + 3 * c])), t) t = [_ for a, b, c, d in [s] for _ in [a < b, b < c, c < d]] self.assertEqual(mpc.run(mpc.output([a < b, b < c, c < d])), t) t = s[0] < s[1] and s[1] < s[2] self.assertEqual(mpc.run(mpc.output((a < b) & (b < c))), t) t = s[0] < s[1] or s[1] < s[2] self.assertEqual(mpc.run(mpc.output((a < b) | (b < c))), t) t = (int(s[0] < s[1]) ^ int(s[1] < s[2])) self.assertEqual(mpc.run(mpc.output((a < b) ^ (b < c))), t) t = (int(not s[0] < s[1]) ^ int(s[1] < s[2])) self.assertEqual(mpc.run(mpc.output(~(a < b) ^ b < c)), t) t = [s[0] > 1, 10 * s[1] < 5, 10 * s[0] == 5] self.assertEqual( mpc.run(mpc.output([a > 1, 10 * b < 5, 10 * a == 5])), t) s[3] = -0.120 d = secfxp(s[3]) t = s[3] / 0.25 self.assertAlmostEqual(mpc.run(mpc.output(d / 0.25)), t, delta=2**(1 - f)) t = round(s[3] / s[2] + s[0]) self.assertEqual(round(mpc.run(mpc.output(d / c + a))), t) t = ((s[0] + s[1])**2 + 3 * s[2]) / s[2] self.assertAlmostEqual(mpc.run(mpc.output( ((a + b)**2 + 3 * c) / c)), t, delta=2**(8 - f)) t = 1 / s[3] self.assertAlmostEqual(mpc.run(mpc.output(1 / d)), t, delta=2**(6 - f)) t = s[2] / s[3] self.assertAlmostEqual(mpc.run(mpc.output(c / d)), t, delta=2**(3 - f)) t = -s[3] / s[2] self.assertAlmostEqual(mpc.run(mpc.output(-d / c)), t, delta=2**(3 - f)) self.assertEqual(mpc.run(mpc.output(mpc.sgn(+a))), s[0] > 0) self.assertEqual(mpc.run(mpc.output(mpc.sgn(-a))), -(s[0] > 0)) self.assertEqual(mpc.run(mpc.output(mpc.sgn(secfxp(0)))), 0) self.assertEqual(mpc.run(mpc.output(abs(secfxp(-1.5)))), 1.5) self.assertEqual(mpc.run(mpc.output(mpc.min(a, b, c, d))), min(s)) self.assertEqual(mpc.run(mpc.output(mpc.min(a, 0))), min(s[0], 0)) self.assertEqual(mpc.run(mpc.output(mpc.min(0, b))), min(0, s[1])) self.assertEqual(mpc.run(mpc.output(mpc.max(a, b, c, d))), max(s)) self.assertEqual(mpc.run(mpc.output(mpc.max(a, 0))), max(s[0], 0)) self.assertEqual(mpc.run(mpc.output(mpc.max(0, b))), max(0, s[1])) self.assertEqual( mpc.run(mpc.output(list(mpc.min_max(a, b, c, d)))), [min(s), max(s)]) self.assertEqual(mpc.run(mpc.output(mpc.argmin([a, b, c, d])[0])), 1) self.assertEqual( mpc.run(mpc.output(mpc.argmin([a, b], key=operator.neg)[1])), max(s)) self.assertEqual(mpc.run(mpc.output(mpc.argmax([a, b, c, d])[0])), 0) self.assertEqual( mpc.run(mpc.output(mpc.argmax([a, b], key=operator.neg)[1])), min(s)) self.assertEqual(mpc.run(mpc.output(secfxp(5) % 2)), 1) self.assertEqual(mpc.run(mpc.output(secfxp(1) % 2**(1 - f))), 0) self.assertEqual(mpc.run(mpc.output(secfxp(2**-f) % 2**(1 - f))), 2**-f) self.assertEqual( mpc.run(mpc.output(secfxp(2 * 2**-f) % 2**(1 - f))), 0) self.assertEqual(mpc.run(mpc.output(secfxp(1) // 2**(1 - f))), 2**(f - 1)) self.assertEqual(mpc.run(mpc.output(secfxp(27.0) % 7.0)), 6.0) self.assertEqual(mpc.run(mpc.output(secfxp(-27.0) // 7.0)), -4.0) self.assertEqual( mpc.run(mpc.output(list(divmod(secfxp(27.0), 6.0)))), [4.0, 3.0]) self.assertEqual(mpc.run(mpc.output(secfxp(21.5) % 7.5)), 6.5) self.assertEqual(mpc.run(mpc.output(secfxp(-21.5) // 7.5)), -3.0) self.assertEqual( mpc.run(mpc.output(list(divmod(secfxp(21.5), 0.5)))), [43.0, 0.0])
def test_secfxp(self): secfxp = mpc.SecFxp() c = mpc.to_bits(secfxp(0), 0) # mpc.output() only works for non-empty lists self.assertEqual(c, []) c = mpc.run(mpc.output(mpc.to_bits(secfxp(0)))) self.assertEqual(c, [0.0] * 32) c = mpc.run(mpc.output(mpc.to_bits(secfxp(1)))) self.assertEqual(c, [0.0] * 16 + [1.0] + [0.0] * 15) c = mpc.run(mpc.output(mpc.to_bits(secfxp(8113)))) self.assertEqual(c, [0.0] * 16 + [ float(b) for b in [1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0] ]) c = mpc.run(mpc.output(mpc.to_bits(secfxp(2**15 - 1)))) self.assertEqual(c, [float(b) for b in [0] * 16 + [1] * 15 + [0]]) c = mpc.run(mpc.output(mpc.to_bits(secfxp(-1)))) self.assertEqual(c, [float(b) for b in [0] * 16 + [1] * 16]) c = mpc.run(mpc.output(mpc.to_bits(secfxp(-2**15)))) self.assertEqual(c, [float(b) for b in [0] * 31 + [1]]) for f in [8, 16, 32, 64]: secfxp = mpc.SecFxp(2 * f) d = mpc.run(mpc.output(secfxp(1) + secfxp(1))) self.assertEqual(d.frac_length, f) self.assertEqual(d, 2) d = mpc.run(mpc.output(secfxp(2**-f) + secfxp(1))) f == 64 or self.assertEqual( d, 1 + 2**-f) # NB: 1 + 2**-64 == 1 in Python d = mpc.run(mpc.output(secfxp(0.5) * secfxp(2.0))) self.assertEqual(d, 1) d = mpc.run(mpc.output(secfxp(2.0) * secfxp(0.5))) self.assertEqual(d, 1) s = [10.7, -3.4, 0.1, -0.11] self.assertEqual(mpc.run(mpc.output(list(map(secfxp, s)))), s) s = [10.5, -3.25, 0.125, -0.125] x, y, z, w = list(map(secfxp, s)) s2 = [v * v for v in s] self.assertEqual(mpc.run(mpc.output([x * x, y * y, z * z, w * w])), s2) self.assertEqual( mpc.run(mpc.output(mpc.schur_prod([x, y, z, w], [x, y, z, w]))), s2) s2 = [_ for x, y, z, w in [s] for _ in [x + y, x * y, x - y]] self.assertEqual(mpc.run(mpc.output([x + y, x * y, x - y])), s2) s2 = [ _ for x, y, z, w in [s] for _ in [(x + y)**2, (x + y)**2 + 3 * z] ] self.assertEqual( mpc.run(mpc.output([(x + y)**2, (x + y)**2 + 3 * z])), s2) s2 = [int(_) for x, y, z, w in [s] for _ in [x < y, y < z, z < w]] self.assertEqual(mpc.run(mpc.output([x < y, y < z, z < w])), s2) s2 = int(s[0] < s[1] and s[1] < s[2]) self.assertEqual(mpc.run(mpc.output((x < y) & (y < z))), s2) s2 = int(s[0] < s[1] or s[1] < s[2]) self.assertEqual(mpc.run(mpc.output((x < y) | (y < z))), s2) s2 = (int(s[0] < s[1]) ^ int(s[1] < s[2])) self.assertEqual(mpc.run(mpc.output((x < y) ^ (y < z))), s2) s2 = (int(not s[0] < s[1]) ^ int(s[1] < s[2])) self.assertEqual(mpc.run(mpc.output(~(x < y) ^ y < z)), s2) s2 = [int(s[0] < 1), int(10 * s[1] < 5), int(10 * s[0] == 5)] self.assertEqual( mpc.run(mpc.output([x < 1, 10 * y < 5, 10 * x == 5])), s2) s[3] = -0.120 w = secfxp(s[3]) for _ in range(3): s2 = s[3] / s[2] + s[0] self.assertAlmostEqual(mpc.run(mpc.output(w / z + x)).signed(), s2, delta=1) ss2 = round(s2 * (1 << f)) self.assertAlmostEqual(mpc.run(mpc.output(w / z + x)), ss2, delta=1) s2 = ((s[0] + s[1])**2 + 3 * s[2]) / s[2] self.assertAlmostEqual(mpc.run( mpc.output(((x + y)**2 + 3 * z) / z)).signed(), s2, delta=2) s2 = 1 / s[3] self.assertAlmostEqual((mpc.run(mpc.output(1 / w))).signed(), s2, delta=1) s2 = s[2] / s[3] self.assertAlmostEqual(mpc.run(mpc.output(z / w)).signed(), s2, delta=1) s2 = -s[3] / s[2] ss2 = round(s2 * (1 << f)) self.assertAlmostEqual(mpc.run(mpc.output(-w / z)), ss2, delta=1) s2 = s[2] / s[3] ss2 = round(s2 * (1 << f)) self.assertAlmostEqual(mpc.run(mpc.output(w / z)), ss2, delta=1) self.assertEqual(mpc.run(mpc.output(mpc.sgn(x))), int(s[0] > 0)) self.assertEqual(mpc.run(mpc.output(mpc.sgn(-x))), -int(s[0] > 0)) self.assertEqual(mpc.run(mpc.output(mpc.sgn(secfxp(0)))), 0) self.assertEqual(mpc.run(mpc.output(mpc.min(x, y, w, z))), min(s)) self.assertEqual(mpc.run(mpc.output(mpc.min(x, 0))), min(s[0], 0)) self.assertEqual(mpc.run(mpc.output(mpc.min(0, y))), min(0, s[1])) self.assertEqual(mpc.run(mpc.output(mpc.max(x, y, w, z))), max(s)) self.assertEqual(mpc.run(mpc.output(mpc.max(x, 0))), max(s[0], 0)) self.assertEqual(mpc.run(mpc.output(mpc.max(0, y))), max(0, s[1])) self.assertEqual(mpc.run(mpc.output(secfxp(5) % 2)), 1 * (2**f)) self.assertEqual(mpc.run(mpc.output(secfxp(1) % 2**(1 - f))), 0 * (2**f)) self.assertEqual( mpc.run(mpc.output(secfxp(1 / 2**f) % 2**(1 - f))), 1) self.assertEqual( mpc.run(mpc.output(secfxp(2 / 2**f) % 2**(1 - f))), 0) self.assertEqual(mpc.run(mpc.output(secfxp(1) // 2**(1 - f))), 2**(f - 1)) self.assertEqual(mpc.run(mpc.output(secfxp(27.0) % 7.0)), 6.0) self.assertEqual(mpc.run(mpc.output(secfxp(-27.0) // 7.0)), -4.0) self.assertEqual( mpc.run(mpc.output(list(divmod(secfxp(27.0), 6.0)))), [4.0, 3.0]) self.assertEqual(mpc.run(mpc.output(secfxp(21.5) % 7.5)), 6.5) self.assertEqual(mpc.run(mpc.output(secfxp(-21.5) // 7.5)), -3.0) self.assertEqual( mpc.run(mpc.output(list(divmod(secfxp(21.5), 0.5)))), [43.0, 0.0])
def main(): parser = argparse.ArgumentParser() parser.add_argument('-d', '--data', help='Filename for tableau.') parser.add_argument('options', nargs='*') parser.set_defaults(data='default') args = parser.parse_args(mpc.args) if not args.options: certificate_filename = "c" + str(mpc.id) + ".cert" logging.info('Setting certificate file to default = %s', certificate_filename) else: certificate_filename = args.options[0] T = load_tableau(args.data) m = len(T) - 1 n = len(T[0]) - 1 l = mpc.options.bit_length secfxp = mpc.SecFxp(l) for i in range(len(T)): for j in range(len(T[0])): T[i][j] = secfxp(T[i][j]) basis = [secfxp(i + n) for i in range(m)] cobasis = [secfxp(j) for j in range(n)] mpc.start() iteration = 0 logging.info('%d Termination?...', iteration) p_col_index, minimum = argmin_int(T[-1][:-1]) while mpc.run(mpc.output(minimum < 0)): iteration += 1 logging.info('%d Determining pivot...', iteration) p_col = index_matrix_prod(p_col_index + [secfxp(0)], T, True) constraints = [(T[i][-1] + (p_col[i] <= 0), p_col[i]) for i in range(m)] p_row_index, _ = argmin_rat(constraints) pivot = mpc.in_prod(p_row_index, p_col) pivot1 = 1 / pivot mpc.run(mpc.barrier()) logging.info('%d Updating tableau...', iteration) h = mpc.scalar_mul(pivot1, [(p_row_index[i] if i < m else 0) - p_col[i] for i in range(m + 1)]) p_row = index_matrix_prod(p_row_index, T[:-1]) v = mpc.vector_add(p_row, p_col_index + [0]) for i in range(m + 1): T[i] = mpc.vector_add(T[i], mpc.scalar_mul(h[i], v)) #swap basis entries delta = mpc.in_prod(basis, p_row_index) - mpc.in_prod( cobasis, p_col_index) p_row_index = mpc.scalar_mul(delta, p_row_index) basis = mpc.vector_sub(basis, p_row_index) p_col_index = mpc.scalar_mul(delta, p_col_index) cobasis = mpc.vector_add(cobasis, p_col_index) logging.info('%d Termination?...', iteration) p_col_index, minimum = argmin_int(T[-1][:-1]) logging.info('Termination...') mx = mpc.run(mpc.output(T[-1][-1])) print(' max(f) =', mx) logging.info('Computing solution...') solution = [secfxp(0) for _ in range(n)] for i in range(m): x = unit_vector(basis[i], m + n)[:n] y = mpc.scalar_mul(T[i][-1], x) solution = mpc.vector_add(solution, y) solution = mpc.run(mpc.output(solution)) logging.info('Computing dual solution...') dual_solution = [secfxp(0) for _ in range(m)] for j in range(n): x = unit_vector(cobasis[j], m + n)[n:] y = mpc.scalar_mul(T[-1][j], x) dual_solution = mpc.vector_add(dual_solution, y) dual_solution = mpc.run(mpc.output(dual_solution)) mpc.shutdown() logging.info('Writing output to %s.', certificate_filename) with open(os.path.join('data', 'lp', certificate_filename), 'w') as f: f.write('# tableau = \n' + args.data + '\n') f.write('# bit-length = \n' + str(mpc.options.bit_length) + '\n') f.write('# security parameter = \n' + str(mpc.options.security_parameter) + '\n') f.write('# threshold = \n' + str(mpc.threshold) + '\n') f.write('# solution = \n') f.write('\t'.join(x.__repr__() for x in solution) + '\n') f.write('# dual solution = \n') f.write('\t'.join(x.__repr__() for x in dual_solution) + '\n')
def send_shares_mpc_combined(data, dataname, datapart, hosts, ports): #print(f'Sending combined data...') if isinstance(data, np.ndarray): data = data.flatten().tolist() secnum = mpc.SecFxp() test_sample = secnum(10) stype = type(test_sample) field = stype.field data_sec_ = np.vectorize(secnum)(data) data_sec_ = data_sec_.tolist() data_sec = [a.df for a in data_sec_] m = len(hosts) t = 1 start = timer() # Generate shares for each data sample #data_shares = [None]*m data_shares = thresha.random_split(data_sec, t, m) end = timer() global running_time_compute_share running_time_compute_share = end - start data_shares_str = [] for other_pid, data in enumerate(data_shares): data = field.to_bytes(data) data_shares_str.append(base64.b64encode(data).decode()) #print(data_shares_str) start = timer() parallel = True if parallel: #print('send parallel') timestamp = datetime.datetime.now().isoformat() sample_json = [] for j in np.arange(m): sample = { "timestamp" : timestamp, dataname[0] : data_shares_str[j] } sample_json.append(json.dumps(sample)) #send_data(sample_json, datapart, hosts[j], ports[j]) Parallel(n_jobs=m)(delayed(send_data)(sample_json[i], datapart, hosts[i], ports[i]) for i in np.arange(m)) else: timestamp = datetime.datetime.now().isoformat() for j in np.arange(m): sample = { "timestamp" : timestamp, dataname[0] : data_shares_str[j] } sample_json = json.dumps(sample) send_data(sample_json, datapart, hosts[j], ports[j]) global running_time_upload_share end = timer() running_time_upload_share = end - start
async def main(): parser = argparse.ArgumentParser() parser.add_argument( '-i', '--dataset', type=int, metavar='I', help=('dataset 0=btrial(default) 1=waltons 2=aml 3=lung 4=dd' ' 5=stanford_heart_transplants 6=kidney_transplant')) parser.add_argument('-s', '--stride', type=int, metavar='S', help='interval length for aggregated events') parser.add_argument('-a', '--accuracy', type=int, metavar='A', help='number of fractional bits') parser.add_argument('--collapse', action='store_true', default=False, help='days->weeks->month->years') parser.add_argument('--print-tables', action='store_true', default=False, help='print survival tables') parser.add_argument('--plot-curves', action='store_true', default=False, help='plot survival curves') parser.set_defaults(dataset=0) args = parser.parse_args() settings = [('btrial.csv', 12, 28, 'months', 'time', 'death', 'im', ('-ve immunohistochemical response', '+ve immunohistochemical response'), (1, 2)), ('waltons', 10, 32, 'days', 'T', 'E', 'group', ('miR-137', 'control'), ('miR-137', 'control')), ('aml.csv', 16, 32, 'weeks', 'time', 'cens', 'group', ('Maintained', 'Not maintained'), (1, 2)), ('lung', 73, 32, 'days', 'time', 'status', 'sex', ('Male', 'Female'), (1, 2)), ('dd', 3, 48, 'years', 'duration', 'observed', 'democracy', ('Democracy', 'Non-democracy'), ('Democracy', 'Non-democracy')), ('stanford_heart_transplants', 90, 32, 'days', 'time', 'event', 'transplant', ('no transplant', 'transplant'), (0, 1)), ('kidney_transplant', 180, 40, 'days', 'time', 'death', 'sex', ('male', 'female'), (1, 0))] (name, stride, accuracy, unit_of_time, times, events, groups, (label1, label2), (value1, value2)) = settings[args.dataset] if name.endswith('.csv'): df = pd.read_csv(os.path.join('data', 'surv', name)) name = name[:-4] else: df = eval('lifelines.datasets.load_' + name)() if name == 'lung': df['status'] = df['status'] - 1 # 1-2 -> 0-1 = censored-death elif name == 'stanford_heart_transplants': df = df[(df['transplant'] == 1) | ~df['id'].isin(set(df[df['transplant'] == 1]['id']))] df['time'] = round(df['stop'] - df['start'] + 0.5) elif name == 'kidney_transplant': df['sex'] = df['black_male'] + df['white_male'] if args.stride: stride = args.stride if args.collapse: if unit_of_time == 'days': unit_of_time = 'weeks' df[times] = (df[times] + 6) // 7 # convert days to weeks stride //= 7 elif unit_of_time == 'weeks': unit_of_time = 'months' df[times] = (df[times] + 3) // 4 # convert weeks to months stride //= 4 elif unit_of_time == 'months': unit_of_time = 'years' df[times] = (df[times] + 11) // 12 # convert months to years stride //= 12 if args.accuracy: accuracy = args.accuracy secfxp = mpc.SecFxp(2 * accuracy) print(f'Using secure fixed-point numbers: {secfxp.__name__}') maxT_clear = int(df[times].max()) m = len(mpc.parties) print(f'Dataset: {name}, with {m}-party split,' f' time 1 to {maxT_clear} (stride {stride}) {unit_of_time}') logging.info('Logrank test on all events in the clear.') T, E = df[times], df[events] ix = df[groups] == value1 results = lifelines.statistics.logrank_test(T[ix], T[~ix], E[ix], E[~ix]) print(f'Chi2={results.test_statistic:.6f}, p={results.p_value:.6f}' ' for all events in the clear') await mpc.start() df = df[mpc.pid::m] # simple partition of dataset between m parties my_maxT = int(df[times].max()) maxT = int(await mpc.output(mpc.max(mpc.input(secfxp(my_maxT))))) assert maxT == maxT_clear logging.info('Logrank test on own events in the clear.') T, E = df[times], df[events] ix = df[groups] == value1 T1, T2, E1, E2 = T[ix], T[~ix], E[ix], E[~ix] results = lifelines.statistics.logrank_test(T1, T2, E1, E2) print(f'Chi2={results.test_statistic:.6f}, p={results.p_value:.6f}' ' for own events in the clear') if args.print_tables or args.plot_curves: plt.figure(1) title = f'Party {mpc.pid}: {name} Survival - individual events' kmf1, kmf2 = fit_plot(T1, T2, E1, E2, title, unit_of_time, label1, label2) if args.print_tables: print(kmf1.event_table) print(kmf2.event_table) # expand to timeline 1..maxT and add all input data homomorphically per group d1, n1 = events_to_table(maxT, T1, E1) d2, n2 = events_to_table(maxT, T2, E2) d1, n1, d2, n2 = (reduce(mpc.vector_add, mpc.input(list(map(secfxp, _)))) for _ in (d1, n1, d2, n2)) agg_d1, agg_n1 = aggregate(d1, n1, stride) agg_d2, agg_n2 = aggregate(d2, n2, stride) agg_d1, agg_n1, agg_d2, agg_n2 = [ list(map(int, await mpc.output(_))) for _ in (agg_d1, agg_n1, agg_d2, agg_n2) ] T1, E1 = events_from_table(agg_d1, agg_n1) T2, E2 = events_from_table(agg_d2, agg_n2) logging.info('Logrank test on aggregated events in the clear.') results = lifelines.statistics.logrank_test(T1, T2, E1, E2) print(f'Chi2={results.test_statistic:.6f}, p={results.p_value:.6f}' ' for aggregated events in the clear') if args.print_tables or args.plot_curves: plt.figure(2) title = f'Party {mpc.pid}: {name} Survival - aggregated by {stride} {unit_of_time}' kmf1, kmf2 = fit_plot([t * stride for t in T1], [t * stride for t in T2], E1, E2, title, unit_of_time, label1, label2) if args.print_tables: print(kmf1.event_table) print(kmf2.event_table) if args.plot_curves: plt.show() logging.info('Optimized secure logrank test on all individual events.') results = await agg_logrank_test(secfxp, d1, d2, n1, n2, agg_d1, agg_d2, stride) print(f'Chi2={results.test_statistic:.6f}, p={results.p_value:.6f}' ' for all events secure, exploiting aggregates') logging.info(f'Secure logrank test for all {maxT} time moments.') results = await logrank_test(secfxp, d1, d2, n1, n2) print(f'Chi2={results.test_statistic:.6f}, p={results.p_value:.6f}' f' for all {maxT} time moments secure') await mpc.shutdown()
- Using mpc.transfer(a). This will send (a copy of) a to all parties as long as the type of a can be pickled using Python's pickle module. Note that the rank values are exchanged in the same way as the input values. """ import random from mpyc.runtime import mpc mpc.threshold = 0 # No secrecy. m = len(mpc.parties) k = 2**(m - 1) # any k=O(2^m) allowed, ensuring that n = m*k = O(m 2^m) secint = mpc.SecInt() secfxp = mpc.SecFxp() secflt = mpc.SecFlt() flatten = lambda s: [a for _ in s for a in _] def rank(x, i): """Return rank of x[i] w.r.t. all values in x. Rank of x[i] is the number of elements below x[i], that is, elements smaller than x[i], or equal to x[i] but left from it in x. """ a = x[i] return sum(int(b < a or (b == a and j < i)) for j, b in enumerate(x))