Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import random
- import time
- import json
- from decimal import Decimal, getcontext
- #########################################################
- # Alice #
- #########################################################
- def crown_npsn_rng() -> int:
- """This mocks the Crown RNG that generates non-perfect square numbers."""
- return random.choice([2,3,5,6,7,8,10,11,12,13,14,15,17,18,19,20,21,22,23,24,26])
- def int_to_bytes(x: int) -> bytes:
- return x.to_bytes((x.bit_length() + 7) // 8, 'big')
- def generate_otp(seed: int, length: int, offset: int) -> bytes:
- getcontext().prec = 5 * (length + offset)
- square_root = Decimal(seed).sqrt()
- decimal_expansion = str(square_root).split('.')[1]
- keystream_integer = int(decimal_expansion[offset:])
- one_time_pad = int_to_bytes(keystream_integer)[:length]
- return one_time_pad
- def xor_bytestrings(var: bytes, key: bytes) -> bytes:
- assert len(var) == len(key)
- return bytes(a ^ b for a, b in zip(var, key))
- #########################################################
- # Eve (Eavesdropper) #
- #########################################################
- def crack_crown_otp(ciphertext: bytes) -> str:
- """Crack the OTP ciphertext.
- Crown Sterling's claim is their OTP has perfect secrecy.
- Therefore brute force attack like the one below should
- not be possible.
- """
- for seed in range(1, 30):
- for offset in range(1, 30):
- try:
- pad_candidate = generate_otp(seed=seed, length=len(ciphertext), offset=offset)
- except IndexError:
- continue
- try:
- decryption_candidate = xor_bytestrings(ciphertext, pad_candidate).decode()
- data_structure = json.loads(decryption_candidate)
- return 'Successful decryption: ' + data_structure['message']
- except UnicodeDecodeError:
- continue
- return 'Error: Decryption failed'
- #########################################################
- # Main #
- #########################################################
- def main():
- message = 'Attack at dusk'
- packet_data_structure = {'message': message, 'send_unix_timestamp': time.time()}
- plaintext_packet = json.dumps(packet_data_structure, default=(lambda o: {k: packet_data_structure[k] for k in packet_data_structure}), indent=0).encode()
- # Alice
- one_time_pad = generate_otp(seed=crown_npsn_rng(),
- length=len(plaintext_packet),
- offset=random.randint(1, 10))
- ciphertext = xor_bytestrings(plaintext_packet, one_time_pad)
- # Eve
- decryption = crack_crown_otp(ciphertext=ciphertext)
- print(decryption)
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment