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
def B2U_from_Pow2(pow2a, l, kappa): #assert(pow2a.value == 2**a.value) r = [types.sint() for i in range(l)] t = types.sint() c = types.cint() for i in range(l): bit(r[i]) comparison.PRandInt(t, kappa) asm_open(c, pow2a + two_power(l) * t + sum(two_power(i)*r[i] for i in range(l))) comparison.program.curr_tape.require_bit_length(l + kappa) c = list(bits(c, l)) x = [c[i] + r[i] - 2*c[i]*r[i] for i in range(l)] #print ' '.join(str(b.value) for b in x) y = PreOR(x, kappa) #print ' '.join(str(b.value) for b in y) return [1 - y[i] for i in range(l)]
def Trunc(a, l, m, kappa, compute_modulo=False): """ Oblivious truncation by secret m """ if l == 1: if compute_modulo: return a * m, 1 + m else: return a * (1 - m) 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: pow2inv = Inv(pow2m) #assert(pow2inv.value * pow2m.value % comparison.program.P == 1) b = (a - c_dprime + r_prime) * pow2inv - d return b