示例#1
0
def ref_generator(d, ref, io_sums=False):
    circuit = circuit_model.Circuit()
    var_inputs = [circuit.var(f'x_{i}', kind='input') for i in range(d)]
    var_outputs = [circuit.var(f'y_{i}', kind='output') for i in range(d)]
    ref(circuit=circuit, inputs=var_inputs, outputs=var_outputs)
    if io_sums:
        s = circuit.var('s')
        circuit.p_sum(s, var_inputs)
        circuit.p_sum(s, var_outputs)
    return circuit
示例#2
0
def test_refresh(d, ref=simple_ref):
    circuit = circuit_model.Circuit()
    var_inputs = [circuit.var(f'x_{i}', kind='input') for i in range(d)]
    var_outputs = [circuit.var(f'y_{i}', kind='output') for i in range(d)]
    ref(circuit=circuit, inputs=var_inputs, outputs=var_outputs)
    g = circuit_model.CompGraph(circuit)
    x = gen_random_input(d)
    inputs = {f'x_{i}': v for i, v in enumerate(x)}
    res, _ = g.compute(inputs)
    y = [
        v for var, v in res.items() if circuit.vars[var].name.startswith('y_')
    ]
    assert (sum(x) % 2) == (sum(y) % 2)
示例#3
0
def pini3(d, mat_gen, tmp_sums, strong_bij=False):
    c = circuit_model.Circuit()
    sx, sy, sz, x, y, z = mul_preamble(d, c, strong_bij)

    if tmp_sums:
        var_sums = (sx, sy)
    else:
        var_sums = None
    ref_prods = mat_gen(c, x, y, var_sums=var_sums)

    # randoms & temps in matrix
    r = [{
        j: c.var(f'r_{i}_{j}', kind='random' if j < i else 'intermediate')
        for j in range(d) if j != i
    } for i in range(d)]
    for i in range(d):
        for j in range(i):
            c.assign(r[j][i], r[i][j])

    s = [{j: c.var(f's_{i}_{j}')
          for j in range(d) if j != i} for i in range(d)]
    p = [{
        j: [c.var(f'p_{i}_{j}_{k}') for k in range(3)]
        for j in range(d) if j != i
    } for i in range(d)]
    t = [{j: c.var(f't_{i}_{j}') for j in range(d)} for i in range(d)]
    for i in range(d):
        c.l_prod(t[i][i], ref_prods[i][i])
        for j in range(d):
            if j != i:
                xi, yj = ref_prods[i][j]
                # not(x_i)
                #nxi = c.var(f'nxi_{i}_{j}')
                #c.l_sum(nxi, (xi,))
                c.l_sum(s[i][j], (yj, r[i][j]))
                c.l_prod(p[i][j][0], (xi, r[i][j]))
                c.l_prod(p[i][j][1], (xi, s[i][j]))
                c.l_sum(p[i][j][2], (p[i][j][0], r[i][j]))
                c.l_sum(t[i][j], (p[i][j][2], p[i][j][1]))

    c_var = [[c.var(f'c_{i}_{j}') for j in range(d)] for i in range(d)]
    for i in range(d):
        c.assign(c_var[i][0], t[i][0])
        for j in range(1, d):
            c.l_sum(c_var[i][j], (c_var[i][j - 1], t[i][j]))
        c.assign(z[i], c_var[i][d - 1])

    return c
示例#4
0
def BBP15(d, strong_bij=False):
    d2 = d - 1
    c = circuit_model.Circuit()
    _, _, _, x, y, z = mul_preamble(d, c, strong_bij)

    # product matrix
    p = [[c.var(f'p_{i}_{j}') for j in range(d)] for i in range(d)]
    for i, j in it.product(range(d), range(d)):
        c.l_prod(p[i][j], (x[i], y[j]))

    # randoms & temps in matrix & compression
    r = [{
        d2 - j: c.var(f'r_{i}_{j}', kind='random')
        for j in range(0, d2 - i, 2)
    } for i in range(d)]
    r2 = {j: c.var(f'r2_{j}', kind='random') for j in range(d2 - 1, 0, -2)}
    t = [{
        j: [c.var(f't_{i}_{j}_{k}') for k in range(5)]
        for j in range(d2, i + 1, -2)
    } for i in range(d)]
    c_var = [{j: c.var(f'c_{i}_{j}')
              for j in range(d2 + 2, i + 1, -2)} for i in range(d)]
    for i in range(d):
        c.assign(c_var[i][d2 + 2], p[i][i])
        for j in range(d2, i + 1, -2):
            c.l_sum(t[i][j][0], (r[i][j], p[i][j]))
            c.l_sum(t[i][j][1], (t[i][j][0], p[j][i]))
            c.l_sum(t[i][j][2], (t[i][j][1], r2[j - 1]))
            c.l_sum(t[i][j][3], (t[i][j][2], p[i][j - 1]))
            c.l_sum(t[i][j][4], (t[i][j][3], p[j - 1][i]))
            c.l_sum(c_var[i][j], (c_var[i][j + 2], t[i][j][4]))
        if (i - d2) % 2 != 0:
            t[i][i + 1] = [c.var(f't_{i}_{i+1}_0'), c.var(f't_{i}_{i+1}_1')]
            c_var[i][i + 1] = c.var(f'c_{i}_{i+1}')
            c.l_sum(t[i][i + 1][0], (r[i][i + 1], p[i][i + 1]))
            c.l_sum(t[i][i + 1][1], (t[i][i + 1][0], p[i + 1][i]))
            c.l_sum(c_var[i][i + 1], (c_var[i][i + 3], t[i][i + 1][1]))
            if i % 2 == 1:
                c.l_sum(z[i], (c_var[i][i + 1], r2[i]))
            else:
                c.assign(z[i], c_var[i][i + 1])
        else:
            for j in range(i - 1, -1, -1):
                c_var[i][j + 2] = c.var(f'c_{i}_{j+2}')
                c.l_sum(c_var[i][j + 2], (c_var[i][j + 3], r[j][i]))
            c.assign(z[i], c_var[i][2])

    return c
