diff --git a/include/secp256k1_whitelist.h b/include/secp256k1_whitelist.h index 760b719a..e2f82173 100644 --- a/include/secp256k1_whitelist.h +++ b/include/secp256k1_whitelist.h @@ -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, diff --git a/src/modules/whitelist/whitelist_impl.h b/src/modules/whitelist/whitelist_impl.h index f26c255c..10b6e6d4 100644 --- a/src/modules/whitelist/whitelist_impl.h +++ b/src/modules/whitelist/whitelist_impl.h @@ -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); }