Homepage › Solution manuals › Ivan Niven › An Introduction to the Theory of Numbers › Exercise 2.9.8* (Cubic roots modulo $p$)
Exercise 2.9.8* (Cubic roots modulo $p$)
Suppose that with and . Show that if then the order of is a power of if and only if the congruence has a solution. If then put . If then put . Show that in either case, , and that the order of is a power of , say . Choose so that , and set . Show that has order exactly , and that there is an integer , such that . Show that one of the numbers has order , and that the order of the other one is a smaller power of , say . Let denote this number with smaller order. Determine so that . Continuing in this manner, construct an algorithm for computing the solutions of the congruence .
Answers
Proof.
- (a)
-
Suppose that
with
and
.
Let be the field with elements. Then is an abelian group, and
are group homomorphisms. We show first that
We estimate the orders of the subgroups and . Let a generator of . For any , for some integer , where , and
Since the order of is ,
where the elements are distinct, thus .
Similarly,
Therefore
and .
By the first isomorphism theorem, , thus
Moreover, if , then for some . Therefore
thus . This shows that
where , hence
So, for every ,
We write the order of in the group . It remains to shows the equivalence
- If , then , thus for some .
- Conversely, if , since , then , where , hence , thus , and .
Combining (1) and (2), we obtain for every ,
If we translate (3) in , we obtain, for every integer such that (using ):
The congruence has a solution if and only if the order of modulo is a power of .
Note that those integers are the integers such that . Write the subgroup . By part (a),
- (b)
-
We want to solve the congruence
, where
. This congruence has a solution if and only if
. Indeed, if
, then
. Conversely, suppose that
. Let
be a primitive root modulo
. Then
for some positive integer
, so that
. The order of
is
, therefore
, thus
, so
for some positive integer
, and
, with
.
We assume now that the condition
so that we know that the congruence has a solution.
-
If , then is an integer. Put
Then
Moreover implies by part (a) that the order of modulo is a power of .
The condition (4) is equivalent to .
-
If , then is an integer. Put
Then
Moreover, implies by part (a) that the order of modulo is a power of .
The condition (4) gives . Conversely, if , then , and .
In both cases, , and , so the order of is a power of , say , where . The condition is a necessary and sufficient condition to the existence of a solution of the congruence .
-
- (c)
-
Choose
so that
. Such an element
exists: let
be a primitive root modulo
(
is a generator of
). Thus
for some integer
. Then
Take , where (for instance ). Then .
(To find such a , we can use a probabilistic algorithm. If we take a random , the probability that is , so we find quickly such a , the average of the waiting time being . )
Now set . Then , thus , where the order of is . We show that the order of is .
Since
and
the order of modulo is . Since , and the order is is , is a generator of the subgroup .
Since , for some , , thus
- (d)
-
Suppose that
. Since the order of
is
, the order of
is
(
, and
). Since the order
of
is equal to the order of
, by Problem 6, one of the numbers
has order
, and the order of the other one is a smaller power of
, say
.
From , we deduce
Put
so that in both cases , where
We continue until one of the number is congruent to modulo , say . Then , so that is a solution of the congruence .
To obtain the other roots, we note that is equivalent to , where is a particular solution. Therefore the solutions are , where is a solution of .
To solve in , we use . Moreover, for all ,
If is a square root of in , obtained with the RESSOL algorithm (if such a root exists, that is if ), we obtain
The inverse of is , thus a root of if is
Since , the roots are . So, for all ,
(See the algorith below.)
Here is our (non optimized) code in Python on jupyter-lab to obtain the list of cubic roots. The function “ressol” used here is written in the solution of Problem 4.
def cubic_roots_of_unity(p):
"""input : prime p>3
output : list of the roots of x^3 = 1 mod p
"""
if p % 3 == 2:
return [1]
omega = (((p+1) // 2) * (ressol(-3,p) - 1)) % p
return [1,omega , omega ** 2 % p]
def cubic_roots(a,p):
"""input : prime p>3, integer a
output : list of the roots of x^3 = 1 mod p
"""
def exponent_order(x):
" output: k such that o(x) = 3^k"
i = 0
npower = x
while npower != 1:
npower = (npower ** 3) % p
i = i + 1
return i
if a == 0: return [0]
if p % 3 == 2:
return [pow(a, (2*p - 1) // 3, p)]
# (p % 3 = 1)
if pow(a, (p-1) // 3, p) != 1:
return []
m, k = p - 1, 0
while m % 3 == 0:
m //= 3
k += 1
found = False
while not found:
z = randint(1, p - 1)
if pow(z,(p-1) // 3, p) != 1:
found = True
c = pow(z, m , p)
if m % 3 == 2:
r = pow(a, (m + 1) // 3, p)
n = pow(a, m, p)
else:
r = pow(a, (2 * m + 1) // 3, p)
n = pow(a, 2 * m, p)
while n != 1:
i = exponent_order(n)
b = pow(c, 3 ** (k - i), p)
u, v = (n * b) % p, (n * b ** 2) % p
if exponent_order(u) < exponent_order(v):
n = u
r = (r * pow(c, 3 ** (k-i-1), p)) % p
else:
n = v
r = (r * pow(c, 2 * 3 ** (k-i-1), p)) % p
return [(r * omega) % p for omega in cubic_roots_of_unity(p)]
p = 1234567891
print(cubic_roots(15, p))
[915966894, 170527222, 148073775]
print((148073775 ** 3) % p, (915966894 ** 3) % p, (170527222 ** 3) % p))
(15, 15, 15)
% timeit cubic_roots(15, p)
per loop (mean std. dev. of 7 runs, loops each)