4

I'm trying to create an algorithm to find the public exponent e given a plain (non-CRT) private key that doesn't include the public exponent, i.e. I've only got $n$ and $d$.

A question has already been asked how easy it would be to find the public key given a private key. The answer was that it was likely to be easier, but none of the answers specify a good algorithm for RSA.

What would be the most efficient algorithm for finding the public exponent for RSA given the private key?

Maarten Bodewes
  • 92,551
  • 13
  • 161
  • 313
  • yes, I've got some ideas like checking the often used ones first and then check a simple encrypt/decrypt, but I would like the answers not to be influenced by my non-optimal ideas :) And yes, I am aware that this may be hard to do if the public exponent is very large, but this is not commonly the case. – Maarten Bodewes May 25 '15 at 15:37
  • so does one know $n$, does one know $p,q$, does one know $\varphi(n)=(p-1)(q-1)$ or is it supposed to be "without modulus"? – SEJPM May 25 '15 at 15:47
  • As calculating $e\equiv d^{-1} \pmod {\varphi(n)}$ would be too easy I guess a plain (non-CRT) private key consists solely of $(d,n)$. In this case all standard attacks against weak RSA private exponents would apply. – SEJPM May 25 '15 at 16:02
  • @SOJPM Right, that's the problem. I've got $n$ and $d$. Note that $n$ and $d$ are supposed to have been correctly calculated. If I could calculate $p$ and $q$ then my problems would disappear, but $p$ and $q$ calculation from $n$ and $d$ seems to rely on $e$ being available. – Maarten Bodewes May 25 '15 at 16:04
  • 2
    So you're in the exact same situation as if you would know $(e,n)$ and you would know that $d$ probably is rather small. There's no known algorithm to solve this problem fast in every circumstance, as this would mean you'd be able to break RSA. IMO the best route would be to try the most used $e$, like $3,17,2^{16}+1$, then brute-force the first $\approx 2^{32}$ ones and then try to apply Wieners's attack, if $log_2(e)<160$ – SEJPM May 25 '15 at 16:24
  • Yep, that's about the gist of it I guess. Would the best way of validating the most used ones to calculate $n$ from $p$ and $q$ and then compare? That seems slow, just performing modular exponentiation seems faster. – Maarten Bodewes May 25 '15 at 16:29
  • We know that for the correct $e, d$, we have $z^{ed} = z$. The obvious way to validate a $e$ is to select a random $z$, compute $z^d$, and then compare $(z^d)^e$ to $z$. This makes the brute-forcing of all $e < 2^{32}$ not too horribly expensive (as checking the next $e$ is just a modular multiplication and compare). If you want to put in the effort, using the big-step/little-step makes it practical to test this for all $e < 2^{64}$. However, if we know that $e> 2^{32}$, going directly to Weiner's may make more sense – poncho May 25 '15 at 16:33
  • You don't know $p,q$. If you would, you could calculate $e$ in poly-time. (If that wasn't what you meant with the above comment, then idk what you meant) The "check" algorithm I had in mind was to "decrypt" a message using your $d$ and then "re-encrypt" using the above mentioned order, maybe even in a "clever" way like $m \equiv m$? No? Use the previous $m, m^2, m^3$ and multiply by $m$ for the next check..., poncho was faster :( – SEJPM May 25 '15 at 16:35
  • I've no idea what you're talking about :) I just provided the reference. I hope wikipedia and the original paper will eliminate all problems. – SEJPM May 25 '15 at 17:04

1 Answers1

3

The fastest way to solve your problem instance is as outlined in the above comments.

First choose yourself a random message $m$ with $1<m<n-1$. Now compute $c\equiv m^d \pmod n$.

Try if any of the following equations holds, if an equation does hold you've found the public exponent $e$. $m \equiv c^3 \pmod n$
$m \equiv c^{17} \pmod n$
$m \equiv c^{65537} \pmod n$

If none of the above equations held you have two choices, based on the effort you're willing to spend and the probability that $e$ is rather small.

If you suspect $e<\frac{1}{3}N^{\frac{1}{4}}$, then you should use Wiener's attack on small decryption exponent RSA with the lost public exponent taking the role of the decryption exponent to find. Wikipedia explains the basics and Wiener's original attack.
As Maarten points out in the comments below this attack is very fast and consumes moderate amounts of memory.

