If n and a are coprime and positive,
The exponent is Euler's totient function.
It counts the number of integers less than n that are coprime to it.
(in general)
(if p is prime)
if:
then:
If p is prime, then Euler's theorem contains Fermat's as a special case:
So let's pick a = 2. If that monster number is prime, then we expect it to be 1 mod p.
Thus we know the number is composite!
(But no idea what its factors are)
In crypto, calculating these numbers raised to large powers happens all the time. Here's an example of the algorithm.
Let's calculate:
Expand the exponent in base-2:
Notice how each subsequent term involves squaring the previous one (sometimes multiple times)
def expmod(g, A, m):
bits = bin(A)[2:][::-1]
a = []
for i, bit in enumerate(bits):
a.append(g%m)
g = (g%m) * (g%m)
res = 1
for i, bit in enumerate(bits):
res *= a[i]**(int(bit)) % m
res %= m
return res
print expmod(3, 218, 1000)
$ python expmod.py
489Write the exponent in binary.
Then reading the bits from right to left, you can build a table of intermediate products, taking mods at each step.
(assuming e, c, and N are known)
The difficulty of this problem accounts for the security of RSA.
However, it's feasible to solve this problem if N is prime, or you know its factors.
Let p and q be distinct prime numbers,
and let e be coprime to (p-1)(q-1).
Then e has an inverse mod (p-1)(q-1):
Then, the unique solution is:
(by Euler's theorem)
(definition of inverse)
Not all numbers have an inverse mod N.
An inverse for a number g mod N exists if and only if g and N are coprime.
So 4 has an inverse mod 15. Since
4 is its own inverse! (mod 15)
So 7 has an inverse mod 11. Since
Euclid's algorithm for the GCD can also give you numbers u,v that satisfy
def egcd(a,b):
"""Extended GCD algorithm"""
if b == 0:
return (a, 1, 0)
else:
g, x, y = egcd(b, a%b)
u = y
v = x - (a/b)*y
assert a*u + b*v == g
GCD = namedtuple('GCD', 'gcd u v')
return GCD(gcd = g, u = y, v = x - (a/b)*y)
print egcd(18,24)
$ python gcd.py
GCD(gcd=6, u=-1, v=1)The definition of an inverse of x mod m is a number y such that
But the definition of mod means this is equivalent to
or
Given that x and m are coprime, we can use Euclid's algorithm to find y (and k, which we don't care about)
Thus 1583 and 7918 are coprime, and we can use Euclid's algorithm.
def invmod(a, m):
assert gcd(a,m) == 1
g = egcd(a,m)
result = g.u
# find the smallest positive solution
while result < 0:
result += m
return result
$ python invmod.py
5277
>>> (5277 * 1583) % 7918
1Is 30069476293 prime?
Since it's not congruent to 1, it's not prime.
This problem is really hard to solve.
But: what if I told you how to factor this number?
>>> n = 30069476293
>>> print expmod(2, n-1, n)
18152503626>>> 104729 * 287117
30069476293Now it's easy to solve!
"Let p and q be distinct prime numbers,
and let e be coprime to (p-1)(q-1)."
Is 9843 coprime to
(104729-1)(287117-1)?
>>> e = 9843
>>> p = 104729
>>> q = 287117
>>> print gcd(e, (p-1)*(q-1))
1Yep.
Use Euclid's algorithm
to get d:
>>> print invmod(e, (p-1)*(q-1))
18472798299 # mod (p-1)(q-1)>>> print expmod(134872, 18472798299, 30069476293)
25470280263Let's say Alice wants to send a message securely to Bob without Eve knowing the contents.
First, Bob has picked two big prime numbers, p and q. He keeps these secret!
Second, Bob picks another positive number e (for encryption exponent) that is coprime to (p-1)(q-1). Publish N = pq and e somewhere. This is his public key.
She sends the ciphertext to Bob. Eve can see it too, but she can't decrypt it because this problem is really hard. Finally, Bob can decrypt Alice's message by calculating:
Third, Alice takes her message m and computes the ciphertext c, encrypted with Bob's public key (N,e):
where:
Bob picks p and q.
He also picks e such that it's coprime to (p-1)(q-1).
>>> e = 948047
>>> p = 1223
>>> q = 1987
>>> print gcd(e, (p-1)*(q-1))
1So (2430101, 948047) is Bob's public key.
Alice wants to send Bob the message m = 1070777.
She calculates:
>>> print expmod(1070777, 948047, 2430101)
1473513She sends Bob the encrypted message 1473513.
Eve sees 1473513 and thinks, "Huh, just gibberish."
Bob can decrypt this ciphertext since he knows p and q. First, he calculates d, the decryption exponent using Euclid's algorithm:
>>> print invmod(e, (p-1)*(q-1))
1051235Now he can recover the message:
>>> print expmod(1473513, 1051235, 2430101)
1070777Bob sees 1070777 and thinks, "Oh, that makes obvious sense."
I skipped over very important implementation details. A really great book for mathematical cryptography is:
Introduction to Mathematical Cryptography, by
Hoffstein, Pipher, Silverman. My examples all came straight from this book.
Another is Koblitz's Number Theory and Cryptography. Koblitz is a leader in the field and co-created elliptic curve crypto (for another time).
RSA needs very very large primes. If you pick a random number, how can you see if it's prime?
-Fermat's Little Theorem, Miller-Rabin Test
RSA depends on the difficulty of factorization. How well can we factor numbers?
-Pollard's p-1 algorithm:
-Difference of squares:
-Quadratic and number field sieve: