async def main(): await mpc.start() print(f"One 64-byte block of ChaCha20 with input 0, key 0, nonce 0\n") print("initializing ...".ljust(32), end='', flush=True) t1 = time.perf_counter() constant[0] = secint.field(1634760805) constant[1] = secint.field(857760878) constant[2] = secint.field(2036477234) constant[3] = secint.field(1797285236) key = [mpc.input(secint(0))[0] for _ in range(8)] nonce = [mpc.input(secint(0))[0] for _ in range(2)] inp = [mpc.input(secint(0))[0] for _ in range(16)] t2 = time.perf_counter() print(f"{(t2 - t1):.5} seconds") print("encrypting ...".ljust(32), end='', flush=True) t1 = time.perf_counter() code(key, nonce, inp) res = await (mpc.output(inp)) t2 = time.perf_counter() print(f"{(t2 - t1):.5} seconds") print("\nchecking ...".ljust(32), end='', flush=True) assert res == vec, f"{res} != {vec}" print("ok!") await mpc.shutdown()
async def main(): await mpc.start() print( f"LowMC with blocksize {blocksize}, keysize {keysize}, {numofboxes} s-boxes, {rounds} rounds\n" ) print("generating input ...".ljust(32), end='', flush=True) t1 = time.perf_counter() linmatrices, invlinmatrices, roundconstants, keymatrices = initialize() key = mpc.random.getrandbits(sec, keysize, bits=True) inp = mpc.random.getrandbits(sec, blocksize, bits=True) inp0 = await mpc.output(mpc.from_bits(inp)) t2 = time.perf_counter() print(f"{(t2 - t1):.5} seconds") print("reading in constants ...".ljust(32), end='', flush=True) t1 = time.perf_counter() for r in range(rounds): t = await mpc.output(mpc.input(sec(roundconstants[r]))[0]) roundconstants[r] = to_bits(t.value.value, blocksize) for x in range(blocksize): t = await mpc.output(mpc.input(sec(linmatrices[r][x]))[0]) linmatrices[r][x] = to_bits(t.value.value, blocksize) t = await mpc.output(mpc.input(sec(invlinmatrices[r][x]))[0]) invlinmatrices[r][x] = to_bits(t.value.value, blocksize) for r in range(rounds + 1): for x in range(keysize): t = await mpc.output(mpc.input(sec(keymatrices[r][x]))[0]) keymatrices[r][x] = to_bits(t.value.value, keysize) t2 = time.perf_counter() print(f"{(t2 - t1):.5} seconds") print("scheduling keys ...".ljust(32), end='', flush=True) t1 = time.perf_counter() roundkeys = keyschedule(key, keymatrices) for r in range(rounds + 1): rnd = await mpc.gather(roundkeys[r]) roundkeys[r] = [sec(0) for _ in range(blocksize - keysize)] + rnd t2 = time.perf_counter() print(f"{(t2 - t1):.5} seconds") print("encrypting ...".ljust(32), end='', flush=True) t1 = time.perf_counter() enc = encrypt(inp, roundkeys, linmatrices, roundconstants) encc = await mpc.output(enc) t2 = time.perf_counter() print(f"{(t2 - t1):.5} seconds") print("decrypting ...".ljust(32), end='', flush=True) t1 = time.perf_counter() dec = decrypt(enc, roundkeys, invlinmatrices, roundconstants) dec0 = await mpc.output(mpc.from_bits(dec)) t2 = time.perf_counter() print(f"{(t2 - t1):.5} seconds") print("\nchecking ...".ljust(32), end='', flush=True) assert inp0 == dec0, f"{inp0.value.value} != {dec0.value.value}" print("ok!") await mpc.shutdown()
async def main(): # initialize mpc, define secure int type LEN = 100000 await mpc.start() secint = mpc.SecInt(128) # party 0 samples the inputs locally... if mpc.pid == 0: vec1 = [np.random.randint(1, 1000) for _ in range(LEN)] vec2 = [np.random.randint(1, 1000) for _ in range(LEN)] # ...and secret-shares them with the others result_type = [secint()] * LEN sec_vec1 = mpc.input([secint(v) for v in vec1] if mpc.pid == 0 else result_type, senders=0) sec_vec2 = mpc.input([secint(v) for v in vec2] if mpc.pid == 0 else result_type, senders=0) # compute inner product ip = mpc.in_prod(sec_vec1, sec_vec2) # output result (to everybody) result = await mpc.output(ip) print("result:", result) if mpc.pid == 0: assert (result == np.dot(vec1, vec2)) await mpc.shutdown()
async def _main_MPC(self, election, validate_ballots=True): async with mpc: #___emulating ballots sharing +++ABSOLUTELY SECURE+++ # and aggregated scores of all candidates evaluating: candidates_number = len(election.candidates) secret_shared_ballots = [] ordered_aggregated_scores = [ mpc.input(self.secint(0 if mpc.pid == 0 else None), senders=0) ] * candidates_number for voters_i in range(len(election.voters)): secret_shared_ballots.append([]) ballot = election.voters[voters_i].send_ballots(election) for value, candidate_index in zip(ballot, range(len(ballot))): secint_value = mpc.input( self.secint((int(value)) if mpc.pid == 0 else None), senders=0) secret_shared_ballots[voters_i].append(secint_value) ordered_aggregated_scores[candidate_index] += secint_value #___MPC ballots validating: if validate_ballots: ballot_is_valid = await self._ballot_validation( secret_shared_ballots[voters_i], election.voting_rules) if not ballot_is_valid: print( f'stop right there, voter number {voters_i}! You violating the law!' ) return "illegal ballot by voter" #___MPC magic of top K candidates finding: comparsions_vector = [ mpc.input(self.secint(0 if mpc.pid == 0 else None), senders=0) ] * candidates_number for candidate_i_scores, candidate_index in zip( ordered_aggregated_scores, range(candidates_number)): for candidate_j_scores in ordered_aggregated_scores: comparsions_vector[candidate_index] += ( candidate_i_scores > candidate_j_scores) for candidate_index in range(candidates_number): comparsions_vector[candidate_index] = ( comparsions_vector[candidate_index] >= (candidates_number - election.winners_number_sought)) elections_result = [] for win_indicator in comparsions_vector: elections_result.append(await mpc.output(win_indicator)) return elections_result
async def main(): # initialize mpc, define secure int type await mpc.start() secint = mpc.SecInt(64) # initialize inputs # 3 parties: random value for each party # any other number of parties: just use player 0's value 3 times. value = np.random.randint(1,10000) print("player {} input: {}".format(mpc.pid, value)) n = len(mpc.parties) if n != 3: inputs = [secint(value), secint(value), secint(value)] print("expected: {}".format(value ** 3)) else: inputs = mpc.input(secint(value), senders=[0,1,2]) # compute product prod = mpc.prod(inputs) # output result result = await mpc.output(prod) print("result:", result) await mpc.shutdown()
def test_bsecfld(self): secfld = mpc.SecFld(char=2, min_order=2**8) a = secfld(57) b = secfld(67) self.assertEqual(int(mpc.run(mpc.output(mpc.input(a, 0)))), 57) self.assertEqual(int(mpc.run(mpc.output(+a - -a))), 0) self.assertEqual(int(mpc.run(mpc.output(a * b))), 137) self.assertEqual(int(mpc.run(mpc.output(a * b / a))), 67) self.assertEqual(int(mpc.run(mpc.output(a**254 * a))), 1) self.assertEqual(int(mpc.run(mpc.output(a & b))), 1) self.assertEqual(int(mpc.run(mpc.output(a | b))), 123) self.assertEqual(int(mpc.run(mpc.output(a ^ b))), 122) self.assertEqual(int(mpc.run(mpc.output(~a))), 198) c = mpc.run(mpc.output(mpc.to_bits(secfld(0)))) self.assertEqual(c, [0, 0, 0, 0, 0, 0, 0, 0]) c = mpc.run(mpc.output(mpc.to_bits(secfld(1)))) self.assertEqual(c, [1, 0, 0, 0, 0, 0, 0, 0]) c = mpc.run(mpc.output(mpc.to_bits(secfld(255)))) self.assertEqual(c, [1, 1, 1, 1, 1, 1, 1, 1]) c = mpc.run(mpc.output(mpc.to_bits(secfld(255), 1))) self.assertEqual(c, [1]) c = mpc.run(mpc.output(mpc.to_bits(secfld(255), 4))) self.assertEqual(c, [1, 1, 1, 1]) self.assertEqual(mpc.run(mpc.output(mpc.matrix_sub([[a]], [[a]])[0])), [0]) self.assertEqual( mpc.run(mpc.output(mpc.matrix_prod([c], [[a] * 4], True)[0])), [0]) self.assertEqual( mpc.run(mpc.output(mpc.matrix_prod([[a] * 4], [c], True)[0])), [0])
def test_secflt(self): secflt = mpc.SecFlt() a = secflt(1.25) b = secflt(2.5) self.assertEqual(mpc.run(mpc.output(mpc.input(a, 0))), 1.25) self.assertEqual(mpc.run(mpc.output(a + b)), 3.75) self.assertEqual(mpc.run(mpc.output(-a + -b)), -3.75) self.assertEqual(mpc.run(mpc.output(a * 2**10 + 2**10 * b)), 3.75 * 2**10) self.assertEqual(mpc.run(mpc.output(-b + b)), 0) self.assertEqual(mpc.run(mpc.output(abs(1.25 - +b))), 1.25) self.assertEqual(mpc.run(mpc.output(a * b)), 1.25 * 2.5) self.assertAlmostEqual(mpc.run(mpc.output(a / b)), 0.5, delta=2**-21) self.assertTrue(mpc.run(mpc.output(a < b))) self.assertTrue(mpc.run(mpc.output(a <= b))) self.assertFalse(mpc.run(mpc.output(a == b))) self.assertFalse(mpc.run(mpc.output(a >= b))) self.assertFalse(mpc.run(mpc.output(a > b))) self.assertTrue(mpc.run(mpc.output(a != b))) self.assertFalse(mpc.run(mpc.eq_public(a, b))) self.assertTrue(mpc.run(mpc.eq_public(a, a))) phi = secflt((math.sqrt(5) + 1) / 2) self.assertAlmostEqual(mpc.run(mpc.output(phi**2 - phi - 1)), 0, delta=2**-21) @mpc.coroutine async def nop(a) -> secflt: return a self.assertEqual(mpc.run(mpc.output(nop(a))), 1.25)
def test_bsecfld(self): secfld = mpc.SecFld(char=2, min_order=2**8) a = secfld(57) b = secfld(67) c = mpc.run(mpc.output(mpc.input(a, 0))) self.assertEqual(int(c), 57) c = mpc.run(mpc.output(a - (-a))) self.assertEqual(int(c), 0) c = mpc.run(mpc.output(a * b)) self.assertEqual(int(c), 137) c = mpc.run(mpc.output(c / a)) self.assertEqual(int(c), 67) c = mpc.run(mpc.output(a**254 * a)) self.assertEqual(int(c), 1) c = mpc.run(mpc.output(a & b)) self.assertEqual(int(c), 1) c = mpc.run(mpc.output(a | b)) self.assertEqual(int(c), 123) c = mpc.run(mpc.output(a ^ b)) self.assertEqual(int(c), 122) c = mpc.run(mpc.output(~a)) self.assertEqual(int(c), 198) c = mpc.run(mpc.output(mpc.to_bits(secfld(0)))) self.assertEqual(c, [0, 0, 0, 0, 0, 0, 0, 0]) c = mpc.run(mpc.output(mpc.to_bits(secfld(1)))) self.assertEqual(c, [1, 0, 0, 0, 0, 0, 0, 0]) c = mpc.run(mpc.output(mpc.to_bits(secfld(255)))) self.assertEqual(c, [1, 1, 1, 1, 1, 1, 1, 1]) c = mpc.run(mpc.output(mpc.to_bits(secfld(255), 1))) self.assertEqual(c, [1]) c = mpc.run(mpc.output(mpc.to_bits(secfld(255), 4))) self.assertEqual(c, [1, 1, 1, 1])
def test_bsecfld(self): secfld = mpc.SecFld(char2=True, l=8) a = secfld(57) b = secfld(67) c = mpc.run(mpc.output(mpc.input(a, 0))) self.assertEqual(c.value.value, 57) c = mpc.run(mpc.output(a - (-a))) self.assertEqual(c.value.value, 0) c = mpc.run(mpc.output(a * b)) self.assertEqual(c.value.value, 137) c = mpc.run(mpc.output(c / a)) self.assertEqual(c.value.value, 67) c = mpc.run(mpc.output(a**254 * a)) self.assertEqual(c.value.value, 1) c = mpc.run(mpc.output(a & b)) self.assertEqual(c.value.value, 1) c = mpc.run(mpc.output(a | b)) self.assertEqual(c.value.value, 123) c = mpc.run(mpc.output(a ^ b)) self.assertEqual(c.value.value, 122) c = mpc.run(mpc.output(~a)) self.assertEqual(c.value.value, 198) c = mpc.run(mpc.output(mpc.to_bits(secfld(0)))) self.assertEqual(c, [0, 0, 0, 0, 0, 0, 0, 0]) c = mpc.run(mpc.output(mpc.to_bits(secfld(1)))) self.assertEqual(c, [1, 0, 0, 0, 0, 0, 0, 0]) c = mpc.run(mpc.output(mpc.to_bits(secfld(255)))) self.assertEqual(c, [1, 1, 1, 1, 1, 1, 1, 1]) c = mpc.run(mpc.output(mpc.to_bits(secfld(255), 1))) self.assertEqual(c, [1]) c = mpc.run(mpc.output(mpc.to_bits(secfld(255), 4))) self.assertEqual(c, [1, 1, 1, 1])
async def parsort1(a): """Sort m numbers in O(m) time, each party providing one number a.""" if isinstance(a, (secint, secfxp, secflt)): x = await mpc.output(mpc.input(a)) else: x = await mpc.transfer(a) print('Random inputs, one per party: ', x) p = rank(x, mpc.pid) # x[mpc.pid] = a if isinstance(a, (secint, secfxp, secflt)): p = await mpc.output(mpc.input(type(a)(p))) p = [int(a) for a in p] else: p = await mpc.transfer(p) y = [x[a] for a in inverse(p)] assert y == sorted(x) print('Sorted outputs, one per party:', y)
async def main(): # Use 32-bit (default) secure integers: secint = mpc.SecInt() # Each party locally generates LOAD random entries of type secint: my_entries_for_vec_x = [secint(randint(-1000, 1000)) for _ in range(LOAD)] my_entries_for_vec_y = [secint(randint(-1000, 1000)) for _ in range(LOAD)] # Start MPyC runtime to let all parties connect: await mpc.start() # The entries for vectors x and y are secret-shared between all parties: vec_x = flatten(mpc.input(my_entries_for_vec_x)) vec_y = flatten(mpc.input(my_entries_for_vec_y)) # Secure dot products are supported natively and *very* efficiently: c = mpc.in_prod(vec_x, vec_y) # Open the secret-shared value c and let all parties print the result: print('Dot product:', await mpc.output(c)) # Shutdown MPyC runtime to close all connections: await mpc.shutdown()
def prepare_list(input_bits): # define placeholder type as int sec_int = mpc.SecInt() # distribute secret data input_list = [None] * len(input_bits) for i in range(len(input_bits)): # each process finds its own data at the position of its id and writes it in its own secret version of the list if mpc.pid == i: input_list[i] = input_bits[i] # prepare special internal list with placeholders and secret data sec_vec_l = [None] * len(input_bits) for i in range(len(input_bits)): sec_vec_l[i] = mpc.input( sec_int(input_list[i]) if mpc.pid == i else sec_int(), senders=i) return sec_vec_l
async def main(): # initialize mpc, define secure int type LEN = 10 await mpc.start() secint = mpc.SecInt(64) # initialize inputs values = [np.random.randint(1,1000) for _ in range(LEN)] n = len(mpc.parties) inputs = mpc.input([secint(v)for v in values], senders=list(range(n))) # compute pairwise products prod = inputs[0] for inp in inputs[1:]: prod = mpc.schur_prod(prod, inp) ip = mpc.sum(prod) # output result result = await mpc.output(ip) print("result:", result) await mpc.shutdown()
The protocol provides no secrecy but shows that a parallel computation can be seen as a special case of a secure multiparty computation. Accordingly, we set the threshold for the number of corrupt parties simply to 0. """ import random from mpyc.runtime import mpc mpc.threshold = 0 # no secret sharing mpc.start() secint = mpc.SecInt() print('Using secure integers:', secint) x = mpc.run(mpc.output(mpc.input(secint(random.randint(0, 99))))) print('Random inputs, one per party: ', x) x = [a.signed() for a in x] x.sort() x = mpc.run(mpc.output(mpc.input(secint(x[mpc.id])))) print('Sorted outputs, one per party: ', x) secfxp = mpc.SecFxp() print('Using secure fixed-point numbers:', secfxp) x = mpc.run(mpc.output(mpc.input(secfxp(0.5 - random.randint(0, 99))))) print('Random inputs, one per party: ', x) x = [a.signed() for a in x] x.sort() x = mpc.run(mpc.output(mpc.input(secfxp(x[mpc.id])))) print('Sorted outputs, one per party: ', x)
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_secint(self): secint = mpc.SecInt() a = secint(12) b = secint(13) self.assertEqual(mpc.run(mpc.output(mpc.input(a, 0))), 12) self.assertEqual(mpc.run(mpc.output(mpc.input([a, b], 0))), [12, 13]) self.assertEqual(mpc.run(mpc.output(-a)), -12) self.assertEqual(mpc.run(mpc.output(+a)), 12) self.assertNotEqual(id(a), id(+a)) # NB: +a creates a copy self.assertEqual(mpc.run(mpc.output(a * b + b)), 12 * 13 + 13) self.assertEqual(mpc.run(mpc.output((a * b) / b)), 12) self.assertEqual(mpc.run(mpc.output((a * b) / 12)), 13) self.assertEqual(mpc.run(mpc.output(a**11 * a**-6 * a**-5)), 1) self.assertEqual(mpc.run(mpc.output(a**(secint.field.modulus - 1))), 1) c = mpc.to_bits( mpc.SecInt(0)(0)) # mpc.output() only works for nonempty lists self.assertEqual(c, []) c = mpc.run(mpc.output(mpc.to_bits(mpc.SecInt(1)(0)))) self.assertEqual(c, [0]) c = mpc.run(mpc.output(mpc.to_bits(mpc.SecInt(1)(1)))) self.assertEqual(c, [1]) c = mpc.to_bits(secint(0), 0) # mpc.output() only works for nonempty lists self.assertEqual(c, []) c = mpc.run(mpc.output(mpc.to_bits(secint(0)))) self.assertEqual(c, [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) c = mpc.run(mpc.output(mpc.to_bits(secint(1)))) self.assertEqual(c, [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) c = mpc.run(mpc.output(mpc.to_bits(secint(8113)))) self.assertEqual(c, [ 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) c = mpc.run(mpc.output(mpc.to_bits(secint(2**31 - 1)))) self.assertEqual(c, [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 ]) c = mpc.run(mpc.output(mpc.to_bits(secint(2**31 - 1), 16))) self.assertEqual(c, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) c = mpc.run(mpc.output(mpc.to_bits(secint(-1), 8))) self.assertEqual(c, [1, 1, 1, 1, 1, 1, 1, 1]) c = mpc.run(mpc.output(mpc.to_bits(secint(-2**31)))) self.assertEqual(c, [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ]) c = mpc.run(mpc.output(mpc.to_bits(secint(-2**31), 16))) self.assertEqual(c, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) c = mpc.run(mpc.output(mpc.from_bits(mpc.to_bits(secint(8113))))) self.assertEqual(c, 8113) c = mpc.run(mpc.output(mpc.from_bits(mpc.to_bits(secint(2**31 - 1))))) self.assertEqual(c, 2**31 - 1) # TODO: from_bits for negative numbers # c = mpc.run(mpc.output(mpc.from_bits(mpc.to_bits(secint(-2**31))))) # self.assertEqual(c, -2**31) self.assertFalse(mpc.run(mpc.eq_public(secint(4), secint(2)))) self.assertTrue(mpc.run(mpc.eq_public(secint(42), secint(42)))) self.assertEqual(mpc.run(mpc.output(abs(secint(1)))), 1) self.assertEqual(mpc.run(mpc.output(secint(-2**31) % 2)), 0) self.assertEqual(mpc.run(mpc.output(secint(-2**31 + 1) % 2)), 1) self.assertEqual(mpc.run(mpc.output(secint(-1) % 2)), 1) self.assertEqual(mpc.run(mpc.output(secint(0) % 2)), 0) self.assertEqual(mpc.run(mpc.output(secint(1) % 2)), 1) self.assertEqual(mpc.run(mpc.output(secint(2**31 - 1) % 2)), 1) self.assertEqual(mpc.run(mpc.output(secint(5) % 2)), 1) self.assertEqual(mpc.run(mpc.output(secint(-5) % 2)), 1) self.assertEqual(mpc.run(mpc.output(secint(50) % 2)), 0) self.assertEqual(mpc.run(mpc.output(secint(50) % 4)), 2) self.assertEqual(mpc.run(mpc.output(secint(50) % 32)), 18) self.assertEqual(mpc.run(mpc.output(secint(-50) % 2)), 0) self.assertEqual(mpc.run(mpc.output(secint(-50) % 32)), 14) self.assertEqual(mpc.run(mpc.output(secint(5) // 2)), 2) self.assertEqual(mpc.run(mpc.output(secint(50) // 2)), 25) self.assertEqual(mpc.run(mpc.output(secint(50) // 4)), 12) self.assertEqual(mpc.run(mpc.output(secint(11) << 3)), 88) self.assertEqual(mpc.run(mpc.output(secint(-11) << 3)), -88) self.assertEqual(mpc.run(mpc.output(secint(70) >> 2)), 17) self.assertEqual(mpc.run(mpc.output(secint(-70) >> 2)), -18) self.assertEqual(mpc.run(mpc.output(secint(50) % 17)), 16) self.assertEqual(mpc.run(mpc.output(secint(177) % 17)), 7) self.assertEqual(mpc.run(mpc.output(secint(-50) % 17)), 1) self.assertEqual(mpc.run(mpc.output(secint(-177) % 17)), 10) self.assertEqual(mpc.run(mpc.output(secint(3)**0)), 1) self.assertEqual(mpc.run(mpc.output(secint(3)**18)), 3**18) self.assertIn(mpc.run(mpc.output(mpc.random_bit(secint))), [0, 1]) self.assertIn(mpc.run(mpc.output(mpc.random_bit(secint, signed=True))), [-1, 1])
def to_bits(n, secret=False): if secret: return [mpc.input(sec((n >> i) & 1))[0] for i in range(31, -1, -1)] else: return [(n >> i) & 1 for i in range(31, -1, -1)]
def test_io(self): x = ({4, 3}, [1 - 1j, 2.5], 0, range(7)) self.assertEqual(mpc.run(mpc.transfer(x))[0], x) self.assertEqual(mpc.run(mpc.transfer(x, senders=0)), x) self.assertEqual(mpc.run(mpc.transfer(x, senders=[0]))[0], x) self.assertEqual( mpc.run(mpc.transfer(x, senders=iter(range(1))))[0], x) self.assertEqual(mpc.run(mpc.transfer(x, receivers=0))[0], x) self.assertEqual(mpc.run(mpc.transfer(x, receivers=[0]))[0], x) self.assertEqual( mpc.run(mpc.transfer(x, receivers=iter(range(1))))[0], x) self.assertEqual(mpc.run(mpc.transfer(x, senders=0, receivers=0)), x) self.assertEqual( mpc.run(mpc.transfer(x, senders=[0], receivers=[0]))[0], x) self.assertEqual( mpc.run(mpc.transfer(x, sender_receivers=[(0, 0)]))[0], x) self.assertEqual( mpc.run(mpc.transfer(x, sender_receivers={0: {0}}))[0], x) a = mpc.SecInt()(7) self.assertEqual(mpc.run(mpc.output(mpc.input(a)))[0], 7) self.assertEqual(mpc.run(mpc.output(mpc.input(a)[0])), 7) self.assertEqual(mpc.run(mpc.output(mpc.input(a, senders=0))), 7) self.assertEqual(mpc.run(mpc.output(mpc.input(a, senders=[0])))[0], 7) self.assertEqual( mpc.run(mpc.output(mpc.input(a, senders=iter(range(1)))))[0], 7) self.assertEqual(mpc.run(mpc.output(mpc.input(a, senders=[0])))[0], 7) self.assertEqual(mpc.run(mpc.output(mpc.input(a, senders=[0])[0])), 7) self.assertEqual(mpc.run(mpc.output(mpc.input(a), receivers=0))[0], 7) self.assertEqual(mpc.run(mpc.output(mpc.input(a)[0], receivers=0)), 7) self.assertEqual( mpc.run(mpc.output(mpc.input(a), receivers=[0]))[0], 7) self.assertEqual( mpc.run(mpc.output(mpc.input(a), receivers=iter(range(1))))[0], 7) self.assertEqual(mpc.run(mpc.output(mpc.input(a)[0], receivers=[0])), 7) self.assertEqual( mpc.run(mpc.output(mpc.input(a, senders=0), receivers=0)), 7) self.assertEqual( mpc.run(mpc.output(mpc.input(a, senders=[0]), receivers=[0]))[0], 7) self.assertEqual( mpc.run(mpc.output(mpc.input(a, senders=[0])[0], receivers=[0])), 7) x = [a, a] self.assertEqual(mpc.run(mpc.output(mpc.input(x)[0])), [7, 7]) self.assertEqual(mpc.run(mpc.output(mpc.input(x, senders=0))), [7, 7]) self.assertEqual(mpc.run(mpc.output(mpc.input(x, senders=[0])[0])), [7, 7]) self.assertEqual(mpc.run(mpc.output(mpc.input(x)[0], receivers=0)), [7, 7]) self.assertEqual(mpc.run(mpc.output(mpc.input(x)[0], receivers=[0])), [7, 7]) self.assertEqual( mpc.run(mpc.output(mpc.input(x, senders=0), receivers=0)), [7, 7]) self.assertEqual( mpc.run(mpc.output(mpc.input(x, senders=[0])[0], receivers=[0])), [7, 7])
m = len(mpc.parties) if m%2 == 0: print('OT runs with odd number of parties only.') sys.exit() t = m//2 message = [(None, None)] * t choice = [None] * t if mpc.pid == 0: print('You are the trusted third party.') elif 1 <= mpc.pid <= t: message[mpc.pid - 1] = (random.randint(0, 99), random.randint(0, 99)) print(f'You are sender {mpc.pid} holding messages ' f'{message[mpc.pid - 1][0]} and {message[mpc.pid - 1][1]}.') else: choice[mpc.pid - t - 1] = random.randint(0, 1) print(f'You are receiver {mpc.pid - t} with random choice bit {choice[mpc.pid - t - 1]}.') mpc.run(mpc.start()) secnum = mpc.SecInt() for i in range(1, t+1): x = mpc.input([secnum(message[i-1][0]), secnum(message[i-1][1])], i) b = mpc.input(secnum(choice[i-1]), t + i) a = mpc.run(mpc.output(mpc.if_else(b, x[1], x[0]), t + i)) if a is not None: print(f'You have received message {a}.') mpc.run(mpc.shutdown())
m = len(mpc.parties) if m % 2 == 0: print('Odd number of parties required.') sys.exit() t = m // 2 voters = list(range(t + 1)) # parties P[0],...,P[t] if mpc.pid in voters: vote = int(sys.argv[1]) if sys.argv[1:] else 1 # default "yes" else: vote = None # no input secbit = mpc.SecFld(2) # secure bits over GF(2) mpc.run(mpc.start()) votes = mpc.input(secbit(vote), senders=voters) result = mpc.run(mpc.output(mpc.all(votes), receivers=voters)) mpc.run(mpc.shutdown()) if result is None: # no output print('Thanks for serving as oblivious matchmaker;)') elif result: print( f'Match: unanimous agreement between {t+1} part{"ies" if t else "y"}!') else: print( f'No match: someone disagrees among {t+1} part{"ies" if t else "y"}?')
# Convert the votes to secure type my_sec_votes = list(map(secfxp, my_votes)) # Generate this client's noise part my_noise = float(np.random.normal(0, sigma1)) # Convert the noise part to secure type my_sec_noise = secfxp(my_noise) else: # The server is not an input party (it has no votes, and no noise part) my_sec_votes = list(map(secfxp, [None] * NB_CLASSES)) my_sec_noise = secfxp(None) # Secret-share the votes from this party with every other party all_sec_votes = mpc.input(my_sec_votes, senders=list(range(1, M))) # Aggregate the secure votes from all parties total_sec_votes = vector_add_all(all_sec_votes) # Secret-share the noise part from this party with every other party all_sec_noises = mpc.input(my_sec_noise, senders=list(range(1, M))) # Aggregate the secure noises from all parties total_sec_noise = scalar_add_all(all_sec_noises) # Find the secure maximum in the aggregated array of votes sec_max = mpc.max(total_sec_votes) # Add the aggregated noise to this max value noisy_sec_max = sec_max + total_sec_noise
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()
print('You are party', mpc.pid) print('-------------------------------------------\n') # Reading teachers votes from file with open('vote' + str(mpc.pid) + '.txt', 'r') as f: vote = int(f.read()[:-1]) assert (vote >= 0 and vote <= 9) # Perform one hot-encoded on this vote --> 2 becomes [0, 0, 1, 0, 0, 0, 0, 0, 0, 0] vote_one_hot = [1 if x == vote else 0 for x in range(0, NB_CANDIDATES)] sec_vote_one_hot = list(map(secint, vote_one_hot)) senders = list(range(0, M)) inputs_sec_votes = mpc.input( sec_vote_one_hot, senders ) # By default, if doesn't specify the second argument, everyone is a sender sec_total_votes = add_all_votes(inputs_sec_votes) total_votes = mpc.run(mpc.output(sec_total_votes)) total_votes = list(map(int, total_votes)) # Decode the array total_votes as an json repr #votes_count = Counter(total_votes) #print(votes_count) votes_count = {} for i, count in enumerate(total_votes): votes_count[i] = count pprint(votes_count)
def test_secint(self): secint = mpc.SecInt() a = secint(12) b = secint(13) c = mpc.run(mpc.output(mpc.input(a, 0))) self.assertEqual(c, 12) c = mpc.run(mpc.output(mpc.input([a, b], 0))) self.assertEqual(c, [12, 13]) c = mpc.run(mpc.output(a * b + b)) self.assertEqual(c, 12 * 13 + 13) c = mpc.run(mpc.output((a * b) / b)) self.assertEqual(c, 12) c = mpc.run(mpc.output((a * b) / 12)) self.assertEqual(c, 13) c = mpc.run(mpc.output(a**11 * a**(-6) * a**(-5))) self.assertEqual(c, 1) c = mpc.run(mpc.output(a**(secint.field.modulus - 1))) self.assertEqual(c, 1) self.assertEqual(mpc.run(mpc.output(secint(12)**73)), 12**73) c = mpc.to_bits( mpc.SecInt(0)(0)) # mpc.output() only works for non-empty lists self.assertEqual(c, []) c = mpc.run(mpc.output(mpc.to_bits(mpc.SecInt(1)(0)))) self.assertEqual(c, [0]) c = mpc.run(mpc.output(mpc.to_bits(mpc.SecInt(1)(1)))) self.assertEqual(c, [1]) c = mpc.to_bits(secint(0), 0) # mpc.output() only works for non-empty lists self.assertEqual(c, []) c = mpc.run(mpc.output(mpc.to_bits(secint(0)))) self.assertEqual(c, [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) c = mpc.run(mpc.output(mpc.to_bits(secint(1)))) self.assertEqual(c, [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) c = mpc.run(mpc.output(mpc.to_bits(secint(8113)))) self.assertEqual(c, [ 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) c = mpc.run(mpc.output(mpc.to_bits(secint(2**31 - 1)))) self.assertEqual(c, [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 ]) c = mpc.run(mpc.output(mpc.to_bits(secint(2**31 - 1), 16))) self.assertEqual(c, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) c = mpc.run(mpc.output(mpc.to_bits(secint(-1), 8))) self.assertEqual(c, [1, 1, 1, 1, 1, 1, 1, 1]) c = mpc.run(mpc.output(mpc.to_bits(secint(-2**31)))) self.assertEqual(c, [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ]) c = mpc.run(mpc.output(mpc.to_bits(secint(-2**31), 16))) self.assertEqual(c, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) c = mpc.run(mpc.output(mpc.from_bits(mpc.to_bits(secint(8113))))) self.assertEqual(c, 8113) c = mpc.run(mpc.output(mpc.from_bits(mpc.to_bits(secint(2**31 - 1))))) self.assertEqual(c, 2**31 - 1) # TODO: from_bits for negative numbers # c = mpc.run(mpc.output(mpc.from_bits(mpc.to_bits(secint(-2**31))))) # self.assertEqual(c, -2**31) self.assertEqual(mpc.run(mpc.output(secint(-2**31) % 2)), 0) self.assertEqual(mpc.run(mpc.output(secint(-2**31 + 1) % 2)), 1) self.assertEqual(mpc.run(mpc.output(secint(-1) % 2)), 1) self.assertEqual(mpc.run(mpc.output(secint(0) % 2)), 0) self.assertEqual(mpc.run(mpc.output(secint(1) % 2)), 1) self.assertEqual(mpc.run(mpc.output(secint(2**31 - 1) % 2)), 1) self.assertEqual(mpc.run(mpc.output(secint(5) % 2)), 1) self.assertEqual(mpc.run(mpc.output(secint(-5) % 2)), 1) self.assertEqual(mpc.run(mpc.output(secint(50) % 2)), 0) self.assertEqual(mpc.run(mpc.output(secint(50) % 4)), 2) self.assertEqual(mpc.run(mpc.output(secint(50) % 32)), 18) self.assertEqual(mpc.run(mpc.output(secint(-50) % 2)), 0) self.assertEqual(mpc.run(mpc.output(secint(-50) % 32)), 14) self.assertEqual(mpc.run(mpc.output(secint(5) // 2)), 2) self.assertEqual(mpc.run(mpc.output(secint(50) // 2)), 25) self.assertEqual(mpc.run(mpc.output(secint(50) // 4)), 12) self.assertEqual(mpc.run(mpc.output(secint(11) << 3)), 88) self.assertEqual(mpc.run(mpc.output(secint(-11) << 3)), -88) self.assertEqual(mpc.run(mpc.output(secint(70) >> 2)), 17) self.assertEqual(mpc.run(mpc.output(secint(-70) >> 2)), -18) self.assertEqual(mpc.run(mpc.output(secint(50) % 17)), 16) self.assertEqual(mpc.run(mpc.output(secint(177) % 17)), 7) self.assertEqual(mpc.run(mpc.output(secint(-50) % 17)), 1) self.assertEqual(mpc.run(mpc.output(secint(-177) % 17)), 10) self.assertEqual(mpc.run(mpc.output(secint(3)**73)), 3**73) b = mpc.random_bit(secint) self.assertIn(mpc.run(mpc.output(b)), [0, 1]) b = mpc.random_bit(secint, signed=True) self.assertIn(mpc.run(mpc.output(b)), [-1, 1])
# Iterate over all samples in the public dataset for sample_id in range(NB_SAMPLES): if not IS_SERVER: # Take the sample_id°th votes of the list my_votes = list(map(int, np_votes[sample_id])) # Convert the votes to secure type my_sec_votes = list(map(secfxp, my_votes)) else: # The server is not an input party (it has no votes) my_sec_votes = list(map(secfxp, [None] * NB_CLASSES)) # Secret-share the votes from this party with every other party all_sec_votes = mpc.input(my_sec_votes, senders=list(range(1, M))) # Aggregate the secure votes from all parties total_sec_votes = vector_add_all(all_sec_votes) if not IS_SERVER: # Generate two different noise values (from the same distribution) # Each party will end up using one of the two in an oblivious manner noise0 = float(np.random.normal(0, sigma1)) noise1 = float(np.random.normal(0, sigma1)) # Convert them to secure type sec_noise0, sec_noise1 = secfxp(noise0), secfxp(noise1) else: # The server does not generate noise values
""" if l: y = sorted(x)[k:k + l] else: y = sorted(x)[k] return y mpc.threshold = 0 # No secret sharing. m = len(mpc.parties) mpc.run(mpc.start()) secint = mpc.SecInt() print('Using secure integers:', secint) x = mpc.run(mpc.output(mpc.input(secint(random.randint(0, 99))))) print('Random inputs, one per party: ', x) x = [a.signed() for a in x] a = quickselect(x, mpc.pid) x = mpc.run(mpc.output(mpc.input(secint(a)))) print('Sorted outputs, one per party:', x) x = mpc.input([secint(random.randint(0, 999)) for _ in range(m)]) x = list(itertools.chain(*x)) x = mpc.run(mpc.output(x)) print('Random inputs,', m, 'per party: ', x) x = [a.signed() for a in x] x = sorted(quickselect(x, m * mpc.pid, m)) x = mpc.input([secint(a) for a in x]) x = list(itertools.chain(*x)) x = mpc.run(mpc.output(x))
async def main(): parser = argparse.ArgumentParser() parser.add_argument('-i', '--datasets', metavar='I', nargs='+', help='datasets (default = 1 3)') parser.add_argument('-a', '--accuracy', type=int, metavar='A', help='accuracy A (number of decimal places), A>=0') parser.add_argument('-l', '--bit-length', type=int, metavar='L', help='override automatically set bit length') parser.add_argument('-p', '--plot', action='store_true', default=False, help='plot histogram and density') parser.set_defaults(datasets=('1', '3'), accuracy=3) args = parser.parse_args() datadir = os.path.join('data', 'mlat') sensors = pd.read_csv(os.path.join(datadir, 'sensors.csv'), index_col=0) await mpc.start() df = pd.concat( pd.read_csv(os.path.join(datadir, f'set_{i}.csv')) for i in args.datasets) nrows = len(df) l = args.bit_length if l is None: l = 200 + args.accuracy * 45 secint = mpc.SecInt(l) scaling = 10**args.accuracy print( f'Using secure {l}-bit integers: {secint.__name__} (scale factor={scaling})' ) distances = [None] * nrows for ix, row in enumerate(df.itertuples()): # Five sensors (parties i=0..4) give their own location and timestamp as private input: locations = [None] * 5 toas = [None] * 5 for i, sensor_id in enumerate(list(zip(*eval(row.measurements)))[0]): sender_pid = i % len( mpc.parties) # to make demo work with any number of parties if mpc.pid == sender_pid: lla_i = sensors.loc[sensor_id][[ 'latitude', 'longitude', 'height' ]].values x_i, y_i, z_i = DatumTransformation.wgs_to_ecef(*lla_i) position_i = [ int(x_i * scaling), int(y_i * scaling), int(z_i * scaling) ] toas_i = list(zip(*eval(row.measurements)))[1][i] toas_i *= speed_of_light / 1e9 toas_i = int(toas_i * scaling) else: position_i = [None] * 3 toas_i = None locations[i] = mpc.input(list(map(secint, position_i)), senders=sender_pid) toas[i] = mpc.input(secint(toas_i), senders=sender_pid) x, y, z = await schmidt_multilateration(locations, toas) x, y, z = x / scaling, y / scaling, z / scaling latitude, longitude, _ = DatumTransformation.ecef_to_wgs(x, y, z) altitude = row.geoAltitude # fix altitude to reported altitude x, y, z = DatumTransformation.wgs_to_ecef(latitude, longitude, altitude) X, Y, Z = DatumTransformation.wgs_to_ecef(row.latitude, row.longitude, altitude) d = sqrt((x - X)**2 + (y - Y)**2 + (z - Z)**2) distances[ ix] = d # distance between computed and known aircraft position print( f'Processing {len(df)} measurements from sets {"+".join(args.datasets)}: ' f'{round(100*(ix + 1)/nrows)}%', end='\r') print() await mpc.shutdown() distances = pd.Series(distances) print('Location Error [m]:') print(distances.describe()) if mpc.pid == 0 and args.plot: _, ax = plt.subplots(1, 1, figsize=(8, 5)) ax.set_title(f'Frequency and density for {nrows} measurements') distances.plot.kde(bw_method=0.025, ind=range(0, 1000), secondary_y=True, color=(1, 0.55, 0.5), linewidth=3) ax.right_ax.set_yticks([]) # suppress density scale distances.plot.hist(bins=10, range=(0, 1000), rwidth=.9, color=(0, 0.55, 1)) ax.set_xlim([0, 1000]) ax.set_xlabel('Location Error [m]') plt.show()
"""Couple of MPyC oneliners. Run with m parties to compute: - m = sum_{i=0}^{m-1} 1 = sum(1 for i in range(m)) - m**2 = sum_{i=0}^{m-1} 2i+1 = sum(2*i+1 for i in range(m)) - 2**m = prod_{i=0}^{m-1} 2 = prod(2 for i in range(m)) - m! = prod_{i=0}^{m-1} i+1 = prod(i+1 for i in range(m)) Bit lengths of secure integers ensure each result fits for any m, 1<=m<=256. """ from mpyc.runtime import mpc mpc.run(mpc.start()) print('m =', mpc.run(mpc.output(mpc.sum(mpc.input(mpc.SecInt(9)(1)))))) print('m**2 =', mpc.run(mpc.output(mpc.sum(mpc.input(mpc.SecInt(17)(2 * mpc.pid + 1)))))) print('2**m =', mpc.run(mpc.output(mpc.prod(mpc.input(mpc.SecInt(257)(2)))))) print('m! =', mpc.run(mpc.output(mpc.prod(mpc.input(mpc.SecInt(1685)(mpc.pid + 1)))))) mpc.run(mpc.shutdown())
Run with m parties to compute: - m = sum_{i=0}^{m-1} 1 = sum(1 for i in range(m)) - m**2 = sum_{i=0}^{m-1} 2i+1 = sum(2*i+1 for i in range(m)) - 2**m = prod_{i=0}^{m-1} 2 = prod(2 for i in range(m)) - m! = prod_{i=0}^{m-1} i+1 = prod(i+1 for i in range(m)) Bit lengths of secure integers ensure each result fits for any m >= 1. """ from mpyc.runtime import mpc m = len(mpc.parties) l = m.bit_length() mpc.run(mpc.start()) print('m =', mpc.run(mpc.output(mpc.sum(mpc.input(mpc.SecInt(l + 1)(1)))))) print( 'm**2 =', mpc.run( mpc.output(mpc.sum(mpc.input(mpc.SecInt(2 * l + 1)(2 * mpc.pid + 1)))))) print('2**m =', mpc.run(mpc.output(mpc.prod(mpc.input(mpc.SecInt(m + 2)(2)))))) print( 'm! =', mpc.run( mpc.output( mpc.prod(mpc.input( mpc.SecInt(int(m * (l - 1.4) + 3))(mpc.pid + 1)))))) mpc.run(mpc.shutdown())
def test_secfxp(self): secfxp = mpc.SecFxp() self.assertEqual( mpc.run(mpc.output(mpc.input(secfxp(7.7), senders=0))), 7.7) 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 + [ 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) c = mpc.run(mpc.output(secfxp(1) + secfxp(1))) self.assertEqual(c.frac_length, f) 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) 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] 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]) 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 = [int(_) 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 = int(s[0] < s[1] and s[1] < s[2]) self.assertEqual(mpc.run(mpc.output((a < b) & (b < c))), t) t = int(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 = [int(s[0] > 1), int(10 * s[1] < 5), int(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(float(mpc.run(mpc.output(d / 0.25))), t, delta=2**(1 - f)) t = round(s[3] / s[2] + s[0]) # TODO: fix round() vs int() self.assertEqual(int(mpc.run(mpc.output(d / c + a))), t) t = ((s[0] + s[1])**2 + 3 * s[2]) / s[2] self.assertAlmostEqual(float( mpc.run(mpc.output(((a + b)**2 + 3 * c) / c))), t, delta=2**(8 - f)) t = 1 / s[3] self.assertAlmostEqual(float(mpc.run(mpc.output(1 / d))), t, delta=2**(6 - f)) t = s[2] / s[3] self.assertAlmostEqual(float(mpc.run(mpc.output(c / d))), t, delta=2**(3 - f)) t = -s[3] / s[2] t = round(t * (1 << f)) self.assertAlmostEqual(mpc.run(mpc.output(-d / c)), t, delta=2**(3 - f)) self.assertEqual(mpc.run(mpc.output(mpc.sgn(+a))), int(s[0] > 0)) self.assertEqual(mpc.run(mpc.output(mpc.sgn(-a))), -int(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(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])