Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 480
Onion messages v1#1503
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
Uh oh!
There was an error while loading. Please reload this page.
Onion messages v1 #1503
Changes from all commits
4e5381a33ff27460173794c8dc2c9051c38bf007eab26fb85eaff5616500c9939397d417ec697File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -27,6 +27,7 @@ use bitcoin::hash_types::WPubkeyHash; | ||
| use bitcoin::secp256k1::{SecretKey, PublicKey}; | ||
| use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature, Signing}; | ||
| use bitcoin::secp256k1::ecdh::SharedSecret; | ||
| use bitcoin::secp256k1::ecdsa::RecoverableSignature; | ||
| use bitcoin::{secp256k1, Witness}; | ||
| @@ -404,6 +405,12 @@ pub trait KeysInterface { | ||
| /// This method must return the same value each time it is called with a given `Recipient` | ||
| /// parameter. | ||
| fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()>; | ||
| /// Gets the ECDH shared secret of our [`node secret`] and `other_key`, multiplying by `tweak` if | ||
| /// one is provided. Note that this tweak can be applied to `other_key` instead of our node | ||
| /// secret, though this is less efficient. | ||
| /// | ||
| /// [`node secret`]: Self::get_node_secret | ||
| fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&[u8; 32]>) -> Result<SharedSecret, ()>; | ||
| /// Get a script pubkey which we send funds to when claiming on-chain contestable outputs. | ||
| /// | ||
| /// This method should return a different value each time it is called, to avoid linking | ||
| @@ -1133,6 +1140,14 @@ impl KeysInterface for KeysManager { | ||
| } | ||
| } | ||
| fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&[u8; 32]>) -> Result<SharedSecret, ()> { | ||
| let mut node_secret = self.get_node_secret(recipient)?; | ||
| if let Some(tweak) = tweak { | ||
| node_secret.mul_assign(tweak).map_err(|_| ())?; | ||
| } | ||
| Ok(SharedSecret::new(other_key, &node_secret)) | ||
| } | ||
| fn get_inbound_payment_key_material(&self) -> KeyMaterial { | ||
| self.inbound_payment_key.clone() | ||
| } | ||
| @@ -1217,6 +1232,14 @@ impl KeysInterface for PhantomKeysManager { | ||
| } | ||
| } | ||
| fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&[u8; 32]>) -> Result<SharedSecret, ()> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So actually I think you could have a feature combining route blinding + phantom node, where if you select one of the real node as the introduction node, any other node part of the phantom node should be able to decrypt the next I think it would increase the receiver confidentiality as a) if the onion sender doesn't have knowledge of the phantom set, she shouldn't be able to observe the "onion swap" between the phantoms and b) even if the onion sender does have knowledge of the phantom set, this should increase the receiver anonymity set by the topology of any real node. Just an idea for the future, I don't know if it holds. ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool, noted this in the follow-up issue #1607 | ||
| let mut node_secret = self.get_node_secret(recipient)?; | ||
| if let Some(tweak) = tweak { | ||
| node_secret.mul_assign(tweak).map_err(|_| ())?; | ||
| } | ||
| Ok(SharedSecret::new(other_key, &node_secret)) | ||
| } | ||
| fn get_inbound_payment_key_material(&self) -> KeyMaterial { | ||
| self.inbound_payment_key.clone() | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -31,6 +31,8 @@ use bitcoin::blockdata::script::Script; | ||
| use bitcoin::hash_types::{Txid, BlockHash}; | ||
| use ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures}; | ||
| use ln::onion_utils; | ||
| use onion_message; | ||
| use prelude::*; | ||
| use core::fmt; | ||
| @@ -40,7 +42,7 @@ use io_extras::read_to_end; | ||
| use util::events::MessageSendEventsProvider; | ||
| use util::logger; | ||
| use util::ser::{Readable, Writeable, Writer, FixedLengthReader, HighZeroBytesDroppedVarInt, Hostname}; | ||
| use util::ser::{LengthReadable, Readable, ReadableArgs, Writeable, Writer, FixedLengthReader, HighZeroBytesDroppedVarInt, Hostname}; | ||
| use ln::{PaymentPreimage, PaymentHash, PaymentSecret}; | ||
| @@ -304,6 +306,14 @@ pub struct UpdateAddHTLC { | ||
| pub(crate) onion_routing_packet: OnionPacket, | ||
| } | ||
| /// An onion message to be sent or received from a peer | ||
| #[derive(Clone, Debug, PartialEq)] | ||
| pub struct OnionMessage { | ||
| /// Used in decrypting the onion packet's payload. | ||
| pub blinding_point: PublicKey, | ||
| pub(crate) onion_routing_packet: onion_message::Packet, | ||
| } | ||
| /// An update_fulfill_htlc message to be sent or received from a peer | ||
| #[derive(Clone, Debug, PartialEq)] | ||
| pub struct UpdateFulfillHTLC { | ||
| @@ -993,6 +1003,18 @@ pub(crate) struct OnionPacket { | ||
| pub(crate) hmac: [u8; 32], | ||
| } | ||
| impl onion_utils::Packet for OnionPacket { | ||
| type Data = onion_utils::FixedSizeOnionPacket; | ||
| fn new(pubkey: PublicKey, hop_data: onion_utils::FixedSizeOnionPacket, hmac: [u8; 32]) -> Self { | ||
| Self { | ||
| version: 0, | ||
| public_key: Ok(pubkey), | ||
| hop_data: hop_data.0, | ||
| hmac, | ||
| } | ||
| } | ||
| } | ||
| impl PartialEq for OnionPacket { | ||
| fn eq(&self, other: &OnionPacket) -> bool { | ||
| for (i, j) in self.hop_data.iter().zip(other.hop_data.iter()) { | ||
| @@ -1327,6 +1349,29 @@ impl_writeable_msg!(UpdateAddHTLC, { | ||
| onion_routing_packet | ||
| }, {}); | ||
| impl Readable for OnionMessage { | ||
| fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> { | ||
| let blinding_point: PublicKey = Readable::read(r)?; | ||
| let len: u16 = Readable::read(r)?; | ||
| let mut packet_reader = FixedLengthReader::new(r, len as u64); | ||
| let onion_routing_packet: onion_message::Packet = <onion_message::Packet as LengthReadable>::read(&mut packet_reader)?; | ||
| Ok(Self { | ||
| blinding_point, | ||
| onion_routing_packet, | ||
| }) | ||
| } | ||
| } | ||
| impl Writeable for OnionMessage { | ||
| fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> { | ||
| self.blinding_point.write(w)?; | ||
| let onion_packet_len = self.onion_routing_packet.serialized_length(); | ||
| (onion_packet_len as u16).write(w)?; | ||
| self.onion_routing_packet.write(w)?; | ||
| Ok(()) | ||
| } | ||
| } | ||
| impl Writeable for FinalOnionHopData { | ||
| fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> { | ||
| self.payment_secret.0.write(w)?; | ||
| @@ -1372,6 +1417,14 @@ impl Writeable for OnionHopData { | ||
| } | ||
| } | ||
| // ReadableArgs because we need onion_utils::decode_next_hop to accommodate payment packets and | ||
| // onion message packets. | ||
| impl ReadableArgs<()> for OnionHopData { | ||
valentinewallace marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| fn read<R: Read>(r: &mut R, _arg: ()) -> Result<Self, DecodeError> { | ||
| <Self as Readable>::read(r) | ||
| } | ||
| } | ||
| impl Readable for OnionHopData { | ||
| fn read<R: Read>(mut r: &mut R) -> Result<Self, DecodeError> { | ||
| use bitcoin::consensus::encode::{Decodable, Error, VarInt}; | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.