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()
Пример #2
0
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()
Пример #3
0
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()
Пример #4
0
    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
Пример #5
0
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()
Пример #6
0
 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])
Пример #7
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)
Пример #8
0
 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])
Пример #9
0
 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])
Пример #10
0
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)
Пример #11
0
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()
Пример #12
0
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
Пример #13
0
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()
Пример #14
0
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)
Пример #15
0
    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])
Пример #16
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])
Пример #17
0
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)]
Пример #18
0
    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])
Пример #19
0
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())
Пример #20
0
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"}?')
Пример #21
0
        # 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
Пример #22
0
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()
Пример #23
0
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)
Пример #24
0
    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])
Пример #25
0
# 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
Пример #26
0
    """
    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))
Пример #27
0
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()
Пример #28
0
"""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())
Пример #29
0
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())
Пример #30
0
    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])