Multiplicative order: Difference between revisions
(Clarified task; added Haskell example; removed Java example; added notes to J example) |
(Description from Bach & Shallit) |
||
Line 2: | Line 2: | ||
{{clarified-review}} |
{{clarified-review}} |
||
The '''multiplicative order''' of ''a'' relative to ''m'' is the least positive integer ''n'' such that ''a^n'' is 1 (modulo ''m''). |
<p>The '''multiplicative order''' of ''a'' relative to ''m'' is the least positive integer ''n'' such that ''a^n'' is 1 (modulo ''m''). |
||
For example, the multiplicative oder of 37 relative to 1000 is 100 because 37^100 is 1 (modulo 1000), and no number smaller than 100 would do. |
For example, the multiplicative oder of 37 relative to 1000 is 100 because 37^100 is 1 (modulo 1000), and no number smaller than 100 would do. An algorithm can be found in |
||
Bach & Shallit, <i>Algorithmic Number Theory, Volume I: Efficient Algorithms</i>, The MIT Press, 1996.</p> |
|||
Note that the multiplicative order is undefined if ''a'' and ''m'' are not relatively prime. |
|||
<p>Exercise 5.8, page 115:</p> |
|||
One possible algorithm that is efficient also for large numbers is the following: By the [http://en.wikipedia.org/wiki/Chinese_Remainder_Theorem Chinese Remainder Theorem], it's enough to calculate the multiplicative order for each prime exponent ''p^k'' of ''m'', and |
|||
combine the results with the ''least common multiple'' operation. |
|||
Now the order of ''a'' wrt. to ''p^k'' must divide ''Φ(p^k)''. Call this number ''t'', and determine it's factors ''q^e''. Since each multiple of the order will also yield 1 when used as exponent for ''a'', it's enough to find the least d such that ''(q^d)*(t/(q^e))'' yields 1 when used as exponent. |
|||
<p>Suppose you are given a prime<tt> p </tt>and a complete factorization |
|||
Implement a routine to calculate the multiplicative order along these lines. You may assume that routines to determine the factorization into prime powers are available in some library. |
|||
of<tt> p-1</tt> .<tt> </tt>Show how to compute the order of an |
|||
element<tt> a </tt>in<tt> (Z/(p))* </tt>using<tt> O((lg p)<sup>4</sup>/(lg lg p)) </tt>bit |
|||
operations.</p> |
|||
<p>Solution, page 337:</p> |
|||
⚫ | |||
<p>Let the prime factorization of<tt> p-1 </tt> |
|||
The dyadic verb ''mo'' converts it's arguments to exact numbers ''a'' and ''m'', executes ''mopk'' on the factorization of ''m'', and combines the result with the ''least common multiple'' operation. |
|||
be<tt> q1<sup>e1</sup>q2<sup>e2</sup>...qk<sup>ek</sup></tt> .<tt> </tt>We use |
|||
the following observation: |
|||
if<tt> x^((p-1)/qi<sup>fi</sup>) = 1 (mod p)</tt> ,<tt> </tt> |
|||
and<tt> fi=ei </tt>or<tt> x^((p-1)/qi<sup>fi+1</sup>) != 1 (mod p)</tt> ,<tt> </tt> |
|||
then<tt> q<sup>ei-fi</sup>||ord<sub>p</sub> x</tt> .<tt> </tt> |
|||
(This follows by combining Exercises 5.1 and 2.10.) |
|||
Hence it suffices to find, for each<tt> i</tt> ,<tt> </tt>the exponent<tt> fi </tt> |
|||
such that the condition above holds.</p> |
|||
<p>This can be done as follows: first compute<tt> q1<sup>e1</sup>, q2<sup>e2</sup>, ... , |
|||
qk<sup>ek</sup></tt> .<tt> </tt> |
|||
This can be done using<tt> O((lg p)<sup>2</sup>) </tt>bit operations. Next, |
|||
compute<tt> y1=(p-1)/q1<sup>e1</sup>, ... , yk=(p-1)/qk<sup>ek</sup></tt> .<tt> </tt> |
|||
This can be done using<tt> O((lg p)<sup>2</sup>) </tt>bit operations. |
|||
Now, using the binary method, |
|||
compute<tt> x1=a<sup>y1</sup>(mod p), ... , xk=a<sup>yk</sup>(mod p) </tt>.<tt> </tt> |
|||
This can be done using<tt> O(k(lg p)<sup>3</sup>) </tt>bit operations, |
|||
and<tt> k=O((lg p)/(lg lg p)) </tt>by Theorem 8.8.10. |
|||
Finally, for each<tt> i</tt> ,<tt> </tt>repeatedly raise<tt> xi </tt>to |
|||
the<tt> qi</tt>-th power<tt> (mod p) </tt>(as many as<tt> ei-1 </tt> times), |
|||
checking to see when 1 is obtained. |
|||
This can be done using<tt> O((lg p)<sup>3</sup>) </tt>steps. |
|||
The total cost is dominated by<tt> O(k(lg p)<sup>3</sup>)</tt> ,<tt> </tt> |
|||
which is<tt> O(k(lg p)<sup>4</sup>/(lg lg p))</tt> . |
|||
⚫ | |||
mo=: 4 : 0 |
mo=: 4 : 0 |
||
Line 22: | Line 50: | ||
*./ a mopk"1 |: __ q: m |
*./ a mopk"1 |: __ q: m |
||
) |
) |
||
The dyadic verb ''mopk'' expects a pair of prime and exponent |
|||
in the second argument. It sets up a verb ''pm'' to calculate |
|||
powers module ''p^k''. Then calculates ''Φ(p^k)'' as ''t'', |
|||
factorizes it again into ''q'' and ''e'', and calculates |
|||
''a^(t/(q^e))'' as ''x''. Now, it finds the least ''d'' such that subsequent application of ''pm'' yields ''1'' (this line could do with a more detailed explanation). Finally, it combines the |
|||
exponents ''q^d'' into a product. |
|||
mopk=: 4 : 0 |
mopk=: 4 : 0 |
Revision as of 06:21, 10 December 2007
You are encouraged to solve this task according to the task description, using any language you may know.
The multiplicative order of a relative to m is the least positive integer n such that a^n is 1 (modulo m). For example, the multiplicative oder of 37 relative to 1000 is 100 because 37^100 is 1 (modulo 1000), and no number smaller than 100 would do. An algorithm can be found in Bach & Shallit, Algorithmic Number Theory, Volume I: Efficient Algorithms, The MIT Press, 1996.
Exercise 5.8, page 115:
Suppose you are given a prime p and a complete factorization of p-1 . Show how to compute the order of an element a in (Z/(p))* using O((lg p)4/(lg lg p)) bit operations.
Solution, page 337:
Let the prime factorization of p-1 be q1e1q2e2...qkek . We use the following observation: if x^((p-1)/qifi) = 1 (mod p) , and fi=ei or x^((p-1)/qifi+1) != 1 (mod p) , then qei-fi||ordp x . (This follows by combining Exercises 5.1 and 2.10.) Hence it suffices to find, for each i , the exponent fi such that the condition above holds.
This can be done as follows: first compute q1e1, q2e2, ... , qkek . This can be done using O((lg p)2) bit operations. Next, compute y1=(p-1)/q1e1, ... , yk=(p-1)/qkek . This can be done using O((lg p)2) bit operations. Now, using the binary method, compute x1=ay1(mod p), ... , xk=ayk(mod p) . This can be done using O(k(lg p)3) bit operations, and k=O((lg p)/(lg lg p)) by Theorem 8.8.10. Finally, for each i , repeatedly raise xi to the qi-th power (mod p) (as many as ei-1 times), checking to see when 1 is obtained. This can be done using O((lg p)3) steps. The total cost is dominated by O(k(lg p)3) , which is O(k(lg p)4/(lg lg p)) .
J
mo=: 4 : 0 a=. x: x m=. x: y assert. 1=a+.m *./ a mopk"1 |: __ q: m )
mopk=: 4 : 0 a=. x: x 'p k'=. x: y pm=. (p^k)&|@^ t=. (p-1)*p^k-1 NB. totient 'q e'=. __ q: t x=. a pm t%q^e d=. (1<x)+x (pm i. 1:)&> (e-1) */\@$&.> q */q^d )
For example:
37 mo 1000 100 2 mo _1+10^80x 190174169488577769580266953193403101748804183400400
Haskell
Assuming a function to calculate prime power factors,
primeFacsExp :: Integer -> [(Integer, Int)]
and another function
powerMod :: (Integral a, Integral b) => a -> a -> b -> a powerMod m _ 0 = 1 powerMod m x n | n > 0 = f x' (n-1) x' where x' = x `rem` m f _ 0 y = y f a d y = g a d where g b i | even i = g (b*b `rem` m) (i `quot` 2) | otherwise = f b (i-1) (b*y `rem` m) powerMod m _ _ = error "powerMod: negative exponent"
to efficiently calculate powers modulo some integral, we get
multOrder a m | gcd a m /= 1 = error "Arguments not coprime" | otherwise = foldl1' lcm $ map (multOrder' a) $ primeFacsExp m multOrder' a (p,k) = r where pk = p^k t = (p-1)*p^(k-1) -- totient \Phi(p^k) r = product $ map find_qd $ primeFacsExp $ t find_qd (q,e) = q^d where x = powerMod pk a (t `div` (q^e)) d = length $ takeWhile (/= 1) $ iterate (\y -> powerMod pk y q) x