def PRandM(r_dprime, r_prime, b, k, m, kappa, use_dabit=True): """ r_dprime = random secret integer in range [0, 2^(k + kappa - m) - 1] r_prime = random secret integer in range [0, 2^m - 1] b = array containing bits of r_prime """ program.curr_tape.require_bit_length(k + kappa) from .types import sint if program.use_edabit() and m > 1 and not const_rounds: movs(r_dprime, sint.get_edabit(k + kappa - m, True)[0]) tmp, b[:] = sint.get_edabit(m, True) movs(r_prime, tmp) return t = [[program.curr_block.new_reg('s') for j in range(2)] for i in range(m)] t[0][1] = b[-1] PRandInt(r_dprime, k + kappa - m) # r_dprime is always multiplied by 2^m if use_dabit and program.use_dabit and m > 1 and not const_rounds: r, b[:] = zip(*(sint.get_dabit() for i in range(m))) r = sint.bit_compose(r) movs(r_prime, r) return bit(b[-1]) for i in range(1, m): adds(t[i][0], t[i - 1][1], t[i - 1][1]) bit(b[-i - 1]) adds(t[i][1], t[i][0], b[-i - 1]) movs(r_prime, t[m - 1][1])
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 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 to_sint(self, n_bits): bits = sbitvec.from_vec(sbitvec([self]).v[:n_bits]).elements()[0] bits = sint(bits, size=n_bits) return sint.bit_compose(bits)
def to_sint(self, n_bits): """ Convert the :py:obj:`n_bits` least significant bits to :py:obj:`~Compiler.types.sint`. """ bits = sbitvec.from_vec(sbitvec([self]).v[:n_bits]).elements()[0] bits = sint(bits, size=n_bits) return sint.bit_compose(bits)