Skip to content

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

include/secp256k1_schnorrsig.h

+57
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,63 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify(
273273
const secp256k1_xonly_pubkey *pubkey
274274
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(5);
275275

276+
/** Schnorr Anti-Exfil Protocol
277+
*
278+
* The secp256k1_schnorrsig_anti_exfil_*, functions can be used to prevent a signing device from
279+
* exfiltrating the secret signing keys through biased signature nonces. The general
280+
* idea is that a host provides additional randomness to the signing device client
281+
* and the client commits to the randomness in the nonce using sign-to-contract.
282+
*
283+
* The following scheme is described by Stepan Snigirev here:
284+
* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-February/017655.html
285+
* and by Pieter Wuille (as "Scheme 6") here:
286+
* https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-March/017667.html
287+
*
288+
* In order to ensure the host cannot trick the signing device into revealing its
289+
* keys, or the signing device to bias the nonce despite the host's contributions,
290+
* the host and client must engage in a commit-reveal protocol as follows:
291+
* 1. The host draws randomness `rho` and computes a sha256 commitment to it using
292+
* `secp256k1_schnorrsig_anti_exfil_host_commit`. It sends this to the signing device.
293+
* 2. The signing device computes a public nonce `R` using the host's commitment
294+
* as auxiliary randomness, using `secp256k1_schnorrsig_anti_exfil_signer_commit`.
295+
* The signing device sends the resulting `R` to the host as a s2c_opening.
296+
*
297+
* If, at any point from this step onward, the hardware device fails, it is
298+
* okay to restart the protocol using **exactly the same `rho`** and checking
299+
* that the hardware device proposes **exactly the same** `R`. Otherwise, the
300+
* hardware device may be selectively aborting and thereby biasing the set of
301+
* nonces that are used in actual signatures.
302+
*
303+
* It takes many (>100) such aborts before there is a plausible attack, given
304+
* current knowledge in 2024. However such aborts accumulate even across a total
305+
* replacement of all relevant devices (but not across replacement of the actual
306+
* signing keys with new independently random ones).
307+
*
308+
* In case the hardware device cannot be made to sign with the given `rho`, `R`
309+
* pair, wallet authors should alert the user and present a very scary message
310+
* implying that if this happens more than even a few times, say 20 or more times
311+
* EVER, they should change hardware vendors and perhaps sweep their coins.
312+
*
313+
* 3. The host replies with `rho` generated in step 1.
314+
* 4. The device signs with `secp256k1_schnorrsig_sign_custom`, using `rho` as `s2c_data32` of the
315+
* extraparams, and sends the signature to the host.
316+
* 5. The host verifies that the signature's public nonce matches the opening from
317+
* step 2 and its original randomness `rho`, using `secp256k1_schnorrsig_anti_exfil_host_verify`.
318+
*
319+
* Rationale:
320+
* - The reason for having a host commitment is to allow the signing device to
321+
* deterministically derive a unique nonce even if the host restarts the protocol
322+
* using the same message and keys. Otherwise the signer might reuse the original
323+
* nonce in two iterations of the protocol with different `rho`, which leaks the
324+
* the secret key.
325+
* - The signer does not need to check that the host commitment matches the host's
326+
* claimed `rho`. Instead it re-derives the commitment (and its original `R`) from
327+
* the provided `rho`. If this differs from the original commitment, the result
328+
* will be an invalid `s2c_opening`, but since `R` was unique there is no risk to
329+
* the signer's secret keys. Because of this, the signing device does not need to
330+
* maintain any state about the progress of the protocol.
331+
*/
332+
276333
/** Verify a sign-to-contract commitment.
277334
*
278335
* Returns: 1: the signature contains a commitment to data32

0 commit comments

Comments
 (0)