If you think / know that $e<2^{40}$ and/or you're not willing to implement Wiener's attack you can use the following approach, as you can always come back to Wiener's attack in case you think that you've tried long enough.
The brute-force approach would work as follows ($i=3$, optimized using fgrieu's comment):

  1. Set $c_m \gets (c * c) \bmod n$,
  2. Check if $c \equiv m \pmod n$ or $c_m \equiv m \pmod n$, if the first holds, output 1, if the second holds, output 2.
  3. Set $c_3 \gets (c * c_m) \bmod n$
  4. Check if $c_{i}\equiv m \pmod n$ holds. If yes, output $i$
  5. Set $c_{i+2}\gets (c_i*c_m) \bmod n$, goto step 3

If you can not apply Wiener's attack and you consider brute-force "way too inefficient" there are still two methods left:

  1. Use your favorite factorization algorithm to factor $n$ and deduce $e$ from $(d,p,q)$
  2. Use your favorite discrete logarithm algorithm to solve $c^e \equiv m \pmod n$ for $e$.
SEJPM
  • 45,967
  • 7
  • 99
  • 205
  • Performing $m^d (\mod n)$ is much slower on my Java runtime than executing the entire Wiener attack :) – Maarten Bodewes May 25 '15 at 17:33
  • 1
    In the brute-force algorithm, step 2, there's $m$ where $c$ is wanted. Also things can be sped up by a factor of two: set $c_1\gets c$; compute $c_2\gets c\cdot c\bmod n$; then repeatdly for odd $i$ increasing from $3$, compute $c_i=c_{i-2}\cdot c_2\bmod n$, until that's $m$, in which case output $i$ which is the desired $e$. – fgrieu May 25 '15 at 17:37
  • 1
    Actually, if you think $2^{20} < e < 2^{40}$ is at all likely, then doing a Big Step/Little Step is feasible; for $n \approx 2^{20}$, you compute $m\cdot c^{-j}$ for odd $1 \le j < n$, and compute $c^{in}$ (for $0 \le i < n$), and scan the two lists for a common value; this checks all possible e's in the range $[1, n^2]$ in $O(n)$ time – poncho May 25 '15 at 18:13
  • @poncho I might not be able to implement this using this description alone, but I'll look into it. I guess that for most keys $e$ is within $1..2^{16} + 1$. I may be able to use Big Step/Little Step for values larger than $2^{16} + 1$ as Wiener's attack seems to eat memory (which is OK for single fire tools, but not so nice if it is part of a library). Maybe this is more a separate answer than a comment? – Maarten Bodewes May 25 '15 at 18:35
  • @fgrieu, thank you, added that to the brute-force approach. – SEJPM May 25 '15 at 18:41
  • @poncho, I'm not sure if you were aiming for that, but I added that DLP-solving algorithms work as well. – SEJPM May 25 '15 at 18:42
  • @MaartenBodewes, I think Pohlig-Hellman and Baby-Step/Giant-Step are applicable as well. (in the favorite DLP-solving section) – SEJPM May 25 '15 at 18:43
  • @SOJPM: stupid question (and this might be something to ask as a separate question) can Pohlig-Hellman be adapted to work in this scenario? We know the group is large (we don't know the exact size, but a good guess is that the order of $c$ is within a few bits of $n$), but we know (or at least suspect) that $c^e = m$ for some small $e$. How do we use Pohlig-Hellman work to search over small $e$'s, without stepping into the huge group? – poncho May 25 '15 at 19:34
  • @poncho, sorry didn't read my book well enough :( For Pohlig-Hellman we don't need the order to be prime (for pohlig-rho we do), but we still need the group order $n$ and it's factorization. – SEJPM May 25 '15 at 19:37
  • The Wiener attack implementation that I'm using seems fine up to & including 7FFFFFFF but it will fail after that. Does anybody know modern software that uses 32 bit values for $e$? Otherwise I'll just limit $e$ to 31 bit. I think older software either used $e$ fully random or $e = N$, but a fully random $e$ is impossible to calculate and I've personally never met $e = N$. – Maarten Bodewes May 25 '15 at 20:31
  • Well, in a recent (somewhat internal paper) I suggested using $e=2^{32}+2^{16}+2^2+1$ for GQ identity schemes, but in the real world I guess nobody ever even thinks about deviating from $e=65537$ for RSA... BTW why does the implementation use signed 32-bit integers? And I guess some libraries (like Crypto++) support arbitrary-exponent RSA but it's still extremely uncommon not to use 65337 as it's just a fast, nice, secure choice. If you have practical concerns I'd say 31-bit is enough. – SEJPM May 25 '15 at 20:38
  • 1
    Java is very much based on 32 bit signed integers. But I was wrong, I just tested 2^64 - 59 and that one worked too. I mistook the number of iterations with the actual number. It was pretty fast (~1s on my aging laptop) for that number as well and used only about 40K of memory, so for all practical values of $e$ the Wiener attack should suffice. – Maarten Bodewes May 25 '15 at 20:51
  • Based on your empirical studies, I've emphasized that Wiener's attack is superior to the other attacks in the most circumstances. – SEJPM May 25 '15 at 20:58
  • OK, by the way, that was for a 4Kib key. For 8Kib keys it's about 3.3 seconds, but in that case the calculation of $p$ and $q$ from $n$, $d$ and $e$ (unrelated) takes 4 times that. For completeness: this is an Intel T5670 (Core 2 Duo) ... I said old :). – Maarten Bodewes May 25 '15 at 21:18
  • "$<n$" should be replaced with "$<n-1$". $;$ –  May 25 '15 at 23:51