3

Suppose Bob has $k>1$ RSA public keys $(e_i, n_i)$ without any knowledge of their corresponding private keys. Alice also has all the public keys, but also has a private key for only one of them, say, $(d_j, n_j)$. Is it possible for her to prove to Bob that she has at least one of the private keys, without revealing $j$

EDIT: changed notation according to fgrieu suggestions

DeLorean88
  • 155
  • 4

2 Answers2

3

Yes, it is even possible without interaction (nothing Bob needs to send to Alice). The method is called "ring signature".

Let's say she wants to sign a message like "I am Alice an hereby proof to Bob that I know one of the keys". She hashes it to get $m$.

Alice now generates a random value $r_i$ for every public key $k_i$ and encrypts them to get $y_i$.

Note that they all $y_i$ are unpredictable pseudorandom values. The only $y_i$ she can choose is the one that belongs to her key $k_j$, she just chooses $y_j$ and sign it to get $r_j$ ($r_j$ looks like every other random data)

Now she can choose $y_j$ so that the xor of all $y_i$ equals $m$.

She sends the message and all the $r_i$ to Bob (if the order is not clear, add a note which $r_i$ belongs to which key)

To verify, Bob just encrypts every $r_i$ with the public key $k_i$ to get the $y_i$, xors them all and checks if it equals $m$.

Since all $y_i$ are like random numbers, when you don't know the key, there is no way to fake a signature without knowing a private key. Additionally there is no way to tell which $y_i$ and $r_i$ was not randomly generated, because they all look random.

Important EDIT: I forgot the symmetric encryption step in the ring signature. Between the xor steps symmetric encryption should be applied. This still allows allice to recover the $y_i$ she needs, but makes attacks harder. For more details look at Wikipedia

fgrieu
  • 149,326
  • 13
  • 324
  • 622
jjj
  • 469
  • 3
  • 8
2

Here is a proposal (out of my head). Big picture

  • Bob draws a random $X$, and sends it deterministically enciphered under each public key
  • Alice deciphers $X$ with the public key she holds
  • Alice checks Bob did as expected given that $X$
  • Alice reveals $X$ to Bob

More precisely:

  • Define a $8b$-bit hash (say SHA-512) such that $\min(n_i)>2^{16b}$
  • Define a Mask Generation Function (such as MGF1 with that hash) so that for bytestring $X$, $\operatorname{MGF}(X,\ell)$ is an $\ell$-byte hash of $X$
  • Define the byte lengths $\ell_i=\left\lfloor\log_2(n_i)/8\right\rfloor$, which are such that $2^{8\ell_i}<n_i<2^{8\ell_i+8}$ (in order to avoid timing attacks, it's desirable that the $n_i$ have the same bit size, thus the $l_i$ equal)
  • Bob draws a random $X\in\{0,1\}^{8b}$ (a $b$-byte bytestring)
  • For each $i$, Bob
    • computes $M_i=\operatorname{MGF}\bigl(X\mathbin\|H(n_i),l_i-b\bigr)$
    • computes $X_i=M_i\mathbin\|(X\oplus H(M_i\mathbin\|H(n_i)))$ (an $l_i$-byte bytestring)
    • computes and output $C_i={X_i}^{e_i}\bmod n_i$
  • Alice gets the $C_i$, including $C_j$
  • Alice computes $f={C_j}^{d_j}\bmod n_j$
  • Alice expresses $f$ as bytestring $M\mathbin\|G$ with $M$ of $l_i-b$ bytes and $G$ of $b$ bytes.
  • Alice recovers $X$ by computing $X=G\oplus H(M\mathbin\|J)$
  • For each $i$, Alice
    • computes $M_i=\operatorname{MGF}\bigl(X\mathbin\|H(n_i),l_i-b\bigr)$, where $I$ is index $i$ as a bytestring.
    • computes $X_i=M_i\mathbin\|(X\oplus H(M_i\mathbin\|H(n_i)))$ (an $l_i$-byte bytestring)
    • checks ${X_i}^{e_i}\bmod n_i=C_i$ (when $i=j$, this checks $M=\operatorname{MGF}\bigl(X\mathbin\|H(n_j),l_j-b\bigr)$ as a side effect)
  • Only if all the checks passed, and without revealing (e.g. by timing) where an error occurred if any, or which $X_i$ was used to recover $X$
    • Alice reveals $X$
  • Bob checks Alice revealed the right $X$

Rationale:

  • Alice proves she can decipher one of the cryptograms $C_i$, thus that she holds a private key
  • She does not reveal which, since she verified all the cryptograms match the same $X$. There is no risk that a bias in the high-order bits in some quantity in $[0,n_j)$ can give an advantage in guessing $j$ (as could be the case in a naive implementation of that other answer).
  • Representatives $X_i$ of $X$ are spread on $[0,n_i)$ as in RSASSA-OAEP, with independent padding functions. Notice that directly enciphering $X_i=X$, or $X_i=F(X)$ for some fixed injection $F$, would leave the system vulnerable to HÃ¥stad's broadcast attack; further, it could be impossible to define a safe common width for the $X_i$, e.g. if $n_0$ is 2048-bit, $n_1$ 8192-bit, $e_1=3$; the padding solves that.
  • Since $X$ is a challenge drawn by Bob, the protocol is immune to replay: Alice can't get away with data she precomputed before loosing access to her private key, or data previously computed by Amanda, who also holds a private key.

Possible improvements to further guard Alice from becoming a decryption oracle, Bob from tweaking its $X$, and perhaps make a proof easier:

  • Alice first draws $b$-byte $Y$ and sends a commitment $H(Y\mathbin\|S_0)$
  • Bob draws its $b$-byte $X$ and sends a commitment $H(X\mathbin\|S_1)$
  • Alice reveals $Y$, Bob checks it against $H(Y\mathbin\|0)$
  • the above protocol is modified
    • it's used $M_i=\operatorname{MGF}\bigl(X\mathbin\|Y\mathbin\|H(n_i),l_i-b\bigr)$
    • it's used $X_i=M_i\mathbin\|(X\oplus H(M_i\mathbin\|Y\mathbin\|H(n_i)))$
    • Alice further checks $H(X\mathbin\|1)$ matches
    • Alice reveals $H(X\mathbin\|S_2)$ rather than $X$
    • Bob checks that. (where the $S_i$ are distinct arbitrary short non-empty bytestrings)

Update: Another method, outlined in this other answer, is to use an RSA-based ring signature, and make Alice demonstrate to Bob her capacity to sign a challenge message.

fgrieu
  • 149,326
  • 13
  • 324
  • 622