From 80e91e5f9afb1475abaf24425aa9e466453d6470 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 28 May 2021 01:40:22 +0000 Subject: [PATCH] Drop byte_utils in favor of native `to/from_be_bytes` methods Now that our MSRV supports the native methods, we have no need for the helpers anymore. Because LLVM was already matching our byte_utils methods as byteswap functions, this should have no impact on generated (optimzied) code. This removes most of the byte_utils usage, though some remains to keep the patch size reasonable. --- lightning/src/ln/onion_utils.rs | 6 +- lightning/src/ln/peer_channel_encryptor.rs | 9 ++- lightning/src/ln/wire.rs | 6 +- lightning/src/util/byte_utils.rs | 34 ----------- lightning/src/util/chacha20.rs | 68 ++++++++-------------- lightning/src/util/poly1305.rs | 38 ++++++------ lightning/src/util/ser.rs | 23 ++++---- 7 files changed, 65 insertions(+), 119 deletions(-) diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index f80fd676c..0deb8b74f 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -11,7 +11,6 @@ use ln::{PaymentHash, PaymentSecret}; use ln::channelmanager::HTLCSource; use ln::msgs; use routing::router::RouteHop; -use util::byte_utils; use util::chacha20::ChaCha20; use util::errors::{self, APIError}; use util::ser::{Readable, Writeable, LengthCalculatingWriter}; @@ -29,6 +28,7 @@ use bitcoin::secp256k1; use prelude::*; use std::io::Cursor; +use core::convert::TryInto; use core::ops::Deref; pub(super) struct OnionKeys { @@ -367,7 +367,7 @@ pub(super) fn process_onion_failure(secp_ctx: & const NODE: u16 = 0x2000; const UPDATE: u16 = 0x1000; - let error_code = byte_utils::slice_to_be16(&error_code_slice); + let error_code = u16::from_be_bytes(error_code_slice.try_into().expect("len is 2")); error_code_ret = Some(error_code); error_packet_ret = Some(err_packet.failuremsg[2..].to_vec()); @@ -394,7 +394,7 @@ pub(super) fn process_onion_failure(secp_ctx: & } else if error_code & UPDATE == UPDATE { if let Some(update_len_slice) = err_packet.failuremsg.get(debug_field_size+2..debug_field_size+4) { - let update_len = byte_utils::slice_to_be16(&update_len_slice) as usize; + let update_len = u16::from_be_bytes(update_len_slice.try_into().expect("len is 2")) as usize; if let Some(update_slice) = err_packet.failuremsg.get(debug_field_size + 4..debug_field_size + 4 + update_len) { if let Ok(chan_update) = msgs::ChannelUpdate::read(&mut Cursor::new(&update_slice)) { // if channel_update should NOT have caused the failure: diff --git a/lightning/src/ln/peer_channel_encryptor.rs b/lightning/src/ln/peer_channel_encryptor.rs index 76385fc8b..7b42c68a5 100644 --- a/lightning/src/ln/peer_channel_encryptor.rs +++ b/lightning/src/ln/peer_channel_encryptor.rs @@ -21,7 +21,6 @@ use bitcoin::secp256k1::ecdh::SharedSecret; use bitcoin::secp256k1; use util::chacha20poly1305rfc::ChaCha20Poly1305RFC; -use util::byte_utils; use bitcoin::hashes::hex::ToHex; /// Maximum Lightning message data length according to @@ -141,7 +140,7 @@ impl PeerChannelEncryptor { #[inline] fn encrypt_with_ad(res: &mut[u8], n: u64, key: &[u8; 32], h: &[u8], plaintext: &[u8]) { let mut nonce = [0; 12]; - nonce[4..].copy_from_slice(&byte_utils::le64_to_array(n)); + nonce[4..].copy_from_slice(&n.to_le_bytes()[..]); let mut chacha = ChaCha20Poly1305RFC::new(key, &nonce, h); let mut tag = [0; 16]; @@ -152,7 +151,7 @@ impl PeerChannelEncryptor { #[inline] fn decrypt_with_ad(res: &mut[u8], n: u64, key: &[u8; 32], h: &[u8], cyphertext: &[u8]) -> Result<(), LightningError> { let mut nonce = [0; 12]; - nonce[4..].copy_from_slice(&byte_utils::le64_to_array(n)); + nonce[4..].copy_from_slice(&n.to_le_bytes()[..]); let mut chacha = ChaCha20Poly1305RFC::new(key, &nonce, h); if !chacha.decrypt(&cyphertext[0..cyphertext.len() - 16], res, &cyphertext[cyphertext.len() - 16..]) { @@ -406,7 +405,7 @@ impl PeerChannelEncryptor { *sn = 0; } - Self::encrypt_with_ad(&mut res[0..16+2], *sn, sk, &[0; 0], &byte_utils::be16_to_array(msg.len() as u16)); + Self::encrypt_with_ad(&mut res[0..16+2], *sn, sk, &[0; 0], &(msg.len() as u16).to_be_bytes()); *sn += 1; Self::encrypt_with_ad(&mut res[16+2..], *sn, sk, &[0; 0], msg); @@ -435,7 +434,7 @@ impl PeerChannelEncryptor { let mut res = [0; 2]; Self::decrypt_with_ad(&mut res, *rn, rk, &[0; 0], msg)?; *rn += 1; - Ok(byte_utils::slice_to_be16(&res)) + Ok(u16::from_be_bytes(res)) }, _ => panic!("Tried to decrypt a message prior to noise handshake completion"), } diff --git a/lightning/src/ln/wire.rs b/lightning/src/ln/wire.rs index 3433d9e1a..58d336ba0 100644 --- a/lightning/src/ln/wire.rs +++ b/lightning/src/ln/wire.rs @@ -350,8 +350,8 @@ impl Encode for msgs::GossipTimestampFilter { #[cfg(test)] mod tests { use super::*; - use util::byte_utils; use prelude::*; + use core::convert::TryInto; // Big-endian wire encoding of Pong message (type = 19, byteslen = 2). const ENCODED_PONG: [u8; 6] = [0u8, 19u8, 0u8, 2u8, 0u8, 0u8]; @@ -397,7 +397,7 @@ mod tests { #[test] fn read_unknown_message() { - let buffer = &byte_utils::be16_to_array(::core::u16::MAX); + let buffer = &::core::u16::MAX.to_be_bytes(); let mut reader = ::std::io::Cursor::new(buffer); let message = read(&mut reader).unwrap(); match message { @@ -414,7 +414,7 @@ mod tests { let type_length = ::core::mem::size_of::(); let (type_bytes, payload_bytes) = buffer.split_at(type_length); - assert_eq!(byte_utils::slice_to_be16(type_bytes), msgs::Pong::TYPE); + assert_eq!(u16::from_be_bytes(type_bytes.try_into().unwrap()), msgs::Pong::TYPE); assert_eq!(payload_bytes, &ENCODED_PONG[type_length..]); } diff --git a/lightning/src/util/byte_utils.rs b/lightning/src/util/byte_utils.rs index 8ae364978..0c6530f29 100644 --- a/lightning/src/util/byte_utils.rs +++ b/lightning/src/util/byte_utils.rs @@ -7,26 +7,6 @@ // You may not use this file except in accordance with one or both of these // licenses. -#[inline] -pub fn slice_to_be16(v: &[u8]) -> u16 { - ((v[0] as u16) << 8*1) | - ((v[1] as u16) << 8*0) -} -#[inline] -pub fn slice_to_be32(v: &[u8]) -> u32 { - ((v[0] as u32) << 8*3) | - ((v[1] as u32) << 8*2) | - ((v[2] as u32) << 8*1) | - ((v[3] as u32) << 8*0) -} -#[cfg(not(feature = "fuzztarget"))] // Used only by poly1305 -#[inline] -pub fn slice_to_le32(v: &[u8]) -> u32 { - ((v[0] as u32) << 8*0) | - ((v[1] as u32) << 8*1) | - ((v[2] as u32) << 8*2) | - ((v[3] as u32) << 8*3) -} #[inline] pub fn slice_to_be48(v: &[u8]) -> u64 { ((v[0] as u64) << 8*5) | @@ -64,16 +44,6 @@ pub fn be32_to_array(u: u32) -> [u8; 4] { v[3] = ((u >> 8*0) & 0xff) as u8; v } -#[cfg(not(feature = "fuzztarget"))] // Used only by poly1305 -#[inline] -pub fn le32_to_array(u: u32) -> [u8; 4] { - let mut v = [0; 4]; - v[0] = ((u >> 8*0) & 0xff) as u8; - v[1] = ((u >> 8*1) & 0xff) as u8; - v[2] = ((u >> 8*2) & 0xff) as u8; - v[3] = ((u >> 8*3) & 0xff) as u8; - v -} #[inline] pub fn be48_to_array(u: u64) -> [u8; 6] { assert!(u & 0xffff_0000_0000_0000 == 0); @@ -120,14 +90,10 @@ mod tests { #[test] fn test_all() { - assert_eq!(slice_to_be16(&[0xde, 0xad]), 0xdead); - assert_eq!(slice_to_be32(&[0xde, 0xad, 0xbe, 0xef]), 0xdeadbeef); - assert_eq!(slice_to_le32(&[0xef, 0xbe, 0xad, 0xde]), 0xdeadbeef); assert_eq!(slice_to_be48(&[0xde, 0xad, 0xbe, 0xef, 0x1b, 0xad]), 0xdeadbeef1bad); assert_eq!(slice_to_be64(&[0xde, 0xad, 0xbe, 0xef, 0x1b, 0xad, 0x1d, 0xea]), 0xdeadbeef1bad1dea); assert_eq!(be16_to_array(0xdead), [0xde, 0xad]); assert_eq!(be32_to_array(0xdeadbeef), [0xde, 0xad, 0xbe, 0xef]); - assert_eq!(le32_to_array(0xdeadbeef), [0xef, 0xbe, 0xad, 0xde]); assert_eq!(be48_to_array(0xdeadbeef1bad), [0xde, 0xad, 0xbe, 0xef, 0x1b, 0xad]); assert_eq!(be64_to_array(0xdeadbeef1bad1dea), [0xde, 0xad, 0xbe, 0xef, 0x1b, 0xad, 0x1d, 0xea]); assert_eq!(le64_to_array(0xdeadbeef1bad1dea), [0xea, 0x1d, 0xad, 0x1b, 0xef, 0xbe, 0xad, 0xde]); diff --git a/lightning/src/util/chacha20.rs b/lightning/src/util/chacha20.rs index 69e4ed8d1..cbf08f46c 100644 --- a/lightning/src/util/chacha20.rs +++ b/lightning/src/util/chacha20.rs @@ -14,7 +14,7 @@ use std::io; #[cfg(not(feature = "fuzztarget"))] mod real_chacha { use core::cmp; - use util::byte_utils::{slice_to_le32, le32_to_array}; + use core::convert::TryInto; #[derive(Clone, Copy, PartialEq, Eq)] #[allow(non_camel_case_types)] @@ -55,6 +55,17 @@ mod real_chacha { u32x4(self.0 << rhs.0, self.1 << rhs.1, self.2 << rhs.2, self.3 << rhs.3) } } + impl u32x4 { + fn from_bytes(bytes: &[u8]) -> Self { + assert_eq!(bytes.len(), 4*4); + Self ( + u32::from_le_bytes(bytes[0*4..1*4].try_into().expect("len is 4")), + u32::from_le_bytes(bytes[1*4..2*4].try_into().expect("len is 4")), + u32::from_le_bytes(bytes[2*4..3*4].try_into().expect("len is 4")), + u32::from_le_bytes(bytes[3*4..4*4].try_into().expect("len is 4")), + ) + } + } const BLOCK_SIZE: usize = 64; @@ -99,7 +110,7 @@ mod real_chacha { d1,d2,d3,d4 ]; for i in 0..lens.len() { - $output[i*4..(i+1)*4].copy_from_slice(&le32_to_array(lens[i])); + $output[i*4..(i+1)*4].copy_from_slice(&lens[i].to_le_bytes()); } }} } @@ -147,54 +158,23 @@ mod real_chacha { _ => unreachable!(), }; ChaChaState { - a: u32x4( - slice_to_le32(&constant[0..4]), - slice_to_le32(&constant[4..8]), - slice_to_le32(&constant[8..12]), - slice_to_le32(&constant[12..16]) - ), - b: u32x4( - slice_to_le32(&key[0..4]), - slice_to_le32(&key[4..8]), - slice_to_le32(&key[8..12]), - slice_to_le32(&key[12..16]) - ), + a: u32x4::from_bytes(&constant[0..16]), + b: u32x4::from_bytes(&key[0..16]), c: if key.len() == 16 { - u32x4( - slice_to_le32(&key[0..4]), - slice_to_le32(&key[4..8]), - slice_to_le32(&key[8..12]), - slice_to_le32(&key[12..16]) - ) + u32x4::from_bytes(&key[0..16]) } else { - u32x4( - slice_to_le32(&key[16..20]), - slice_to_le32(&key[20..24]), - slice_to_le32(&key[24..28]), - slice_to_le32(&key[28..32]) - ) + u32x4::from_bytes(&key[16..32]) }, d: if nonce.len() == 16 { - u32x4( - slice_to_le32(&nonce[0..4]), - slice_to_le32(&nonce[4..8]), - slice_to_le32(&nonce[8..12]), - slice_to_le32(&nonce[12..16]) - ) + u32x4::from_bytes(&nonce[0..16]) } else if nonce.len() == 12 { - u32x4( - 0, - slice_to_le32(&nonce[0..4]), - slice_to_le32(&nonce[4..8]), - slice_to_le32(&nonce[8..12]) - ) + let mut nonce4 = [0; 4*4]; + nonce4[4..].copy_from_slice(nonce); + u32x4::from_bytes(&nonce4) } else { - u32x4( - 0, - 0, - slice_to_le32(&nonce[0..4]), - slice_to_le32(&nonce[4..8]) - ) + let mut nonce4 = [0; 4*4]; + nonce4[8..].copy_from_slice(nonce); + u32x4::from_bytes(&nonce4) } } } diff --git a/lightning/src/util/poly1305.rs b/lightning/src/util/poly1305.rs index 73db1577b..c329c469f 100644 --- a/lightning/src/util/poly1305.rs +++ b/lightning/src/util/poly1305.rs @@ -8,7 +8,7 @@ // https://github.com/floodyberry/poly1305-donna use core::cmp::min; -use util::byte_utils::{slice_to_le32, le32_to_array}; +use core::convert::TryInto; #[derive(Clone, Copy)] pub struct Poly1305 { @@ -26,16 +26,16 @@ impl Poly1305 { let mut poly = Poly1305{ r: [0u32; 5], h: [0u32; 5], pad: [0u32; 4], leftover: 0, buffer: [0u8; 16], finalized: false }; // r &= 0xffffffc0ffffffc0ffffffc0fffffff - poly.r[0] = (slice_to_le32(&key[0..4]) ) & 0x3ffffff; - poly.r[1] = (slice_to_le32(&key[3..7]) >> 2) & 0x3ffff03; - poly.r[2] = (slice_to_le32(&key[6..10]) >> 4) & 0x3ffc0ff; - poly.r[3] = (slice_to_le32(&key[9..13]) >> 6) & 0x3f03fff; - poly.r[4] = (slice_to_le32(&key[12..16]) >> 8) & 0x00fffff; + poly.r[0] = (u32::from_le_bytes(key[ 0.. 4].try_into().expect("len is 4")) ) & 0x3ffffff; + poly.r[1] = (u32::from_le_bytes(key[ 3.. 7].try_into().expect("len is 4")) >> 2) & 0x3ffff03; + poly.r[2] = (u32::from_le_bytes(key[ 6..10].try_into().expect("len is 4")) >> 4) & 0x3ffc0ff; + poly.r[3] = (u32::from_le_bytes(key[ 9..13].try_into().expect("len is 4")) >> 6) & 0x3f03fff; + poly.r[4] = (u32::from_le_bytes(key[12..16].try_into().expect("len is 4")) >> 8) & 0x00fffff; - poly.pad[0] = slice_to_le32(&key[16..20]); - poly.pad[1] = slice_to_le32(&key[20..24]); - poly.pad[2] = slice_to_le32(&key[24..28]); - poly.pad[3] = slice_to_le32(&key[28..32]); + poly.pad[0] = u32::from_le_bytes(key[16..20].try_into().expect("len is 4")); + poly.pad[1] = u32::from_le_bytes(key[20..24].try_into().expect("len is 4")); + poly.pad[2] = u32::from_le_bytes(key[24..28].try_into().expect("len is 4")); + poly.pad[3] = u32::from_le_bytes(key[28..32].try_into().expect("len is 4")); poly } @@ -61,11 +61,11 @@ impl Poly1305 { let mut h4 = self.h[4]; // h += m - h0 += (slice_to_le32(&m[0..4]) ) & 0x3ffffff; - h1 += (slice_to_le32(&m[3..7]) >> 2) & 0x3ffffff; - h2 += (slice_to_le32(&m[6..10]) >> 4) & 0x3ffffff; - h3 += (slice_to_le32(&m[9..13]) >> 6) & 0x3ffffff; - h4 += (slice_to_le32(&m[12..16]) >> 8) | hibit; + h0 += (u32::from_le_bytes(m[ 0.. 4].try_into().expect("len is 4")) ) & 0x3ffffff; + h1 += (u32::from_le_bytes(m[ 3.. 7].try_into().expect("len is 4")) >> 2) & 0x3ffffff; + h2 += (u32::from_le_bytes(m[ 6..10].try_into().expect("len is 4")) >> 4) & 0x3ffffff; + h3 += (u32::from_le_bytes(m[ 9..13].try_into().expect("len is 4")) >> 6) & 0x3ffffff; + h4 += (u32::from_le_bytes(m[12..16].try_into().expect("len is 4")) >> 8) | hibit; // h *= r let d0 = (h0 as u64 * r0 as u64) + (h1 as u64 * s4 as u64) + (h2 as u64 * s3 as u64) + (h3 as u64 * s2 as u64) + (h4 as u64 * s1 as u64); @@ -196,10 +196,10 @@ impl Poly1305 { if !self.finalized{ self.finish(); } - output[0..4].copy_from_slice(&le32_to_array(self.h[0])); - output[4..8].copy_from_slice(&le32_to_array(self.h[1])); - output[8..12].copy_from_slice(&le32_to_array(self.h[2])); - output[12..16].copy_from_slice(&le32_to_array(self.h[3])); + output[0..4].copy_from_slice(&self.h[0].to_le_bytes()); + output[4..8].copy_from_slice(&self.h[1].to_le_bytes()); + output[8..12].copy_from_slice(&self.h[2].to_le_bytes()); + output[12..16].copy_from_slice(&self.h[3].to_le_bytes()); } } diff --git a/lightning/src/util/ser.rs b/lightning/src/util/ser.rs index a52ba09c9..e971c6c14 100644 --- a/lightning/src/util/ser.rs +++ b/lightning/src/util/ser.rs @@ -29,9 +29,8 @@ use bitcoin::hash_types::{Txid, BlockHash}; use core::marker::Sized; use ln::msgs::DecodeError; use ln::{PaymentPreimage, PaymentHash, PaymentSecret}; -use util::byte_utils; -use util::byte_utils::{be64_to_array, be48_to_array, be32_to_array, be16_to_array, slice_to_be16, slice_to_be32, slice_to_be48, slice_to_be64}; +use util::byte_utils::{be48_to_array, slice_to_be48}; /// serialization buffer size pub const MAX_BUF_SIZE: usize = 64 * 1024; @@ -183,7 +182,7 @@ pub trait Writeable { 0u16.write(&mut msg).unwrap(); self.write(&mut msg).unwrap(); let len = msg.0.len(); - msg.0[..2].copy_from_slice(&byte_utils::be16_to_array(len as u16 - 2)); + msg.0[..2].copy_from_slice(&(len as u16 - 2).to_be_bytes()); msg.0 } } @@ -344,18 +343,18 @@ impl Readable for BigSize { pub(crate) struct HighZeroBytesDroppedVarInt(pub T); macro_rules! impl_writeable_primitive { - ($val_type:ty, $meth_write:ident, $len: expr, $meth_read:ident) => { + ($val_type:ty, $len: expr) => { impl Writeable for $val_type { #[inline] fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - writer.write_all(&$meth_write(*self)) + writer.write_all(&self.to_be_bytes()) } } impl Writeable for HighZeroBytesDroppedVarInt<$val_type> { #[inline] fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { // Skip any full leading 0 bytes when writing (in BE): - writer.write_all(&$meth_write(self.0)[(self.0.leading_zeros()/8) as usize..$len]) + writer.write_all(&self.0.to_be_bytes()[(self.0.leading_zeros()/8) as usize..$len]) } } impl Readable for $val_type { @@ -363,7 +362,7 @@ macro_rules! impl_writeable_primitive { fn read(reader: &mut R) -> Result<$val_type, DecodeError> { let mut buf = [0; $len]; reader.read_exact(&mut buf)?; - Ok($meth_read(&buf)) + Ok(<$val_type>::from_be_bytes(buf)) } } impl Readable for HighZeroBytesDroppedVarInt<$val_type> { @@ -382,7 +381,9 @@ macro_rules! impl_writeable_primitive { } if total_read_len == 0 || buf[$len] != 0 { let first_byte = $len - ($len - total_read_len); - Ok(HighZeroBytesDroppedVarInt($meth_read(&buf[first_byte..first_byte + $len]))) + let mut bytes = [0; $len]; + bytes.copy_from_slice(&buf[first_byte..first_byte + $len]); + Ok(HighZeroBytesDroppedVarInt(<$val_type>::from_be_bytes(bytes))) } else { // If the encoding had extra zero bytes, return a failure even though we know // what they meant (as the TLV test vectors require this) @@ -393,9 +394,9 @@ macro_rules! impl_writeable_primitive { } } -impl_writeable_primitive!(u64, be64_to_array, 8, slice_to_be64); -impl_writeable_primitive!(u32, be32_to_array, 4, slice_to_be32); -impl_writeable_primitive!(u16, be16_to_array, 2, slice_to_be16); +impl_writeable_primitive!(u64, 8); +impl_writeable_primitive!(u32, 4); +impl_writeable_primitive!(u16, 2); impl Writeable for u8 { #[inline] -- 2.39.5