Example #1
0
 def test_misc(self):
     secint = mpc.SecInt()
     secfxp = mpc.SecFxp()
     secfld = mpc.SecFld()
     for secnum in (secint, secfxp, secfld):
         self.assertEqual(type(mpc.run(mpc.output(secnum(0), raw=True))), secnum.field)
         self.assertEqual(mpc.run(mpc.output(mpc._reshare([secnum(0)]))), [0])
         self.assertEqual(mpc.run(mpc.output(mpc.all(secnum(1) for _ in range(5)))), True)
         self.assertEqual(mpc.run(mpc.output(mpc.all([secnum(1), secnum(1), secnum(0)]))), False)
         self.assertEqual(mpc.run(mpc.output(mpc.any(secnum(0) for _ in range(5)))), False)
         self.assertEqual(mpc.run(mpc.output(mpc.any([secnum(0), secnum(1), secnum(1)]))), True)
         self.assertEqual(mpc.run(mpc.output(mpc.sum([secnum(1)], start=1))), 2)
         self.assertEqual(mpc.run(mpc.output(mpc.prod([secnum(1)], start=1))), 1)
         self.assertEqual(mpc.run(mpc.output(mpc.sum([secnum(1)], start=secnum(1)))), 2)
     self.assertEqual(mpc.run(mpc.output(mpc.min(secint(i) for i in range(-1, 2, 1)))), -1)
     self.assertEqual(mpc.run(mpc.output(mpc.argmin(secint(i) for i in range(-1, 2, 1))[0])), 0)
     self.assertEqual(mpc.run(mpc.output(mpc.max(secfxp(i) for i in range(-1, 2, 1)))), 1)
     self.assertEqual(mpc.run(mpc.output(mpc.argmax(secfxp(i) for i in range(-1, 2, 1))[0])), 2)
     self.assertEqual(mpc.run(mpc.output(list(mpc.min_max(map(secfxp, range(5)))))), [0, 4])
     x = (secint(i) for i in range(-3, 3))
     s = [0, -1, 1, -2, 2, -3]
     self.assertEqual(mpc.run(mpc.output(mpc.sorted(x, key=lambda a: a*(2*a+1)))), s)
     x = (secfxp(i) for i in range(5))
     self.assertEqual(mpc.run(mpc.output(mpc.sorted(x, reverse=True))), [4, 3, 2, 1, 0])
     self.assertEqual(mpc.run(mpc.output(mpc.sum(map(secint, range(5))))), 10)
     self.assertEqual(mpc.run(mpc.output(mpc.sum([secfxp(2.75)], start=3.125))), 5.875)
     self.assertEqual(int(mpc.run(mpc.output(mpc.prod(map(secfxp, range(1, 5)))))), 24)
     self.assertEqual(int(mpc.run(mpc.output(mpc.prod([secfxp(1.414214)]*4)))), 4)
Example #2
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()
Example #3
0
async def random_derangement(n, sectype):
    """Random permutation of [sectype(i) for i in range(n)] without fixed point."""
    await mpc.returnType((sectype, True), n)
    p = random_permutation(n, sectype)
    t = mpc.prod([p[i] - i for i in range(n)])
    if await mpc.is_zero_public(t):
        p = random_derangement(n, sectype)
    return p
Example #4
0
def GI(x):
    """Gini impurity for contingency table x."""
    y = [args.alpha * s + 1
         for s in map(mpc.sum, x)]  # NB: alternatively, use s + (s == 0)
    D = mpc.prod(y)
    G = mpc.in_prod(list(map(mpc.in_prod, x, x)), list(map(lambda x: 1 / x,
                                                           y)))
    return [D * G, D]  # numerator, denominator
Example #5
0
async def random_derangement(n):  # returns list of n secint elements
    await mpc.returnType(secint, n)  # set return type of this MPyC coroutine
    p = random_permutation(n)
    t = mpc.prod([p[i] - i for i in range(n)
                  ])  # securely multiply all differences p[i] - i
    if await mpc.is_zero_public(t):  # publicly test whether t is equal to zero
        return random_derangement(n)  # recurse if t is zero
    else:
        return p  # done if t is nonzero
