def norm_simplified_SQ(b, k): z = MSB(b, k) # construct m m = types.sint(0) m_odd = 0 for i in range(k): m = m + (i + 1) * z[i] # determine the parity of the input if (i % 2 == 0): m_odd = m_odd + z[i] # construct w, k_over_2 = k / 2 + 1 w_array = [0] * (k_over_2) w_array[0] = z[0] for i in range(1, k_over_2): w_array[i] = z[2 * i - 1] + z[2 * i] # w aggregation w = types.sint(0) for i in range(k_over_2): w += (2**i) * w_array[i] # return computed values return m_odd, m, w
def norm_SQ(b, k): # calculation of z # x in order 0 - k z = MSB(b,k) # now reverse bits of z[i] to generate v v = types.sint(0) for i in range(k): v += (2**(k - i - 1)) * z[i] c = b * v # construct m m = types.sint(0) for i in range(k): m = m + (i+1) * z[i] # construct w, changes from what is on the paper # and the documentation k_over_2= k/2+1#int(math.ceil((k/2.0)))+1 w_array = [0]*(k_over_2 ) w_array[0] = z[0] for i in range(1, k_over_2): w_array[i] = z[2 * i - 1] + z[2 * i] w = types.sint(0) for i in range(k_over_2): w += (2 ** i) * w_array[i] # return computed values return c, v, m, w
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
def sint_cint_division(a, b, k, f, kappa): """ type(a) = sint, type(b) = cint """ theta = int(ceil(log(k/3.5) / log(2))) two = cint(2) * 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] = 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]
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 = 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() comparison.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
def sint_cint_division(a, b, k, f, kappa): """ type(a) = sint, type(b) = cint """ theta = int(ceil(log(k/3.5) / log(2))) two = cint(2) * 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] = TruncPr(A[i - 1] * W[i - 1], 2*k, f, kappa) temp = shift_two(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]
def TruncRoundNearest(a, k, m, kappa): """ Returns a / 2^m, rounded to the nearest integer. k: bit length of m m: compile-time integer """ from types import sint, cint from library import reveal, load_int_to_secret if m == 1: lsb = sint() Mod2(lsb, a, k, kappa, False) return (a + lsb) / 2 r_dprime = sint() r_prime = sint() r = [sint() for i in range(m)] u = sint() PRandM(r_dprime, r_prime, r, k, m, kappa) c = reveal((cint(1) << (k - 1)) + a + (cint(1) << m) * r_dprime + r_prime) c_prime = c % (cint(1) << (m - 1)) BitLT(u, c_prime, r[:-1], kappa) bit = ((c - c_prime) / (cint(1) << (m - 1))) % 2 xor = bit + u - 2 * bit * u prod = xor * r[-1] # u_prime = xor * u + (1 - xor) * r[-1] u_prime = bit * u + u - 2 * bit * u + r[-1] - prod a_prime = (c % (cint(1) << m)) - r_prime + (cint(1) << m) * u_prime d = (a - a_prime) / (cint(1) << m) rounding = xor + r[-1] - 2 * prod return d + rounding
def BitDecFullBig(a): from Compiler.types import sint, regint from Compiler.library import do_while p=program.P bit_length = p.bit_length() abits = [sint(0)]*bit_length bbits = [sint(0)]*bit_length pbits = list(bits(p,bit_length+1)) # Loop until we get some random integers less than p @do_while def get_bits_loop(): # How can we do this with a vectorized load of the bits? XXXX tbits = [sint(0)]*bit_length for i in range(bit_length): tbits[i] = sint.get_random_bit() tbits[i].store_in_mem(i) c = regint(BitLTFull(tbits, pbits, bit_length).reveal()) return (c!=1) for i in range(bit_length): bbits[i]=sint.load_mem(i) b = SumBits(bbits, bit_length) c = (a-b).reveal() czero = (c==0) d = BitAdd(list(bits(c,bit_length)), bbits) q = BitLTFull( pbits, d, bit_length+1) f = list(bits((1<<bit_length)-p,bit_length)) g = [sint(0)]*(bit_length+1) for i in range(bit_length): g[i]=f[i]*q; h = BitAdd(d, g) for i in range(bit_length): abits[i] = (1-czero)*h[i]+czero*bbits[i] return abits
def test_expand_idx(): actual = expand_idx(7, sint(4)) runtime_assert_arr_equals([1, 1, 1, 1, 1, 0, 0], actual, default_test_name()) actual = expand_idx(7, sint(0)) runtime_assert_arr_equals([1, 0, 0, 0, 0, 0, 0], actual, default_test_name())
def norm_SQ(b, k): # calculation of z # x in order 0 - k x_order = b.bit_decompose() 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 = floatingpoint.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 for i in range(k - 1): z[i] = y[i] - y[i + 1] z[k - 1] = y[k - 1] # now reverse bits of z[i] to generate v v = types.sint() for i in range(k): v += (2**(k - i - 1)) * z[i] c = b * v # construct m m = types.sint() for i in range(k): m = m + (i + 1) * z[i] # construct w, changes from what is on the paper # and the documentation k_over_2 = k / 2 + 1 #int(math.ceil((k/2.0)))+1 w_array = [0] * (k_over_2) for i in range(1, k_over_2): w_array[i] = z[2 * i - 1 - (1 - k % 2)] + z[2 * i - (1 - k % 2)] w_array[0] = types.sfix(0) w = types.sint() for i in range(k_over_2): w += (2**i) * w_array[i] # return computed values return c, v, m, w
def BitLTFull(a, b, bit_length): from Compiler.types import sint e = [sint(0)]*bit_length g = [sint(0)]*bit_length h = [sint(0)]*bit_length for i in range(bit_length): e[bit_length-i-1]=a[i]+b[i]-2*a[i]*b[i] # Compute the XOR (reverse order of e for PreOpL) f = PreOR(e) g[bit_length-1] = f[0] for i in range(bit_length-1): g[i] = f[bit_length-i-1]-f[bit_length-i-2] # reverse order of f due to PreOpL ans = sint(0) for i in range(bit_length): h[i] = g[i]*b[i] ans = ans + h[i] return ans
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
def Mod2mField(a_prime, a, k, m, kappa, signed): from .types import sint r_dprime = program.curr_block.new_reg('s') r_prime = program.curr_block.new_reg('s') r = [sint() for i in range(m)] c = program.curr_block.new_reg('c') c_prime = program.curr_block.new_reg('c') v = program.curr_block.new_reg('s') u = program.curr_block.new_reg('s') t = [program.curr_block.new_reg('s') for i in range(6)] c2m = program.curr_block.new_reg('c') c2k1 = program.curr_block.new_reg('c') PRandM(r_dprime, r_prime, r, k, m, kappa) ld2i(c2m, m) mulm(t[0], r_dprime, c2m) if signed: ld2i(c2k1, k - 1) addm(t[1], a, c2k1) else: t[1] = a adds(t[2], t[0], t[1]) adds(t[3], t[2], r_prime) asm_open(c, t[3]) modc(c_prime, c, c2m) if const_rounds: BitLTC1(u, c_prime, r, kappa) else: BitLTL(u, c_prime, r, kappa) mulm(t[4], u, c2m) submr(t[5], c_prime, r_prime) adds(a_prime, t[5], t[4]) return r_dprime, r_prime, c, c_prime, u, t, c2k1
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 = sint(b < 0) elif simplex_flag == True: temp = 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 = 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 = cint(0) for i in range(k): acc += two_power(k-i-1) * z[i] part_reciprocal = absolute_val * acc signed_acc = sign * acc return part_reciprocal, signed_acc
def LTZ(s, a, k, kappa): """ s = (a ?< 0) k: bit length of a """ from .types import sint, _bitint from .GC.types import sbitvec if program.use_split(): summands = a.split_to_two_summands(k) carry = CarryOutRawLE(*reversed(list(x[:-1] for x in summands))) msb = carry ^ summands[0][-1] ^ summands[1][-1] movs(s, sint.conv(msb)) return elif program.options.ring: from . import floatingpoint require_ring_size(k, 'comparison') m = k - 1 shift = int(program.options.ring) - k r_prime, r_bin = MaskingBitsInRing(k) tmp = a - r_prime c_prime = (tmp << shift).reveal() >> shift a = r_bin[0].bit_decompose_clear(c_prime, m) b = r_bin[:m] u = CarryOutRaw(a[::-1], b[::-1]) movs(s, sint.conv(r_bin[m].bit_xor(c_prime >> m).bit_xor(u))) return t = sint() Trunc(t, a, k, k - 1, kappa, True) subsfi(s, t, 0)
def LTZ(s, a, k, kappa): """ s = (a ?< 0) k: bit length of a """ from .types import sint, _bitint from .GC.types import sbitvec if program.use_split(): movs(s, sint.conv(sbitvec(a, k).v[-1])) return elif program.options.ring: from . import floatingpoint assert (int(program.options.ring) >= k) m = k - 1 shift = int(program.options.ring) - k r_prime, r_bin = MaskingBitsInRing(k) tmp = a - r_prime c_prime = (tmp << shift).reveal() >> shift a = r_bin[0].bit_decompose_clear(c_prime, m) b = r_bin[:m] u = CarryOutRaw(a[::-1], b[::-1]) movs(s, sint.conv(r_bin[m].bit_xor(c_prime >> m).bit_xor(u))) return t = sint() Trunc(t, a, k, k - 1, kappa, True) subsfi(s, t, 0)
def TruncLeakyInRing(a, k, m, signed): """ Returns a >> m. Requires a < 2^k and leaks a % 2^m (needs to be constant or random). """ if k == m: return 0 assert k > m assert int(program.options.ring) >= k from .types import sint, intbitint, cint, cgf2n n_bits = k - m n_shift = int(program.options.ring) - n_bits if n_bits > 1: r, r_bits = MaskingBitsInRing(n_bits, True) else: r_bits = [sint.get_random_bit() for i in range(n_bits)] r = sint.bit_compose(r_bits) if signed: a += (1 << (k - 1)) shifted = ((a << (n_shift - m)) + (r << n_shift)).reveal() masked = shifted >> n_shift u = sint() BitLTL(u, masked, r_bits[:n_bits], 0) res = (u << n_bits) + masked - r if signed: res -= (1 << (n_bits - 1)) return res
def get_bits_loop(): # How can we do this with a vectorized load of the bits? XXXX tbits = [sint(0)]*bit_length for i in range(bit_length): tbits[i] = sint.get_random_bit() tbits[i].store_in_mem(i) c = regint(BitLTFull(tbits, pbits, bit_length).reveal()) return (c!=1)
def test_while(): num_vals = 5 counter = MemValue(sint(num_vals - 1)) source_arr = Array(num_vals, sint) for i in range(num_vals): source_arr[i] = sint(i) target_arr = Array(num_vals, sint) @do_while def body(): counter_val = counter.read() counter_val_open = counter_val.reveal() target_arr[counter_val_open] = source_arr[counter_val_open] + 1 counter.write(counter_val - 1) opened = counter.reveal() return opened >= 0 runtime_assert_arr_equals([1, 2, 3, 4, 5], target_arr, default_test_name())
def LTZ(s, a, k, kappa): """ s = (a ?< 0) k: bit length of a """ from .types import sint t = sint() Trunc(t, a, k, k - 1, kappa, True) subsfi(s, t, 0)
def KMulC(a): """ Return just the product of all items in a """ from .types import sint, cint p = sint() if use_inv: PreMulC_with_inverses(p, a) else: PreMulC_without_inverses(p, a) return p
def wrapper(*args, **kwargs): if isinstance(args[0], sfix): assert len(args) == 1 assert not kwargs assert args[0].size == args[0].v.size k = args[0].k f = args[0].f res = sfix._new(sint(size=args[0].size), k=k, f=f) instruction(res.v, args[0].v, k, f) return res else: return function(*args, **kwargs)
def BitDecFull(a): from Compiler.types import sint, regint from Compiler.library import do_while p = program.P bit_length = p.bit_length() if bit_length > 63: return BitDecFullBig(a) abits = [sint(0)] * bit_length bbits = [sint(0)] * bit_length pbits = list(bits(p, bit_length)) # Loop until we get some random integers less than p @do_while def get_bits_loop(): # How can we do this with a vectorized load of the bits? XXXX tbits = [sint(0)] * bit_length for i in range(bit_length): tbits[i] = sint.get_random_bit() tbits[i].store_in_mem(i) c = regint(BitLTFull(tbits, pbits, bit_length).reveal()) return (c != 1) for i in range(bit_length): bbits[i] = sint.load_mem(i) b = SumBits(bbits, bit_length) # Reveal c in the correct range c = regint((a - b).reveal()) bit = c < 0 c = c + p * bit czero = (c == 0) t = (p - c).bit_decompose(bit_length) q = 1 - BitLTFull(bbits, t, bit_length) fbar = ((1 << bit_length) + c - p).bit_decompose(bit_length) fbard = regint(c).bit_decompose(bit_length) g = [sint(0)] * (bit_length) for i in range(bit_length): g[i] = (fbar[i] - fbard[i]) * q + fbard[i] h = BitAdd(bbits, g) for i in range(bit_length): abits[i] = (1 - czero) * h[i] + czero * bbits[i] return abits
def Mod2mRing(a_prime, a, k, m, signed): assert (int(program.options.ring) >= k) from Compiler.types import sint, intbitint, cint shift = int(program.options.ring) - m r_prime, r_bin = MaskingBitsInRing(m, True) tmp = a + r_prime c_prime = (tmp << shift).reveal() >> shift u = sint() BitLTL(u, c_prime, r_bin[:m], 0) res = (u << m) + c_prime - r_prime if a_prime is not None: movs(a_prime, res) return res
def wrapper(*args, **kwargs): if isinstance(args[0], sfix): for arg in args[1:]: assert util.is_constant(arg) assert not kwargs assert args[0].size == args[0].v.size k = args[0].k f = args[0].f res = sfix._new(sint(size=args[0].size), k=k, f=f) instruction(res.v, args[0].v, k, f, *args[1:]) return res else: return function(*args, **kwargs)
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
def Mod2mRing(a_prime, a, k, m, signed): assert (int(program.options.ring) >= k) from Compiler.types import sint, intbitint, cint shift = int(program.options.ring) - m r = [sint.get_random_bit() for i in range(m)] r_prime = sint.bit_compose(r) tmp = a + r_prime c_prime = (tmp << shift).reveal() >> shift u = sint() BitLTL(u, c_prime, r, 0) res = (u << m) + c_prime - r_prime if a_prime is not None: movs(a_prime, res) return res
def test_partition_on(): sec_mat = input_matrix([[1, 2, 3, 1, 1], [4, 5, 6, 1, 1], [7, 8, 9, 1, 1], [10, 11, 12, 1, 1]]) left, right = partition_on(Samples.from_rows(sec_mat, 3, 0), attr_idx=sint(1), threshold=5, is_leaf=sint(0)) runtime_assert_mat_equals([[1, 2, 3, 1, 1], [4, 5, 6, 1, 1], [7, 8, 9, 1, 0], [10, 11, 12, 1, 0]], transpose(left.columns), default_test_name()) runtime_assert_mat_equals([[1, 2, 3, 1, 0], [4, 5, 6, 1, 0], [7, 8, 9, 1, 1], [10, 11, 12, 1, 1]], transpose(right.columns), default_test_name()) sec_mat = input_matrix([[1, 2, 3, 1, 0], [4, 5, 6, 1, 1], [7, 8, 9, 1, 0], [10, 11, 12, 1, 1]]) left, right = partition_on(Samples.from_rows(sec_mat, 3, 0), attr_idx=sint(1), threshold=5, is_leaf=0) runtime_assert_arr_equals([0, 1, 0, 0], left.get_active_col(), default_test_name()) runtime_assert_arr_equals([0, 0, 0, 1], right.get_active_col(), default_test_name()) sec_mat = input_matrix([[1, 2, 3, 1, 0], [4, 5, 6, 1, 1], [7, 8, 9, 1, 0], [10, 11, 12, 1, 1]]) left, right = partition_on(Samples.from_rows(sec_mat, 3, 0), attr_idx=sint(1), threshold=5, is_leaf=sint(1)) runtime_assert_arr_equals([0, 0, 0, 0], left.get_active_col(), default_test_name()) runtime_assert_arr_equals([0, 0, 0, 0], right.get_active_col(), default_test_name())
def TruncRoundNearest(a, k, m, kappa, signed=False): """ Returns a / 2^m, rounded to the nearest integer. k: bit length of a m: compile-time integer """ if m == 0: return a if k == int(program.options.ring): # cannot work with bit length k+1 tmp = TruncRing(None, a, k, m - 1, signed) return TruncRing(None, tmp + 1, k - m + 1, 1, signed) from .types import sint res = sint() Trunc(res, a + (1 << (m - 1)), k + 1, m, kappa, signed) return res
def TruncRing(d, a, k, m, signed): program.curr_tape.require_bit_length(1) if program.use_split() in (2, 3): if signed: a += (1 << (k - 1)) from Compiler.types import sint from .GC.types import sbitint length = int(program.options.ring) summands = a.split_to_n_summands(length, program.use_split()) x = sbitint.wallace_tree_without_finish(summands, True) if program.use_split() == 2: carries = sbitint.get_carries(*x) low = carries[m] high = sint.conv(carries[length]) else: if m == 1: low = x[1][1] high = sint.conv(CarryOutLE(x[1][:-1], x[0][:-1])) + \ sint.conv(x[0][-1]) else: mid_carry = CarryOutRawLE(x[1][:m], x[0][:m]) low = sint.conv(mid_carry) + sint.conv(x[0][m]) tmp = util.tree_reduce( carry, (sbitint.half_adder(xx, yy) for xx, yy in zip(x[1][m:-1], x[0][m:-1]))) top_carry = sint.conv(carry([None, mid_carry], tmp, False)[1]) high = top_carry + sint.conv(x[0][-1]) shifted = sint() shrsi(shifted, a, m) res = shifted + sint.conv(low) - (high << (length - m)) if signed: res -= (1 << (k - m - 1)) else: a_prime = Mod2mRing(None, a, k, m, signed) a -= a_prime res = TruncLeakyInRing(a, k, m, signed) if d is not None: movs(d, res) return res
def load_int_to_secret(value, size=None): return sint(value, size=size)
def BitLTC1(u, a, b, kappa): """ u = a <? b a: array of clear bits b: array of secret bits (same length as a) """ k = len(b) p = [program.curr_block.new_reg('s') for i in range(k)] from . import floatingpoint a_bits = floatingpoint.bits(a, k) if instructions_base.get_global_vector_size() == 1: a_ = a_bits a_bits = program.curr_block.new_reg('c', size=k) b_vec = program.curr_block.new_reg('s', size=k) for i in range(k): movc(a_bits[i], a_[i]) movs(b_vec[i], b[i]) d = program.curr_block.new_reg('s', size=k) s = program.curr_block.new_reg('s', size=k) t = [program.curr_block.new_reg('s', size=k) for j in range(5)] c = [program.curr_block.new_reg('c', size=k) for j in range(4)] else: d = [program.curr_block.new_reg('s') for i in range(k)] s = [program.curr_block.new_reg('s') for i in range(k)] t = [[program.curr_block.new_reg('s') for i in range(k)] for j in range(5)] c = [[program.curr_block.new_reg('c') for i in range(k)] for j in range(4)] if instructions_base.get_global_vector_size() == 1: vmulci(k, c[2], a_bits, 2) vmulm(k, t[0], b_vec, c[2]) vaddm(k, t[1], b_vec, a_bits) vsubs(k, d, t[1], t[0]) vaddsi(k, t[2], d, 1) t[2].create_vector_elements() pre_input = t[2].vector[:] else: for i in range(k): mulci(c[2][i], a_bits[i], 2) mulm(t[0][i], b[i], c[2][i]) addm(t[1][i], b[i], a_bits[i]) subs(d[i], t[1][i], t[0][i]) addsi(t[2][i], d[i], 1) pre_input = t[2][:] pre_input.reverse() if use_inv: if instructions_base.get_global_vector_size() == 1: PreMulC_with_inverses_and_vectors(p, pre_input) else: if do_precomp: PreMulC_with_inverses(p, pre_input) else: raise NotImplementedError( 'Vectors not compatible with -c sinv') else: PreMulC_without_inverses(p, pre_input) p.reverse() for i in range(k - 1): subs(s[i], p[i], p[i + 1]) subsi(s[k - 1], p[k - 1], 1) subcfi(c[3][0], a_bits[0], 1) mulm(t[4][0], s[0], c[3][0]) from .types import sint t[3] = [sint() for i in range(k)] for i in range(1, k): subcfi(c[3][i], a_bits[i], 1) mulm(t[3][i], s[i], c[3][i]) adds(t[4][i], t[4][i - 1], t[3][i]) Mod2(u, t[4][k - 1], k, kappa, False) return p, a_bits, d, s, t, c, b, pre_input
def load_int_to_secret_vector(vector): res = sint(size=len(vector)) for i,val in enumerate(vector): ldsi(res[i], val) return res
def compare_secret(a, b, length, sec=40): res = sint() instructions.lts(res, a, b, length, sec)