コード例 #1
0
def Norm(b, k, f, kappa, simplex_flag=False):
    """
        Computes secret integer values [c] and [v_prime] st.
        2^{k-1} <= c < 2^k and c = b*v_prime
    """
    # For simplex, we can get rid of computing abs(b)
    temp = None
    if simplex_flag == False:
        temp = types.sint(b < 0)
    elif simplex_flag == True:
        temp = types.cint(0)

    sign = 1 - 2 * temp  # 1 - 2 * [b < 0]
    absolute_val = sign * b

    #next 2 lines actually compute the SufOR for little indian encoding
    bits = absolute_val.bit_decompose(k)[::-1]
    suffixes = AdvInteger.PreOR(bits)[::-1]

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

    #doing complicated stuff to compute v = 2^{k-m}
    acc = types.cint(0)
    for i in range(k):
        acc += AdvInteger.two_power(k - i - 1) * z[i]

    part_reciprocal = absolute_val * acc
    signed_acc = sign * acc

    return part_reciprocal, signed_acc
コード例 #2
0
def Int2FL(a, gamma, l, kappa):
    lam = gamma - 1
    s = types.sint()
    AdvInteger.LTZ(s, a, gamma, kappa)
    z = AdvInteger.EQZ(a, gamma, kappa)
    a = (1 - 2 * s) * a

    a_bits = AdvInteger.BitDec(a, lam, lam, kappa)
    a_bits.reverse()
    b = AdvInteger.PreOR(a_bits)
    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()
            AdvInteger.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
コード例 #3
0
def SDiv_ABZS12(a, b, l, kappa):
    theta = int(ceil(log(l, 2)))
    x = b
    y = a
    for i in range(theta - 1):
        y = y * ((2**(l + 1)) - x)
        y = AdvInteger.TruncPr(y, 2 * l + 1, l, kappa)
        x = x * ((2**(l + 1)) - x)
        x = AdvInteger.TruncPr(x, 2 * l + 1, l, kappa)
    y = y * ((2**(l + 1)) - x)
    y = AdvInteger.TruncPr(y, 2 * l + 1, l, kappa)
    return y
