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 MaskingBitsInRing(m, strict=False): from Compiler.types import sint if program.use_edabit(): return sint.get_edabit(m, strict) elif program.use_dabit: r, r_bin = zip(*(sint.get_dabit() for i in range(m))) else: r = [sint.get_random_bit() for i in range(m)] r_bin = r return sint.bit_compose(r), r_bin
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 get_random_bit(size=None): return sint.get_random_bit(size=size)
def get_random_bit(size=None): return sint.get_random_bit(size=size)