whitelist: document the degenerate W = -P_i destination

This commit is contained in:
DarkWindman
2026-08-10 16:55:05 +03:00
parent 7ea12c2dca
commit 598e22dcde
2 changed files with 12 additions and 0 deletions

View File

@@ -113,6 +113,8 @@ SECP256K1_API int secp256k1_whitelist_signature_serialize(
* online_i + H(offline_i + whitelist)(offline_i + whitelist)
* for each public key pair (offline_i, offline_i). Here H means sha256 of the
* compressed serialization of the key.
*
* See secp256k1_whitelist_verify for the rationale on the degenerate destination W = -P_i.
*/
SECP256K1_API int secp256k1_whitelist_sign(
const secp256k1_context *ctx,
@@ -135,6 +137,13 @@ SECP256K1_API int secp256k1_whitelist_sign(
* offline_pubkeys: list of all offline pubkeys
* n_keys: the number of entries in each of the above two arrays
* sub_pubkey: the key to be whitelisted
*
* When the destination W equals -P_i for a whitelisted offline key, the tweak
* degenerates and the ring key collapses to K_i = Q_i, so the online key alone
* produces a valid proof for that destination. This is accepted deliberately:
* the output is spendable only by the holder of p_i (the discrete log of -P_i
* is -p_i), i.e. the offline half of the same whitelist entry, so no funds can
* be diverted.
*/
SECP256K1_API int secp256k1_whitelist_verify(
const secp256k1_context *ctx,

View File

@@ -117,6 +117,9 @@ static int secp256k1_whitelist_compute_keys_and_message(const secp256k1_context*
/* compute tweaked keys */
secp256k1_gej_set_ge(&tweaked_gej, &offline_ge);
secp256k1_gej_add_ge_var(&tweaked_gej, &tweaked_gej, &subkey_ge, NULL);
/* Fails only for the degenerate destination W = -P_i, where the ring
* key intentionally collapses to Q_i. See the rationale on
* secp256k1_whitelist_verify in include/secp256k1_whitelist.h. */
secp256k1_whitelist_tweak_pubkey(hash_ctx, &tweaked_gej);
secp256k1_gej_add_ge_var(&keys[i], &tweaked_gej, &online_ge, NULL);
}