import random import math import sys def even(n): return n % 2 == 0 # Use the Miller-Rabin algorithm to test primality of x def is_prime(x, k): # Base cases if even(x): return False if x in [2, 3]: return True # Determine s and t s = 0 t = x - 1 while even(t): s += 1 t //= 2 # Gather witnesses witnesses = [random.randrange(2, x - 1) for _ in range(k)] for w in witnesses: if power_mod(w, x - 1, x) != 1: # Basic Fermat test return False for i in range(1, s + 1): # Advanced test if Fermat fails if power_mod(w, 2 ** i * t, x) == 1 and power_mod(w, 2 ** (i - 1) * t, x) not in [1, x - 1]: return False return True # All witnesses must agree to get here # Use repeated-squaring method to determine: base^power % mod def power_mod(base, power, mod): binary = bin(power) squares = [base % mod] # Start with base case result = squares[0] if binary[-1] == "1" else 1 for i in range(1, math.floor(math.log2(power)) + 1): squares.append(squares[i - 1] ** 2 % mod) if binary[-i - 1] == "1": result *= squares[i] return result % mod # Generate a twin prime of bit length m. Only tests values of 6x±1. def generate_twin_prime(m): twin = False while not twin: start, end = bit_range(m) n = random.randrange(start + 6 - (start % 6), end, 6) # Only test m bit ints that are multiples of 6 num_witnesses = max(4, math.ceil(math.log(n, 4))) # Based on probability 4^{-k} that a witness will be wrong. twin = is_prime(n - 1, num_witnesses) and is_prime(n + 1, num_witnesses) # Check twin on either side of 6x return n - 1, n + 1 # Tuple containing range for bit length m def bit_range(m): return 2 ** (m - 1), 2 ** m # Write a twin in the correct format to file def write_twin(twin): with open("output_twin_prime.txt", "w") as file: file.write(f"{twin[0]}\n{twin[1]}") def main(): assert len(sys.argv) >= 2 twin = generate_twin_prime(int(sys.argv[1])) write_twin(twin) print(twin) if __name__ == "__main__": main()