@@ -34,8 +34,8 @@ tlvtype,encrypted_data_tlv,next_node_id,4
|
||||
tlvdata,encrypted_data_tlv,next_node_id,node_id,point,
|
||||
tlvtype,encrypted_data_tlv,path_id,6
|
||||
tlvdata,encrypted_data_tlv,path_id,data,byte,...
|
||||
tlvtype,encrypted_data_tlv,next_blinding_override,8
|
||||
tlvdata,encrypted_data_tlv,next_blinding_override,blinding,point,
|
||||
tlvtype,encrypted_data_tlv,next_path_key_override,8
|
||||
tlvdata,encrypted_data_tlv,next_path_key_override,path_key,point,
|
||||
tlvtype,encrypted_data_tlv,payment_relay,10
|
||||
tlvdata,encrypted_data_tlv,payment_relay,cltv_expiry_delta,u16,
|
||||
tlvdata,encrypted_data_tlv,payment_relay,fee_proportional_millionths,u32,
|
||||
@@ -112,10 +112,10 @@ tlvtype,onionmsg_tlv,invoice_error,68
|
||||
tlvdata,onionmsg_tlv,invoice_error,invoice_error,byte,...
|
||||
subtype,blinded_path
|
||||
subtypedata,blinded_path,first_node_id,sciddir_or_pubkey,
|
||||
subtypedata,blinded_path,blinding,point,
|
||||
subtypedata,blinded_path,first_path_key,point,
|
||||
subtypedata,blinded_path,num_hops,byte,
|
||||
subtypedata,blinded_path,path,onionmsg_hop,num_hops
|
||||
subtype,onionmsg_hop
|
||||
subtypedata,onionmsg_hop,blinded_node_id,point,
|
||||
subtypedata,onionmsg_hop,enclen,u16,
|
||||
subtypedata,onionmsg_hop,encrypted_recipient_data,byte,enclen
|
||||
subtypedata,blinded_path,path,blinded_path_hop,num_hops
|
||||
subtype,blinded_path_hop
|
||||
subtypedata,blinded_path_hop,blinded_node_id,point,
|
||||
subtypedata,blinded_path_hop,enclen,u16,
|
||||
subtypedata,blinded_path_hop,encrypted_recipient_data,byte,enclen
|
||||
|
||||
|
@@ -232,6 +232,6 @@ msgdata,gossip_timestamp_filter,chain_hash,chain_hash,
|
||||
msgdata,gossip_timestamp_filter,first_timestamp,u32,
|
||||
msgdata,gossip_timestamp_filter,timestamp_range,u32,
|
||||
msgtype,onion_message,513
|
||||
msgdata,onion_message,blinding,point,
|
||||
msgdata,onion_message,path_key,point,
|
||||
msgdata,onion_message,len,u16,
|
||||
msgdata,onion_message,onion_message_packet,byte,len
|
||||
|
||||
|
@@ -112,7 +112,7 @@ def create_blinded_path(
|
||||
|
||||
blinded_path = {
|
||||
'first_node_id': introduction_point,
|
||||
'blinding': blinding,
|
||||
'first_path_key': blinding,
|
||||
'num_hops': len(onionmsg_hops),
|
||||
'path': onionmsg_hops
|
||||
}
|
||||
@@ -218,7 +218,7 @@ def send_onion_message_to(
|
||||
|
||||
if lnwallet.node_keypair.pubkey == introduction_point:
|
||||
# blinded path introduction point is me
|
||||
our_blinding = blinded_path['blinding']
|
||||
our_blinding = blinded_path['first_path_key']
|
||||
our_payload = blinded_path['path'][0]
|
||||
remaining_blinded_path = blinded_path['path'][1:]
|
||||
assert len(remaining_blinded_path) > 0, 'sending to myself?'
|
||||
@@ -234,17 +234,17 @@ def send_onion_message_to(
|
||||
assert peer, 'next_node_id not a peer'
|
||||
|
||||
# blinding override?
|
||||
next_blinding_override = recipient_data.get('next_blinding_override')
|
||||
if next_blinding_override:
|
||||
next_blinding = next_blinding_override.get('blinding')
|
||||
next_path_key_override = recipient_data.get('next_path_key_override')
|
||||
if next_path_key_override:
|
||||
next_path_key = next_path_key_override.get('path_key')
|
||||
else:
|
||||
# E_i+1=SHA256(E_i||ss_i) * E_i
|
||||
blinding_factor = sha256(our_blinding + shared_secret)
|
||||
blinding_factor_int = int.from_bytes(blinding_factor, byteorder="big")
|
||||
next_public_key_int = ecc.ECPubkey(our_blinding) * blinding_factor_int
|
||||
next_blinding = next_public_key_int.get_public_key_bytes()
|
||||
next_path_key = next_public_key_int.get_public_key_bytes()
|
||||
|
||||
blinding = next_blinding
|
||||
path_key = next_path_key
|
||||
|
||||
else:
|
||||
# we need a route to introduction point
|
||||
@@ -253,7 +253,7 @@ def send_onion_message_to(
|
||||
# if blinded path introduction point is our direct peer, no need to route-find
|
||||
if peer:
|
||||
# start of blinded path is our peer
|
||||
blinding = blinded_path['blinding']
|
||||
path_key = blinded_path['first_path_key']
|
||||
else:
|
||||
path = create_onion_message_route_to(lnwallet, introduction_point)
|
||||
|
||||
@@ -267,7 +267,7 @@ def send_onion_message_to(
|
||||
path = path[:-1]
|
||||
|
||||
if len(path) == 0:
|
||||
blinding = blinded_path['blinding']
|
||||
path_key = blinded_path['first_path_key']
|
||||
else:
|
||||
payment_path_pubkeys = [edge.end_node for edge in path]
|
||||
hop_shared_secrets, blinded_node_ids = get_shared_secrets_along_route(
|
||||
@@ -281,12 +281,12 @@ def send_onion_message_to(
|
||||
) for x in path[:-1]
|
||||
]
|
||||
|
||||
# final hop pre-ip, add next_blinding_override
|
||||
# final hop pre-ip, add next_path_key_override
|
||||
final_hop_pre_ip = OnionHopsDataSingle(
|
||||
tlv_stream_name='onionmsg_tlv',
|
||||
blind_fields={
|
||||
'next_node_id': {'node_id': introduction_point},
|
||||
'next_blinding_override': {'blinding': blinded_path['blinding']},
|
||||
'next_path_key_override': {'path_key': blinded_path['first_path_key']},
|
||||
}
|
||||
)
|
||||
hops_data.append(final_hop_pre_ip)
|
||||
@@ -300,7 +300,7 @@ def send_onion_message_to(
|
||||
'encrypted_recipient_data': encrypted_recipient_data
|
||||
}
|
||||
|
||||
blinding = ecc.ECPrivkey(session_key).get_public_key_bytes()
|
||||
path_key = ecc.ECPrivkey(session_key).get_public_key_bytes()
|
||||
|
||||
# append (remaining) blinded path and payload
|
||||
blinded_path_blinded_ids = []
|
||||
@@ -360,11 +360,11 @@ def send_onion_message_to(
|
||||
packet = new_onion_packet(blinded_node_ids, session_key, hops_data)
|
||||
packet_b = packet.to_bytes()
|
||||
|
||||
blinding = ecc.ECPrivkey(session_key).get_public_key_bytes()
|
||||
path_key = ecc.ECPrivkey(session_key).get_public_key_bytes()
|
||||
|
||||
peer.send_message(
|
||||
"onion_message",
|
||||
blinding=blinding,
|
||||
path_key=path_key,
|
||||
len=len(packet_b),
|
||||
onion_message_packet=packet_b
|
||||
)
|
||||
@@ -703,27 +703,27 @@ class OnionMessageManager(Logger):
|
||||
return
|
||||
|
||||
# blinding override?
|
||||
next_blinding_override = recipient_data.get('next_blinding_override')
|
||||
if next_blinding_override:
|
||||
next_blinding = next_blinding_override.get('blinding')
|
||||
next_path_key_override = recipient_data.get('next_path_key_override')
|
||||
if next_path_key_override:
|
||||
next_path_key = next_path_key_override.get('path_key')
|
||||
else:
|
||||
# E_i+1=SHA256(E_i||ss_i) * E_i
|
||||
blinding_factor = sha256(blinding + shared_secret)
|
||||
blinding_factor_int = int.from_bytes(blinding_factor, byteorder="big")
|
||||
next_public_key_int = ecc.ECPubkey(blinding) * blinding_factor_int
|
||||
next_blinding = next_public_key_int.get_public_key_bytes()
|
||||
next_path_key = next_public_key_int.get_public_key_bytes()
|
||||
|
||||
if is_dummy_hop:
|
||||
self.process_onion_message_packet(next_blinding, onion_packet)
|
||||
self.process_onion_message_packet(next_path_key, onion_packet)
|
||||
return
|
||||
|
||||
self.submit_forward(onion_packet=onion_packet, blinding=next_blinding, node_id=next_node_id)
|
||||
self.submit_forward(onion_packet=onion_packet, blinding=next_path_key, node_id=next_node_id)
|
||||
|
||||
def on_onion_message(self, payload: dict) -> None:
|
||||
"""handle arriving onion_message."""
|
||||
blinding = payload.get('blinding')
|
||||
if not blinding:
|
||||
self.logger.error('missing blinding')
|
||||
path_key = payload.get('path_key')
|
||||
if not path_key:
|
||||
self.logger.error('missing path_key')
|
||||
return
|
||||
packet = payload.get('onion_message_packet')
|
||||
if payload.get('len', 0) != len(packet):
|
||||
@@ -733,7 +733,7 @@ class OnionMessageManager(Logger):
|
||||
self.logger.debug('handling onion message')
|
||||
|
||||
onion_packet = OnionPacket.from_bytes(packet)
|
||||
self.process_onion_message_packet(blinding, onion_packet)
|
||||
self.process_onion_message_packet(path_key, onion_packet)
|
||||
|
||||
def process_onion_message_packet(self, blinding: bytes, onion_packet: OnionPacket) -> None:
|
||||
our_privkey = blinding_privkey(self.lnwallet.node_keypair.privkey, blinding)
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
"hops": [
|
||||
{
|
||||
"alias": "Alice",
|
||||
"comment": "Alice->Bob: note next_blinding_override to match that give by Dave for Bob",
|
||||
"blinding_secret": "6363636363636363636363636363636363636363636363636363636363636363",
|
||||
"comment": "Alice->Bob: note next_path_key_override to match that give by Dave for Bob",
|
||||
"path_key_secret": "6363636363636363636363636363636363636363636363636363636363636363",
|
||||
"tlvs": {
|
||||
"next_node_id": "0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c",
|
||||
"next_blinding_override": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f",
|
||||
"blinding_override_secret": "0101010101010101010101010101010101010101010101010101010101010101"
|
||||
"next_path_key_override": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f",
|
||||
"path_key_override_secret": "0101010101010101010101010101010101010101010101010101010101010101"
|
||||
},
|
||||
"encrypted_data_tlv": "04210324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c0821031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f",
|
||||
"ss": "c04d2a4c518241cb49f2800eea92554cb543f268b4c73f85693541e86d649205",
|
||||
@@ -26,7 +26,7 @@
|
||||
{
|
||||
"alias": "Bob",
|
||||
"comment": "Bob->Carol",
|
||||
"blinding_secret": "0101010101010101010101010101010101010101010101010101010101010101",
|
||||
"path_key_secret": "0101010101010101010101010101010101010101010101010101010101010101",
|
||||
"tlvs": {
|
||||
"next_node_id": "027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007",
|
||||
"unknown_tag_561": "123456"
|
||||
@@ -44,7 +44,7 @@
|
||||
{
|
||||
"alias": "Carol",
|
||||
"comment": "Carol->Dave",
|
||||
"blinding_secret": "f7ab6dca6152f7b6b0c9d7c82d716af063d72d8eef8816dfc51a8ae828fa7dce",
|
||||
"path_key_secret": "f7ab6dca6152f7b6b0c9d7c82d716af063d72d8eef8816dfc51a8ae828fa7dce",
|
||||
"tlvs": {
|
||||
"padding": "0000000000",
|
||||
"next_node_id": "032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991"
|
||||
@@ -62,7 +62,7 @@
|
||||
{
|
||||
"alias": "Dave",
|
||||
"comment": "Dave is final node, hence path_id",
|
||||
"blinding_secret": "5de52bb427cc148bf23e509fdc18012004202517e80abcfde21612ae408e6cea",
|
||||
"path_key_secret": "5de52bb427cc148bf23e509fdc18012004202517e80abcfde21612ae408e6cea",
|
||||
"tlvs": {
|
||||
"padding": "",
|
||||
"path_id": "deadbeefbadc0ffeedeadbeefbadc0ffeedeadbeefbadc0ffeedeadbeefbadc0",
|
||||
@@ -82,8 +82,8 @@
|
||||
},
|
||||
"route": {
|
||||
"comment": "The resulting blinded route Alice to Dave.",
|
||||
"introduction_node_id": "02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619",
|
||||
"blinding": "031195a8046dcbb8e17034bca630065e7a0982e4e36f6f7e5a8d4554e4846fcd99",
|
||||
"first_node_id": "02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619",
|
||||
"first_path_key": "031195a8046dcbb8e17034bca630065e7a0982e4e36f6f7e5a8d4554e4846fcd99",
|
||||
"hops": [
|
||||
{
|
||||
"blinded_node_id": "02d1c3d73f8cac67e7c5b6ec517282d5ba0a52b06a29ec92ff01e12decf76003c1",
|
||||
|
||||
@@ -44,13 +44,13 @@ BOB_TLVS = HOPS[1]['tlvs']
|
||||
CAROL_TLVS = HOPS[2]['tlvs']
|
||||
DAVE_TLVS = HOPS[3]['tlvs']
|
||||
|
||||
ALICE_PUBKEY = bfh(test_vectors['route']['introduction_node_id'])
|
||||
ALICE_PUBKEY = bfh(test_vectors['route']['first_node_id'])
|
||||
BOB_PUBKEY = bfh(ALICE_TLVS['next_node_id'])
|
||||
CAROL_PUBKEY = bfh(BOB_TLVS['next_node_id'])
|
||||
DAVE_PUBKEY = bfh(CAROL_TLVS['next_node_id'])
|
||||
|
||||
BLINDING_SECRET = bfh(HOPS[0]['blinding_secret'])
|
||||
BLINDING_OVERRIDE_SECRET = bfh(ALICE_TLVS['blinding_override_secret'])
|
||||
BLINDING_SECRET = bfh(HOPS[0]['path_key_secret'])
|
||||
BLINDING_OVERRIDE_SECRET = bfh(ALICE_TLVS['path_key_override_secret'])
|
||||
|
||||
SESSION_KEY = bfh(test_vectors['generate']['session_key'])
|
||||
|
||||
@@ -74,7 +74,7 @@ class TestOnionMessage(ElectrumTestCase):
|
||||
tlv_stream_name='onionmsg_tlv',
|
||||
blind_fields={
|
||||
'next_node_id': {'node_id': bfh(ALICE_TLVS['next_node_id'])},
|
||||
'next_blinding_override': {'blinding': bfh(ALICE_TLVS['next_blinding_override'])},
|
||||
'next_path_key_override': {'path_key': bfh(ALICE_TLVS['next_path_key_override'])},
|
||||
}
|
||||
),
|
||||
OnionHopsDataSingle(
|
||||
@@ -150,7 +150,7 @@ class TestOnionMessage(ElectrumTestCase):
|
||||
msgtype, data = decode_msg(bfh(msg))
|
||||
self.assertEqual(msgtype, 'onion_message')
|
||||
self.assertEqual(data, {
|
||||
'blinding': bfh(test_vectors['route']['blinding']),
|
||||
'path_key': bfh(test_vectors['route']['first_path_key']),
|
||||
'len': 1366,
|
||||
'onion_message_packet': ONION_MESSAGE_PACKET,
|
||||
})
|
||||
@@ -158,7 +158,7 @@ class TestOnionMessage(ElectrumTestCase):
|
||||
def test_decrypt_onion_message(self):
|
||||
o = OnionPacket.from_bytes(ONION_MESSAGE_PACKET)
|
||||
our_privkey = bfh(test_vectors['decrypt']['hops'][0]['privkey'])
|
||||
blinding = bfh(test_vectors['route']['blinding'])
|
||||
blinding = bfh(test_vectors['route']['first_path_key'])
|
||||
|
||||
shared_secret = get_ecdh(our_privkey, blinding)
|
||||
b_hmac = get_bolt04_onion_key(b'blinded_node_id', shared_secret)
|
||||
@@ -179,7 +179,7 @@ class TestOnionMessage(ElectrumTestCase):
|
||||
msgtype, data = decode_msg(bfh(onion_message_bob))
|
||||
self.assertEqual(msgtype, 'onion_message')
|
||||
self.assertEqual(data, {
|
||||
'blinding': bfh(ALICE_TLVS['next_blinding_override']),
|
||||
'path_key': bfh(ALICE_TLVS['next_path_key_override']),
|
||||
'len': 1366,
|
||||
'onion_message_packet': p.next_packet.to_bytes(),
|
||||
})
|
||||
@@ -196,7 +196,7 @@ class TestOnionMessage(ElectrumTestCase):
|
||||
rp = create_blinded_path(session_key, [pubkey], final_recipient_data)
|
||||
|
||||
self.assertEqual(pubkey, rp['first_node_id'])
|
||||
self.assertEqual(bfh('022ed557f5ad336b31a49857e4e9664954ac33385aa20a93e2d64bfe7f08f51277'), rp['blinding'])
|
||||
self.assertEqual(bfh('022ed557f5ad336b31a49857e4e9664954ac33385aa20a93e2d64bfe7f08f51277'), rp['first_path_key'])
|
||||
self.assertEqual(1, rp['num_hops'])
|
||||
self.assertEqual([{
|
||||
'blinded_node_id': bfh('031e5d91e6c417f6e8c16d1086db1887edef7be9334f5e744d04edb8da7507481e'),
|
||||
@@ -234,7 +234,7 @@ class TestOnionMessage(ElectrumTestCase):
|
||||
tlv_stream_name='onionmsg_tlv',
|
||||
blind_fields={
|
||||
'next_node_id': {'node_id': BOB_PUBKEY},
|
||||
'next_blinding_override': {'blinding': bfh(ALICE_TLVS['next_blinding_override'])},
|
||||
'next_path_key_override': {'path_key': bfh(ALICE_TLVS['next_path_key_override'])},
|
||||
}
|
||||
),
|
||||
]
|
||||
@@ -434,7 +434,7 @@ class TestOnionMessageManager(ElectrumTestCase):
|
||||
onionmsg = bfh(test_vectors['onionmessage']['onion_message_packet'])
|
||||
try:
|
||||
t.on_onion_message({
|
||||
'blinding': bfh(test_vectors['route']['blinding']),
|
||||
'blinding': bfh(test_vectors['route']['first_path_key']),
|
||||
'len': len(onionmsg),
|
||||
'onion_message_packet': onionmsg
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user