PRIMES_64 = [
(0x3a00000000000001, 57, 29), (0x8e00000000000001, 57, 71), (0x9600000000000001, 57, 75), ]
MAX_LOG_N_64 = 57
PRIMES_32 = [
(0x1c000001, 26, 7), (0x78000001, 27, 15), (0x88000001, 27, 17), ]
MAX_LOG_N_32 = 26
def mod_pow(base, exp, mod):
result = 1
while exp > 0:
if exp & 1:
result = (result * base) % mod
base = (base * base) % mod
exp >>= 1
return result
def mod_inv(a, mod):
return mod_pow(a, mod - 2, mod)
def factorize(n):
factors = []
d = 2
m = n
while d * d <= m:
if m % d == 0:
factors.append(d)
while m % d == 0:
m //= d
d += 1 if d == 2 else 2 if m > 1:
factors.append(m)
return factors
def is_primitive_root(g, p, factors_of_pm1):
for q in factors_of_pm1:
if mod_pow(g, (p - 1) // q, p) == 1:
return False
return True
def find_primitive_root(p):
factors = factorize(p - 1)
for g in range(2, min(p, 2000)):
if is_primitive_root(g, p, factors):
return g
raise ValueError(f"No primitive root found for p = {p} (tried up to 2000)")
def compute_omega(p, g, max_log_n):
assert (p - 1) % (1 << max_log_n) == 0, \
f"max_log_n={max_log_n} does not divide p-1 for p={p:#x}"
exp = (p - 1) >> max_log_n
return mod_pow(g, exp, p)
def verify_omega(omega, p, max_log_n):
w = omega
for _ in range(max_log_n - 1):
w = (w * w) % p
assert w == p - 1, f"omega^(2^{max_log_n-1}) != -1 mod p, got {w:#x}"
w = (w * w) % p
assert w == 1, f"omega^(2^{max_log_n}) != 1 mod p, got {w:#x}"
def compute_crt_constants(primes):
k = len(primes)
crt = [[0] * k for _ in range(k)]
for i in range(k):
for j in range(i + 1, k):
pi = primes[i]
pj = primes[j]
crt[i][j] = mod_inv(pi % pj, pj)
return crt
def print_results(name, primes_data, max_log_n):
primes = [p for p, _, _ in primes_data]
print(f"===== {name} =====")
print(f" MAX_LOG_N = {max_log_n}")
print()
for i, (p, n, k) in enumerate(primes_data):
print(f" PI={i}: p = {p:#018x} ({k} * 2^{n} + 1)")
v2 = ((p - 1) & -(p - 1)).bit_length() - 1 print(f" v2(p-1) = {v2}")
print()
for i, (p, n, k) in enumerate(primes_data):
print(f" PI={i}: finding primitive root...")
g = find_primitive_root(p)
omega = compute_omega(p, g, max_log_n)
verify_omega(omega, p, max_log_n)
print(f" g = {g}")
bit_width = 64 if max_log_n == 57 else 32
print(f" omega_max = {omega:#0{bit_width//4 + 2}x}")
print()
crt = compute_crt_constants(primes)
bit_width = 64 if max_log_n == 57 else 32
print(f" CRT_INV_IJ:")
for i in range(len(primes)):
for j in range(len(primes)):
if crt[i][j] != 0:
print(f" inv(p{i} mod p{j}) = {crt[i][j]:#0{bit_width//4 + 2}x}")
prod_01 = primes[0] * primes[1]
print(f"\n p0 * p1 = {prod_01:#x}")
print()
if __name__ == "__main__":
print_results("64-bit", PRIMES_64, MAX_LOG_N_64)
print_results("32-bit", PRIMES_32, MAX_LOG_N_32)