예제 #1
0
def Norm(b, k, f, kappa):
    """
        Computes secret integer values [c] and [v_prime] st.
        2^{k-1} <= c < 2^k and c = b*v_prime
    """
    temp = types.sint()
    comparison.LTZ(temp, b, k, kappa)
    sign = 1 - 2 * temp  # 1 - 2 * [b < 0]

    x = sign * b
    #x = |b|
    bits = x.bit_decompose(k)
    y = PreOR(bits)

    z = [0] * k
    for i in range(k - 1):
        z[i] = y[i] - y[i + 1]

    z[k - 1] = y[k - 1]
    # z[i] = 0 for all i except when bits[i + 1] = first one

    #now reverse bits of z[i]
    v = types.sint()
    for i in range(k):
        v += two_power(k - i - 1) * z[i]
    c = x * v
    v_prime = sign * v
    return c, v_prime
예제 #2
0
def Int2FL(a, gamma, l, kappa):
    lam = gamma - 1
    s = types.sint()
    comparison.LTZ(s, a, gamma, kappa)
    z = EQZ(a, gamma, kappa)
    a = (1 - 2 * s) * a

    a_bits = BitDec(a, lam, lam, kappa)
    a_bits.reverse()
    b = PreOR(a_bits, kappa)
    t = a * (1 + sum(2**i * (1 - b_i) for i, b_i in enumerate(b)))
    p = -(lam - sum(b))
    if lam > l:
        if types.sfloat.round_nearest:
            v, overflow = TruncRoundNearestAdjustOverflow(
                t, gamma - 1, l, kappa)
            p = p + overflow
        else:
            v = types.sint()
            comparison.Trunc(v, t, gamma - 1, gamma - l - 1, kappa, False)
            #TODO: Shouldnt this be only gamma
    else:
        v = 2**(l - gamma + 1) * t
    p = (p + gamma - 1 - l) * (1 - z)
    return v, p, z, s
def FLRound(x, mode):
    """ Rounding with floating point output.
    *mode*: 0 -> floor, 1 -> ceil, -1 > trunc """
    v1, p1, z1, s1, l, k = x.v, x.p, x.z, x.s, x.vlen, x.plen
    a = types.sint()
    comparison.LTZ(a, p1, k, x.kappa)
    b = p1.less_than(-l + 1, k, x.kappa)
    v2, inv_2pow_p1 = Trunc(v1, l, -a * (1 - b) * x.p, x.kappa, True)
    c = EQZ(v2, l, x.kappa)
    if mode == -1:
        away_from_zero = 0
        mode = x.s
    else:
        away_from_zero = mode + s1 - 2 * mode * s1
    v = v1 - v2 + (1 - c) * inv_2pow_p1 * away_from_zero
    d = v.equal(two_power(l), l + 1, x.kappa)
    v = d * two_power(l-1) + (1 - d) * v
    v = a * ((1 - b) * v + b * away_from_zero * two_power(l-1)) + (1 - a) * v1
    s = (1 - b * mode) * s1
    z = or_op(EQZ(v, l, x.kappa), z1)
    v = v * (1 - z)
    p = ((p1 + d * a) * (1 - b) + b * away_from_zero * (1 - l)) * (1 - z)
    return v, p, z, s