Advertisement
Guest User

LFSRsuiteV05.py

a guest
Mar 5th, 2025
15
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.67 KB | None | 0 0
  1. import math
  2. import time
  3. import os
  4.  
  5. def lfsr(seed, size, iter, taps, non_linear_taps=None):
  6. """Run an LFSR with the given seed, size, iterations, and taps."""
  7. state = seed
  8. if seed >= 2**size:
  9. print("Error: seed out of bounds")
  10. return None
  11. elif any(tap >= size for tap in taps):
  12. print("Error: tap number out of bounds")
  13. return None
  14.  
  15. if non_linear_taps is None:
  16. non_linear_taps = []
  17.  
  18. for _ in range(iter):
  19. feedback_bits = [math.floor((state / (2**tap)) % 2) for tap in taps]
  20. newbit = sum(feedback_bits) % 2 # XOR tap bits
  21.  
  22. if len(non_linear_taps) == 2:
  23. and_bit = (math.floor((state / (2**non_linear_taps[0])) % 2) &
  24. math.floor((state / (2**non_linear_taps[1])) % 2))
  25. newbit ^= and_bit # Add non-linearity
  26.  
  27. state = math.floor(state / 2) + (newbit * (2**(size - 1))) # Shift and insert new bit
  28.  
  29. return state
  30.  
  31. def encrypt_decrypt(text=None, file_path=None, seed=0, size=0, taps=None, non_linear_taps=None, init_iters=0, decrypt=False):
  32. """Encrypt or decrypt a string or file bit by bit using LFSR, with initialization iterations."""
  33.  
  34. if taps is None:
  35. taps = []
  36. if non_linear_taps is None:
  37. non_linear_taps = []
  38.  
  39. if file_path:
  40. # Read the file as binary
  41. with open(file_path, "rb") as file:
  42. binary_data = file.read()
  43.  
  44. # Convert binary data to a binary string
  45. binary_text = ''.join(format(byte, '08b') for byte in binary_data)
  46. elif text:
  47. # Convert ASCII text to binary
  48. binary_text = ''.join(format(ord(c), '08b') for c in text)
  49. else:
  50. print("No input provided.")
  51. return None
  52.  
  53. state = lfsr(seed, size, init_iters, taps, non_linear_taps) # Run initialization iterations
  54. output_bits = ''
  55.  
  56. for bit in binary_text:
  57. key_bit = math.floor(state % 2) # Use LSB of the register
  58. state = lfsr(state, size, 1, taps, non_linear_taps) # Update LFSR state
  59. output_bits += str(int(bit) ^ key_bit) # XOR input bit with LFSR key bit
  60.  
  61. if file_path:
  62. # Convert output binary string back to bytes
  63. encrypted_bytes = int(output_bits, 2).to_bytes(len(output_bits) // 8, byteorder="big")
  64.  
  65. if decrypt:
  66. new_file_path = file_path.replace(".enc", "") # Restore original file name
  67. else:
  68. new_file_path = file_path + ".enc" # Append .enc to the filename
  69.  
  70. with open(new_file_path, "wb") as file:
  71. file.write(encrypted_bytes)
  72.  
  73. print(f"Processed file saved as: {new_file_path}")
  74. return new_file_path
  75. else:
  76. # Convert binary to hex for encryption output
  77. 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))
  78. print("Result:", encrypted_text)
  79.  
  80. save_option = input("Do you want to save the result to a file? (y/n): ").strip().lower()
  81. if save_option == "y":
  82. filename = input("Enter filename (including extension, e.g., output.txt): ").strip()
  83. with open(filename, "w") as file:
  84. file.write(encrypted_text)
  85. print(f"Result saved to {filename}")
  86.  
  87. return encrypted_text
  88.  
  89. def generate_keystream(seed, size, taps, non_linear_taps, num_bits):
  90. """Generate a raw keystream of specified bits, displayed in hex groups of 5."""
  91. state = seed
  92. keystream = ''
  93.  
  94. for _ in range(num_bits):
  95. key_bit = math.floor(state % 2) # Use LSB of the register
  96. keystream += str(key_bit)
  97. state = lfsr(state, size, 1, taps, non_linear_taps) # Update LFSR state
  98.  
  99. hex_keystream = hex(int(keystream, 2))[2:]
  100. grouped_keystream = ' '.join(hex_keystream[i:i+5] for i in range(0, len(hex_keystream), 5))
  101. print("Raw Keystream (hex):", grouped_keystream)
  102.  
  103. def test_period(initial_seed, size, taps, non_linear_taps=None):
  104. """Test the period of an LFSR configuration with an option to resume from a previous state."""
  105. start_time = time.time()
  106. log_file = "lfsr_period_log.txt"
  107.  
  108. resume = input("Do you want to resume from a previous state? (y/n): ").strip().lower()
  109.  
  110. if resume == "y":
  111. resume_seed = int(input("Enter the last known state: "))
  112. elapsed_iterations = int(input("Enter the number of iterations already elapsed: "))
  113. else:
  114. resume_seed = initial_seed # Start fresh if not resuming
  115. elapsed_iterations = 0
  116.  
  117. # Write initial conditions to the file
  118. with open(log_file, "w") as file:
  119. file.write(f"Initial Seed: {initial_seed}\n")
  120. file.write(f"Register Size: {size}\n")
  121. file.write(f"Taps: {taps}\n")
  122. file.write(f"Non-Linear Taps: {non_linear_taps}\n\n")
  123.  
  124. state = resume_seed # Start from the resume point
  125. period = elapsed_iterations
  126.  
  127. if non_linear_taps is None:
  128. non_linear_taps = []
  129.  
  130. while True:
  131. state = lfsr(state, size, 1, taps, non_linear_taps) # Update LFSR state
  132. period += 1
  133.  
  134. if period % 100_000_000 == 0:
  135. with open(log_file, "a") as file:
  136. file.write(f"Iteration: {period}, State: {state}\n")
  137.  
  138. if state == initial_seed: # Check if we have returned to the initial seed
  139. break # Found full cycle, exit loop
  140.  
  141. if period % 1_000_000 == 0:
  142. elapsed_time = time.time() - start_time
  143. iterations_per_sec = (1000000 / elapsed_time)
  144. estimated_total_time = ((2**size) - period) / iterations_per_sec
  145.  
  146. if estimated_total_time > 3600:
  147. hours = int(estimated_total_time // 3600)
  148. minutes = int((estimated_total_time % 3600) // 60)
  149. seconds = int(estimated_total_time % 60)
  150. time_display = f"{hours}h {minutes}m {seconds}s"
  151. elif estimated_total_time > 60:
  152. minutes = int(estimated_total_time // 60)
  153. seconds = int(estimated_total_time % 60)
  154. time_display = f"{minutes}m {seconds}s"
  155. else:
  156. time_display = f"{estimated_total_time:.2f} sec"
  157.  
  158. print(f"Iterations: {period}, Speed: {iterations_per_sec:.2f} it/s, Estimated Time Remaining: {time_display}, latest state: {state}")
  159. start_time = time.time()
  160.  
  161. print(f"LFSR period: {period}")
  162. print(f"Final state before loop restart: {state}")
  163. return period
  164.  
  165. if __name__ == "__main__":
  166. choice = input("Choose an option: (1) Encrypt Text, (2) Decrypt Text, (3) Encrypt File, (4) Decrypt File, (5) Test Period, (6) Raw Keystream: ")
  167.  
  168. initial_seed = int(input("Enter seed (integer): "))
  169. size = int(input("Enter register length (size): "))
  170. taps = list(map(int, input("Enter taps (comma-separated): ").split(',')))
  171. non_linear_taps_input = input("Enter non-linear taps (comma-separated, or leave blank): ")
  172. non_linear_taps = list(map(int, non_linear_taps_input.split(','))) if non_linear_taps_input else []
  173.  
  174. if choice in ["1", "2", "3", "4"]:
  175. init_iters = int(input("Enter number of initialization iterations: "))
  176.  
  177. if choice == "1":
  178. text = input("Enter text: ")
  179. encrypt_decrypt(text=text, seed=initial_seed, size=size, taps=taps, non_linear_taps=non_linear_taps, init_iters=init_iters)
  180.  
  181. elif choice == "2":
  182. hex_text = input("Enter hex ciphertext: ")
  183. encrypt_decrypt(text=hex_text, seed=initial_seed, size=size, taps=taps, non_linear_taps=non_linear_taps, init_iters=init_iters, decrypt=True)
  184.  
  185. elif choice == "3":
  186. file_name = input("Enter filename to encrypt (must be in the same directory): ").strip()
  187. encrypt_decrypt(file_path=file_name, seed=initial_seed, size=size, taps=taps, non_linear_taps=non_linear_taps, init_iters=init_iters)
  188.  
  189. elif choice == "4":
  190. file_name = input("Enter filename to decrypt (must be in the same directory and have .enc extension): ").strip()
  191. 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)
  192.  
  193. elif choice == "5":
  194. test_period(initial_seed, size, taps, non_linear_taps)
  195.  
  196. elif choice == "6":
  197. num_bits = int(input("Enter number of keystream bits to generate: "))
  198. generate_keystream(initial_seed, size, taps, non_linear_taps, num_bits)
  199.  
  200. else:
  201. print("Invalid choice.")
  202.  
  203.  
  204.  
  205.  
  206.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement