I fully understand the how the RSA algorithm works, but now I am trying to reason with the formula. I want to know:
why the public key e and the private key d in the RSA encryption have to satisfy the equation ed = 1 mod (p − 1)(q − 1)?
Is it because of the standard modular arithmetic rule where 1 mod anything is 1, or is there a more to this answer?
Say you have a message called x and you want to encrypt it with your public key (pq, e). If you encrypt x, you get x^e mod pq. Someone who knows d can get x^(ed) mod pq.
Because ed = 1 mod (p - 1)(q - 1), by Fermat's little theorem, we get that x^(ed) mod pq = x, thus decrypting the message. If ed != 1 mod (p - 1)(q - 1), then the message could not be decrypted.
A link to Fermat's little theorem:
https://en.wikipedia.org/wiki/Fermat%27s_little_theorem
Related
I'm trying to create an implementation of the Pohlig-Hellman algorithm in order to create a utility to craft / exploit backdoors in implementations of the Diffie-Hellman protocol. This project is inspired by this 2016 white-paper by NCC Group.
I currently have an implementation, here, that works for relatively small exponents – i.e. Given a linear congruence, g^x = h (mod n), for some specially-crafted modulus, n = pq, where p and q are prime, my implementation can solve for values of x smaller than min{ p, q }.
However, if x is larger than the smallest prime factor of n, then my implementation will give an incorrect solution. I suspect that the issue may not be with my implementation of Pohlig-Hellman, itself, but with the arguments I am passing to it. All the code can be found at the link, provided above, but I'll copy the relevant code snippets, here:
#
# Implementation of Pohlig-Hellman algorithm
#
# The `crt` function implements the Chinese Remainder Theorem, and the `pollard` function implements
# Pollard's Rho algorithm for discrete logarithms (see /dph/crt.py and /dph/pollard.py).
#
def pohlig(G, H, P, factors):
g = [pow(G, divexact(P - 1, f), P) for f in factors]
h = [pow(H, divexact(P - 1, f), P) for f in factors]
if Config.verbose:
x = []
total = len(factors)
for i, (gi, hi) in enumerate(zip(g, h), start=1):
print('Solving discrete logarithm {}/{}...'.format(str(i).rjust(len(str(total))), total))
result = pollard(gi, hi, P)
x.append(result)
print(f'x = 0x{result.digits(16)}')
else:
x = [pollard(gi, hi, P) for gi, hi in zip(g, h)]
return crt(x, factors)
Above is my implementation of Pohlig-Hellman, and below is where I call it to exploit a backdoor in some implementation of the Diffie-Hellman protocol.
def _exp(args):
g = args.g
h = args.h
p_factors = list(map(mpz, args.p_factors.split(',')))
try:
p_factors.remove(2)
except ValueError:
pass
q_factors = list(map(mpz, args.q_factors.split(',')))
try:
q_factors.remove(2)
except ValueError:
pass
p = 2 * _product(*p_factors) + 1
q = 2 * _product(*q_factors) + 1
if Config.verbose:
print(f'p = 0x{p.digits(16)}')
print(f'q = 0x{q.digits(16)}')
print()
print(f'Compute the discrete logarithm modulo `p`')
print(f'-----------------------------------------')
px = pohlig(g % p, h % p, p, p_factors)
if Config.verbose:
print()
print(f'Compute the discrete logarithm modulo `q`')
print(f'-----------------------------------------')
qx = pohlig(g % q, h % q, q, q_factors)
if Config.verbose:
print()
x = crt([px, qx], [p, q])
print(f'x = 0x{x.digits(16)}')
Here is a summary of what I am doing:
Choose a prime p = 2 * prod{ p_i } + 1, where p_i denotes a set of primes.
Choose a prime q = 2 * prod{ q_j } + 1, where q_j denotes a set of primes.
Inject n = pq as the backdoor modulus in some implementation of Diffie-Hellman.
Wait for a victim (e.g. Alice computes A = g^a (mod n), and Bob computes B = g^b (mod n)).
Solve for Alice's or Bob's secret exponent, a or b, and compute their shared secret key, K = A^b = B^a (mod n).
Step #5 is done by performing the Pohlig-Hellman algorithm twice to solve for x (mod p) and x (mod q), and then the Chinese Remainder Theorem is used to solve for x (mod n).
EDIT
The x that I am referring to in the description of step #5 is either Alice's secret exponent, a, or Bob's secret exponent, b, depending on which we choose to solve for, since only one is needed to compute the shared secret key, K.
I have been given the question:
"Decrypt this message using RSA: 072 062 120 129 (Hint you will need to convert your final answer from ASCII to plain text.
The public key used to encrypt the message was (n, e) = (143, 7)."
I don't have any clue how to decrypt it, and this is the only information we have been given. However, I do know that p and q are 13 and 11, which you can get from finding 2 primes that multiply to make n.
Does anyone know how to decrypt this?
Thanks in advance, this has been kind of overwhelming.
You can use the wikipedia article as a guide.
From p and q you can compute λ(n):
λ(n) = lcm(p-1, q-1) = lcm(12, 10) = 60
Once you know λ(n), you can use it to calculate d, the multiplicative inverse of e modulo λ(n):
d = e⁻¹ (mod λ(n))
This essentially means finding a natural number d, such that d*e = 1 (mod 60).
The following snippet of Python code does that:
d = next(d for d in range(60) if d*7 % 60 == 1)
The value of d is 43.
Once we have d, we can use that to decrypt the individual numbers of the message:
decrypted_ascii = [(x**d) % 143 for x in [72, 62, 120, 129]]
decrypted_text = ''.join(chr(x) for x in decrypted_ascii)
The decrypted text is Text.
The goal is to have a encryption like:
c = m^e mod n
where c = m
I messed up in my conclusion by estimating that e=1 or e=4^x when 4^x < n, the second part is not true and a result of messy written code.
For better understanding:
c= encryptet Text
m= plain Text
n= the procuct of two primes
There is no reason for an arbitrary message m to have m^{4^x} = m mod n
A counterexample;
n=47∗43=2021
5^{4^2} = 1803 mod 2021 , see at WolframAlpha
import math
for m in range(1,2020):
for e in (4**x for x in range(1, int(math.log(2021,4))) ):
if (m**(e) % 2021) == m:
print (m,e)
With this python code you can see the examples for the specific modulus 2021.
As you can see many of the cases happens
(423, 4)
(423, 16)
(423, 64)
(423, 256)
Now, the reason is clear if you remember the RSA definition.
the e must have an inverse in phi(n). See live at WolframAlpha
So this choice of e is not RSA.
Note since phi(n) = (p-1)(q-1), any even e cannot be a public modulus.
How can I calculate the private key(d)?
The problem is that d(private key) has to be an int number but I keep getting d=0.0000152585.. Help please?
p=92092076805892533739724722602668675840671093008520241548191914215399824020372076186460768206814914423802230398410980218741906960527104568970225804374404612617736579286959865287226538692911376507934256844456333236362669879347073756238894784951597211105734179388300051579994253565459304743059533646753003894559
q=97846775312392801037224396977012615848433199640105786119757047098757998273009741128821931277074555731813289423891389911801250326299324018557072727051765547115514791337578758859803890173153277252326496062476389498019821358465433398338364421624871010292162533041884897182597065662521825095949253625730631876637
e=65537
n=9010912747277787249738727439840427055736519196538871349093408340706668231808840540195374015916168031416186859836416053338250477003776576736854137538279810042409758765948034443613881324504120707334213544491046703922409406729564516371394804946909037646047891880347940067132730874804943893719672960932378043325067514786209219718314429979032869544980643978919561908707109629612202311323626173343456843249212057093980583352634168733656443959925428846968193413110401346035535595817965624054783296380268863401241570313602685481219583686719199499297832165308522137209299081956650614940546284136240753995440003473611843518083
ϕ(n)=9010912747277787249738727439840427055736519196538871349093408340706668231808840540195374015916168031416186859836416053338250477003776576736854137538279810042409758765948034443613881324504120707334213544491046703922409406729564516371394804946909037646047891880347940067132730874804943893719672960932378043324975422709403327184574705256430200869139972885911041667158917715396802487303254097156996075042397142670178352954223188514914536999398324277997967608735996733417799016531005758767556757687357486893307313469146352244856913807372125743058937380356924926103564902568350563360552030570781449252380469826858839623524
So with the formula:
d=e-1 mod ϕ(n)
I keep getting 0.0000152585. Any ideas?
You need to use the Modular Multiplicative Inverse, not the inverse.
Here is an example in python using the cryptography module.
from cryptography.hazmat.primitives.asymmetric.rsa import _modinv
p=92092076805892533739724722602668675840671093008520241548191914215399824020372076186460768206814914423802230398410980218741906960527104568970225804374404612617736579286959865287226538692911376507934256844456333236362669879347073756238894784951597211105734179388300051579994253565459304743059533646753003894559
q=97846775312392801037224396977012615848433199640105786119757047098757998273009741128821931277074555731813289423891389911801250326299324018557072727051765547115514791337578758859803890173153277252326496062476389498019821358465433398338364421624871010292162533041884897182597065662521825095949253625730631876637
e=65537
phi = (p-1) * (q-1)
d = _modinv(e, phi)
print(d) # 1405046269503207469140791548403639533127416416214210694972085079171787580463776820425965898174272870486015739516125786182821637006600742140682552321645503743280670839819078749092730110549881891271317396450158021688253989767145578723458252769465545504142139663476747479225923933192421405464414574786272963741656223941750084051228611576708609346787101088759062724389874160693008783334605903142528824559223515203978707969795087506678894006628296743079886244349469131831225757926844843554897638786146036869572653204735650843186722732736888918789379054050122205253165705085538743651258400390580971043144644984654914856729
print((e * d) % phi) # 1
You can find the implementation of _modinv() here.
By fips.186-4 standard, you have to use λ not φ in RSA;
λ(n)=lcm(p−1,q−1)
to calculate d= e-1 mod λ(n) you must use extendedGCD algorithm.
find x and y that satisfify Bezout Identity
e x + λ(n) y = gcd(e,λ(n))
e x -1 = (-y)λ(n)
take mod λ(n)
e x ≡ 1 mod λ(n)
Let's say we have a encryption function like this :
f(x) = x^5 mod 21
How can I get the plain text from the encrypted text which generated by this function? How can I denote the decryption function?
Is this homework? If so, you should tag it homework, and accept answers on some of your past questions.
This looks like RSA, where the modulus is the product of two primes (i.e. n = p*q). Just follow the steps of the algorithm.In this case, n = 21 = 7*3. This tells you phi(n) = (6*2) = 12.
If 5 is the encrypting exponent (e), and phi(n) = 12, then to calculate the decrypting exponent, you need to find d such that e*d = 1 (mod phi(n)). Written another way, e-1 = d (mod phi(n)). You can do this with the PowerMod function in Mathematica: PowerMod[5, -1, 12].
Once you know the modular inverse, the rest becomes easy:
c = (m)^5 mod 21
m = (c)^d mod 21