Example #6
0
 def test_misc(self):
     secint = mpc.SecInt()
     secfxp = mpc.SecFxp()
     secfld = mpc.SecFld()
     for secnum in (secint, secfxp, secfld):
         self.assertEqual(mpc.run(mpc.output(mpc._reshare([secnum(0)]))),
                          [0])
         self.assertEqual(
             mpc.run(mpc.output(mpc.all(secnum(1) for _ in range(5)))),
             True)
         self.assertEqual(
             mpc.run(mpc.output(mpc.all([secnum(1),
                                         secnum(1),
                                         secnum(0)]))), False)
         self.assertEqual(
             mpc.run(mpc.output(mpc.any(secnum(0) for _ in range(5)))),
             False)
         self.assertEqual(
             mpc.run(mpc.output(mpc.any([secnum(0),
                                         secnum(1),
                                         secnum(1)]))), True)
         self.assertEqual(
             mpc.run(mpc.output(mpc.sum([secnum(1)], start=1))), 2)
         self.assertEqual(
             mpc.run(mpc.output(mpc.prod([secnum(1)], start=1))), 1)
         self.assertEqual(
             mpc.run(mpc.output(mpc.sum([secnum(1)], start=secnum(1)))), 2)
     self.assertEqual(
         mpc.run(mpc.output(mpc.min(secint(i) for i in range(-1, 2, 1)))),
         -1)
     self.assertEqual(
         mpc.run(mpc.output(mpc.max(secfxp(i) for i in range(-1, 2, 1)))),
         1)
     self.assertEqual(
         mpc.run(mpc.output(list(mpc.min_max(map(secfxp, range(5)))))),
         [0, 4])
     self.assertEqual(mpc.run(mpc.output(mpc.sum(map(secint, range(5))))),
                      10)
     self.assertEqual(
         mpc.run(mpc.output(mpc.sum([secfxp(2.72)], start=3.14))), 5.86)
     self.assertEqual(
         int(mpc.run(mpc.output(mpc.prod(map(secfxp, range(1, 5)))))), 24)
     self.assertEqual(
         int(mpc.run(mpc.output(mpc.prod([secfxp(1.414214)] * 4)))), 4)
Example #7
0
def random_matrix_determinant(secfld, d):
    d_2 = d * (d - 1) // 2
    L = np.diagflat([secfld(1)] * d)
    L[np.tril_indices(d, -1)] = mpc._randoms(secfld, d_2)
    L[np.triu_indices(d, 1)] = [secfld(0)] * d_2
    diag = mpc._randoms(secfld, d)
    U = np.diagflat(diag)
    U[np.tril_indices(d, -1)] = [secfld(0)] * d_2
    U[np.triu_indices(d, 1)] = mpc._randoms(secfld, d_2)
    R = mpc.matrix_prod(L.tolist(), U.tolist())
    detR = mpc.prod(diag)  # detR != 0 with overwhelming probability
    return R, detR
Example #8
0
 def test_empty_input(self):
     secint = mpc.SecInt()
     self.assertEqual(mpc.run(mpc.gather([])), [])
     self.assertEqual(mpc.run(mpc.output([])), [])
     self.assertEqual(mpc._reshare([]), [])
     self.assertEqual(mpc.convert([], None), [])
     self.assertEqual(mpc.sum([]), 0)
     self.assertEqual(mpc.prod([]), 1)
     self.assertEqual(mpc.in_prod([], []), 0)
     self.assertEqual(mpc.vector_add([], []), [])
     self.assertEqual(mpc.vector_sub([], []), [])
     self.assertEqual(mpc.scalar_mul(secint(0), []), [])
     self.assertEqual(mpc.schur_prod([], []), [])
     self.assertEqual(mpc.from_bits([]), 0)
