Given the following RSA keys, how does one go about determining what the values of p and q are?
Public Key: (10142789312725007, 5)
Private Key: (10142789312725007, 8114231289041741)
Given the following RSA keys, how does one go about determining what the values of p and q are?
Public Key: (10142789312725007, 5)
Private Key: (10142789312725007, 8114231289041741)
Wolframalpha tells me that the factors are 100711409 and 100711423
I just wrote a naive Python script to bruteforce it. As amdfan pointed out, starting from the top is a better approach:
This could be heavily improved, but it still works without a problem. You could improve it by just testing primfactors, but for small values like yours this should be enough.
These two papers could possibly come in useful
Came across them when I was doing some basic research on continued fractions.
Sorry for the necromancy, but a friend asked me about this, and after pointing him here, I realized that I didn't really like any of the answers. After factoring the modulus and getting the primes (p and q), you need to find the totient, which is
(p-1)*(q-1)
.Now, to find the private exponent, you find the inverse of the public exponent mod the totient.
And now you have your private key, that easy. All of this except for the factorization can be done almost instantly for huge integers.
I wrote some code:
The factorization algorithm I used is stupid, but concise, so grain of salt there. In this particular example the code runs almost instantly, but that is largely because the instructor in question provided an example that uses two primes in a row, which isn't really realistic for RSA.
If you wanted to cut out my stupid iterative search, you could put in some real factorization algorithm, and factor keys likely up to around 256 bits in a reasonable amount of time.
I suggest you read about the Quadratic Sieve. If you implement one yourself, this is surely worth the credit. If you understand the principles, you already gained something.
The algorithm to do this is (and this will work for any example, not only this small one that can be factored easily by any computer):
ed - 1
is a multiple ofphi(n) = (p-1)(q-1)
, so is at least a multiple of 4.ed - 1
can be computed as 40571156445208704 which equals2^7 * 316962159728193
, and we calls=7
andt = 316962159728193
. (in general: any even number is a power of 2 times an odd number). Now pick a in[2,n-1)
at random, and compute (by successive squaring modulon
) the sequencea^t (mod n), a^(2t) (mod n), a^(4t) (mod n)..
until at mosta^((2^7)*t) (mod n)
, where the last one is guaranteed to be 1, by the construction ofe
andd
.We now look for the first 1 in that sequence. The one before it will either be
+1
or-1
(a trivial root of 1,mod n
) and we redo with a different a, or some numberx
which does not equal+1
or-1
mod n
. In the latter casegcd(x-1, n)
is a non-trivial divisor ofn
, and sop
orq
, and we are done. One can show that a random a will work with probability about 0.5, so we need a few tries, but not very many in general.You need to factorize the modulus, that's the first parameter of the public key, 10142789312725007. Brute force will do (check every odd number from 3 to sqrt(n) if it's a factor), although more sophisticated/fast algorithms exist.
Since the number is too big to fit into a conventional integer (even 64-bit), you might want a numeric library that supports arbitrary-lenth integers. For C, there's GMP and MPIR (more Windows-friendly). For PHP, there's Bignum. Python comes with a built-in one - the built-in integer datatype is already arbitrary-length.