// You may not use this file except in accordance with one or both of these
// licenses.
-use ln::{PaymentHash, PaymentPreimage, PaymentSecret};
-use ln::channelmanager::HTLCSource;
-use ln::msgs;
-use ln::wire::Encode;
-use routing::gossip::NetworkUpdate;
-use routing::router::RouteHop;
-use util::chacha20::{ChaCha20, ChaChaReader};
-use util::errors::{self, APIError};
-use util::ser::{Readable, ReadableArgs, Writeable, LengthCalculatingWriter};
-use util::logger::Logger;
+use crate::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
+use crate::ln::channelmanager::HTLCSource;
+use crate::ln::msgs;
+use crate::ln::wire::Encode;
+use crate::routing::gossip::NetworkUpdate;
+use crate::routing::router::RouteHop;
+use crate::util::chacha20::{ChaCha20, ChaChaReader};
+use crate::util::errors::{self, APIError};
+use crate::util::ser::{Readable, ReadableArgs, Writeable, LengthCalculatingWriter};
+use crate::util::logger::Logger;
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::hashes::cmp::fixed_time_eq;
use bitcoin::secp256k1::ecdh::SharedSecret;
use bitcoin::secp256k1;
-use prelude::*;
-use io::{Cursor, Read};
+use crate::prelude::*;
+use crate::io::{Cursor, Read};
use core::convert::{AsMut, TryInto};
use core::ops::Deref;
} else { unreachable!(); }
}
-/// An input used when decoding an onion packet.
-pub(crate) trait DecodeInput {
- type Arg;
- /// If Some, this is the input when checking the hmac of the onion packet.
- fn payment_hash(&self) -> Option<&PaymentHash>;
- /// Read argument when decrypting our hop payload.
- fn read_arg(self) -> Self::Arg;
-}
-
-impl DecodeInput for PaymentHash {
- type Arg = ();
- fn payment_hash(&self) -> Option<&PaymentHash> {
- Some(self)
- }
- fn read_arg(self) -> Self::Arg { () }
-}
-
-impl DecodeInput for SharedSecret {
- type Arg = SharedSecret;
- fn payment_hash(&self) -> Option<&PaymentHash> {
- None
- }
- fn read_arg(self) -> Self::Arg { self }
-}
-
/// Allows `decode_next_hop` to return the next hop packet bytes for either payments or onion
/// message forwards.
pub(crate) trait NextPacketBytes: AsMut<[u8]> {
}
pub(crate) fn decode_next_payment_hop(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], payment_hash: PaymentHash) -> Result<Hop, OnionDecodeErr> {
- match decode_next_hop(shared_secret, hop_data, hmac_bytes, payment_hash) {
+ match decode_next_hop(shared_secret, hop_data, hmac_bytes, Some(payment_hash), ()) {
Ok((next_hop_data, None)) => Ok(Hop::Receive(next_hop_data)),
Ok((next_hop_data, Some((next_hop_hmac, FixedSizeOnionPacket(new_packet_bytes))))) => {
Ok(Hop::Forward {
}
}
-pub(crate) fn decode_next_hop<D: DecodeInput, R: ReadableArgs<D::Arg>, N: NextPacketBytes>(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], decode_input: D) -> Result<(R, Option<([u8; 32], N)>), OnionDecodeErr> {
+pub(crate) fn decode_next_untagged_hop<T, R: ReadableArgs<T>, N: NextPacketBytes>(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], read_args: T) -> Result<(R, Option<([u8; 32], N)>), OnionDecodeErr> {
+ decode_next_hop(shared_secret, hop_data, hmac_bytes, None, read_args)
+}
+
+fn decode_next_hop<T, R: ReadableArgs<T>, N: NextPacketBytes>(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], payment_hash: Option<PaymentHash>, read_args: T) -> Result<(R, Option<([u8; 32], N)>), OnionDecodeErr> {
let (rho, mu) = gen_rho_mu_from_shared_secret(&shared_secret);
let mut hmac = HmacEngine::<Sha256>::new(&mu);
hmac.input(hop_data);
- if let Some(payment_hash) = decode_input.payment_hash() {
- hmac.input(&payment_hash.0[..]);
+ if let Some(tag) = payment_hash {
+ hmac.input(&tag.0[..]);
}
if !fixed_time_eq(&Hmac::from_engine(hmac).into_inner(), &hmac_bytes) {
return Err(OnionDecodeErr::Malformed {
let mut chacha = ChaCha20::new(&rho, &[0u8; 8]);
let mut chacha_stream = ChaChaReader { chacha: &mut chacha, read: Cursor::new(&hop_data[..]) };
- match R::read(&mut chacha_stream, decode_input.read_arg()) {
+ match R::read(&mut chacha_stream, read_args) {
Err(err) => {
let error_code = match err {
msgs::DecodeError::UnknownVersion => 0x4000 | 1, // unknown realm byte
#[cfg(test)]
mod tests {
- use io;
- use prelude::*;
- use ln::PaymentHash;
- use ln::features::{ChannelFeatures, NodeFeatures};
- use routing::router::{Route, RouteHop};
- use ln::msgs;
- use util::ser::{Writeable, Writer};
+ use crate::io;
+ use crate::prelude::*;
+ use crate::ln::PaymentHash;
+ use crate::ln::features::{ChannelFeatures, NodeFeatures};
+ use crate::routing::router::{Route, RouteHop};
+ use crate::ln::msgs;
+ use crate::util::ser::{Writeable, Writer};
use hex;