示例#5
0
def pinic(d, mat_gen, tmp_sums, strong_bij=False):
    c = circuit_model.Circuit()
    x, y, z, shx, shy, shz = mul_preamble(d,
                                          c,
                                          strong_bij=False,
                                          x_kind='intermediate',
                                          x_name='x2')
    shx2 = [c.var(f'x_{i}', kind='input') for i in range(d)]
    if strong_bij:
        for sx, sy in zip(shx2, shy):
            c.bij(sx, sy)
    x2 = c.var('x', kind='property')
    c.bij(x2, x)
    refs_gen.bat_ref(c, shx2, shx)
    if tmp_sums:
        c.p_sum(x, shx2)
    bat_mul_inner(d, mat_gen, tmp_sums, c, x, y, z, shx, shy, shz)
    return c
示例#6
0
def pini1(d, strong_bij=False):
    c = circuit_model.Circuit()
    sx, sy, sz, x, y, z = mul_preamble(d, c, strong_bij)

    # randoms & temps in matrix
    r = [{
        j: c.var(f'r_{i}_{j}', kind='random' if j < i else 'intermediate')
        for j in range(d) if j != i
    } for i in range(d)]
    for i in range(d):
        for j in range(i):
            c.assign(r[j][i], r[i][j])

    s = [{j: c.var(f's_{i}_{j}')
          for j in range(d) if j != i} for i in range(d)]
    p = [{
        j: [c.var(f'p_{i}_{j}_{k}') for k in range(2)]
        for j in range(d) if j != i
    } for i in range(d)]
    t = [{j: c.var(f't_{i}_{j}') for j in range(d)} for i in range(d)]
    for i in range(d):
        c.l_prod(t[i][i], (x[i], y[i]))
        # not(x_i)
        nxi = c.var(f'nxi_{i}')
        c.l_sum(nxi, (x[i], ))
        for j in range(d):
            if j != i:
                xi, yj = x[i], y[j]
                c.l_sum(s[i][j], (yj, r[i][j]))
                c.l_prod(p[i][j][0], (nxi, r[i][j]))
                c.l_prod(p[i][j][1], (xi, s[i][j]))
                c.l_sum(t[i][j], (p[i][j][0], p[i][j][1]))

    c_var = [[c.var(f'c_{i}_{j}') for j in range(d)] for i in range(d)]
    for i in range(d):
        c.assign(c_var[i][0], t[i][0])
        for j in range(1, d):
            c.l_sum(c_var[i][j], (c_var[i][j - 1], t[i][j]))
        c.assign(z[i], c_var[i][d - 1])

    return c
示例#7
0
def bat_mul(d, mat_gen, tmp_sums, strong_bij=False):
    c = circuit_model.Circuit()
    sx, sy, sz, x, y, z = mul_preamble(d, c, strong_bij)
    bat_mul_inner(d, mat_gen, tmp_sums, c, sx, sy, sz, x, y, z)
    return c
