def normalized_sample(self, W): """ Normalized sampling without division. Args: W: a set of weights from which to sample. Returns: an integer in [0,len(W)] corresponding to the index sampled. """ t = gmpy2.fsum(W) # compute total weight C = [gmpy2.fsum(W[0:i + 1]) for i in range(0, len(W))] # compute cumulative weights # Determine the maximum power of two for sampling i_max = 0 while gmpy2.exp2(i_max) > t: i_max -= 1 while gmpy2.exp2(i_max) <= t: i_max += 1 # sample a random number s = gmpy2.exp2(i_max + 1) while s > t: s = self.get_random_value(i_max, self.context.precision) # return the element that matches the sampled index for i in range(0, len(W)): if C[i] >= s: return i
def get_random_value(self, start_pow, p=None): """ Sample a random value based on self.rng of p bits between [0,2^(start_pow+1)). """ if p == None: p = self.context.precision s = mpfr(0) nextbit = gmpy2.exp2(start_pow) for i in range(1, p): s = gmpy2.add(s, gmpy2.mul(nextbit, mpfr(self.rng()))) nextbit = gmpy2.exp2(start_pow - i) return s
def aby_prng(Len): """Generates a random mpz with bitlength Len.""" global global_random_state if global_random_state is None: global_random_state = gmpy2.random_state(int(time.time())) result = mpz(0) for i in range(Len): if gmpy2.mpz_random(global_random_state, 2) == 1: result += gmpy2.exp2(i) return mpz(result)
def powers_of_two_spacing(): exp_spacing=[] with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundToNearest, precision=mpfr_proxy_precision) as ctx: exponent=gmpy2.mpfr("0") while abs(exponent)<discretization_points: value=gmpy2.exp2(exponent) exp_spacing.insert(0, round_number_nearest_to_digits(value, digits_for_input_discretization)) exponent=gmpy2.sub(exponent,gmpy2.mpfr("1")) exp_spacing.insert(0, "0.0") for index, value in enumerate(exp_spacing[:-1]): if value==exp_spacing[index+1]: print("Problem with digits in powers of 2") exit(-1) return exp_spacing
def optimized_normalized_sample(self, W): """ Optimized Normalized sampling without division. Args: W: a set of weights from which to sample. Returns: an integer in [0,len(W)] corresponding to the index sampled. WARNING: introduces a timing channel for differing weight distributions. """ t = gmpy2.fsum(W) # compute total weight C = [gmpy2.fsum(W[0:i + 1]) for i in range(0, len(W))] # compute cumulative weights s = 0 log2t = 0 while gmpy2.exp2(log2t) > t: log2t -= 1 while gmpy2.exp2(log2t) <= t: log2t += 1 j = log2t - 1 remaining = [i for i in range(0, len(W))] if t < gmpy2.exp2(log2t): remaining.append(len(W)) # add a dummy value C.append(gmpy2.exp2(log2t)) while len(remaining) > 1: r = self.rng() s = s + r * gmpy2.exp2(j) to_remove = [] for i in remaining: # check if each remaining index is still reachable if C[i] <= s: to_remove.append(i) if i > 0: if C[i - 1] >= s + gmpy2.exp2(j): to_remove.append(i) for i in to_remove: remaining.remove(i) if len(remaining) == 1 and remaining[0] == len(W): s = 0 j = log2t # don't subtract 1, it's going to be decremented remaining = [i for i in range(0, len(W))] if t < gmpy2.exp2(log2t): remaining.append(len(W)) # add a dummy value C.append(gmpy2.exp2(log2t)) j -= 1 return remaining[0]
def check_precision(self): """ Performs test computations at the current precision intended to capture the workload of the exponential mechanism and catch if the current precision is sufficient. """ # 1. Compute base = 2^(-eta) self.base = mpfr(pow(self.eta_x, self.eta_z)) self.base *= mpfr(gmpy2.exp2(-gmpy2.mul(self.eta_y, self.eta_z))) # 2. Compute (base)^u_max max_weight = mpfr(pow(self.base, self.u_min)) # 3. Compute Combinations for u in range(self.u_min, self.u_max): u_weight = pow(self.base, u) ceil_max_weight = gmpy2.rint_ceil(max_weight) combination = ceil_max_weight + u_weight
def powers_of_two_error(precision): exp_spacing=[] with gmpy2.local_context(gmpy2.context(), round=gmpy2.RoundToNearest, precision=mpfr_proxy_precision) as ctx: exponent=gmpy2.mpfr(-precision) counter=0 while counter<discretization_points//2: value=gmpy2.exp2(exponent) exp_spacing.insert(0, round_number_nearest_to_digits(value, digits_for_input_discretization)) exponent=gmpy2.sub(exponent,gmpy2.mpfr("1")) counter=counter+1 exp_spacing_reverse=copy.deepcopy(exp_spacing) exp_spacing_reverse.reverse() exp_spacing_reverse=["-"+s for s in exp_spacing_reverse] exp_spacing=exp_spacing_reverse+["0.0"]+exp_spacing for index, value in enumerate(exp_spacing[:-1]): if value==exp_spacing[index+1]: print("Problem with digits in powers of 2") exit(-1) return exp_spacing
def check_precision(self): """ Performs test computations at the current precision intended to capture the workload of the exponential mechanism and catch if the current precision is sufficient. """ # 1. Compute base = 2^(-eta) self.base = mpfr(pow(self.eta_x, self.eta_z)) self.base *= mpfr(gmpy2.exp2(-gmpy2.mul(self.eta_y, self.eta_z))) # 2. Compute (base)^u_min and (base)^u_max min_weight = pow(self.base, self.u_min) max_weight = pow(self.base, self.u_max) mm = max_weight + min_weight # 3. Compute maximum total utility and minimum total utility max_total = max_weight * self.max_outcomes min_total = min_weight * self.max_outcomes # 4. Add max and min total utilities max_min_total = max_total + min_weight min_max_total = min_total + max_weight
def dgk_keygen(modulusbits, lbits): pub = dgk_pubkey(0,0,0,0,0,0) prv = dgk_prvkey(0,0,0,0,0,0,0,0) lbits = lbits * 2 + 2 pub.bits = modulusbits pub.lbits = lbits # vp and vq are primes prv.vp = aby_prng(160) prv.vp = gmpy2.next_prime(prv.vp) prv.vq = aby_prng(160) prv.vq = gmpy2.next_prime(prv.vq) while prv.vp == prv.vq: prv.vq = gmpy2.next_prime(prv.vq) # u = 2 ^ lbits pub.u = mpz(gmpy2.exp2(lbits)) # p found = False while not found: f1 = aby_prng(modulusbits // 2 - 160 - lbits) f1 = gmpy2.next_prime(f1) prv.p = mpz(pub.u * prv.vp) prv.p *= f1 prv.p += 1 found = gmpy2.is_prime(prv.p, 50) # q found = False while not found: f2 = aby_prng(modulusbits // 2 - 159 - lbits) f2 = gmpy2.next_prime(f2) prv.q = mpz(pub.u * prv.vq) prv.q *= f2 prv.q += 1 found = gmpy2.is_prime(prv.q, 50) # p-1, q-1 prv.p_minusone = prv.p - 1 prv.q_minusone = prv.q - 1 # n = pq pub.n = mpz(prv.p * prv.q) # xp exp1 = mpz(gmpy2.exp2(lbits - 1)) exp1 *= prv.vp exp1 *= f1 exp2 = mpz(prv.vp * pub.u) exp3 = mpz(f1 * pub.u) found = False while not found: xp = mpz(aby_prng(prv.p.bit_length() + 128)) xp %= prv.p tmp = gmpy2.powmod(xp, exp1, prv.p) if tmp != 1: tmp = gmpy2.powmod(xp, exp2, prv.p) if tmp != 1: tmp = gmpy2.powmod(xp, exp3, prv.p) if tmp != 1: found = True # xq exp1 = mpz(gmpy2.exp2(lbits - 1)) exp1 *= prv.vq exp1 *= f2 exp2 = mpz(prv.vq * pub.u) exp3 = mpz(f2 * pub.u) found = False while not found: xq = aby_prng(prv.q.bit_length() + 128) xq %= prv.q tmp = gmpy2.powmod(xq, exp1, prv.q) if tmp != 1: tmp = gmpy2.powmod(xq, exp2, prv.q) if tmp != 1: tmp = gmpy2.powmod(xq, exp3, prv.q) if tmp != 1: found = True # compute CRT: g = xp*q*(q^{-1} mod p) + xq*p*(p^{-1} mod q) mod n prv.qinv = gmpy2.invert(prv.q, prv.p) prv.pinv = gmpy2.invert(prv.p, prv.q) pub.g = (xp * prv.q * prv.qinv + xq * prv.p * prv.pinv) % pub.n # line 206 tmp = mpz(f1 * f2) pub.g = gmpy2.powmod(pub.g, tmp, pub.n) pub.h = mpz(aby_prng(mpz(pub.n).bit_length() + 128)) pub.h %= pub.n tmp *= pub.u pub.h = gmpy2.powmod(pub.h, tmp, pub.n) # array holding powers of two for i in range(lbits): powtwo.append(mpz(gmpy2.exp2(i))) f1 = gmpy2.powmod(pub.g, prv.vp, prv.p) tmp2 = pub.u - 1 for i in range(lbits): gvpvqptmp = mpz(gmpy2.powmod(f1, powtwo[i], prv.p)) gvpvqptmp = mpz(gmpy2.powmod(gvpvqptmp, tmp2, prv.p)) gvpvqp.append(gvpvqptmp) return pub, prv
new_energy = newer_energy optimal_step_size = (step_size / 4) * ( new_energy - 4 * newer_energy + 3 * initial_energy) / ( new_energy - 2 * newer_energy + initial_energy) if 0 < optimal_step_size < step_size: return optimal_step_size else: return step_size / 2 ################################################################################ if __name__ == '__main__': random.seed() gmpy2.get_context().precision = 100 epsilon = gmpy2.exp2(-gmpy2.get_context().precision + 20) num_points = 100 num_dims = 3 point_indices = range(num_points) dim_indices = range(num_dims) all_indices = range(num_points * num_dims) points = [[gmpy2.mpfr(random.gauss(0, 1)) for _ in dim_indices] for _ in point_indices] normalize_each_in_place(points) energy = riesz_energy(points, 1) force = riesz_force(points, 1) constrain_force_in_place(points, force)