lightningd: use tweak on node_id of different key, for createinvoicerequest.

It's an internal difference, so doesn't actually break compatibility
(it would if we tried to prove we owned an old invoicerequest, but we
don't have infrastructure for that anyway).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2024-08-01 09:33:36 +09:30
parent fa33a2fece
commit 74ef03d361
7 changed files with 38 additions and 48 deletions

View File

@ -218,23 +218,3 @@ void sighash_from_merkle(const char *messagename,
sha256_update(&sctx, merkle, sizeof(*merkle));
sha256_done(&sctx, sighash);
}
/* We use the SHA(pubkey | publictweak); so reader cannot figure out the
* tweak and derive the base key.
*/
void payer_key_tweak(const struct pubkey *bolt12,
const u8 *publictweak, size_t publictweaklen,
struct sha256 *tweak)
{
u8 rawkey[PUBKEY_CMPR_LEN];
struct sha256_ctx sha;
pubkey_to_der(rawkey, bolt12);
sha256_init(&sha);
sha256_update(&sha, rawkey, sizeof(rawkey));
sha256_update(&sha,
memcheck(publictweak, publictweaklen),
publictweaklen);
sha256_done(&sha, tweak);
}

View File

@ -21,12 +21,4 @@ void sighash_from_merkle(const char *messagename,
const char *fieldname,
const struct sha256 *merkle,
struct sha256 *sighash);
/**
* payer_key_tweak - get the actual tweak to use for a payer_key
*/
void payer_key_tweak(const struct pubkey *bolt12,
const u8 *publictweak, size_t publictweaklen,
struct sha256 *tweak);
#endif /* LIGHTNING_COMMON_BOLT12_MERKLE_H */

View File

@ -730,6 +730,21 @@ static u8 *handle_sign_option_will_fund_offer(struct hsmd_client *c,
return towire_hsmd_sign_option_will_fund_offer_reply(NULL, &sig);
}
static void payer_key_tweak(const struct pubkey *bolt12,
const u8 *publictweak, size_t publictweaklen,
struct sha256 *tweak)
{
u8 rawkey[PUBKEY_CMPR_LEN];
struct sha256_ctx sha;
pubkey_to_der(rawkey, bolt12);
sha256_init(&sha);
sha256_update(&sha, rawkey, sizeof(rawkey));
sha256_update(&sha, publictweak, publictweaklen);
sha256_done(&sha, tweak);
}
/*~ lightningd asks us to sign a bolt12 (e.g. offer). */
static u8 *handle_sign_bolt12(struct hsmd_client *c, const u8 *msg_in)
{

View File

@ -87,6 +87,7 @@ struct ext_key *hsm_init(struct lightningd *ld)
int fds[2];
struct ext_key *bip32_base;
u32 hsm_version;
struct pubkey unused;
/* We actually send requests synchronously: only status is async. */
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0)
@ -142,7 +143,7 @@ struct ext_key *hsm_init(struct lightningd *ld)
&hsm_version,
&ld->hsm_capabilities,
&ld->our_nodeid, bip32_base,
&ld->bolt12_base)) {
&unused)) {
/* nothing to do. */
} else {
if (ld->config.keypass)

View File

@ -151,10 +151,7 @@ struct lightningd {
struct node_id our_nodeid;
struct pubkey our_pubkey;
/* The public base for our payer_id keys */
struct pubkey bolt12_base;
/* Secret base for our invoices */
/* Secret base for our invoices. */
struct secret invoicesecret_base;
/* Secret base for node aliases */

View File

@ -56,12 +56,16 @@ static void hsm_sign_b12(struct lightningd *ld,
{
const u8 *msg;
struct sha256 sighash;
/* Needs to be a (non-nul-terminated) tal_arr */
const u8 *info = tal_dup_arr(tmpctx, u8,
(const u8 *)NODE_ALIAS_BASE_STRING,
strlen(NODE_ALIAS_BASE_STRING), 0);
msg = towire_hsmd_sign_bolt12(NULL, messagename, fieldname, merkle,
publictweak);
msg = towire_hsmd_sign_bolt12_2(NULL, messagename, fieldname, merkle,
info, publictweak);
msg = hsm_sync_req(tmpctx, ld, take(msg));
if (!fromwire_hsmd_sign_bolt12_reply(msg, sig))
fatal("HSM gave bad sign_offer_reply %s",
if (!fromwire_hsmd_sign_bolt12_2_reply(msg, sig))
fatal("HSM gave bad sign_bolt12_2 %s",
tal_hex(msg, msg));
/* Now we sanity-check! */
@ -361,10 +365,11 @@ static bool payer_key(struct lightningd *ld,
{
struct sha256 tweakhash;
payer_key_tweak(&ld->bolt12_base, public_tweak, public_tweak_len,
*key = ld->our_pubkey;
bolt12_alias_tweak(&ld->nodealias_base,
public_tweak, public_tweak_len,
&tweakhash);
*key = ld->bolt12_base;
return secp256k1_ec_pubkey_tweak_add(secp256k1_ctx,
&key->pubkey,
tweakhash.u.u8) == 1;

View File

@ -5246,13 +5246,13 @@ def test_payerkey(node_factory):
"""payerkey calculation should not change across releases!"""
nodes = node_factory.get_nodes(7)
expected_keys = ["02294ec1cd3f100947fe859d71a42cb87932e36e7771abf2d50b02a7a92be8e4d5",
"026a4a3b6b0c694da6f14629ca5140713fc703591a6d8aae5c79ba9b5556fc5723",
"03defd2b1f3004b0145351f469f34512c6fa4d02fe891a977bafdb34fe7b73ea48",
"03eccb00c0a3c760465bb69a6297d7cfa5bcbd989d5a88e435bd8d6e4c723013cd",
"021b4bfa652f0df7498d734b0ca888b4e3b07f59e1a974ec7d4a9d6046e8e5ab92",
"03fc91d60b061e517f9182e3e40ea14c27df520c51db204f1409ff50e5cf9a5e4d",
"03a3bbda0137722ba62207b9d3e5e6cc2a11e58480f801892093e01383aacb7fb2"]
expected_keys = ["035e43e4ec029ee6cc0e320ebefdf863bc0f284ec0208275f780837d17e21bba32",
"02411811b24f4940de49ad460ee14ecb96810e29ca49cdd3600a985da2eda06b87",
"036a19f00424ff244af1841715e89f3716c08f1f62a8e5d9bd0f69a21aa96a7b8d",
"026d8b82fe6039fe16f8ef376174b630247e821331b90620315a1e9c3db8384056",
"0393fb950e04916c063a585aa644df3d72642c16de4eb44ccf5dbede194836140f",
"030b68257230f7057e694222bbd54d9d108decced6b647a90da6f578360af53f7d",
"02f402bd7374a1304b07c7236d9c683b83f81072517195ddede8ab328026d53157"]
for n, k in zip(nodes, expected_keys):
b12 = n.rpc.createinvoicerequest('lnr1qqgz2d7u2smys9dc5q2447e8thjlgq3qqc3xu3s3rg94nj40zfsy866mhu5vxne6tcej5878k2mneuvgjy8ssqvepgz5zsjrg3z3vggzvkm2khkgvrxj27r96c00pwl4kveecdktm29jdd6w0uwu5jgtv5v9qgqxyfhyvyg6pdvu4tcjvpp7kkal9rp57wj7xv4pl3ajku70rzy3pu', False)['bolt12']