def encrypt(bit, key, s_size=31, e_size=16, p=P): """ usage: encrypt(bit, key, s_size=31, e_size=16, p=P) => ciphertext Returns a ciphertext integer. """ a, ai = key s = (random_integer(s_size) >> 1) << 1 e = random_integer(e_size) return ((a * (s + bit)) + e) % p
def generate_secret_key(inverse_size=64, p=P): """ usage: generate_secret_key(inverse_size=64, p=P) => a, ai Returns 2 integers. The size of the inverse places a limit on how many cipher multiplications may be performed. """ ai = random_integer(inverse_size) return modular_inverse(ai, p), ai
def generate_public_key(private_key, parameters=PARAMETERS): """ usage: generate_public_key(private_key, parameters=PARAMETERS) => public_key : int Returns a pubic key for use with the key agreement scheme. It is recommended to use generate_keypair instead. """ s = private_key r = random_integer(parameters["r_size"]) return ((parameters['e'] * s) + r) % parameters['n']
def generate_backdoor_private_key(parameters=PARAMETERS): """ usage: generate_backdoor_private_key(parameters=PARAMETERS) => backdoor_key : tuple Generates a private backdoor key. It is recommended to use generate_backdoor_keypair instead. """ d_size = parameters["d_size"] n_size = parameters["n_size"] k = random_integer(parameters["k_size"]) while True: d = random_integer(d_size) | (1 << (d_size * 8)) n = random_integer(n_size) | (1 << (n_size * 8)) try: modular_inverse(d, n - k) except ValueError: continue else: break return d, n, n - k
def test_encrypt_decrypt(): key = generate_secret_key() iterations = 10000 for count in range(iterations): bit = random_integer(1) & 1 ciphertext = encrypt(bit, key) _bit = decrypt(ciphertext, key) if bit != _bit: raise Warning("cipher.py unit test failed.") for count in range(iterations): for bit1 in range(2): for bit2 in range(2): assert bit1 in (0, 1) assert bit2 in (0, 1) ciphertext1 = encrypt(bit1, key) ciphertext2 = encrypt(bit2, key) ciphertext3 = ciphertext1 + ciphertext2 ciphertext4 = ciphertext1 * ciphertext2 plaintext3 = decrypt(ciphertext3, key) plaintext4 = decrypt(ciphertext4, key, depth=2) assert plaintext3 == (bit1 ^ bit2) assert plaintext4 == (bit1 & bit2), (bit1, bit2) print("cipher.py unit test passed")
def generate_private_key(parameters=PARAMETERS): """ usage: generate_private_key(parameters=PARAMETERS) => private_key : int Returns a private key for use with the key agreement scheme. It is recommended to use generate_keypair instead. """ return random_integer(parameters["s_size"])