Merge pull request #436 from LNP-BP/feat-u256u8

Big integers (Uint*) from byte slice array with `from_be_bytes`
This commit is contained in:
Andrew Poelstra 2020-09-09 16:42:32 +00:00 committed by GitHub
commit c8633b5bce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 1 deletions

View File

@ -1,5 +1,6 @@
extern crate bitcoin;
use std::str::FromStr;
use std::convert::Into;
fn do_test(data: &[u8]) {
macro_rules! read_ints {
@ -11,6 +12,12 @@ fn do_test(data: &[u8]) {
}
// Note BE:
let uint128 = bitcoin::util::uint::Uint128::from(&[native as u64, (native >> 8*8) as u64][..]);
// Checking two conversion methods against each other
let mut slice = [0u8; 16];
slice.copy_from_slice(&data[$start..$start + 16]);
assert_eq!(uint128, bitcoin::util::uint::Uint128::from_be_bytes(slice));
(native, uint128)
} }
}

View File

@ -52,6 +52,7 @@ macro_rules! define_le_to_array {
}
define_slice_to_be!(slice_to_u32_be, u32);
define_slice_to_be!(slice_to_u64_be, u64);
define_be_to_array!(u32_to_array_be, u32, 4);
define_slice_to_le!(slice_to_u16_le, u16);
define_slice_to_le!(slice_to_u32_le, u32);
@ -105,6 +106,7 @@ mod tests {
#[test]
fn endianness_test() {
assert_eq!(slice_to_u32_be(&[0xde, 0xad, 0xbe, 0xef]), 0xdeadbeef);
assert_eq!(slice_to_u64_be(&[0xde, 0xad, 0xbe, 0xef, 0x1b, 0xad, 0xca, 0xfe]), 0xdeadbeef1badcafe);
assert_eq!(u32_to_array_be(0xdeadbeef), [0xde, 0xad, 0xbe, 0xef]);
assert_eq!(slice_to_u16_le(&[0xad, 0xde]), 0xdead);

View File

@ -73,6 +73,7 @@ macro_rules! construct_uint {
}
/// Create an object from a given unsigned 64-bit integer
#[inline]
pub fn from_u64(init: u64) -> Option<$name> {
let mut ret = [0; $n_words];
ret[0] = init;
@ -80,11 +81,24 @@ macro_rules! construct_uint {
}
/// Create an object from a given signed 64-bit integer
#[inline]
pub fn from_i64(init: i64) -> Option<$name> {
assert!(init >= 0);
$name::from_u64(init as u64)
}
/// Creates big integer value from a byte slice array using
/// big-endian encoding
pub fn from_be_bytes(bytes: [u8; $n_words * 8]) -> $name {
use super::endian::slice_to_u64_be;
let mut slice = [0u64; $n_words];
slice.iter_mut()
.rev()
.zip(bytes.chunks(8))
.for_each(|(word, bytes)| *word = slice_to_u64_be(bytes));
$name(slice)
}
// divmod like operation, returns (quotient, remainder)
#[inline]
fn div_rem(self, other: Self) -> (Self, Self) {
@ -409,7 +423,7 @@ impl Uint256 {
#[cfg(test)]
mod tests {
use consensus::{deserialize, serialize};
use util::uint::Uint256;
use util::uint::{Uint256, Uint128};
use util::BitArray;
#[test]
@ -467,6 +481,16 @@ mod tests {
assert!(small <= small);
}
#[test]
pub fn uint_from_be_bytes() {
assert_eq!(Uint128::from_be_bytes([0x1b, 0xad, 0xca, 0xfe, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xaf, 0xba, 0xbe, 0x2b, 0xed, 0xfe, 0xed]),
Uint128([0xdeafbabe2bedfeed, 0x1badcafedeadbeef]));
assert_eq!(Uint256::from_be_bytes([0x1b, 0xad, 0xca, 0xfe, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xaf, 0xba, 0xbe, 0x2b, 0xed, 0xfe, 0xed,
0xba, 0xad, 0xf0, 0x0d, 0xde, 0xfa, 0xce, 0xda, 0x11, 0xfe, 0xd2, 0xba, 0xd1, 0xc0, 0xff, 0xe0]),
Uint256([0x11fed2bad1c0ffe0, 0xbaadf00ddefaceda, 0xdeafbabe2bedfeed, 0x1badcafedeadbeef]));
}
#[test]
pub fn uint256_arithmetic_test() {
let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();