Exemplo 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)
    ]
Exemplo 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
Exemplo n.º 3
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)]
Exemplo n.º 4
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)]
Exemplo n.º 5
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)
Exemplo n.º 6
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)
Exemplo n.º 7
0
        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
        sec_noise0, sec_noise1 = secfxp(None), secfxp(None)

    # Secret-share both noise values with every other party
    all_sec_noises0 = mpc.input(sec_noise0, senders=list(range(1, M)))
    all_sec_noises1 = mpc.input(sec_noise1, senders=list(range(1, M)))

    # Collectively (and securely) draw M-1 random bits (one for each client)
    # These will be use to select which noise to use (0 or 1), for all clients
    sec_selection_bits = mpc.random_bits(secfxp, M - 1)

    sec_chosen_noises = []
    for client_id, selection_bit_for_client in enumerate(sec_selection_bits):
        # If b is 0, we select noise0 from this client
        # If b is 1, we select noise1 from this client
        sec_chosen_noise = mpc.if_else(selection_bit_for_client,
                                       all_sec_noises1[client_id],
                                       all_sec_noises0[client_id])
        sec_chosen_noises.append(sec_chosen_noise)

    # Aggregate the secure noise values from all parties
    total_sec_noise = scalar_add_all(sec_chosen_noises)

    # Find the secure maximum in the aggregated array of votes
    sec_max = mpc.max(total_sec_votes)