示例#8
0
def pini2(d, mat_gen, tmp_sums, strong_bij=False):
    d2 = d - 1
    c = circuit_model.Circuit()
    sx, sy, sz, x, y, z = mul_preamble(d, c, strong_bij)

    if tmp_sums:
        var_sums = (sx, sy)
    else:
        var_sums = None
    ref_prods = mat_gen(c, x, y, var_sums=var_sums)

    # product matrix
    s1 = [c.var(f's1_{i}', kind='random') for i in range(d)]
    s = [{j: c.var(f's_{i}_{j}') for j in range(i + 1, d)} for i in range(d)]
    u = [{
        j: [c.var(f's_{i}_{j}_{k}') for k in range(2)]
        for j in range(i + 1, d)
    } for i in range(d)]
    p = [{
        j: [c.var(f's_{i}_{j}_{k}') for k in range(4)]
        for j in range(i + 1, d)
    } for i in range(d)]
    for i in range(d):
        for j in range(i + 1, d):
            c.l_sum(s[i][j], (s1[i], s1[j]))
            xi, yj = ref_prods[i][j]
            xj, yi = ref_prods[j][i]
            c.l_sum(u[i][j][0], (yj, s[i][j]))
            c.l_sum(u[i][j][1], (xj, s[i][j]))
            c.l_prod(p[i][j][0], (xi, s[i][j]))
            c.l_prod(p[i][j][1], (xi, u[i][j][0]))
            c.l_prod(p[i][j][2], (yi, s[i][j]))
            c.l_prod(p[i][j][3], (yi, u[i][j][1]))

    # randoms & temps in matrix & compression
    r = [{
        d2 - j: c.var(f'r_{i}_{j}', kind='random')
        for j in range(0, d2 - i, 2)
    } for i in range(d)]
    r2 = {j: c.var(f'r2_{j}', kind='random') for j in range(d2 - 1, 0, -2)}
    t = [{
        j: [c.var(f't_{i}_{j}_{k}') for k in range(9)]
        for j in range(d2, i + 1, -2)
    } for i in range(d)]
    c_var = [{j: c.var(f'c_{i}_{j}')
              for j in range(d2 + 2, i + 1, -2)} for i in range(d)]
    for i in range(d):
        pi = c.var(f'p_{i}_{i}')
        c.l_prod(pi, ref_prods[i][i])
        c.assign(c_var[i][d2 + 2], pi)
        for j in range(d2, i + 1, -2):
            c.l_sum(t[i][j][0], (r[i][j], p[i][j][0]))
            c.l_sum(t[i][j][1], (t[i][j][0], p[i][j][1]))
            c.l_sum(t[i][j][2], (t[i][j][1], p[i][j][2]))
            c.l_sum(t[i][j][3], (t[i][j][2], p[i][j][3]))
            c.l_sum(t[i][j][4], (t[i][j][3], r2[j - 1]))
            c.l_sum(t[i][j][5], (t[i][j][4], p[i][j - 1][0]))
            c.l_sum(t[i][j][6], (t[i][j][5], p[i][j - 1][1]))
            c.l_sum(t[i][j][7], (t[i][j][6], p[i][j - 1][2]))
            c.l_sum(t[i][j][8], (t[i][j][7], p[i][j - 1][3]))
            c.l_sum(c_var[i][j], (c_var[i][j + 2], t[i][j][8]))
        if (i - d2) % 2 != 0:
            t[i][i + 1] = [c.var(f't_{i}_{i+1}_{k}') for k in range(4)]
            c_var[i][i + 1] = c.var(f'c_{i}_{i+1}')
            c.l_sum(t[i][i + 1][0], (r[i][i + 1], p[i][i + 1][0]))
            c.l_sum(t[i][i + 1][1], (t[i][i + 1][0], p[i][i + 1][1]))
            c.l_sum(t[i][i + 1][2], (t[i][i + 1][1], p[i][i + 1][2]))
            c.l_sum(t[i][i + 1][3], (t[i][i + 1][2], p[i][i + 1][3]))
            c.l_sum(c_var[i][i + 1], (c_var[i][i + 3], t[i][i + 1][3]))
            if i % 2 == 1:
                c.l_sum(z[i], (c_var[i][i + 1], r2[i]))
            else:
                c.assign(z[i], c_var[i][i + 1])
        else:
            for j in range(i - 1, -1, -1):
                c_var[i][j + 2] = c.var(f'c_{i}_{j+2}')
                c.l_sum(c_var[i][j + 2], (c_var[i][j + 3], r[j][i]))
            c.assign(z[i], c_var[i][2])

    return c
示例#9
0
def test_refresh(d, ref=simple_ref):
    circuit = circuit_model.Circuit()
    var_inputs = [circuit.var(f'x_{i}', kind='input') for i in range(d)]
    var_outputs = [circuit.var(f'y_{i}', kind='output') for i in range(d)]
    ref(circuit=circuit, inputs=var_inputs, outputs=var_outputs)
    g = circuit_model.CompGraph(circuit)
    x = gen_random_input(d)
    inputs = {f'x_{i}': v for i, v in enumerate(x)}
    res, _ = g.compute(inputs)
    y = [
        v for var, v in res.items() if circuit.vars[var].name.startswith('y_')
    ]
    assert (sum(x) % 2) == (sum(y) % 2)


if __name__ == '__main__':
    import sys
    try:
        d = int(sys.argv[1])
    except IndexError:
        d = 3
    for ref_name, ref_f in refs.items():
        #for ref_name, ref_f in ():
        print(f'---- {ref_name}, d={d} ----')
        circuit = circuit_model.Circuit()
        var_inputs = [circuit.var(f'x_{i}', kind='input') for i in range(d)]
        ref_f(circuit, var_inputs, out_name='y')
        print(circuit)
        for _ in range(100):
            test_refresh(d, ref_f)