def decrypt_recursive(self, ciphertext, in_range, out_range): in_size = in_range.size() # M out_size = out_range.size() # N in_edge = in_range.start - 1 # d out_edge = out_range.start - 1 # r mid = out_edge + int(math.ceil(out_size / 2.0)) # y assert in_size <= out_size if in_range.size() == 1: in_range_min = in_range.start coins = self.tape_gen(in_range_min) sampled_ciphertext = stat.sample_uniform(out_range, coins) if sampled_ciphertext == ciphertext: return in_range_min else: raise InvalidCiphertextError('Invalid ciphertext') coins = self.tape_gen(mid) x = stat.sample_hgd(in_range, out_range, mid, coins) if ciphertext <= mid: in_range = ValueRange(in_edge + 1, x) out_range = ValueRange(out_edge + 1, mid) else: in_range = ValueRange(x + 1, in_edge + in_size) out_range = ValueRange(mid + 1, out_edge + out_size) return self.decrypt_recursive(ciphertext, in_range, out_range)
def encrypt_recursive(self, plaintext, in_range, out_range): in_size = in_range.size() # M out_size = out_range.size() # N in_edge = in_range.start - 1 # d out_edge = out_range.start - 1 # r mid = out_edge + int(math.ceil(out_size / 2.0)) # y assert in_size <= out_size if in_range.size() == 1: coins = self.tape_gen(plaintext) ciphertext = stat.sample_uniform(out_range, coins) return ciphertext coins = self.tape_gen(mid) x = stat.sample_hgd(in_range, out_range, mid, coins) if plaintext <= x: in_range = ValueRange(in_edge + 1, x) out_range = ValueRange(out_edge + 1, mid) else: in_range = ValueRange(x + 1, in_edge + in_size) out_range = ValueRange(mid + 1, out_edge + out_size) return self.encrypt_recursive(plaintext, in_range, out_range)
def test_uniform(): # Short ranges value = 10 unit_range = ValueRange(value, value) assert sample_uniform(unit_range, []) == value short_range = ValueRange(value, value + 1) assert sample_uniform(short_range, [0]) == value assert sample_uniform(short_range, [1]) == value + 1 assert sample_uniform(short_range, [0, 0, 1, 0, 'llama']) == value, "More bits yield no effect" with pytest.raises(Exception): sample_uniform(short_range, []) # Medium ranges start_range = 20 end_range = start_range + 15 range1 = ValueRange(start_range, start_range + 15) assert sample_uniform(range1, [0, 0, 0, 0]) == start_range assert sample_uniform(range1, [0, 0, 0, 1]) == start_range + 1 assert sample_uniform(range1, [1, 1, 1, 1]) == end_range # Test with a generator object assert sample_uniform(range1, itertools.repeat(0, 10)) == start_range # Negative range start_range = -32 end_range = -17 range = ValueRange(start_range, end_range) assert sample_uniform(range, [0] * 5) == start_range assert sample_uniform(range, [1] * 5) == end_range # Mixed range start_range = -32 end_range = 31 range = ValueRange(start_range, end_range) assert sample_uniform(range, [0] * 6) == start_range assert sample_uniform(range, [1] * 6) == end_range