Skip to content

Commit 3e45cb2

Browse files
committed
Add non-vector cryptography tests [expound]
1 parent 6b0b8df commit 3e45cb2

File tree

1 file changed

+184
-0
lines changed

1 file changed

+184
-0
lines changed

lightning/src/ln/onion_utils.rs

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2493,6 +2493,190 @@ mod tests {
24932493
assert_eq!(decrypted_failure.onion_error_code, Some(0x400f));
24942494
}
24952495

2496+
#[test]
2497+
fn test_trampoline_onion_decryption() {
2498+
// In this test, we construct a dummy path that uses Trampoline hops, and ensure that the
2499+
// correct shared secrets are used to decrypt the error packets. The actual path configuration
2500+
// is not particularly relevant.
2501+
2502+
let dummy_amt_msat = 150_000_000;
2503+
2504+
let path = Path {
2505+
hops: vec![
2506+
// Bob
2507+
RouteHop {
2508+
pubkey: PublicKey::from_slice(&<Vec<u8>>::from_hex("0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c").unwrap()).unwrap(),
2509+
node_features: NodeFeatures::empty(),
2510+
short_channel_id: 0,
2511+
channel_features: ChannelFeatures::empty(),
2512+
fee_msat: 3_000,
2513+
cltv_expiry_delta: 24,
2514+
maybe_announced_channel: false,
2515+
},
2516+
2517+
// Carol
2518+
RouteHop {
2519+
pubkey: PublicKey::from_slice(&<Vec<u8>>::from_hex("027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007").unwrap()).unwrap(),
2520+
node_features: NodeFeatures::empty(),
2521+
short_channel_id: (572330 << 40) + (42 << 16) + 2821,
2522+
channel_features: ChannelFeatures::empty(),
2523+
fee_msat: 153_000,
2524+
cltv_expiry_delta: 0,
2525+
maybe_announced_channel: false,
2526+
},
2527+
],
2528+
blinded_tail: Some(BlindedTail {
2529+
trampoline_hops: vec![
2530+
// Carol's pubkey
2531+
TrampolineHop {
2532+
pubkey: PublicKey::from_slice(&<Vec<u8>>::from_hex("027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007").unwrap()).unwrap(),
2533+
node_features: Features::empty(),
2534+
fee_msat: 2_500,
2535+
cltv_expiry_delta: 24,
2536+
},
2537+
// Dave's pubkey
2538+
TrampolineHop {
2539+
pubkey: PublicKey::from_slice(&<Vec<u8>>::from_hex("020e2dbadcc2005e859819ddebbe88a834ae8a6d2b049233c07335f15cd1dc5f22").unwrap()).unwrap(),
2540+
node_features: Features::empty(),
2541+
fee_msat: 2_500,
2542+
cltv_expiry_delta: 24,
2543+
},
2544+
// Emily's pubkey (the intro node needs to be duplicated)
2545+
TrampolineHop {
2546+
pubkey: PublicKey::from_slice(&<Vec<u8>>::from_hex("032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991").unwrap()).unwrap(),
2547+
node_features: Features::empty(),
2548+
fee_msat: 150_500,
2549+
cltv_expiry_delta: 36,
2550+
}
2551+
],
2552+
hops: vec![
2553+
// Emily's blinded node id
2554+
BlindedHop {
2555+
blinded_node_id: PublicKey::from_slice(&<Vec<u8>>::from_hex("0295d40514096a8be54859e7dfe947b376eaafea8afe5cb4eb2c13ff857ed0b4be").unwrap()).unwrap(),
2556+
encrypted_payload: vec![],
2557+
},
2558+
// Forrest's blinded node id
2559+
BlindedHop {
2560+
blinded_node_id: PublicKey::from_slice(&<Vec<u8>>::from_hex("020e2dbadcc2005e859819ddebbe88a834ae8a6d2b049233c07335f15cd1dc5f22").unwrap()).unwrap(),
2561+
encrypted_payload: vec![],
2562+
}
2563+
],
2564+
blinding_point: PublicKey::from_slice(&<Vec<u8>>::from_hex("02988face71e92c345a068f740191fd8e53be14f0bb957ef730d3c5f76087b960e").unwrap()).unwrap(),
2565+
excess_final_cltv_expiry_delta: 0,
2566+
final_value_msat: dummy_amt_msat
2567+
}),
2568+
};
2569+
2570+
// all dummy values
2571+
let secp_ctx = Secp256k1::new();
2572+
let session_priv = get_test_session_key();
2573+
2574+
let trampoline_onion_keys = construct_trampoline_onion_keys(
2575+
&secp_ctx,
2576+
&path.blinded_tail.as_ref().unwrap(),
2577+
&session_priv,
2578+
)
2579+
.unwrap();
2580+
2581+
let outer_onion_keys = {
2582+
let session_priv_hash = Sha256::hash(&session_priv.secret_bytes()).to_byte_array();
2583+
let outer_session_priv = SecretKey::from_slice(&session_priv_hash[..]).unwrap();
2584+
construct_onion_keys(&Secp256k1::new(), &path, &outer_session_priv).unwrap()
2585+
};
2586+
2587+
let logger: Arc<TestLogger> = Arc::new(TestLogger::new());
2588+
let htlc_source = HTLCSource::OutboundRoute {
2589+
path,
2590+
session_priv,
2591+
first_hop_htlc_msat: dummy_amt_msat,
2592+
payment_id: PaymentId([1; 32]),
2593+
};
2594+
2595+
{
2596+
let error_code = 0x2002;
2597+
let mut first_hop_error_packet = build_unencrypted_failure_packet(
2598+
outer_onion_keys[0].shared_secret.as_ref(),
2599+
error_code,
2600+
&[0; 0],
2601+
);
2602+
2603+
crypt_failure_packet(
2604+
outer_onion_keys[0].shared_secret.as_ref(),
2605+
&mut first_hop_error_packet,
2606+
);
2607+
2608+
let decrypted_failure = process_onion_failure(
2609+
&secp_ctx,
2610+
&logger,
2611+
&htlc_source,
2612+
first_hop_error_packet,
2613+
None,
2614+
);
2615+
assert_eq!(decrypted_failure.onion_error_code, Some(error_code));
2616+
};
2617+
2618+
{
2619+
let error_code = 0x2003;
2620+
let mut trampoline_outer_hop_error_packet = build_unencrypted_failure_packet(
2621+
outer_onion_keys[1].shared_secret.as_ref(),
2622+
error_code,
2623+
&[0; 0],
2624+
);
2625+
2626+
crypt_failure_packet(
2627+
outer_onion_keys[1].shared_secret.as_ref(),
2628+
&mut trampoline_outer_hop_error_packet,
2629+
);
2630+
2631+
crypt_failure_packet(
2632+
outer_onion_keys[0].shared_secret.as_ref(),
2633+
&mut trampoline_outer_hop_error_packet,
2634+
);
2635+
2636+
let decrypted_failure = process_onion_failure(
2637+
&secp_ctx,
2638+
&logger,
2639+
&htlc_source,
2640+
trampoline_outer_hop_error_packet,
2641+
None,
2642+
);
2643+
assert_eq!(decrypted_failure.onion_error_code, Some(error_code));
2644+
};
2645+
2646+
{
2647+
let error_code = 0x2004;
2648+
let mut trampoline_inner_hop_error_packet = build_unencrypted_failure_packet(
2649+
trampoline_onion_keys[0].shared_secret.as_ref(),
2650+
error_code,
2651+
&[0; 0],
2652+
);
2653+
2654+
crypt_failure_packet(
2655+
trampoline_onion_keys[0].shared_secret.as_ref(),
2656+
&mut trampoline_inner_hop_error_packet,
2657+
);
2658+
2659+
crypt_failure_packet(
2660+
outer_onion_keys[1].shared_secret.as_ref(),
2661+
&mut trampoline_inner_hop_error_packet,
2662+
);
2663+
2664+
crypt_failure_packet(
2665+
outer_onion_keys[0].shared_secret.as_ref(),
2666+
&mut trampoline_inner_hop_error_packet,
2667+
);
2668+
2669+
let decrypted_failure = process_onion_failure(
2670+
&secp_ctx,
2671+
&logger,
2672+
&htlc_source,
2673+
trampoline_inner_hop_error_packet,
2674+
None,
2675+
);
2676+
assert_eq!(decrypted_failure.onion_error_code, Some(error_code));
2677+
}
2678+
}
2679+
24962680
#[test]
24972681
fn test_non_attributable_failure_packet_onion() {
24982682
// Create a failure packet with bogus data.

0 commit comments

Comments
 (0)