Ejemplo n.º 1
0
async def vector_bsgn_1(x):
    """Compute bsgn_1(a) for all elements a of x in parallel."""
    stype = type(x[0])
    n = len(x)
    await mpc.returnType(stype, n)
    Zp = stype.field
    p = Zp.modulus
    legendre_p = lambda a: gmpy2.legendre(a.value, p)

    s = mpc.random_bits(Zp, 3 * n, signed=True)  # 3n random signs
    r = mpc._randoms(Zp, 3 * n)
    r = mpc.schur_prod(r, r)  # 3n random squares modulo p
    x, s, r = await mpc.gather(x, s, r)
    y = [b + 2 * i for b in (2 * a + 1 for a in x) for i in (-1, 0, 1)]
    y.extend(s[:n])
    s.extend(s[n:2 * n])
    r.extend(s[-n:])
    y = await mpc.schur_prod(y, s)
    y = await mpc.schur_prod(y, r)
    y = await mpc.output(y)
    h = [legendre_p(y[j]) for j in range(3 * n)]
    t = [s[j] * h[j] for j in range(3 * n)]
    z = [
        h[3 * j] * h[3 * j + 1] * h[3 * j + 2] * y[3 * n + j] for j in range(n)
    ]
    q = (p + 1) >> 1  # q = 1/2 mod p
    return [
        Zp((u.value + v.value + w.value - uvw.value) * q)
        for u, v, w, uvw in zip(*[iter(t)] * 3, z)
    ]