Example #9
0
async def vector_sge(x):
    """Compute binary signs securely for all elements of x in parallel.

    Vectorized version of MPyC's built-in secure comparison.
    Cf. mpc.sgn() with GE=True (and EQ=False).

    NB: mpc.prod() and mpc.is_zero_public() are not (yet) vectorized.
    """
    stype = type(x[0])
    n = len(x)
    await mpc.returnType(stype, n)
    Zp = stype.field
    l = stype.bit_length
    k = mpc.options.sec_param

    r_bits = await mpc.random_bits(Zp, (l + 1) * n)
    r_bits = [b.value for b in r_bits]
    r_modl = [0] * n
    for j in range(n):
        for i in range(l - 1, -1, -1):
            r_modl[j] <<= 1
            r_modl[j] += r_bits[l * j + i]
    r_divl = mpc._randoms(Zp, n, 1 << k)
    x = await mpc.gather(x)
    x_r = [a + ((1 << l) + b) for a, b in zip(x, r_modl)]
    c = await mpc.output([a + (b.value << l) for a, b in zip(x_r, r_divl)])

    c = [c.value % (1 << l) for c in c]
    e = [[None] * (l + 1) for _ in range(n)]
    for j in range(n):
        s_sign = (r_bits[l * n + j] << 1) - 1
        sumXors = 0
        for i in range(l - 1, -1, -1):
            c_i = (c[j] >> i) & 1
            e[j][i] = Zp(s_sign + r_bits[l * j + i] - c_i + 3 * sumXors)
            sumXors += 1 - r_bits[l * j + i] if c_i else r_bits[l * j + i]
        e[j][l] = Zp(s_sign - 1 + 3 * sumXors)
    e = await mpc.gather([mpc.prod(_) for _ in e])
    g = await mpc.gather([mpc.is_zero_public(stype(_)) for _ in e])
    UF = [1 - b if g else b for b, g in zip(r_bits[-n:], g)]
    z = [(a - (c + (b << l))) / (1 << l - 1) - 1
         for a, b, c in zip(x_r, UF, c)]
    return z
Example #10
0
async def bsgn_0(a):
    """Compute binary sign of a securely.

    Binary sign of a (1 if a>=0 else -1) is obtained by securely computing (2a+1 | p).

    Legendre symbols (a | p) for secret a are computed securely by evaluating
    (a s r^2 | p) in the clear for secret random sign s and secret random r modulo p,
    and outputting secret s * (a s r^2 | p).
    """
    stype = type(a)
    await mpc.returnType(stype)
    Zp = stype.field
    p = Zp.modulus
    legendre_p = lambda a: gmpy2.legendre(a.value, p)

    s = mpc.random_bits(Zp, 1, signed=True)  # random sign
    r = mpc._random(Zp)
    r = mpc.prod([r, r])  # random square modulo p
    a, s, r = await mpc.gather(a, s, r)
    b = await mpc.prod([2 * a + 1, s[0], r])
    b = await mpc.output(b)
    return s[0] * legendre_p(b)
Example #11
0
async def schmidt_multilateration(locations, toas):
    """Schmidt's multilateration algorithm."""
    # Transform sensor locations and ToA measurements
    # into linear system A w = b, using Schmidt's method:
    norm = [mpc.in_prod(p, p) for p in locations]
    A, b = [], []
    for i, j, k in itertools.combinations(range(len(locations)), 3):
        Delta = [toas[j] - toas[k], toas[k] - toas[i], toas[i] - toas[j]]
        XYZN = [
            locations[i] + [norm[i]], locations[j] + [norm[j]],
            locations[k] + [norm[k]]
        ]
        r_x, r_y, r_z, r_n = mpc.matrix_prod([Delta], XYZN)[0]
        A.append([2 * r_x, 2 * r_y, 2 * r_z])
        b.append(mpc.prod(Delta) + r_n)

    # Compute least-squares solution w satisfying A^T A w = A^T b:
    AT, bT = list(map(list, zip(*A))), [b]  # transpose of A and b
    ATA = mpc.matrix_prod(AT, AT, tr=True)  # A^T (A^T)^T = A^T A
    ATb = mpc.matrix_prod(AT, bT, tr=True)  # A^T (b^T)^T = A^T b
    w_det = linear_solve(ATA, ATb)
    x, y, z, det = await mpc.output(w_det)
    w = x / det, y / det, z / det
    return w
Example #12
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())
Example #13
0
 def test_misc(self):
     secint = mpc.SecInt()
     secfxp = mpc.SecFxp()
     secfld = mpc.SecFld()
     for secnum in (secint, secfxp, secfld):
         self.assertEqual(type(mpc.run(mpc.output(secnum(0), raw=True))),
                          secnum.field)
         self.assertEqual(mpc.run(mpc.output(mpc._reshare([secnum(0)]))),
                          [0])
         self.assertEqual(
             mpc.run(mpc.output(mpc.all(secnum(1) for _ in range(5)))),
             True)
         self.assertEqual(
             mpc.run(mpc.output(mpc.all([secnum(1),
                                         secnum(1),
                                         secnum(0)]))), False)
         self.assertEqual(
             mpc.run(mpc.output(mpc.any(secnum(0) for _ in range(5)))),
             False)
         self.assertEqual(
             mpc.run(mpc.output(mpc.any([secnum(0),
                                         secnum(1),
                                         secnum(1)]))), True)
         self.assertEqual(
             mpc.run(mpc.output(mpc.sum([secnum(1)], start=1))), 2)
         self.assertEqual(
             mpc.run(mpc.output(mpc.prod([secnum(1)], start=1))), 1)
         self.assertEqual(
             mpc.run(mpc.output(mpc.sum([secnum(1)], start=secnum(1)))), 2)
         self.assertEqual(
             mpc.run(mpc.output(mpc.find([secnum(1)], 0, e=-1))), -1)
         self.assertEqual(mpc.run(mpc.output(mpc.find([secnum(1)], 1))), 0)
         self.assertEqual(
             mpc.run(mpc.output(mpc.find([secnum(1)], 1, f=lambda i: i))),
             0)
     self.assertEqual(
         mpc.run(mpc.output(mpc.min(secint(i) for i in range(-1, 2, 1)))),
         -1)
     self.assertEqual(
         mpc.run(
             mpc.output(mpc.argmin(secint(i) for i in range(-1, 2, 1))[0])),
         0)
     self.assertEqual(
         mpc.run(mpc.output(mpc.max(secfxp(i) for i in range(-1, 2, 1)))),
         1)
     self.assertEqual(
         mpc.run(
             mpc.output(mpc.argmax(secfxp(i) for i in range(-1, 2, 1))[0])),
         2)
     self.assertEqual(
         mpc.run(mpc.output(list(mpc.min_max(map(secfxp, range(5)))))),
         [0, 4])
     x = (secint(i) for i in range(-3, 3))
     s = [0, -1, 1, -2, 2, -3]
     self.assertEqual(
         mpc.run(mpc.output(mpc.sorted(x, key=lambda a: a * (2 * a + 1)))),
         s)
     x = (secfxp(i) for i in range(5))
     self.assertEqual(mpc.run(mpc.output(mpc.sorted(x, reverse=True))),
                      [4, 3, 2, 1, 0])
     self.assertEqual(mpc.run(mpc.output(mpc.sum(map(secint, range(5))))),
                      10)
     self.assertEqual(
         mpc.run(mpc.output(mpc.sum([secfxp(2.75)], start=3.125))), 5.875)
     self.assertEqual(
         int(mpc.run(mpc.output(mpc.prod(map(secfxp, range(1, 5)))))), 24)
     self.assertEqual(
         int(mpc.run(mpc.output(mpc.prod([secfxp(1.414214)] * 4)))), 4)
     self.assertEqual(mpc.find([], 0), 0)
     self.assertEqual(mpc.find([], 0, e=None), (1, 0))
     self.assertEqual(
         mpc.run(mpc.output(list(mpc.find([secfld(1)], 1, e=None)))),
         [0, 0])
     self.assertEqual(
         mpc.run(mpc.output(mpc.find([secfld(2)], 2, bits=False))), 0)
     x = [secint(i) for i in range(5)]
     f = lambda i: [i**2, 3**i]
     self.assertEqual(mpc.run(mpc.output(mpc.find(x, 2, bits=False, f=f))),
                      [4, 9])
     cs_f = lambda b, i: [b * (2 * i + 1) + i**2, (b * 2 + 1) * 3**i]
     self.assertEqual(
         mpc.run(mpc.output(mpc.find(x, 2, bits=False, cs_f=cs_f))), [4, 9])
Example #14
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())
async def main():
  await mpc.start()
  with open(f"icissp2020-{len(mpc.parties)}_parties-output.csv", 'w', newline='') as csvfile:
    print(f"running benchmarks; output will be in {csvfile.name}")
    print("clearing netem delay just in case ...")
    subprocess.run(["sudo", "tc", "qdisc","del","dev","lo","root","netem","delay", '0ms'])
    subprocess.run(["sudo", "tc", "qdisc","del","dev","lo","root","netem","loss", '0%'])
    fieldnames = ["length","delay","loss","addition","mpc.vector_add()","summation","mpc.sum()","multiplication","mpc.schur_prod()","product","mpc.prod()"]
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    writer.writeheader()
    for d in range(0,55,5):
      for p in range(0,11,1):
        for length in [1,10,100]:
          print("generating random inputs ...")
          a = [ [ mpc.input(sec(secrets.randbits(sec.bit_length)))[0] for _ in range(length) ] for _ in range(loop) ]
          b = [ [ mpc.input(sec(secrets.randbits(sec.bit_length)))[0] for _ in range(length) ] for _ in range(loop) ]
          r1 = [None] * loop
          r2 = [None] * loop
          res = [None] * 8
          for i in range(loop):
            await mpc.output(a[i])
            await mpc.output(b[i])
          time.sleep(1)
          print(f"comparing {loop} runs on vectors of length {length} with latency {d*2}ms and {p}% loss\n")

          subprocess.run(["sudo", "tc", "qdisc","add","dev","lo","root","netem","delay", f"{d}ms"])
          subprocess.run(["sudo", "tc", "qdisc","add","dev","lo","root","netem","loss", f"{p}%"])

          print("elementwise addition".ljust(32), end='', flush=True)
          t1 = time.perf_counter()
          for i in range(loop):
            r = list(map(operator.add, a[i], b[i]))
            r1[i] = await mpc.gather(r)
          t2 = time.perf_counter()
          print(f"{(t2 - t1):.5} seconds")
          res[0] = f"{(t2 - t1):f}"
          time.sleep(1)

          print("mpc.vector_add()".ljust(32), end='', flush=True)
          t1 = time.perf_counter()
          for i in range(loop):
            r = mpc.vector_add(a[i], b[i])
            r2[i] = await mpc.gather(r)
          t2 = time.perf_counter()
          print(f"{(t2 - t1):.5} seconds")
          res[1] = f"{(t2 - t1):f}"
          time.sleep(1)

          print("summation".ljust(32), end='', flush=True)
          t1 = time.perf_counter()
          for i in range(loop):
            r = functools.reduce(operator.add, a[i])
            r1[i] = await mpc.gather(r)
          t2 = time.perf_counter()
          print(f"{(t2 - t1):.5} seconds")
          res[2] = f"{(t2 - t1):f}"
          time.sleep(1)

          print("mpc.sum()".ljust(32), end='', flush=True)
          t1 = time.perf_counter()
          for i in range(loop):
            r = mpc.sum(a[i])
            r2[i] = await mpc.gather(r)
          t2 = time.perf_counter()
          print(f"{(t2 - t1):.5} seconds")
          res[3] = f"{(t2 - t1):f}"
          time.sleep(1)

          print("elementwise multiplication".ljust(32), end='', flush=True)
          t1 = time.perf_counter()
          for i in range(loop):
            r = list(map(operator.mul, a[i], b[i]))
            r1[i] = await mpc.gather(r)
          t2 = time.perf_counter()
          print(f"{(t2 - t1):.5} seconds")
          res[4] = f"{(t2 - t1):f}"
          time.sleep(1)

          print("mpc.schur_prod()".ljust(32), end='', flush=True)
          t1 = time.perf_counter()
          for i in range(loop):
            r = mpc.schur_prod(a[i], b[i])
            r2[i] = await mpc.gather(r)
          t2 = time.perf_counter()
          print(f"{(t2 - t1):.5} seconds")
          res[5] = f"{(t2 - t1):f}"
          time.sleep(1)

          print("product".ljust(32), end='', flush=True)
          t1 = time.perf_counter()
          for i in range(loop):
            r = functools.reduce(operator.mul, a[i])
            r1[i] = await mpc.gather(r)
          t2 = time.perf_counter()
          print(f"{(t2 - t1):.5} seconds")
          res[6] = f"{(t2 - t1):f}"
          time.sleep(1)

          print("mpc.prod()".ljust(32), end='', flush=True)
          t1 = time.perf_counter()
          for i in range(loop):
            r = mpc.prod(a[i])
            r2[i] = await mpc.gather(r)
          t2 = time.perf_counter()
          print(f"{(t2 - t1):.5} seconds")
          res[7] = f"{(t2 - t1):f}"
          time.sleep(1)

          subprocess.run(["sudo", "tc", "qdisc","del","dev","lo","root","netem","delay", "0ms"])
          subprocess.run(["sudo", "tc", "qdisc","del","dev","lo","root","netem","loss", "0%"])

          writer.writerow({
            'length': f"{length}",
            'delay': f"{d*2}",
            'loss': f"{p}",
            'addition': res[0],
            'mpc.vector_add()': res[1],
            'summation': res[2],
            'mpc.sum()': res[3],
            'multiplication': res[4],
            'mpc.schur_prod()': res[5],
            'product': res[6],
            'mpc.prod()': res[7]
            })
  await mpc.shutdown()