# Is it safe to use RSA as a proof-of-work system?

Suppose I devised the following challenge-response proof-of-work system:

A server generates a 2048-bit RSA modulus, and uses the "public" exponent (usually 65537) to sign a random nonce a fixed number of times, say, 256.

The server then sends the signed nonce to the client, along with the "private" exponent (which is much larger) and modulus, asking it to un-sign it using the private key 256 times, sending the answer back for the server to verify. Because the private operation takes about 300 times longer at 2048 bits, the client will take longer to un-sign the key than the server took to sign it.

Is this usable/secure? Or does the generation of the modulus outweigh any gains in the difference in signing time? If so, how could I make it usable, if at all?

-

"uses the public exponent to sign" - You lost me.  In RSA, signing always uses the private exponent, not the public exponent, so I'm not sure what you are referring to here.  Can you be more precise about exactly what the process is?  Are you calculating $((r^d)^d)^{...} = r^{d^{256}} \bmod n$, where $r$ is the random nonce and $d$ is the private exponent? – D.W. Jan 19 at 8:28
I should also ask: Why do you want to use RSA in particular, as opposed to any of the many other proof-of-work systems?  It is possible there might be other, even better ways to achieve your requirements, depending upon what your requirements may be.  I don't know if that interests you or not. – D.W. Jan 19 at 8:32
@D.W. This is a rather hypothetical question. Any public-key algorithm should work. – Joe Z. Jan 19 at 14:54
I think this scheme is broken; see my answer for details. – D.W. Jan 19 at 20:51

## 2 Answers

Edit: I just realized that the scheme that was proposed has serious security problems, and should not be used.

The question is rather confused and ambiguous, but there seems to be a serious security problem. If I understand the proposal correctly, you are giving the client the private exponent $d$ and the modulus $n$ and the iteration count $k$ (say, $k=256$) and a challenge $a$, and it is the client's job to respond with $$\textrm{proof} = a^{d^k} \bmod n.$$

This is not secure. Once the client knows $d$ and $n$, it is trivial to factor $n$ into $n=pq$. Thus the client learns the primes $p$ and $q$. Once the client knows this factorization, the scheme falls apart, as explained below.

In particular, the client can use the Chinese remainder theorem and Fermat's little theorem to greatly speed up the computation of the proof. First, the client works out the value of $\textrm{proof} \bmod p$, as follows: $$\textrm{proof} \equiv a^{d^k} \equiv a^{d'} \pmod p,$$ where $d' = d^k \bmod p-1$. Note that $d'$ can be computed efficiently: first we reduce $d$ modulo $p$, then we compute $d'$ using square-and-multiply (or another efficient exponentiation algorithm). Through a similar process, the client can recover the value of $\textrm{proof} \bmod q$. Finally, the client can combine these values using the Chinese remainder theorem to recover the value of $\textrm{proof} \bmod n$ and send it to the server.

How much work does the client have to do? If $k=256$ and $e=3$, the client does 8 squarings modulo $p-1$, 8 squarings modulo $q-1$, one modular exponentiation modulo $p$, one modular exponentiation modulo $q$, and then a Chinese remainder computation (which is very fast and basically requires one or two extended Euclidean algorithm computations on $\gcd(p,q)$). This is not much more work than the server has to do to create the challenge.

In summary: the client can solve the puzzle using not much more computation than it takes the server to create the puzzle in the first place. There are shortcut methods that the client can use to greatly speed up its computation, and as a result, the server has little or no advantage over the client. This is not a good proof-of-work system.

There are other ways to build proof-of-work schemes other than using RSA. Some of them are secure, and do give the server a major advantage over the client. For example, one standard scheme is to give the client a random 20-bit string $r$, and ask the client to respond with a value $x$ such that the first 20 bits of $\textrm{SHA256}(x)$ are equal to $r$. It will take the client about $2^{20}$ steps of computation to find such an $r$, but the server can check the client's answer very quickly -- merely by hashing a single value -- which is much faster than RSA.

Therefore, you should avoid the RSA scheme described in this question. Instead, use other proof-of-work schemes that have been more carefully vetted.

-

"However, I wanted to point out that there are other ways to build proof-of-work schemes other than using RSA. Some of them may be superior to RSA-based schemes." I know; I was just wondering whether that thing worked or not. – Joe Z. Jan 19 at 20:26
re: last edit, in fact I suspect the client can compute the proof asymptotically just as fast as the server can as $k$ increases, making the scheme useless. I will update my answer as well as it is now misleading. – Thomas Jan 19 at 21:02

Is this usable? Or does the generation of the modulus outweigh any gains in the difference in signing time?

No, it does not work. The generation cost itself isn't too important, because signing any one nonce doesn't help the client sign any other nonce, so you can just use a single key all the time (if you had to create a new keypair for every puzzle, this would be very impractical and nobody would use it).

But the problem is that the advantage of the server on the client is asymptotically more or less zero, so this is quite useless as a proof of work scheme. See D.W.'s answer for one way of breaking the scheme.

Another way similar to D.W.'s is to realize that your scheme requires the client to compute, given a random nonce $a$ and a work factor $k$, modulus $n$ and private exponent $d$:

$$\text{proof} = ((a^d)^d)^{\cdots ~ k ~ \text{times}} ~ \text{mod} ~ n$$

And this is equal to:

$$\text{proof} = a^{d^k} ~ \text{mod} ~ n$$

But because the client knows $d$ (you gave it to him!) he can factorize $n$ in constant time and compute $\varphi{(n)} = (p - 1)(q - 1)$, which gives him the ability to reduce the inner exponent:

$$\text{proof} = a^{d^k ~ \text{mod} ~ \varphi{(n)} } ~ \text{mod} ~ n$$

The client can calculate this in $\log{k}$ modular multiplications or squarings by $d$, and $\log{n}$ (on average) modular multiplications or squarings by $a$. But the server has to do pretty much the same amount of work - the only difference is it saves some time because $e$ is smaller than $d$. The gain is minimal and very difficult to control, since there's a point where you just can't make $e$ any smaller and need to increase $n$ to compensate.

In conclusion, this is not a good proof-of-work scheme, as it provides basically no control over the work factor desired and the server will need to work about just as much as the client for realistic values of $n$ and $k$.

If so, how could I make it usable, if at all?

However, it's possible to take your scheme a step further to make it cleaner (and not depend on RSA). The idea is to choose a "difficulty factor" $t$, a random number $a$, a large $n = pq$, and ask the client to compute:

$$\text{proof} = a^{2^t} ~ \text{mod} ~ n$$

The client will require $t$ squarings to achieve this (there is no known way to do better, and it cannot be parallelized to any significant degree), while the server, knowing the factorization of $n$ (since it generated it) can just compute:

$$e = 2^t ~ \text{mod} ~ \varphi{(n)}$$

And hence, from Euler's Theorem:

$$\text{proof} = a^e ~ \text{mod} ~ n$$

Which the server can then compute in logarithmic time. In effect, the server only needs $O(\log{nt})$ time, but the client needs $O(t)$ time. By making $t$ arbitrarily large, you can fine-tune the amount of work you want the client to do, linearly, but the work stays logarithmic for the server, which is practical.

The generation cost is also irrelevant, because the server can generate it once and reuse it all the time with different values of $a$ (that's not always true, but in this case it is - the attacker can't use the results of a previous proof of work to quickly solve another assuming $a$ is random and $n$ is large).

Note your scheme doesn't care if the client can factorize $n$ since you are basically giving away $d$, but in this scheme it is imperative that $n$ be large enough so that factorization is not possible. But this is easy to address, just create a 2048-bit modulus (or 4096-bit if you are paranoid) and be done with it.

For more details and supporting theory on this method, see:

Time-lock puzzles and timed-release Crypto, Ron Rivest, Adi Shamir, David Wagner.

Puzzle description for the MIT time capsule.

-
Another option is to have the server generate two primes and give the client the product of the two primes. The client must factor the product and return the smaller prime. – David Schwartz Jan 19 at 6:36

1
@DavidSchwartz Your proof of work scheme can be parallelized. – Thomas Jan 19 at 6:45
In the vast majority of realistic applications, any proof of work system can be parallelized simply by requesting many challenges from the server. – David Schwartz Jan 19 at 8:06

1
There are some math errors in here: $((a^d)^d)^{\cdots}$ is not the same as $a^{kd}$. Rather, it is $a^{d^k}$. – D.W. Jan 19 at 8:31
@D.W. Fixed, thank you. – Thomas Jan 19 at 8:43
show 1 more comment
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 70, "mathjax_display_tex": 8, "mathjax_asciimath": 0, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0}, "config": {"markdown_headings": true, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.18, "absolute_threshold": 10, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "github"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "english_confidence": 0.9388567209243774, "perplexity_flag": "middle"}