Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blinded Paths are probe-able #3117

Closed
TheBlueMatt opened this issue Jun 11, 2024 · 9 comments · Fixed by #3139
Closed

Blinded Paths are probe-able #3117

TheBlueMatt opened this issue Jun 11, 2024 · 9 comments · Fixed by #3139
Assignees
Milestone

Comments

@TheBlueMatt
Copy link
Collaborator

See #3085 (comment) We probably need to get this done ASAP in the next release since this will invalidate all existing offers.

@TheBlueMatt TheBlueMatt added this to the 0.0.124 milestone Jun 11, 2024
@jkczyz jkczyz self-assigned this Jun 12, 2024
@jkczyz
Copy link
Contributor

jkczyz commented Jun 18, 2024

We discussed offline possible including a 16-byte nonce in each BlindedPath and using this when deriving Offer::signing_pubkey. However, we already include an encrypted nonce in Offer::metadata. If we include the same nonce in each BlindedPath, we could simply check that this nonce matches the nonce in the metadata (after decrypting it) when handling an InvoiceRequest. @TheBlueMatt Is this sufficient?

@TheBlueMatt
Copy link
Collaborator Author

Isn't the metadata in Offer visible to senders? They'd be able to use that to build a blinded path to candidate nodes and probe still, I think.

@jkczyz
Copy link
Contributor

jkczyz commented Jun 18, 2024

Oh, actually the Nonce isn't encrypted. I was confusing that with the PaymentId in the payer metadata. But we use the nonce when encrypting that.

@jkczyz
Copy link
Contributor

jkczyz commented Jun 18, 2024

I had been thinking if it were encrypted with the ExpandedKey then we could check against it... but we'd still need some nonce for doing the actual encryption, so I guess that wouldn't work.

@TheBlueMatt
Copy link
Collaborator Author

Is there some world where we could drop the metadata from Offer and use the one in the blinded path instead?

@jkczyz
Copy link
Contributor

jkczyz commented Jun 18, 2024

We use the one in the metadata to verify the offer, and computing it requires knowing all the fields (including the paths) in advance. So we'd need to exclude the paths from verification and only construct them when calling OfferBuilder::build, which would entail having the user pass a MessageRouter or not expose the builder at all in the ChannelManager usage.

Hmm... might also be a problem for offers with no amount and description since no other fields would be set? Though maybe having the unique nonce is sufficient?

There's also the case where no paths are given (i.e., deriving metadata for verification and signing using the node id), so we'd need to conditionally set the metadata then.

@TheBlueMatt
Copy link
Collaborator Author

I was thinking basically we'd put a nonce in the blinded path (and in the offer if there's no BP, I guess), then do basically H(offer || nonce) as the key derivation secret.

@jkczyz
Copy link
Contributor

jkczyz commented Jun 18, 2024

Ah, so IIUC we are essentially doing H(offer || nonce) already:

hmac: expanded_key.hmac_for_offer(nonce, iv_bytes),

And deriving the secret after including the offer TLVs in the HMAC:

Metadata::DerivedSigningPubkey(mut metadata_material) => {
tlv_stream.write(&mut metadata_material.hmac).unwrap();
let secp_ctx = secp_ctx.unwrap();
let (metadata, keys) = metadata_material.derive_metadata_and_keys(secp_ctx);
(Metadata::Bytes(metadata), Some(keys))
},

let hmac = Hmac::from_engine(self.hmac);
let privkey = SecretKey::from_slice(hmac.as_byte_array()).unwrap();
let keys = Keypair::from_secret_key(secp_ctx, &privkey);

So we'd simply keep the metadata empty and use the same nonce in the blinded paths. When handling a request, we'd pass the received nonce to InvoiceRequest::verify instead of using the now-empty metadata. Do I have that right?

@TheBlueMatt
Copy link
Collaborator Author

TheBlueMatt commented Jun 18, 2024

I think that works, yea. Its even backwards compatible (if we want to bother) because we can keep accepting our old offers by accepting the metadata but we wont generate new offers with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants