Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import math
- import time
- import os
- def lfsr(seed, size, iter, taps, non_linear_taps=None):
- """Run an LFSR with the given seed, size, iterations, and taps."""
- state = seed
- if seed >= 2**size:
- print("Error: seed out of bounds")
- return None
- elif any(tap >= size for tap in taps):
- print("Error: tap number out of bounds")
- return None
- if non_linear_taps is None:
- non_linear_taps = []
- for _ in range(iter):
- feedback_bits = [math.floor((state / (2**tap)) % 2) for tap in taps]
- newbit = sum(feedback_bits) % 2 # XOR tap bits
- if len(non_linear_taps) == 2:
- and_bit = (math.floor((state / (2**non_linear_taps[0])) % 2) &
- math.floor((state / (2**non_linear_taps[1])) % 2))
- newbit ^= and_bit # Add non-linearity
- state = math.floor(state / 2) + (newbit * (2**(size - 1))) # Shift and insert new bit
- return state
- def encrypt_decrypt(text=None, file_path=None, seed=0, size=0, taps=None, non_linear_taps=None, init_iters=0, decrypt=False):
- """Encrypt or decrypt a string or file bit by bit using LFSR, with initialization iterations."""
- if taps is None:
- taps = []
- if non_linear_taps is None:
- non_linear_taps = []
- if file_path:
- # Read the file as binary
- with open(file_path, "rb") as file:
- binary_data = file.read()
- # Convert binary data to a binary string
- binary_text = ''.join(format(byte, '08b') for byte in binary_data)
- elif text:
- # Convert ASCII text to binary
- binary_text = ''.join(format(ord(c), '08b') for c in text)
- else:
- print("No input provided.")
- return None
- state = lfsr(seed, size, init_iters, taps, non_linear_taps) # Run initialization iterations
- output_bits = ''
- for bit in binary_text:
- key_bit = math.floor(state % 2) # Use LSB of the register
- state = lfsr(state, size, 1, taps, non_linear_taps) # Update LFSR state
- output_bits += str(int(bit) ^ key_bit) # XOR input bit with LFSR key bit
- if file_path:
- # Convert output binary string back to bytes
- encrypted_bytes = int(output_bits, 2).to_bytes(len(output_bits) // 8, byteorder="big")
- if decrypt:
- new_file_path = file_path.replace(".enc", "") # Restore original file name
- else:
- new_file_path = file_path + ".enc" # Append .enc to the filename
- with open(new_file_path, "wb") as file:
- file.write(encrypted_bytes)
- print(f"Processed file saved as: {new_file_path}")
- return new_file_path
- else:
- # Convert binary to hex for encryption output
- encrypted_text = hex(int(output_bits, 2))[2:] if not decrypt else ''.join(chr(int(output_bits[i:i+8], 2)) for i in range(0, len(output_bits), 8))
- print("Result:", encrypted_text)
- save_option = input("Do you want to save the result to a file? (y/n): ").strip().lower()
- if save_option == "y":
- filename = input("Enter filename (including extension, e.g., output.txt): ").strip()
- with open(filename, "w") as file:
- file.write(encrypted_text)
- print(f"Result saved to {filename}")
- return encrypted_text
- def generate_keystream(seed, size, taps, non_linear_taps, num_bits):
- """Generate a raw keystream of specified bits, displayed in hex groups of 5."""
- state = seed
- keystream = ''
- for _ in range(num_bits):
- key_bit = math.floor(state % 2) # Use LSB of the register
- keystream += str(key_bit)
- state = lfsr(state, size, 1, taps, non_linear_taps) # Update LFSR state
- hex_keystream = hex(int(keystream, 2))[2:]
- grouped_keystream = ' '.join(hex_keystream[i:i+5] for i in range(0, len(hex_keystream), 5))
- print("Raw Keystream (hex):", grouped_keystream)
- def test_period(initial_seed, size, taps, non_linear_taps=None):
- """Test the period of an LFSR configuration with an option to resume from a previous state."""
- start_time = time.time()
- log_file = "lfsr_period_log.txt"
- resume = input("Do you want to resume from a previous state? (y/n): ").strip().lower()
- if resume == "y":
- resume_seed = int(input("Enter the last known state: "))
- elapsed_iterations = int(input("Enter the number of iterations already elapsed: "))
- else:
- resume_seed = initial_seed # Start fresh if not resuming
- elapsed_iterations = 0
- # Write initial conditions to the file
- with open(log_file, "w") as file:
- file.write(f"Initial Seed: {initial_seed}\n")
- file.write(f"Register Size: {size}\n")
- file.write(f"Taps: {taps}\n")
- file.write(f"Non-Linear Taps: {non_linear_taps}\n\n")
- state = resume_seed # Start from the resume point
- period = elapsed_iterations
- if non_linear_taps is None:
- non_linear_taps = []
- while True:
- state = lfsr(state, size, 1, taps, non_linear_taps) # Update LFSR state
- period += 1
- if period % 100_000_000 == 0:
- with open(log_file, "a") as file:
- file.write(f"Iteration: {period}, State: {state}\n")
- if state == initial_seed: # Check if we have returned to the initial seed
- break # Found full cycle, exit loop
- if period % 1_000_000 == 0:
- elapsed_time = time.time() - start_time
- iterations_per_sec = (1000000 / elapsed_time)
- estimated_total_time = ((2**size) - period) / iterations_per_sec
- if estimated_total_time > 3600:
- hours = int(estimated_total_time // 3600)
- minutes = int((estimated_total_time % 3600) // 60)
- seconds = int(estimated_total_time % 60)
- time_display = f"{hours}h {minutes}m {seconds}s"
- elif estimated_total_time > 60:
- minutes = int(estimated_total_time // 60)
- seconds = int(estimated_total_time % 60)
- time_display = f"{minutes}m {seconds}s"
- else:
- time_display = f"{estimated_total_time:.2f} sec"
- print(f"Iterations: {period}, Speed: {iterations_per_sec:.2f} it/s, Estimated Time Remaining: {time_display}, latest state: {state}")
- start_time = time.time()
- print(f"LFSR period: {period}")
- print(f"Final state before loop restart: {state}")
- return period
- if __name__ == "__main__":
- choice = input("Choose an option: (1) Encrypt Text, (2) Decrypt Text, (3) Encrypt File, (4) Decrypt File, (5) Test Period, (6) Raw Keystream: ")
- initial_seed = int(input("Enter seed (integer): "))
- size = int(input("Enter register length (size): "))
- taps = list(map(int, input("Enter taps (comma-separated): ").split(',')))
- non_linear_taps_input = input("Enter non-linear taps (comma-separated, or leave blank): ")
- non_linear_taps = list(map(int, non_linear_taps_input.split(','))) if non_linear_taps_input else []
- if choice in ["1", "2", "3", "4"]:
- init_iters = int(input("Enter number of initialization iterations: "))
- if choice == "1":
- text = input("Enter text: ")
- encrypt_decrypt(text=text, seed=initial_seed, size=size, taps=taps, non_linear_taps=non_linear_taps, init_iters=init_iters)
- elif choice == "2":
- hex_text = input("Enter hex ciphertext: ")
- encrypt_decrypt(text=hex_text, seed=initial_seed, size=size, taps=taps, non_linear_taps=non_linear_taps, init_iters=init_iters, decrypt=True)
- elif choice == "3":
- file_name = input("Enter filename to encrypt (must be in the same directory): ").strip()
- encrypt_decrypt(file_path=file_name, seed=initial_seed, size=size, taps=taps, non_linear_taps=non_linear_taps, init_iters=init_iters)
- elif choice == "4":
- file_name = input("Enter filename to decrypt (must be in the same directory and have .enc extension): ").strip()
- encrypt_decrypt(file_path=file_name, seed=initial_seed, size=size, taps=taps, non_linear_taps=non_linear_taps, init_iters=init_iters, decrypt=True)
- elif choice == "5":
- test_period(initial_seed, size, taps, non_linear_taps)
- elif choice == "6":
- num_bits = int(input("Enter number of keystream bits to generate: "))
- generate_keystream(initial_seed, size, taps, non_linear_taps, num_bits)
- else:
- print("Invalid choice.")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement