import random from utils.binary_writer import BinaryWriter from hashlib import sha1 def generate_random_long(signed=True): """Generates a random long integer (8 bytes), which is optionally signed""" result = random.getrandbits(64) if not signed: result &= 0xFFFFFFFFFFFFFFFF # Ensure it's unsigned return result def generate_random_bytes(count): """Generates a random bytes array""" with BinaryWriter() as writer: for _ in range(count): writer.write(random.getrandbits(8)) return writer.get_bytes() def calc_key(shared_key, msg_key, client): """Calculate the key based on Telegram guidelines, specifying whether it's the client or not""" x = 0 if client else 8 buffer = [0] * 48 buffer[0:16] = msg_key buffer[16:48] = shared_key[x:x + 32] sha1a = sha1(buffer) buffer[0:16] = shared_key[x + 32:x + 48] buffer[16:32] = msg_key buffer[32:48] = shared_key[x + 48:x + 64] sha1b = sha1(buffer) buffer[0:32] = shared_key[x + 64:x + 96] buffer[32:48] = msg_key sha1c = sha1(buffer) buffer[0:16] = msg_key buffer[16:48] = shared_key[x + 96:x + 128] sha1d = sha1(buffer) key = sha1a[0:8] + sha1b[8:20] + sha1c[4:16] iv = sha1a[8:20] + sha1b[0:8] + sha1c[16:20] + sha1d[0:8] return key, iv def calc_msg_key(data): """Calculates the message key from the given data""" return sha1(data)[4:20] def calc_msg_key_offset(data, offset, limit): """Calculates the message key from offset given data, with an optional offset and limit""" # TODO untested, may not be offset like this # In the original code it was as parameters for the sha function, not slicing the array return sha1(data[offset:offset + limit])[4:20] def generate_key_data_from_nonces(serverNonce, newNonce): # TODO unsure that this works nonces = [0] * 48 nonces[00:32] = newNonce nonces[32:48] = serverNonce hash1 = hash(bytes(nonces)) nonces[00:16] = serverNonce nonces[16:32] = newNonce hash2 = hash(bytes(nonces)) nonces = [0] * 64 nonces[00:32] = newNonce nonces[32:64] = newNonce hash2 = hash(bytes(nonces)) with BinaryWriter() as keyBuffer: with BinaryWriter() as ivBuffer: """ using (var keyBuffer = new MemoryStream(32)) using (var ivBuffer = new MemoryStream(32)) { keyBuffer.Write(hash1, 0, hash1.Length); keyBuffer.Write(hash2, 0, 12); ivBuffer.Write(hash2, 12, 8); ivBuffer.Write(hash3, 0, hash3.Length); ivBuffer.Write(newNonce, 0, 4); return new AESKeyData(keyBuffer.ToArray(), ivBuffer.ToArray()); } """ # TODO implement raise NotImplementedError()