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.
This commit is contained in:
Matt Corallo 2021-05-28 01:40:22 +00:00
parent 08ecb53915
commit 615419d525
7 changed files with 65 additions and 119 deletions

View file

@ -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<T: secp256k1::Signing, L: Deref>(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<T: secp256k1::Signing, L: Deref>(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:

View file

@ -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"),
}

View file

@ -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::<u16>();
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..]);
}

View file

@ -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]);

View file

@ -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)
}
}
}

View file

@ -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());
}
}

View file

@ -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<T>(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<W: Writer>(&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<W: Writer>(&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<R: 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]