]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Drop byte_utils in favor of native `to/from_be_bytes` methods
authorMatt Corallo <git@bluematt.me>
Fri, 28 May 2021 01:40:22 +0000 (01:40 +0000)
committerMatt Corallo <git@bluematt.me>
Sat, 29 May 2021 19:25:12 +0000 (19:25 +0000)
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
lightning/src/ln/peer_channel_encryptor.rs
lightning/src/ln/wire.rs
lightning/src/util/byte_utils.rs
lightning/src/util/chacha20.rs
lightning/src/util/poly1305.rs
lightning/src/util/ser.rs

index f80fd676c75d14397ac2e4c693f64cc3b2fffa50..0deb8b74fdcfc1542cb56f044dd387b83af72c7a 100644 (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:
index 76385fc8b063221259fbe3b99d791e49e28cfa15..7b42c68a578154aedcc0116cffac9c1a4ee5d799 100644 (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"),
                }
index 3433d9e1a3968681d2fb9356807cfeeed26ebc2c..58d336ba06942206e306423e8b643e86a982c8aa 100644 (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..]);
        }
 
index 8ae3649780634cd6a6b2c3243222cc9f40b1e782..0c6530f29e0eb1cb8b937f9842b9c83eb3d504be 100644 (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]);
index 69e4ed8d113d1cdb5a101a5fa1b60338a68d13be..cbf08f46c226a568d1bebc8c368e74d518624433 100644 (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)
                                }
                        }
                }
index 73db1577bb6df75feac3f2a26ed8047d21b2c0f7..c329c469f4685c7a84d662b1bd43d6e6e8e12bce 100644 (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());
        }
 }
 
index a52ba09c9c94100df8018ef3209f7469d46a5027..e971c6c145142a1f677437afccc51bc107c287b8 100644 (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]