diff --git a/ethereum-types/src/hash.rs b/ethereum-types/src/hash.rs index 82372ee64..070124268 100644 --- a/ethereum-types/src/hash.rs +++ b/ethereum-types/src/hash.rs @@ -74,12 +74,12 @@ macro_rules! impl_uint_conversions { fn from_uint(value: &$uint) -> Self { let mut ret = $hash::zero(); - value.to_big_endian(ret.as_bytes_mut()); + value.write_as_big_endian(ret.as_bytes_mut()); ret } fn into_uint(&self) -> $uint { - $uint::from(self.as_ref() as &[u8]) + $uint::from_big_endian(self.as_ref() as &[u8]) } } }; diff --git a/ethereum-types/src/uint.rs b/ethereum-types/src/uint.rs index 7b9b8f07e..5dfbdb310 100644 --- a/ethereum-types/src/uint.rs +++ b/ethereum-types/src/uint.rs @@ -102,8 +102,8 @@ mod tests { #[test] fn fixed_arrays_roundtrip() { let raw: U256 = "7094875209347850239487502394881".into(); - let array: [u8; 32] = raw.into(); - let new_raw = array.into(); + let array: [u8; 32] = raw.to_big_endian(); + let new_raw = U256::from_big_endian(&array); assert_eq!(raw, new_raw); } diff --git a/primitive-types/impls/codec/src/lib.rs b/primitive-types/impls/codec/src/lib.rs index feacec08a..905d17d12 100644 --- a/primitive-types/impls/codec/src/lib.rs +++ b/primitive-types/impls/codec/src/lib.rs @@ -19,8 +19,7 @@ macro_rules! impl_uint_codec { ($name: ident, $len: expr) => { impl $crate::codec::Encode for $name { fn using_encoded R>(&self, f: F) -> R { - let mut bytes = [0u8; $len * 8]; - self.to_little_endian(&mut bytes); + let bytes = self.to_little_endian(); bytes.using_encoded(f) } } diff --git a/primitive-types/impls/rlp/src/lib.rs b/primitive-types/impls/rlp/src/lib.rs index 71382a303..9b17ea4f7 100644 --- a/primitive-types/impls/rlp/src/lib.rs +++ b/primitive-types/impls/rlp/src/lib.rs @@ -23,8 +23,7 @@ macro_rules! impl_uint_rlp { impl $crate::rlp::Encodable for $name { fn rlp_append(&self, s: &mut $crate::rlp::RlpStream) { let leading_empty_bytes = $size * 8 - (self.bits() + 7) / 8; - let mut buffer = [0u8; $size * 8]; - self.to_big_endian(&mut buffer); + let buffer = self.to_big_endian(); s.encoder().encode_value(&buffer[leading_empty_bytes..]); } } @@ -35,7 +34,7 @@ macro_rules! impl_uint_rlp { if !bytes.is_empty() && bytes[0] == 0 { Err($crate::rlp::DecoderError::RlpInvalidIndirection) } else if bytes.len() <= $size * 8 { - Ok($name::from(bytes)) + Ok($name::from_big_endian(bytes)) } else { Err($crate::rlp::DecoderError::RlpIsTooBig) } diff --git a/primitive-types/impls/serde/src/lib.rs b/primitive-types/impls/serde/src/lib.rs index 63fe535cb..50587a91d 100644 --- a/primitive-types/impls/serde/src/lib.rs +++ b/primitive-types/impls/serde/src/lib.rs @@ -32,8 +32,7 @@ macro_rules! impl_uint_serde { S: $crate::serde::Serializer, { let mut slice = [0u8; 2 + 2 * $len * 8]; - let mut bytes = [0u8; $len * 8]; - self.to_big_endian(&mut bytes); + let bytes = self.to_big_endian(); $crate::serialize::serialize_uint(&mut slice, &bytes, serializer) } } @@ -48,7 +47,7 @@ macro_rules! impl_uint_serde { deserializer, $crate::serialize::ExpectedLen::Between(0, &mut bytes), )?; - Ok(bytes[0..wrote].into()) + Ok(Self::from_big_endian(&bytes[0..wrote])) } } }; diff --git a/rlp/tests/tests.rs b/rlp/tests/tests.rs index 768de3dd2..c5224fd5d 100644 --- a/rlp/tests/tests.rs +++ b/rlp/tests/tests.rs @@ -226,7 +226,7 @@ fn encode_u256() { ETestPair::from((U256::from(0x0100_0000_u64), hex!("8401000000"))), ETestPair::from((U256::from(0xffff_ffff_u64), hex!("84ffffffff"))), ETestPair::from(( - hex!(" 8090a0b0c0d0e0f00910203040506077000000000000000100000000000012f0").into(), + U256::from_big_endian(&hex!(" 8090a0b0c0d0e0f00910203040506077000000000000000100000000000012f0")), hex!("a08090a0b0c0d0e0f00910203040506077000000000000000100000000000012f0"), )), ]; @@ -482,7 +482,7 @@ fn decode_untrusted_u256() { DTestPair::from((U256::from(0x0100_0000_u64), hex!("8401000000"))), DTestPair::from((U256::from(0xffff_ffff_u64), hex!("84ffffffff"))), DTestPair::from(( - hex!(" 8090a0b0c0d0e0f00910203040506077000000000000000100000000000012f0").into(), + U256::from_big_endian(&hex!(" 8090a0b0c0d0e0f00910203040506077000000000000000100000000000012f0")), hex!("a08090a0b0c0d0e0f00910203040506077000000000000000100000000000012f0"), )), ]; diff --git a/uint/benches/bigint.rs b/uint/benches/bigint.rs index c092dfc5f..697f641d4 100644 --- a/uint/benches/bigint.rs +++ b/uint/benches/bigint.rs @@ -78,8 +78,7 @@ criterion_group!( criterion_main!(bigint); fn to_biguint(x: U256) -> BigUint { - let mut bytes = [0u8; 32]; - x.to_little_endian(&mut bytes); + let mut bytes = x.to_little_endian(); BigUint::from_bytes_le(&bytes) } @@ -662,8 +661,8 @@ fn from_fixed_array(c: &mut Criterion) { [255, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0]; c.bench_function("from_fixed_array", move |b| { b.iter(|| { - let _: U512 = black_box(black_box(ary512).into()); - let _: U256 = black_box(black_box(ary256).into()); + let _: U512 = black_box(U512::from_big_endian(black_box(&ary512))); + let _: U256 = black_box(U256::from_big_endian(black_box(&ary256))); }) }); } diff --git a/uint/src/uint.rs b/uint/src/uint.rs index bc4b7416c..08081412a 100644 --- a/uint/src/uint.rs +++ b/uint/src/uint.rs @@ -743,9 +743,17 @@ macro_rules! construct_uint { (arr[index / 8] >> (((index % 8)) * 8)) as u8 } + /// convert to big-endian bytes. + #[inline] + pub fn to_big_endian(&self) -> [u8; $n_words * 8] { + let mut bytes = [0u8; $n_words * 8]; + self.write_as_big_endian(&mut bytes); + bytes + } + /// Write to the slice in big-endian format. #[inline] - pub fn to_big_endian(&self, bytes: &mut [u8]) { + pub fn write_as_big_endian(&self, bytes: &mut [u8]) { use $crate::byteorder::{ByteOrder, BigEndian}; debug_assert!($n_words * 8 == bytes.len()); for i in 0..$n_words { @@ -753,9 +761,16 @@ macro_rules! construct_uint { } } - /// Write to the slice in little-endian format. + /// convert to little-endian bytes. #[inline] - pub fn to_little_endian(&self, bytes: &mut [u8]) { + pub fn to_little_endian(&self) -> [u8; $n_words * 8] { + let mut bytes = [0u8; $n_words * 8]; + self.write_as_little_endian(&mut bytes); + bytes + } + + #[inline] + pub fn write_as_little_endian(&self, bytes: &mut [u8]) { use $crate::byteorder::{ByteOrder, LittleEndian}; debug_assert!($n_words * 8 == bytes.len()); for i in 0..$n_words { @@ -1307,26 +1322,6 @@ macro_rules! construct_uint { } } - impl $crate::core_::convert::From<$name> for [u8; $n_words * 8] { - fn from(number: $name) -> Self { - let mut arr = [0u8; $n_words * 8]; - number.to_big_endian(&mut arr); - arr - } - } - - impl $crate::core_::convert::From<[u8; $n_words * 8]> for $name { - fn from(bytes: [u8; $n_words * 8]) -> Self { - Self::from(&bytes) - } - } - - impl<'a> $crate::core_::convert::From<&'a [u8; $n_words * 8]> for $name { - fn from(bytes: &[u8; $n_words * 8]) -> Self { - Self::from(&bytes[..]) - } - } - impl $crate::core_::default::Default for $name { fn default() -> Self { $name::zero() @@ -1360,13 +1355,6 @@ macro_rules! construct_uint { $crate::impl_map_from!($name, i32, i64); $crate::impl_map_from!($name, isize, i64); - // Converts from big endian representation. - impl<'a> $crate::core_::convert::From<&'a [u8]> for $name { - fn from(bytes: &[u8]) -> $name { - Self::from_big_endian(bytes) - } - } - $crate::impl_try_from_for_primitive!($name, u8); $crate::impl_try_from_for_primitive!($name, u16); $crate::impl_try_from_for_primitive!($name, u32); @@ -1736,8 +1724,7 @@ macro_rules! construct_uint { $crate::hex::decode_to_slice(encoded, out).map_err(Self::Err::from)?; } - let bytes_ref: &[u8] = &bytes; - Ok(From::from(bytes_ref)) + Ok(Self::from_big_endian(&bytes)) } } @@ -1787,7 +1774,7 @@ macro_rules! impl_quickcheck_arbitrary_for_uint { } }); - res.as_ref().into() + Self::from_big_endian(res.as_ref()) } } }; @@ -1809,7 +1796,7 @@ macro_rules! impl_arbitrary_for_uint { fn arbitrary(u: &mut $crate::arbitrary::Unstructured<'_>) -> $crate::arbitrary::Result { let mut res = [0u8; $n_bytes]; u.fill_buffer(&mut res)?; - Ok(Self::from(res)) + Ok(Self::from_big_endian(&res)) } } }; diff --git a/uint/tests/uint_tests.rs b/uint/tests/uint_tests.rs index a830e488e..61c03c86d 100644 --- a/uint/tests/uint_tests.rs +++ b/uint/tests/uint_tests.rs @@ -175,18 +175,18 @@ fn uint256_from() { assert_eq!(e, ud); // test initialization from bytes - let va = U256::from(&[10u8][..]); + let va = U256::from_big_endian(&[10u8][..]); assert_eq!(e, va); // more tests for initialization from bytes - assert_eq!(U256([0x1010, 0, 0, 0]), U256::from(&[0x10u8, 0x10][..])); - assert_eq!(U256([0x12f0, 0, 0, 0]), U256::from(&[0x12u8, 0xf0][..])); - assert_eq!(U256([0x12f0, 0, 0, 0]), U256::from(&[0, 0x12u8, 0xf0][..])); - assert_eq!(U256([0x12f0, 0, 0, 0]), U256::from(&[0, 0, 0, 0, 0, 0, 0, 0x12u8, 0xf0][..])); - assert_eq!(U256([0x12f0, 1, 0, 0]), U256::from(&[1, 0, 0, 0, 0, 0, 0, 0x12u8, 0xf0][..])); + assert_eq!(U256([0x1010, 0, 0, 0]), U256::from_big_endian(&[0x10u8, 0x10][..])); + assert_eq!(U256([0x12f0, 0, 0, 0]), U256::from_big_endian(&[0x12u8, 0xf0][..])); + assert_eq!(U256([0x12f0, 0, 0, 0]), U256::from_big_endian(&[0, 0x12u8, 0xf0][..])); + assert_eq!(U256([0x12f0, 0, 0, 0]), U256::from_big_endian(&[0, 0, 0, 0, 0, 0, 0, 0x12u8, 0xf0][..])); + assert_eq!(U256([0x12f0, 1, 0, 0]), U256::from_big_endian(&[1, 0, 0, 0, 0, 0, 0, 0x12u8, 0xf0][..])); assert_eq!( U256([0x12f0, 1, 0x0910203040506077, 0x8090a0b0c0d0e0f0]), - U256::from( + U256::from_big_endian( &[ 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0x09, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x77, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0x12u8, 0xf0 @@ -195,7 +195,7 @@ fn uint256_from() { ); assert_eq!( U256([0x00192437100019fa, 0x243710, 0, 0]), - U256::from(&[0x24u8, 0x37, 0x10, 0, 0x19, 0x24, 0x37, 0x10, 0, 0x19, 0xfa][..]) + U256::from_big_endian(&[0x24u8, 0x37, 0x10, 0, 0x19, 0x24, 0x37, 0x10, 0, 0x19, 0xfa][..]) ); // test initializtion from string @@ -273,9 +273,8 @@ fn uint256_try_into_primitives() { fn uint256_to() { let hex = "8090a0b0c0d0e0f00910203040506077583a2cf8264910e1436bda32571012f0"; let uint = U256::from_str(hex).unwrap(); - let mut bytes = [0u8; 32]; - uint.to_big_endian(&mut bytes); - let uint2 = U256::from(&bytes[..]); + let bytes = uint.to_big_endian(); + let uint2 = U256::from_big_endian(&bytes[..]); assert_eq!(uint, uint2); } @@ -893,7 +892,7 @@ fn big_endian() { assert_eq!(source, U256::from(1)); - source.to_big_endian(&mut target); + source.write_as_big_endian(&mut target); assert_eq!( vec![ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, @@ -905,7 +904,7 @@ fn big_endian() { let source = U256([512, 0, 0, 0]); let mut target = vec![0u8; 32]; - source.to_big_endian(&mut target); + source.write_as_big_endian(&mut target); assert_eq!( vec![ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, @@ -917,7 +916,7 @@ fn big_endian() { let source = U256([0, 512, 0, 0]); let mut target = vec![0u8; 32]; - source.to_big_endian(&mut target); + source.write_as_big_endian(&mut target); assert_eq!( vec![ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, @@ -927,7 +926,7 @@ fn big_endian() { ); let source = U256::from_str("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20").unwrap(); - source.to_big_endian(&mut target); + source.write_as_big_endian(&mut target); assert_eq!( vec![ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, @@ -1008,7 +1007,7 @@ fn little_endian() { 0xbb, 0xc5, 0x3c, 0x7d, 0x2b, 0x72, 0xe5, 0xf6, 0xa3, 0x1d, 0xca, 0x2c, 0x02, 0x00, ]; let mut result = [0u8; 32]; - number.to_little_endian(&mut result); + number.write_as_little_endian(&mut result); assert_eq!(expected, result); } @@ -1019,11 +1018,11 @@ fn slice_roundtrip() { 107, 109, 113, 127, ]; - let u256: U256 = (&raw[..]).into(); + let u256 = U256::from_big_endian(&raw[..]); let mut new_raw = [0u8; 32]; - u256.to_big_endian(&mut new_raw); + u256.write_as_big_endian(&mut new_raw); assert_eq!(&raw, &new_raw); } @@ -1039,7 +1038,7 @@ fn slice_roundtrip_le() { let mut new_raw = [0u8; 32]; - u256.to_little_endian(&mut new_raw); + u256.write_as_little_endian(&mut new_raw); assert_eq!(&raw, &new_raw); } @@ -1055,7 +1054,7 @@ fn slice_roundtrip_le2() { let mut new_raw = [0u8; 32]; - u256.to_little_endian(&mut new_raw); + u256.write_as_little_endian(&mut new_raw); assert_eq!(&raw, &new_raw[..31]); } @@ -1090,17 +1089,17 @@ fn from_big_endian() { fn into_fixed_array() { let expected: [u8; 32] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]; - let ary: [u8; 32] = U256::from(1).into(); + let ary: [u8; 32] = U256::from(1).to_big_endian(); assert_eq!(ary, expected); } #[test] fn test_u256_from_fixed_array() { let ary = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 123]; - let num: U256 = ary.into(); + let num = U256::from_big_endian(&ary); assert_eq!(num, U256::from(core::u64::MAX) + 1 + 123); - let a_ref: &U256 = &ary.into(); + let a_ref = &U256::from_big_endian(&ary); assert_eq!(a_ref, &(U256::from(core::u64::MAX) + 1 + 123)); } @@ -1108,7 +1107,7 @@ fn test_u256_from_fixed_array() { fn test_from_ref_to_fixed_array() { let ary: &[u8; 32] = &[1, 0, 1, 2, 1, 0, 1, 2, 3, 0, 3, 4, 3, 0, 3, 4, 5, 0, 5, 6, 5, 0, 5, 6, 7, 0, 7, 8, 7, 0, 7, 8]; - let big: U256 = ary.into(); + let big = U256::from_big_endian(ary); // the numbers are each row of 8 bytes reversed and cast to u64 assert_eq!(big, U256([504410889324070664, 360293493601469702, 216176097878868740, 72058702156267778u64])); } @@ -1119,11 +1118,11 @@ fn test_u512_from_fixed_array() { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, ]; - let num: U512 = ary.into(); + let num = U512::from_big_endian(&ary); assert_eq!(num, U512::from(123)); - let a_ref: &U512 = &ary.into(); - assert_eq!(a_ref, &U512::from(123)); + let a_ref = U512::from_big_endian(&ary); + assert_eq!(a_ref, U512::from(123)); } #[test] @@ -1138,7 +1137,7 @@ fn leading_zeros() { fn issue_507_roundtrip() { let mut b32 = <[u8; 32]>::default(); let a = U256::from(10); - a.to_little_endian(&mut b32); + a.write_as_little_endian(&mut b32); let b = U256::from_little_endian(&b32[..]); assert_eq!(a, b); }