コード例 #4
0
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()
    AdvInteger.LTZ(a, p1, k, x.kappa)
    b = p1.less_than(-l + 1, k, x.kappa)
    v2, inv_2pow_p1 = AdvInteger.Oblivious_Trunc(v1, l, -a * (1 - b) * x.p,
                                                 x.kappa, True)
    c = AdvInteger.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(AdvInteger.two_power(l), l + 1, x.kappa)
    v = d * AdvInteger.two_power(l - 1) + (1 - d) * v
    v = a * ((1 - b) * v +
             b * away_from_zero * AdvInteger.two_power(l - 1)) + (1 - a) * v1
    s = (1 - b * mode) * s1
    z = AdvInteger.or_op(AdvInteger.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
コード例 #5
0
def cint_cint_division(a, b, k, f):
    """
        Goldschmidt method implemented with
        SE aproximation:
        http://stackoverflow.com/questions/2661541/picking-good-first-estimates-for-goldschmidt-division
    """
    from types import cint, Array
    from library import for_range
    # theta can be replaced with something smaller
    # for safety we assume that is the same theta from previous GS method

    theta = int(ceil(log(k / 3.5) / log(2)))
    two = cint(2) * AdvInteger.two_power(f)

    sign_b = cint(1) - 2 * cint(b < 0)
    sign_a = cint(1) - 2 * cint(a < 0)
    absolute_b = b * sign_b
    absolute_a = a * sign_a
    w0 = approximate_reciprocal(absolute_b, k, f, theta)

    A = Array(theta, cint)
    B = Array(theta, cint)
    W = Array(theta, cint)

    A[0] = absolute_a
    B[0] = absolute_b
    W[0] = w0

    @for_range(1, theta)
    def block(i):
        A[i] = (A[i - 1] * W[i - 1]) >> f
        B[i] = (B[i - 1] * W[i - 1]) >> f
        W[i] = two - B[i]

    return (sign_a * sign_b) * A[theta - 1]
コード例 #6
0
ファイル: mpc_math.py プロジェクト: wqruan/SCALE-MAMBA
def lin_app_SQ(b, k, f):
    alpha = types.cfix((-0.8099868542) * 2**(k))
    beta = types.cfix(1.787727479 * 2**(2 * k))

    # obtain normSQ parameters
    c, v, m, W = FixedPt.norm_SQ(types.sint(b), k)

    # c is now escalated
    w = alpha * load_sint(
        c, types.sfix) + beta  # equation before b and reduction by order of k

    # m even or odd determination
    m_bit = types.sint()
    AdvInteger.Mod2(m_bit, m, int(math.ceil(math.log(k, 2))), w.kappa, False)
    m = load_sint(m_bit, types.sfix)

    # w times v  this way both terms have 2^3k and can be symplified
    w = w * v
    factor = 1.0 / (2**(3.0 * k - 2 * f))
    w = w * factor  # w escalated to 3k -2 * f
    # normalization factor W* 1/2 ^{f/2}
    w = w * W * types.cfix(1.0 / (2**(f / 2.0)))
    # now we need to  elminate an additional root of 2 in case m was odd
    sqr_2 = types.cfix((2**(1 / 2.0)))
    w = (1 - m) * w + sqr_2 * w * m

    return w
コード例 #7
0
def sint_cint_division(a, b, k, f, kappa):
    """
        type(a) = sint, type(b) = cint
    """
    from types import cint, sint, Array
    from library import for_range

    theta = int(ceil(log(k / 3.5) / log(2)))
    two = cint(2) * AdvInteger.two_power(f)
    sign_b = cint(1) - 2 * cint(b < 0)
    sign_a = sint(1) - 2 * sint(a < 0)
    absolute_b = b * sign_b
    absolute_a = a * sign_a
    w0 = approximate_reciprocal(absolute_b, k, f, theta)

    A = Array(theta, sint)
    B = Array(theta, cint)
    W = Array(theta, cint)

    A[0] = absolute_a
    B[0] = absolute_b
    W[0] = w0

    @for_range(1, theta)
    def block(i):
        A[i] = AdvInteger.TruncPr(A[i - 1] * W[i - 1], 2 * k, f, kappa)
        temp = (B[i - 1] * W[i - 1]) >> f
        # no reading and writing to the same variable in a for loop.
        W[i] = two - temp
        B[i] = temp

    return (sign_a * sign_b) * A[theta - 1]
コード例 #8
0
ファイル: mpc_math.py プロジェクト: wqruan/SCALE-MAMBA
def trunc(x):
    if type(x) is types.sfix:
        return AdvInteger.Oblivious_Trunc(x.v, x.k, x.f, x.kappa)
    elif type(x) is types.sfloat:
        v, p, z, s = floatingpoint.FLRound(x, 0)
        return types.sfloat(v, p, z, s, x.err)
    return x
コード例 #9
0
def MSB(b, k):
    # calculation of z
    # x in order 0 - k
    if (k > types.program.bit_length):
        raise OverflowError("The supported bit \
        lenght of the application is smaller than k")

    x_order = b.bit_decompose(k)
    x = [0] * k
    # x i now inverted
    for i in range(k - 1, -1, -1):
        x[k - 1 - i] = x_order[i]
    # y is inverted for PReOR and then restored
    y_order = AdvInteger.PreOR(x)

    # y in order (restored in orginal order
    y = [0] * k
    for i in range(k - 1, -1, -1):
        y[k - 1 - i] = y_order[i]

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

    return z
コード例 #10
0
def approximate_reciprocal(divisor, k, f, theta):
    """
        returns aproximation of 1/divisor
        where type(divisor) = cint
    """
    from types import cint, Array, MemValue, regint
    from library import for_range, if_

    def twos_complement(x):
        bits = x.bit_decompose(k)[::-1]
        bit_array = Array(k, cint)
        bit_array.assign(bits)

        twos_result = MemValue(cint(0))

        @for_range(k)
        def block(i):
            val = twos_result.read()
            val <<= 1
            val += 1 - bit_array[i]
            twos_result.write(val)

        return twos_result.read() + 1

    bit_array = Array(k, cint)
    bits = divisor.bit_decompose(k)[::-1]
    bit_array.assign(bits)

    cnt_leading_zeros = MemValue(regint(0))

    flag = MemValue(regint(0))
    cnt_leading_zeros = MemValue(regint(0))
    normalized_divisor = MemValue(divisor)

    @for_range(k)
    def block(i):
        flag.write(flag.read() | bit_array[i] == 1)

        @if_(flag.read() == 0)
        def block():
            cnt_leading_zeros.write(cnt_leading_zeros.read() + 1)
            normalized_divisor.write(normalized_divisor << 1)

    q = MemValue(AdvInteger.two_power(k))
    e = MemValue(twos_complement(normalized_divisor.read()))

    @for_range(theta)
    def block(i):
        qread = q.read()
        eread = e.read()
        qread += (qread * eread) >> k
        eread = (eread * eread) >> k

        q.write(qread)
        e.write(eread)

    res = q >> cint(2 * k - 2 * f - cnt_leading_zeros)

    return res
コード例 #11
0
def SDiv_mono(a, b, l, kappa):
    theta = int(ceil(log(l / 3.5) / log(2)))
    alpha = two_power(2 * l)
    w = types.cint(int(2.9142 * two_power(l))) - 2 * b
    x = alpha - b * w
    y = a * w
    y = AdvInteger.TruncPr(y, 2 * l + 1, l + 1, kappa)
    for i in range(theta - 1):
        y = y * (alpha + x)
        # keep y with l bits
        y = AdvInteger.TruncPr(y, 3 * l, 2 * l, kappa)
        x = x**2
        # keep x with 2l bits
        x = AdvInteger.TruncPr(x, 4 * l, 2 * l, kappa)
    y = y * (alpha + x)
    y = AdvInteger.TruncPr(y, 3 * l, 2 * l, kappa)
    return y
コード例 #12
0
ファイル: FixedPt.py プロジェクト: weizheng92/SCALE-MAMBA
def Div(a, b, k, f, kappa, simplex_flag=False):
    theta = int(ceil(log(k / 3.5) / log(2)))
    alpha = AdvInteger.two_power(2 * f)
    w = AppRcr(b, k, f, kappa, simplex_flag)
    x = alpha - b * w

    y = a * w
    y = AdvInteger.TruncPr(y, 2 * k, f, kappa)

    for i in range(theta):
        y = y * (alpha + x)
        x = x * x
        y = AdvInteger.TruncPr(y, 2 * k, 2 * f, kappa)
        x = AdvInteger.TruncPr(x, 2 * k, 2 * f, kappa)

    y = y * (alpha + x)
    y = AdvInteger.TruncPr(y, 2 * k, 2 * f, kappa)
    return y
コード例 #13
0
def AppRcr(b, k, f, kappa, simplex_flag=False):
    """
        Approximate reciprocal of [b]:
        Given [b], compute [1/b]
    """
    alpha = types.cint(int(2.9142 * 2**k))
    c, v = Norm(b, k, f, kappa, simplex_flag)
    #v should be 2**{k - m} where m is the length of the bitwise repr of [b]
    d = alpha - 2 * c
    w = d * v
    w = AdvInteger.TruncPr(w, 2 * k, 2 * (k - f))
    # now w * 2 ^ {-f} should be an initial approximation of 1/b
    return w
コード例 #14
0
def FLLT(fl_a, fl_b):
    t = fl_a.err
    if isinstance(fl_b, types.sfloat):
        t = t + fl_b.err
    t = t == 0
    z1 = fl_a.z
    z2 = fl_b.z
    s1 = fl_a.s
    s2 = fl_b.s
    a = fl_a.p.less_than(fl_b.p, fl_a.plen, fl_a.kappa)
    c = AdvInteger.EQZ(fl_a.p - fl_b.p, fl_a.plen, fl_a.kappa)
    d = ((1 - 2 * fl_a.s) * fl_a.v).less_than((1 - 2 * fl_b.s) * fl_b.v,
                                              fl_a.vlen + 1, fl_a.kappa)
    cd = c * d
    ca = c * a
    b1 = cd + a - ca
    b2 = cd + 1 + ca - c - a
    s12 = fl_a.s * fl_b.s
    z12 = fl_a.z * fl_b.z
    b = (z1 - z12) * (1 - s2) + (z2 - z12) * s1 + (1 + z12 - z1 - z2) * \
        (s1 - s12 + (1 + s12 - s1 - s2) * b1 + s12 * b2) * t
    return b
コード例 #15
0
def SDiv(a, b, l, kappa):
    theta = int(ceil(log(l / 3.5) / log(2)))
    alpha = AdvInteger.two_power(2 * l)
    beta = 1 / types.cint(AdvInteger.two_power(l))
    w = types.cint(int(2.9142 * AdvInteger.two_power(l))) - 2 * b
    x = alpha - b * w
    y = a * w
    y = AdvInteger.TruncPr(y, 2 * l, l, kappa)
    x2 = types.sint()
    AdvInteger.Mod2m(x2, x, 2 * l + 1, l, kappa, False)
    x1 = (x - x2) * beta
    for i in range(theta - 1):
        y = y * (x1 + two_power(l)) + AdvInteger.TruncPr(
            y * x2, 2 * l, l, kappa)
        y = AdvInteger.TruncPr(y, 2 * l + 1, l + 1, kappa)
        x = x1 * x2 + AdvInteger.TruncPr(x2**2, 2 * l + 1, l + 1, kappa)
        x = x1 * x1 + AdvInteger.TruncPr(x, 2 * l + 1, l - 1, kappa)
        x2 = types.sint()
        AdvInteger.Mod2m(x2, x, 2 * l, l, kappa, False)
        x1 = (x - x2) * beta
    y = y * (x1 + two_power(l)) + AdvInteger.TruncPr(y * x2, 2 * l, l, kappa)
    y = AdvInteger.TruncPr(y, 2 * l + 1, l - 1, kappa)
    return y
コード例 #16
0
def floor_fx(x):
    return load_sint(AdvInteger.Trunc(x.v, x.k - x.f, x.f, x.kappa), type(x))
コード例 #17
0
 def block(i):
     A[i] = AdvInteger.TruncPr(A[i - 1] * W[i - 1], 2 * k, f, kappa)
     temp = (B[i - 1] * W[i - 1]) >> f
     # no reading and writing to the same variable in a for loop.
     W[i] = two - temp
     B[i] = temp
コード例 #18
0
def TruncRoundNearestAdjustOverflow(a, length, target_length, kappa):
    t = AdvInteger.TruncRoundNearest(a, length, length - target_length, kappa)
    overflow = t.greater_equal(AdvInteger.two_power(target_length),
                               target_length + 1, kappa)
    s = (1 - overflow) * t + overflow * t / 2
    return s, overflow