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 Trunc(a, l, m, kappa, compute_modulo=False, signed=False): """ Oblivious truncation by secret m """ if util.is_constant(m) and not compute_modulo: # cheaper res = type(a)(size=a.size) comparison.Trunc(res, a, l, m, kappa, signed=signed) return res if l == 1: if compute_modulo: return a * m, 1 + m else: return a * (1 - m) if program.Program.prog.options.ring and not compute_modulo: return TruncInRing(a, l, Pow2(m, l, kappa)) r = [types.sint() for i in range(l)] r_dprime = types.sint(0) r_prime = types.sint(0) rk = types.sint() c = types.cint() ci = [types.cint() for i in range(l)] d = types.sint() x, pow2m = B2U(m, l, kappa) #assert(pow2m.value == 2**m.value) #assert(sum(b.value for b in x) == m.value) for i in range(l): bit(r[i]) t1 = two_power(i) * r[i] t2 = t1 * x[i] r_prime += t2 r_dprime += t1 - t2 #assert(r_prime.value == (sum(2**i*x[i].value*r[i].value for i in range(l)) % comparison.program.P)) comparison.PRandInt(rk, kappa) r_dprime += two_power(l) * rk #assert(r_dprime.value == (2**l * rk.value + sum(2**i*(1 - x[i].value)*r[i].value for i in range(l)) % comparison.program.P)) asm_open(c, a + r_dprime + r_prime) for i in range(1, l): ci[i] = c % two_power(i) #assert(ci[i].value == c.value % 2**i) c_dprime = sum(ci[i] * (x[i - 1] - x[i]) for i in range(1, l)) #assert(c_dprime.value == (sum(ci[i].value*(x[i-1].value - x[i].value) for i in range(1,l)) % comparison.program.P)) lts(d, c_dprime, r_prime, l, kappa) if compute_modulo: b = c_dprime - r_prime + pow2m * d return b, pow2m else: to_shift = a - c_dprime + r_prime if program.Program.prog.options.ring: shifted = TruncInRing(to_shift, l, pow2m) else: pow2inv = Inv(pow2m) #assert(pow2inv.value * pow2m.value % comparison.program.P == 1) shifted = to_shift * pow2inv b = shifted - d return b