Skip to content

Commit 1437509

Browse files
authored
Merge pull request #5 from cryptape/any-packet-data-len
allow using arbitrary packet data len
2 parents 42b35bc + 1b14b80 commit 1437509

File tree

1 file changed

+121
-32
lines changed

1 file changed

+121
-32
lines changed

src/lib.rs

Lines changed: 121 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
//! let assoc_data = vec![0x42u8; 32];
2020
2121
//! let packet = new_onion_packet(
22+
//! 1300,
2223
//! hops_path,
2324
//! session_key,
2425
//! hops_data.clone(),
@@ -71,7 +72,7 @@
7172
//! assert_eq!(data, hops_data[2]);
7273
//! ```
7374
use chacha20::{
74-
cipher::{KeyIvInit as _, StreamCipher as _},
75+
cipher::{KeyIvInit as _, StreamCipher},
7576
ChaCha20,
7677
};
7778
use hmac::{Hmac, Mac as _};
@@ -81,8 +82,6 @@ use secp256k1::{
8182
use sha2::{Digest as _, Sha256};
8283
use thiserror::Error;
8384

84-
pub const ONION_PACKET_DATA_LEN: usize = 1300;
85-
8685
const HMAC_KEY_RHO: &[u8] = b"rho";
8786
const HMAC_KEY_MU: &[u8] = b"mu";
8887
const HMAC_KEY_PAD: &[u8] = b"pad";
@@ -95,15 +94,15 @@ pub struct OnionPacket {
9594
// The public key of the next hop
9695
pub public_key: PublicKey,
9796
// Encrypted packet data
98-
pub packet_data: [u8; ONION_PACKET_DATA_LEN],
97+
pub packet_data: Vec<u8>,
9998
// HMAC of the packet data
10099
pub hmac: [u8; 32],
101100
}
102101

103102
impl OnionPacket {
104103
/// Converts the onion packet into a byte vector.
105104
pub fn into_bytes(self) -> Vec<u8> {
106-
let mut bytes = Vec::with_capacity(1 + 33 + ONION_PACKET_DATA_LEN + 32);
105+
let mut bytes = Vec::with_capacity(1 + 33 + self.packet_data.len() + 32);
107106
bytes.push(self.version);
108107
bytes.extend_from_slice(&self.public_key.serialize());
109108
bytes.extend_from_slice(&self.packet_data);
@@ -127,6 +126,7 @@ impl OnionPacket {
127126
C: Verification,
128127
F: FnOnce(&[u8]) -> Option<usize>,
129128
{
129+
let packet_data_len = self.packet_data.len();
130130
let shared_secret = SharedSecret::new(&self.public_key, secret_key);
131131
let rho = derive_key(HMAC_KEY_RHO, shared_secret.as_ref());
132132
let mu = derive_key(HMAC_KEY_MU, shared_secret.as_ref());
@@ -144,12 +144,15 @@ impl OnionPacket {
144144

145145
// data | hmac | remaining
146146
let data_len = get_hop_data_len(&packet_data).ok_or(SphinxError::HopDataLenUnavailable)?;
147+
if data_len > packet_data_len {
148+
return Err(SphinxError::HopDataLenTooLarge);
149+
}
147150
let hop_data = (&packet_data[0..data_len]).to_vec();
148151
let mut hmac = [0; 32];
149152
hmac.copy_from_slice(&packet_data[data_len..(data_len + 32)]);
150153
shift_slice_left(&mut packet_data[..], data_len + 32);
151154
// Encrypt 0 bytes until the end
152-
chacha.apply_keystream(&mut packet_data[(ONION_PACKET_DATA_LEN - data_len - 32)..]);
155+
chacha.apply_keystream(&mut packet_data[(packet_data_len - data_len - 32)..]);
153156

154157
let public_key =
155158
derive_next_hop_ephemeral_public_key(self.public_key, shared_secret.as_ref(), secp_ctx);
@@ -168,12 +171,6 @@ impl OnionPacket {
168171

169172
#[derive(Error, Debug, Eq, PartialEq)]
170173
pub enum SphinxError {
171-
#[error("The generated packet length is too large")]
172-
PacketLenTooLarge,
173-
174-
#[error("The filler length is too large")]
175-
FillerLenTooLarge,
176-
177174
#[error("The hops path does not match the hops data length")]
178175
HopsLenMismatch,
179176

@@ -185,6 +182,9 @@ pub enum SphinxError {
185182

186183
#[error("Unable to parse the data len for the current hop")]
187184
HopDataLenUnavailable,
185+
186+
#[error("The parsed data len is larger than the onion packet len")]
187+
HopDataLenTooLarge,
188188
}
189189

190190
#[inline]
@@ -218,6 +218,14 @@ fn compute_hmac(mu: &[u8; 32], packet_data: &[u8], assoc_data: Option<&[u8]>) ->
218218
hmac_engine.finalize().into_bytes().into()
219219
}
220220

221+
/// Forwards the cursor of the stream cipher by `n` bytes.
222+
fn forward_stream_cipher<S: StreamCipher>(stream: &mut S, n: usize) {
223+
for _ in 0..n {
224+
let mut dummy = [0; 1];
225+
stream.apply_keystream(&mut dummy);
226+
}
227+
}
228+
221229
/// Derives the ephemeral secret key for the next hop.
222230
///
223231
/// Assume that the current hop is $n_{i-1}$, and the next hop is $n_i$.
@@ -314,34 +322,33 @@ fn derive_key(hmac_key: &[u8], shared_secret: &[u8]) -> [u8; 32] {
314322
mac.finalize().into_bytes().into()
315323
}
316324

317-
/// Generates the initial 1300 bytes of onion packet padding data from PRG.
325+
/// Generates the initial bytes of onion packet padding data from PRG.
318326
///
319327
/// Uses Chacha as the PRG. The key is derived from the session key using HMAC, and the nonce is all zeros.
320-
fn generate_padding_data(pad_key: &[u8]) -> [u8; ONION_PACKET_DATA_LEN] {
328+
fn generate_padding_data(packet_data_len: usize, pad_key: &[u8]) -> Vec<u8> {
321329
let mut cipher = ChaCha20::new(pad_key.into(), &CHACHA_NONCE.into());
322-
let mut buffer = [0u8; ONION_PACKET_DATA_LEN];
330+
let mut buffer = vec![0u8; packet_data_len];
323331
cipher.apply_keystream(&mut buffer);
324332
buffer
325333
}
326334

327335
/// Generates the filler to obfuscate the onion packet.
328-
fn generate_filler(hops_keys: &[HopKeys], hops_data: &[Vec<u8>]) -> Result<Vec<u8>, SphinxError> {
336+
fn generate_filler(
337+
packet_data_len: usize,
338+
hops_keys: &[HopKeys],
339+
hops_data: &[Vec<u8>],
340+
) -> Result<Vec<u8>, SphinxError> {
329341
let mut filler = Vec::new();
330342
let mut pos = 0;
331343

332344
for (i, (data, keys)) in hops_data.iter().zip(hops_keys.iter()).enumerate() {
333345
let mut chacha = ChaCha20::new(&keys.rho.into(), &[0u8; 12].into());
334-
335-
// Skip `ONION_PACKET_DATA_LEN - pos` bytes in the stream
336-
for _ in 0..(ONION_PACKET_DATA_LEN - pos) {
337-
let mut dummy = [0; 1];
338-
chacha.apply_keystream(&mut dummy);
339-
}
346+
forward_stream_cipher(&mut chacha, packet_data_len - pos);
340347

341348
// 32 for mac
342349
pos += data.len() + 32;
343-
if pos > ONION_PACKET_DATA_LEN {
344-
return Err(SphinxError::PacketLenTooLarge);
350+
if pos > packet_data_len {
351+
return Err(SphinxError::HopDataLenTooLarge);
345352
}
346353

347354
if i == hops_data.len() - 1 {
@@ -364,7 +371,7 @@ fn generate_filler(hops_keys: &[HopKeys], hops_data: &[Vec<u8>]) -> Result<Vec<u
364371
/// HMAC. This allows each hop to verify that the associated data has not been tampered with.
365372
/// - `filler`: The filler to obfuscate the packet data, which is generated by `generate_filler`.
366373
fn construct_onion_packet(
367-
mut packet_data: [u8; ONION_PACKET_DATA_LEN],
374+
mut packet_data: Vec<u8>,
368375
hops_keys: &[HopKeys],
369376
hops_data: &[Vec<u8>],
370377
assoc_data: Option<Vec<u8>>,
@@ -382,10 +389,10 @@ fn construct_onion_packet(
382389
chacha.apply_keystream(&mut packet_data);
383390

384391
if i == 0 {
385-
let stop_index = ONION_PACKET_DATA_LEN;
392+
let stop_index = packet_data.len();
386393
let start_index = stop_index
387394
.checked_sub(filler.len())
388-
.ok_or(SphinxError::FillerLenTooLarge)?;
395+
.ok_or(SphinxError::HopDataLenTooLarge)?;
389396
packet_data[start_index..stop_index].copy_from_slice(&filler[..]);
390397
}
391398

@@ -402,6 +409,7 @@ fn construct_onion_packet(
402409

403410
/// Creates a new onion packet internally.
404411
///
412+
/// - `onion_packet_len`: The length of the onion packet. The packet has the same size for each hop.
405413
/// - `hops_path`: The public keys for each hop.
406414
/// - `session_key`: The ephemeral secret key for the onion packet. It must be generated securely using a random process.
407415
/// - `hops_data`: The unencrypted data for each hop. **Attention** that the data for each hop will be concatenated with
@@ -410,6 +418,7 @@ fn construct_onion_packet(
410418
/// - `assoc_data`: The associated data. It will not be included in the packet itself but will be covered by the packet's
411419
/// HMAC. This allows each hop to verify that the associated data has not been tampered with.
412420
pub fn new_onion_packet(
421+
packet_data_len: usize,
413422
hops_path: Vec<PublicKey>,
414423
session_key: SecretKey,
415424
hops_data: Vec<Vec<u8>>,
@@ -424,8 +433,8 @@ pub fn new_onion_packet(
424433

425434
let hops_keys = derive_hops_keys(&hops_path, session_key, &Secp256k1::new());
426435
let pad_key = derive_key(HMAC_KEY_PAD, &session_key.secret_bytes());
427-
let packet_data = generate_padding_data(&pad_key);
428-
let filler = generate_filler(&hops_keys, &hops_data)?;
436+
let packet_data = generate_padding_data(packet_data_len, &pad_key);
437+
let filler = generate_filler(packet_data_len, &hops_keys, &hops_data)?;
429438

430439
construct_onion_packet(packet_data, &hops_keys, &hops_data, assoc_data, filler)
431440
}
@@ -434,6 +443,7 @@ pub fn new_onion_packet(
434443
mod tests {
435444
use super::*;
436445
use hex_conservative::prelude::*;
446+
const PACKET_DATA_LEN: usize = 1300;
437447

438448
fn get_test_session_key() -> SecretKey {
439449
SecretKey::from_slice(&[0x41; 32]).expect("32 bytes, within curve order")
@@ -572,7 +582,7 @@ mod tests {
572582
"70fa47d28edc4faf3e733ae0f4d2a12b8c5f09cbd74408eb7bc6ba2f1ebf88a2",
573583
)
574584
.unwrap();
575-
let padding = generate_padding_data(&pad_key);
585+
let padding = generate_padding_data(PACKET_DATA_LEN, &pad_key);
576586
let expected_hex = "77b5a170c57c6ff643fd6f46f5537c2fec4c5258f89fafbd722f9041f1cead9b2ab563384bc052ab9179e7d97defbee5324b29d5655f6816916310c4f08b69ad20a51ad7ffa2e07f5b28c30a2b3175adbf8d249c1fa55b02daa7c463eaf4b843ff9567afec9ef70cfc1d84ef29a802d1755c3cc6d04536744a71aa94a2419a6b5501ee8a8209191c1f43b357442a5c0847140db9c907bb2a325c414bfd1e72b1867526b071f96d718c176ff52894b45d1480149ad5d36614fb68b043d23aeb2806344832e8f925ed5428866912f4f1e7203ec73ec37fbb581e36b25fadc42bb4a5acf50d7ef1139a8482c7588bbfdfe5bde63ccb13b54d4368a4891e9c6c876814f189e9681a4efb59a91564e9f72e2047ce30840c06653ecc998ba216585cbeca617434a91a05bd8ae20b41ed84de5cfb0c3eb57ec721d4be57cf5f3223f99cfcb4250daee92b00b0de4c2d8e9e6cc6dafca49c136ef3b8ba7d983d52b079ef249f3c487ed6e982410bf86ab22636d22e06f3db5bbb887503167383f631e318ab71270528202994741264a40c69abe78eb0320ad420b229eca2335b928a3497cba182a427b0826260976608d5f50d35a5edc3574b532e28f114d21f93055f681f658fe9f6af8bac4ab5b1ec86dd575767501b6555963faba6766d70513c2cb8fbe6285f3ffea20b3b70b2e6960aca1633aa5368e19bec042ef32eacb5d326de1bc0e3120d9fe6da7f5407c7e77a66dac8f91ae11d727a5720a42ed152e6a95f61a61d80374fb0d6021d8f0a34e812bdba530bb4907b3192576a8021fae60615f89a420ada2f616fb9d006cc23621f72573e510417e91efe2335c246d614d105661866e878a1cae8dc29b92141b8d3e57479e73efa159e4a030531b54f0f9315a88e307bc0d152840166b88ed1afe6fbf159c3b74d04b7e9a31b93123fc5de7918eb1a8bd0a07ab4f07315ac5abbc36df06f613099d7f42d075366f42dd7ace9d975636363a5da4ea575a05c7114352a4b579b7aa129691e0b17934dd1146e34fa6246c953080503b9dfee62380669ebcb049e58bb259c6b1b64ff13891d0beb26dea5e624e5115ac1266e4facc65d5a0878066a253d1e9b3a2e465709ede22b312da118ad0446f2e725177452fd8f8b2eb743dbdbe3298e628c6910eb722415167eae745a28d15e2a0221db7ac7b684523b0af415acbcb9bed1d5a6fe74bb0e4e20543d684da1fad2199830e7ac421168acbc6ed547fd1ab4acd32adc34329af0a2ebfa80edeefb6fff2d6a4828b7b67da22f59ca68edcae4832be0ea856b075efbb4e14fad5e0ea5269cd75bac001acbc512833b44bbead8c861c8b2755ced0d594b7fd6b61f7f80341fe02549600298e1f68685f582d8bf5f51c01e2a68324456fd4cc342200252fd9a0025ce6b921bee965a350638830920a90f715959a936bc7cb6fef1fde4524c7eae46677efcd87be375ce25afa0d7c82bf445578ff6c49a3e461fcbe18faf4c6d711fd62a2a14e683f5919e7672deec93ccc0a843e90f7d88365bf469151793dbd9b15ef16a44909238f23cf84bcf11736089ab5ed0a0063c023cc0f90374dc37430e4279c05adb333e98cea0e650345d989b53653a1a3820410b7a1ad25bcfb39618c2b6ac29b2baa5325cc92647c9d13428d8be77b8c5f9c0492fc85a6d770ee6f123edc25b3009304c8691d90c2c54abf07413ac2ddd4d1abe34841739d4d88e865f7dda32bfe7a914400c7aa41a05745d9a4158641b26c510d671e4a539ac8d5f7a3ddb227d02788ba7b33222f2d1af605378636cddfa81825ebea6b68b0d8fca71277cdda7af17";
577587
assert_eq!(padding.to_lower_hex_string(), expected_hex);
578588
}
@@ -584,7 +594,7 @@ mod tests {
584594
let hops_keys = derive_hops_keys(&hops_path, session_key, &Secp256k1::new());
585595
let hops_data = get_test_hops_data();
586596

587-
let filler = generate_filler(&hops_keys, &hops_data);
597+
let filler = generate_filler(PACKET_DATA_LEN, &hops_keys, &hops_data);
588598
assert!(filler.is_ok());
589599
let expected_hex = "51c30cc8f20da0153ca3839b850bcbc8fefc7fd84802f3e78cb35a660e747b57aa5b0de555cbcf1e6f044a718cc34219b96597f3684eee7a0232e1754f638006cb15a14788217abdf1bdd67910dc1ca74a05dcce8b5ad841b0f939fca8935f6a3ff660e0efb409f1a24ce4aa16fc7dc074cd84422c10cc4dd4fc150dd6d1e4f50b36ce10fef29248dd0cec85c72eb3e4b2f4a7c03b5c9e0c9dd12976553ede3d0e295f842187b33ff743e6d685075e98e1bcab8a46bff0102ca8b2098ae91798d370b01ca7076d3d626952a03663fe8dc700d1358263b73ba30e36731a0b72092f8d5bc8cd346762e93b2bf203d00264e4bc136fc142de8f7b69154deb05854ea88e2d7506222c95ba1aab06";
590600
assert_eq!(filler.unwrap().to_lower_hex_string(), expected_hex);
@@ -603,10 +613,89 @@ mod tests {
603613
];
604614
let assoc_data = vec![0x42u8; 32];
605615

606-
let packet = new_onion_packet(hops_path, session_key, hops_data, Some(assoc_data)).unwrap();
616+
let packet = new_onion_packet(
617+
PACKET_DATA_LEN,
618+
hops_path,
619+
session_key,
620+
hops_data,
621+
Some(assoc_data),
622+
)
623+
.unwrap();
607624
let packet_bytes = packet.into_bytes();
608625
let expected_hex = "0002eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619f7f3416a5aa36dc7eeb3ec6d421e9615471ab870a33ac07fa5d5a51df0a8823aabe3fea3f90d387529d4f72837f9e687230371ccd8d263072206dbed0234f6505e21e282abd8c0e4f5b9ff8042800bbab065036eadd0149b37f27dde664725a49866e052e809d2b0198ab9610faa656bbf4ec516763a59f8f42c171b179166ba38958d4f51b39b3e98706e2d14a2dafd6a5df808093abfca5aeaaca16eded5db7d21fb0294dd1a163edf0fb445d5c8d7d688d6dd9c541762bf5a5123bf9939d957fe648416e88f1b0928bfa034982b22548e1a4d922690eecf546275afb233acf4323974680779f1a964cfe687456035cc0fba8a5428430b390f0057b6d1fe9a8875bfa89693eeb838ce59f09d207a503ee6f6299c92d6361bc335fcbf9b5cd44747aadce2ce6069cfdc3d671daef9f8ae590cf93d957c9e873e9a1bc62d9640dc8fc39c14902d49a1c80239b6c5b7fd91d05878cbf5ffc7db2569f47c43d6c0d27c438abff276e87364deb8858a37e5a62c446af95d8b786eaf0b5fcf78d98b41496794f8dcaac4eef34b2acfb94c7e8c32a9e9866a8fa0b6f2a06f00a1ccde569f97eec05c803ba7500acc96691d8898d73d8e6a47b8f43c3d5de74458d20eda61474c426359677001fbd75a74d7d5db6cb4feb83122f133206203e4e2d293f838bf8c8b3a29acb321315100b87e80e0edb272ee80fda944e3fb6084ed4d7f7c7d21c69d9da43d31a90b70693f9b0cc3eac74c11ab8ff655905688916cfa4ef0bd04135f2e50b7c689a21d04e8e981e74c6058188b9b1f9dfc3eec6838e9ffbcf22ce738d8a177c19318dffef090cee67e12de1a3e2a39f61247547ba5257489cbc11d7d91ed34617fcc42f7a9da2e3cf31a94a210a1018143173913c38f60e62b24bf0d7518f38b5bab3e6a1f8aeb35e31d6442c8abb5178efc892d2e787d79c6ad9e2fc271792983fa9955ac4d1d84a36c024071bc6e431b625519d556af38185601f70e29035ea6a09c8b676c9d88cf7e05e0f17098b584c4168735940263f940033a220f40be4c85344128b14beb9e75696db37014107801a59b13e89cd9d2258c169d523be6d31552c44c82ff4bb18ec9f099f3bf0e5b1bb2ba9a87d7e26f98d294927b600b5529c47e04d98956677cbcee8fa2b60f49776d8b8c367465b7c626da53700684fb6c918ead0eab8360e4f60edd25b4f43816a75ecf70f909301825b512469f8389d79402311d8aecb7b3ef8599e79485a4388d87744d899f7c47ee644361e17040a7958c8911be6f463ab6a9b2afacd688ec55ef517b38f1339efc54487232798bb25522ff4572ff68567fe830f92f7b8113efce3e98c3fffbaedce4fd8b50e41da97c0c08e423a72689cc68e68f752a5e3a9003e64e35c957ca2e1c48bb6f64b05f56b70b575ad2f278d57850a7ad568c24a4d32a3d74b29f03dc125488bc7c637da582357f40b0a52d16b3b40bb2c2315d03360bc24209e20972c200566bcf3bbe5c5b0aedd83132a8a4d5b4242ba370b6d67d9b67eb01052d132c7866b9cb502e44796d9d356e4e3cb47cc527322cd24976fe7c9257a2864151a38e568ef7a79f10d6ef27cc04ce382347a2488b1f404fdbf407fe1ca1c9d0d5649e34800e25e18951c98cae9f43555eef65fee1ea8f15828807366c3b612cd5753bf9fb8fced08855f742cddd6f765f74254f03186683d646e6f09ac2805586c7cf11998357cafc5df3f285329366f475130c928b2dceba4aa383758e7a9d20705c4bb9db619e2992f608a1ba65db254bb389468741d0502e2588aeb54390ac600c19af5c8e61383fc1bebe0029e4474051e4ef908828db9cca13277ef65db3fd47ccc2179126aaefb627719f421e20";
609626
assert_eq!(packet_bytes.len(), expected_hex.len() / 2);
610627
assert_eq!(packet_bytes.to_lower_hex_string(), expected_hex);
611628
}
629+
630+
#[test]
631+
fn test_packet_data_len_2000() {
632+
let secp = Secp256k1::new();
633+
let hops_keys = vec![
634+
SecretKey::from_slice(&[0x20; 32]).expect("32 bytes, within curve order"),
635+
SecretKey::from_slice(&[0x21; 32]).expect("32 bytes, within curve order"),
636+
SecretKey::from_slice(&[0x22; 32]).expect("32 bytes, within curve order"),
637+
];
638+
let hops_path = hops_keys.iter().map(|sk| sk.public_key(&secp)).collect();
639+
let session_key = SecretKey::from_slice(&[0x41; 32]).expect("32 bytes, within curve order");
640+
// Use the first byte to indicate the data len
641+
let hops_data = vec![vec![0], vec![1, 0], vec![5, 0, 1, 2, 3, 4]];
642+
let get_length = |packet_data: &[u8]| Some(packet_data[0] as usize + 1);
643+
let assoc_data = vec![0x42u8; 32];
644+
645+
let packet = new_onion_packet(
646+
2000,
647+
hops_path,
648+
session_key,
649+
hops_data.clone(),
650+
Some(assoc_data.clone()),
651+
)
652+
.expect("new onion packet");
653+
654+
assert_eq!(packet.packet_data.len(), 2000);
655+
656+
// Hop 0
657+
{
658+
// error cases
659+
let res = packet.clone().peel(&hops_keys[0], None, &secp, get_length);
660+
assert_eq!(res, Err(SphinxError::HmacMismatch));
661+
let res = packet
662+
.clone()
663+
.peel(&hops_keys[0], Some(&assoc_data), &secp, |_| None);
664+
assert_eq!(res, Err(SphinxError::HopDataLenUnavailable));
665+
}
666+
let res = packet.peel(&hops_keys[0], Some(&assoc_data), &secp, get_length);
667+
assert!(res.is_ok());
668+
let (data, packet) = res.unwrap();
669+
assert_eq!(data, hops_data[0]);
670+
671+
// Hop 1
672+
{
673+
// error cases
674+
let res = packet.clone().peel(&hops_keys[1], None, &secp, get_length);
675+
assert_eq!(res, Err(SphinxError::HmacMismatch));
676+
let res = packet
677+
.clone()
678+
.peel(&hops_keys[1], Some(&assoc_data), &secp, |_| None);
679+
assert_eq!(res, Err(SphinxError::HopDataLenUnavailable));
680+
}
681+
let res = packet.peel(&hops_keys[1], Some(&assoc_data), &secp, get_length);
682+
assert!(res.is_ok());
683+
let (data, packet) = res.unwrap();
684+
assert_eq!(data, hops_data[1]);
685+
686+
// Hop 2
687+
{
688+
// error cases
689+
let res = packet.clone().peel(&hops_keys[2], None, &secp, get_length);
690+
assert_eq!(res, Err(SphinxError::HmacMismatch));
691+
let res = packet
692+
.clone()
693+
.peel(&hops_keys[2], Some(&assoc_data), &secp, |_| None);
694+
assert_eq!(res, Err(SphinxError::HopDataLenUnavailable));
695+
}
696+
let res = packet.peel(&hops_keys[2], Some(&assoc_data), &secp, get_length);
697+
assert!(res.is_ok());
698+
let (data, _packet) = res.unwrap();
699+
assert_eq!(data, hops_data[2]);
700+
}
612701
}

0 commit comments

Comments
 (0)