Im trying to understand the maths in a RSA asymetric keys generation. I founded few articles in the web, and my idea is not very clear, so i came here with the hope to finally be able to complete an example.
I understand very well maths, but im a bit confused with the steps so i will go step by step until I understand.
I will try this example with numbers lower than 16[0..15] (4bits)
To encrypt/decript the message: "hello world"
Step 1: Select 2 randomly prime numbers
P= 11
Q= 5
Step 2: Calculate H [(P-1)*(Q-1)]
H = (11-1) * (5-1) = 10* 4= 40
Step 3: Select a random prime number lower than H (E) (I believe coprimes of H also works for E)
E = 7
And now?
We can continue from step 2:
Step 3) Select E such that Greatest Common Divisor(H,E)=1 and (1 < E < H)
In your example we have gcd(40,?)=1 and 1<?<40 --> 7 satisfies this, so we choose E=7
Step 4) Compute d such that (dE) mod H =1 and d<H
In the example we have (d*7) mod 40=1 and d< 40 so we get d= 23
Step 5) public key is {E,n} and private key is {d,n} in which n = P * Q.
In the example we have the public key={7,55} and the private key={23,55}
Step 6) Compute C= M^E(mod n) for encrypting in which M is the numerical representation of the message we want to encrypt.
In the example, we have to interpret M="hello world" as a number. Here, I assume it is equal to 39 for keeping it simple (this number should be less than n). You can refer to here to know more about how to encode a text to a numeric value.
C= 39 ^7 mod 55 = 19 (encrypted value of M)
Step 7) Compute M= C^d(mod n) for decrypting 19
In the example, we have M=19^23 mod 55 = 39 (the Message which should be decoded to "hello world").
I have this function to calculate log of returns. It works as expected.
def log_returns(prices):
return np.log(prices / prices.shift(1))
data.apply(lambda x: log_returns(x))
The values returned are very close to pct_change method. Is this expected?
data.pct_change()
It is, for small variations in the natural log are almost equal to percentage change, that's not a code issue.
Since :
log(A/B) = log(A) - log(B)
and in your case, A is equal to some small change e of B.
log(A/B) = log(A) - log(B) = log(B(1+e)) - log(B)
log(A/B) = log(B) + log((1+e)) - log(B) = log(1+e)
For small values of e, meaning that the log is a good approx. around 1
log(1+e) ≈ e
For a more mathy explanation, see this SO post.
See for yourself with this code :
import pandas as pd
import numpy as np
small = np.linspace(0.01, 0.1, 100)
df = pd.DataFrame({"vals" : small})
df["changes"] = df["vals"].pct_change()
df["log div"] = np.log(df["vals"]/df["vals"].shift())
diff_log = np.log(df["vals"]) - np.log(df["vals"].shift())
df["diff log"] = diff_log
diff_log = diff_log[~np.isnan(diff_log)]
log_div = df["log div"].dropna().values
assert(np.allclose(log_div, diff_log))
and df.head(10):
values changes log div diff log
0 0.010000 NaN NaN NaN
1 0.010909 0.090909 0.087011 0.087011
2 0.011818 0.083333 0.080043 0.080043
3 0.012727 0.076923 0.074108 0.074108
4 0.013636 0.071429 0.068993 0.068993
5 0.014545 0.066667 0.064539 0.064539
6 0.015455 0.062500 0.060625 0.060625
7 0.016364 0.058824 0.057158 0.057158
8 0.017273 0.055556 0.054067 0.054067
9 0.018182 0.052632 0.051293 0.051293
Yes, this is indeed not that strange. For a small y, it holds that y ≈ log (1+y). See for more information this Mathematics Exchange post.
A percentage change is calculated as xi+1/xi-1, whereas you calculate log(xi+1/xi). If we thus substitute y for y = xi+1/xi-1, we see the approximation pop up.
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.
I know I need to use the extended euclidean algorithm, but I'm not sure exactly what calculations I need to do. I have huge numbers. Thanks
Well, d is chosen such that d * e == 1 modulo (p-1)(q-1), so you could use the Euclidean algorithm for that (finding the modular multiplicative inverse).
If you are not interested in understanding the algorithm, you can just call BigInteger#modInverse directly.
d = e.modInverse(p_1.multiply(q_1))
Given that, p=11, q=7, e =17, n=77, φ (n) = 60 and d=?
First substitute values from the formula:-
ed mod φ (n) =1
17 d mod 60 = 1
The next step: – take the totient of n, which is 60 to your left hand side and [e] to your right hand side.
60 = 17
3rd step: – ask how many times 17 goes to 60. That is 3.5….. Ignore the remainder and take 3.
60 = 3(17)
Step 4: – now you need to balance this equation 60 = 3(17) such that left hand side equals to right hand side. How?
60 = 3(17) + 9 <== if you multiply 3 by 17 you get 51 then plus 9, that is 60. Which means both sides are now equal.
Step 5: – Now take 17 to your left hand side and 9 to your right hand side.
17 = 9
Step 6:- ask how many times 9 goes to 17. That is 1.8…….
17 = 1(9)
Step 7:- Step 4: – now you need to balance this 17 = 1(9)
17 = 1(9) + 8 <== if you multiply 1 by 9 you get 9 then plus 8, that is 17. Which means both sides are now equal.
Step 8:- again take 9 to your left hand side and 8 to your right hand side.
9 = 1(8)
9 = 1(8) + 1 <== once you reached +1 to balance your equation, you may stop and start doing back substitution.
Step A:-Last equation in step 8 which is 9 = 1(8) + 1 can be written as follows:
1.= 9 – 1(8)
Step B:-We know what is (8) by simple saying 8 = 17 – 1(9) from step 7. Now we can re-write step A as:-
1=9 -1(17 – 1(9)) <== here since 9=1(9) we can re-write as:-
1=1(9)-1(17) +1(9) <== group similar terms. In this case you add 1(9) with 1(9) – that is 2(9).
1=2(9)-1(17)
Step C: – We know what is (9) by simple saying 9 = 60 – 3(17) from step 4. Now we can re-write step B as:-
1=2(60-3(17) -1(17)
1=2(60)-6(17) -1(17) <== group similar terms. In this case you add 6(17) with 1(17) – that is 7(17).
1=2(60)-7(17) <== at this stage we can stop, nothing more to substitute, therefore take the value next 17. That is 7. Subtract it with the totient.
60-7=d
Then therefore the value of d= 53.
I just want to augment the Sidudozo's answer and clarify some important points.
First of all, what should we pass to Extended Euclidean Algorthim to compute d ?
Remember that ed mod φ(n) = 1 and cgd(e, φ(n)) = 1.
Knowing that the Extended Euclidean Algorthim is based on the formula cgd(a,b) = as + bt, hence cgd(e, φ(n)) = es + φ(n)t = 1, where d should be equal to s + φ(n) in order to satisfy the
ed mod φ(n) = 1 condition.
So, given the e=17 and φ(n)=60 (borrowed from the Sidudozo's answer), we substitute the corresponding values in the formula mentioned above:
cgd(e, φ(n)) = es + φ(n)t = 1 ⇔ 17s + 60t = 1.
At the end of the Sidudozo's answer we obtain s = -7. Thus d = s + φ(n) ⇔ d = -7 + 60 ⇒ d = 53.
Let's verify the results. The condition was ed mod φ(n) = 1.
Look 17 * 53 mod 60 = 1. Correct!
The approved answer by Thilo is incorrect as it uses Euler's totient function instead of Carmichael's totient function to find d. While the original method of RSA key generation uses Euler's function, d is typically derived using Carmichael's function instead for reasons I won't get into. The math needed to find the private exponent d given p q and e without any fancy notation would be as follows:
d = e^-1*mod(((p-1)/GCD(p-1,q-1))(q-1))
Why is this? Because d is defined in the relationship
de = 1*mod(λ(n))
Where λ(n) is Carmichael's function which is
λ(n)=lcm(p-1,q-1)
Which can be expanded to
λ(n)=((p-1)/GCD(p-1,q-1))(q-1)
So inserting this into the original expression that defines d we get
de = 1*mod(((p-1)/GCD(p-1,q-1))(q-1))
And just rearrange that to the final formula
d = e^-1*mod(((p-1)/GCD(p-1,q-1))(q-1))
More related information can be found here.
Here's the code for it, in python:
def inverse(a, n):
t, newt = 0, 1
r, newr = n, a
while newr:
quotient = r // newr # floor division
t, newt = newt, t - quotient * newt
r, newr = newr, r - quotient * newr
if r > 1:
return None # there's no solution
if t < 0:
t = t + n
return t
inverse(17, 60) # returns 53
adapted from pseudocode found in wiki: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Pseudocode
Simply use this formula,
d = (1+K(phi))/e. (Very useful when e and phi are small numbers)
Lets say, e = 3 and phi = 40
we assume K = 0, 1, 2... until your d value is not a decimal
assume K = 0, then
d = (1+0(40))/3 = 0. (if it is a decimal increase the K value, don't bother finding the exact value of the decimal)
assume K = 2, then
d = (1+2(40)/3) = 81/3 = 27
d = 27.
Assuming K will become exponentially easy with practice.
Taken the values p=7, q=11 and e=17.
then the value of n=p*q=77 and f(n)=(p-1)(q-1)=60.
Therefore, our public key pair is,(e,n)=(7,77)
Now for calvulating the value of d we have the constraint,
e*d == 1 mod (f(n)), [here "==" represents the **congruent symbol**].
17*d == 1 mod 60
(17*53)*d == 53 mod 60, [7*53=901, which gives modulus value 1]
1*d == 53 mod 60
hence,this gives the value of d=53.
Therefore our private key pair will be, (d,n)=(53,77).
Hope this help. Thank you!
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