Ejemplo n.º 2
0
async def bsgn_1(a):
    """Compute binary sign of a securely.

    Binary sign of a (1 if a>=0 else -1) is obtained by securely computing
    (u+v+w - u*v*w)/2 with u=(2a-1 | p), v=(2a+1 | p), and w=(2a+3 | 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, 3, signed=True)  # 3 random signs
    r = mpc._randoms(Zp, 3)
    r = mpc.schur_prod(r, r)  # 3 random squares modulo p
    a, s, r = await mpc.gather(a, s, r)
    y = [b + 2 * i for b in (2 * a + 1, ) for i in (-1, 0, 1)]
    y.append(s[0])
    s.append(s[1])
    r.append(s[2])
    y = await mpc.schur_prod(y, s)
    y = await mpc.schur_prod(y, r)
    y = await mpc.output(y)
    h = [legendre_p(y[i]) for i in range(3)]
    u, v, w = [s[i] * h[i] for i in range(3)]
    uvw = h[0] * h[1] * h[2] * y[3]
    return (u + v + w - uvw) / 2
Ejemplo n.º 3
0
async def add(a, b):
    await asyncoro.returnType(sec, 32)
    res = [None] * 32
    c = None
    atb = mpc.schur_prod(a, b)
    apb = mpc.vector_add(a, b)
    for i in range(31, -1, -1):
        res[i], c = add_(atb[i], apb[i], c)
    return res
Ejemplo n.º 4
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)
Ejemplo n.º 5
0
async def vector_bsgn_0(x):
    """Compute bsgn_0(a) for all elements a of x in parallel."""
    stype = type(x[0])
    n = len(x)
    await mpc.returnType(stype, n)
    Zp = stype.field
    p = Zp.modulus
    legendre_p = lambda a: gmpy2.legendre(a.value, p)

    s = mpc.random_bits(Zp, n, signed=True)  # n random signs
    r = mpc._randoms(Zp, n)
    r = mpc.schur_prod(r, r)  # n random squares modulo p
    x, s, r = await mpc.gather(x, s, r)
    y = [2 * a + 1 for a in x]
    y = await mpc.schur_prod(y, s)
    y = await mpc.schur_prod(y, r)
    y = await mpc.output(y)
    return [s[j] * legendre_p(y[j]) for j in range(n)]
Ejemplo n.º 6
0
async def vector_bsgn_2(x):
    """Compute bsgn_2(a) for all elements a of x in parallel."""
    stype = type(x[0])
    n = len(x)
    await mpc.returnType(stype, n)
    Zp = stype.field
    p = Zp.modulus
    legendre_p = lambda a: gmpy2.legendre(a.value, p)

    s = mpc.random_bits(Zp, 6*n, signed=True)  # 6n random signs
    r = mpc._randoms(Zp, 6*n)
    r = mpc.schur_prod(r, r)  # 6n random squares modulo p
    x, s, r = await mpc.gather(x, s, r)
    y = [b + 2 * i for b in (2 * a + 1 for a in x) for i in (-2, -1, 0, 1, 2)]
    y = await mpc.schur_prod(y, s[:-n])
    y.extend(s[-n:])
    y = await mpc.schur_prod(y, r)
    y = await mpc.output(y)
    t = [sum(s[5*j + i] * legendre_p(y[5*j + i]) for i in range(5)) for j in range(n)]
    t = await mpc.output(await mpc.schur_prod(t, y[-n:]))
    return [c * legendre_p(d) for c, d in zip(s[-n:], t)]
Ejemplo n.º 7
0
def argmin(x, arg_le):
    n = len(x)
    if n == 1:
        return ([1], x[0])
    if n == 2:
        b, m = arg_le(x[0], x[1])
        return ([1 - b, b], m)
    b2 = [None] * (n // 2)
    m2 = [None] * ((n + 1) // 2)
    for i in range(n // 2):
        b2[i], m2[i] = arg_le(x[2 * i], x[2 * i + 1])
    if n % 2 == 1:
        m2[-1] = x[-1]
    a2, m = argmin(m2, arg_le)
    a = [None] * n
    if n % 2 == 1:
        a[-1] = a2.pop()
    b2 = mpc.schur_prod(b2, a2)
    for i in range(n // 2):
        a[2 * i] = a2[i] - b2[i]
        a[2 * i + 1] = b2[i]
    return a, m
Ejemplo n.º 8
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()
Ejemplo n.º 9
0
async def id3(T, R) -> asyncio.Future:
    sizes = [mpc.in_prod(T, v) for v in S[C]]
    i, mx = mpc.argmax(sizes)
    sizeT = mpc.sum(sizes)
    stop = (sizeT <= int(args.epsilon * len(T))) + (mx == sizeT)
    if not (R and await mpc.is_zero_public(stop)):
        i = await mpc.output(i)
        logging.info(f'Leaf node label {i}')
        tree = i
    else:
        T_R = [[mpc.schur_prod(T, v) for v in S[A]] for A in R]
        gains = [GI(mpc.matrix_prod(T_A, S[C], True)) for T_A in T_R]
        k = await mpc.output(mpc.argmax(gains, key=SecureFraction)[0])
        T_Rk = T_R[k]
        del T_R, gains  # release memory
        A = list(R)[k]
        logging.info(f'Attribute node {A}')
        if args.parallel_subtrees:
            subtrees = await mpc.gather(
                [id3(Tj, R.difference([A])) for Tj in T_Rk])
        else:
            subtrees = [await id3(Tj, R.difference([A])) for Tj in T_Rk]
        tree = A, subtrees
    return tree
Ejemplo n.º 10
0
async def bsgn_2(a):
    """Compute binary sign of a securely.

    Binary sign of a (1 if a>=0 else -1) is obtained by securely computing
    (t | p), with t = sum((2a+1+2i | p) for i=-2,-1,0,1,2).
    """
    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, 6, signed=True)  # 6 random signs
    r = mpc._randoms(Zp, 6)
    r = mpc.schur_prod(r, r)  # 6 random squares modulo p
    a, s, r = await mpc.gather(a, s, r)
    y = [b + 2 * i for b in (2 * a + 1, ) for i in (-2, -1, 0, 1, 2)]
    y = await mpc.schur_prod(y, s[:-1])
    y.append(s[-1])
    y = await mpc.schur_prod(y, r)
    y = await mpc.output(y)
    t = sum(s[i] * legendre_p(y[i]) for i in range(5))
    t = await mpc.output(t * y[-1])
    return s[-1] * legendre_p(t)
Ejemplo n.º 11
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])
Ejemplo n.º 12
0
    def test_secfxp(self):
        secfxp = mpc.SecFxp()
        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(mpc.run(mpc.output(d / 0.25)).signed(),
                                   t,
                                   delta=1)
            t = s[3] / s[2] + s[0]
            self.assertAlmostEqual(mpc.run(mpc.output(d / c + a)).signed(),
                                   t,
                                   delta=1)
            t = round(t * (1 << f))
            self.assertAlmostEqual(mpc.run(mpc.output(d / c + a)), t, delta=1)
            t = ((s[0] + s[1])**2 + 3 * s[2]) / s[2]
            self.assertAlmostEqual(mpc.run(mpc.output(
                ((a + b)**2 + 3 * c) / c)).signed(),
                                   t,
                                   delta=2)
            t = 1 / s[3]
            self.assertAlmostEqual((mpc.run(mpc.output(1 / d))).signed(),
                                   t,
                                   delta=1)
            t = s[2] / s[3]
            self.assertAlmostEqual(mpc.run(mpc.output(c / d)).signed(),
                                   t,
                                   delta=1)
            t = -s[3] / s[2]
            t = round(t * (1 << f))
            self.assertAlmostEqual(mpc.run(mpc.output(-d / c)), t, delta=1)
            t = s[2] / s[3]
            t = round(t * (1 << f))
            self.assertAlmostEqual(mpc.run(mpc.output(d / c)), t, delta=1)

            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])
Ejemplo n.º 13
0
    def test_secfxp(self):
        secfxp = mpc.SecFxp()
        c = mpc.to_bits(secfxp(0),
                        0)  # mpc.output() only works for non-empty lists
        self.assertEqual(c, [])
        c = mpc.run(mpc.output(mpc.to_bits(secfxp(0))))
        self.assertEqual(c, [0.0] * 32)
        c = mpc.run(mpc.output(mpc.to_bits(secfxp(1))))
        self.assertEqual(c, [0.0] * 16 + [1.0] + [0.0] * 15)
        c = mpc.run(mpc.output(mpc.to_bits(secfxp(8113))))
        self.assertEqual(c, [0.0] * 16 + [
            float(b) for b in [1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0]
        ])
        c = mpc.run(mpc.output(mpc.to_bits(secfxp(2**15 - 1))))
        self.assertEqual(c, [float(b) for b in [0] * 16 + [1] * 15 + [0]])
        c = mpc.run(mpc.output(mpc.to_bits(secfxp(-1))))
        self.assertEqual(c, [float(b) for b in [0] * 16 + [1] * 16])
        c = mpc.run(mpc.output(mpc.to_bits(secfxp(-2**15))))
        self.assertEqual(c, [float(b) for b in [0] * 31 + [1]])

        for f in [8, 16, 32, 64]:
            secfxp = mpc.SecFxp(2 * f)
            d = mpc.run(mpc.output(secfxp(1) + secfxp(1)))
            self.assertEqual(d.frac_length, f)
            self.assertEqual(d, 2)
            d = mpc.run(mpc.output(secfxp(2**-f) + secfxp(1)))
            f == 64 or self.assertEqual(
                d, 1 + 2**-f)  # NB: 1 + 2**-64 == 1 in Python
            d = mpc.run(mpc.output(secfxp(0.5) * secfxp(2.0)))
            self.assertEqual(d, 1)
            d = mpc.run(mpc.output(secfxp(2.0) * secfxp(0.5)))
            self.assertEqual(d, 1)

            s = [10.7, -3.4, 0.1, -0.11]
            self.assertEqual(mpc.run(mpc.output(list(map(secfxp, s)))), s)

            s = [10.5, -3.25, 0.125, -0.125]
            x, y, z, w = list(map(secfxp, s))
            s2 = [v * v for v in s]
            self.assertEqual(mpc.run(mpc.output([x * x, y * y, z * z, w * w])),
                             s2)
            self.assertEqual(
                mpc.run(mpc.output(mpc.schur_prod([x, y, z, w],
                                                  [x, y, z, w]))), s2)
            s2 = [_ for x, y, z, w in [s] for _ in [x + y, x * y, x - y]]
            self.assertEqual(mpc.run(mpc.output([x + y, x * y, x - y])), s2)
            s2 = [
                _ for x, y, z, w in [s]
                for _ in [(x + y)**2, (x + y)**2 + 3 * z]
            ]
            self.assertEqual(
                mpc.run(mpc.output([(x + y)**2, (x + y)**2 + 3 * z])), s2)
            s2 = [int(_) for x, y, z, w in [s] for _ in [x < y, y < z, z < w]]
            self.assertEqual(mpc.run(mpc.output([x < y, y < z, z < w])), s2)
            s2 = int(s[0] < s[1] and s[1] < s[2])
            self.assertEqual(mpc.run(mpc.output((x < y) & (y < z))), s2)
            s2 = int(s[0] < s[1] or s[1] < s[2])
            self.assertEqual(mpc.run(mpc.output((x < y) | (y < z))), s2)
            s2 = (int(s[0] < s[1]) ^ int(s[1] < s[2]))
            self.assertEqual(mpc.run(mpc.output((x < y) ^ (y < z))), s2)
            s2 = (int(not s[0] < s[1]) ^ int(s[1] < s[2]))
            self.assertEqual(mpc.run(mpc.output(~(x < y) ^ y < z)), s2)
            s2 = [int(s[0] < 1), int(10 * s[1] < 5), int(10 * s[0] == 5)]
            self.assertEqual(
                mpc.run(mpc.output([x < 1, 10 * y < 5, 10 * x == 5])), s2)

            s[3] = -0.120
            w = secfxp(s[3])
            for _ in range(3):
                s2 = s[3] / s[2] + s[0]
                self.assertAlmostEqual(mpc.run(mpc.output(w / z + x)).signed(),
                                       s2,
                                       delta=1)
                ss2 = round(s2 * (1 << f))
                self.assertAlmostEqual(mpc.run(mpc.output(w / z + x)),
                                       ss2,
                                       delta=1)
                s2 = ((s[0] + s[1])**2 + 3 * s[2]) / s[2]
                self.assertAlmostEqual(mpc.run(
                    mpc.output(((x + y)**2 + 3 * z) / z)).signed(),
                                       s2,
                                       delta=2)
                s2 = 1 / s[3]
                self.assertAlmostEqual((mpc.run(mpc.output(1 / w))).signed(),
                                       s2,
                                       delta=1)
                s2 = s[2] / s[3]
                self.assertAlmostEqual(mpc.run(mpc.output(z / w)).signed(),
                                       s2,
                                       delta=1)
                s2 = -s[3] / s[2]
                ss2 = round(s2 * (1 << f))
                self.assertAlmostEqual(mpc.run(mpc.output(-w / z)),
                                       ss2,
                                       delta=1)
                s2 = s[2] / s[3]
                ss2 = round(s2 * (1 << f))
                self.assertAlmostEqual(mpc.run(mpc.output(w / z)),
                                       ss2,
                                       delta=1)

            self.assertEqual(mpc.run(mpc.output(mpc.sgn(x))), int(s[0] > 0))
            self.assertEqual(mpc.run(mpc.output(mpc.sgn(-x))), -int(s[0] > 0))
            self.assertEqual(mpc.run(mpc.output(mpc.sgn(secfxp(0)))), 0)

            self.assertEqual(mpc.run(mpc.output(mpc.min(x, y, w, z))), min(s))
            self.assertEqual(mpc.run(mpc.output(mpc.min(x, 0))), min(s[0], 0))
            self.assertEqual(mpc.run(mpc.output(mpc.min(0, y))), min(0, s[1]))
            self.assertEqual(mpc.run(mpc.output(mpc.max(x, y, w, z))), max(s))
            self.assertEqual(mpc.run(mpc.output(mpc.max(x, 0))), max(s[0], 0))
            self.assertEqual(mpc.run(mpc.output(mpc.max(0, y))), max(0, s[1]))

            self.assertEqual(mpc.run(mpc.output(secfxp(5) % 2)), 1 * (2**f))
            self.assertEqual(mpc.run(mpc.output(secfxp(1) % 2**(1 - f))),
                             0 * (2**f))
            self.assertEqual(
                mpc.run(mpc.output(secfxp(1 / 2**f) % 2**(1 - f))), 1)
            self.assertEqual(
                mpc.run(mpc.output(secfxp(2 / 2**f) % 2**(1 - f))), 0)
            self.assertEqual(mpc.run(mpc.output(secfxp(1) // 2**(1 - f))),
                             2**(f - 1))
            self.assertEqual(mpc.run(mpc.output(secfxp(27.0) % 7.0)), 6.0)
            self.assertEqual(mpc.run(mpc.output(secfxp(-27.0) // 7.0)), -4.0)
            self.assertEqual(
                mpc.run(mpc.output(list(divmod(secfxp(27.0), 6.0)))),
                [4.0, 3.0])
            self.assertEqual(mpc.run(mpc.output(secfxp(21.5) % 7.5)), 6.5)
            self.assertEqual(mpc.run(mpc.output(secfxp(-21.5) // 7.5)), -3.0)
            self.assertEqual(
                mpc.run(mpc.output(list(divmod(secfxp(21.5), 0.5)))),
                [43.0, 0.0])
Ejemplo n.º 14
0
 def getitem(self, index):
     """get item with a secret index, returns 0 when item is not included"""
     length = len(self.values)
     unit = mpc.unit_vector(index, length)
     return mpc.sum(mpc.schur_prod(self.included_values_or_zero(), unit))
Ejemplo n.º 15
0
 def included_values_or_zero(self):
     return mpc.schur_prod(self.values, self.included)
Ejemplo n.º 16
0
 def getitem(self, index):
     """get item with a secret index"""
     length = len(self.values)
     unit = mpc.unit_vector(index, length)
     return mpc.sum(mpc.schur_prod(self.values, unit))
Ejemplo n.º 17
0
def get_attribute_value_for_sample(sample, index):
    unit_vector = mpc.unit_vector(index, len(sample))
    return mpc.sum(mpc.schur_prod(sample, unit_vector))
Ejemplo n.º 18
0
 def select(self, *include):
     selection = ObliviousArray(self.values).select(*include)
     included = mpc.schur_prod(self.included, selection.included)
     return ObliviousSelection(selection.values, included)
Ejemplo n.º 19
0
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()