-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path70. A primitive root for 2*5^n.py
130 lines (95 loc) · 2.57 KB
/
70. A primitive root for 2*5^n.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
def primitive_root_for_2_5_n(n):
"""
Finds a primitive root modulo 2 * 5^n.
Args:
n: The exponent.
Returns:
A primitive root modulo 2 * 5^n.
"""
# Check if n is a positive integer.
if n <= 0:
return None
# Find a primitive root modulo 5^n.
primitive_root_mod_5_n = technical_lemma_2(5**n)
# Check if the primitive root modulo 5^n is also a primitive root modulo 2 * 5^n.
if is_primitive_root(primitive_root_mod_5_n, 2 * 5**n):
return primitive_root_mod_5_n
else:
return None
def is_primitive_root(a, n):
"""
Checks if the integer a is a primitive root modulo n.
Args:
a: The integer.
n: The modulus.
Returns:
True if the integer a is a primitive root modulo n, False otherwise.
"""
# Check if a is an integer greater than 1 and less than n.
if a <= 1 or a >= n:
return False
# Check if the order of a modulo n is n - 1.
order_of_a = order_of_integer(a, n)
if order_of_a != n - 1:
return False
# Check if a is a primitive root modulo n.
for i in range(2, n):
if pow(a, i) % n == 1:
return False
return True
def order_of_integer(a, n):
"""
Calculates the order of the integer a mod n.
Args:
a: The integer.
n: The modulus.
Returns:
The order of the integer a mod n.
"""
# Initialize the order to 0.
order = 0
# Iterate over all positive integers.
for i in range(1, n):
# If a^(i * d) is congruent to 1 mod n, then the order of a mod n is i * d.
if pow(a, i * order) % n == 1:
return i * order
return order
def technical_lemma_2(p):
"""
Finds all primitive roots modulo p.
Args:
p: The modulus.
Returns:
A list of all primitive roots modulo p.
"""
# Check if p is an odd prime number.
if p % 2 == 0 or not is_prime(p):
return []
# Find all primitive roots modulo p.
primitive_roots_mod_p = []
for i in range(2, p):
if is_primitive_root_2(i, p):
primitive_roots_mod_p.append(i)
return primitive_roots_mod_p
def is_primitive_root_2(a, p):
"""
Checks if the integer a is a primitive root modulo p.
Args:
a: The integer.
p: The modulus.
Returns:
True if the integer a is a primitive root modulo p, False otherwise.
"""
# Check if a is an integer greater than 1 and less than p.
if a <= 1 or a >= p:
return False
# Check if the order of a modulo p is (p - 1) / 2.
order_of_a = order_of_integer_2(a, p)
if order_of_a != (p - 1) / 2:
return False
# Check if a is a primitive root modulo p.
for i in range(2, p):
if pow(a, i) % p == 1:
return False
return True
def