From 918397684a2db21990a9e69571129b806aa5f911 Mon Sep 17 00:00:00 2001 From: Psilon Date: Fri, 20 Jul 2018 18:18:45 +0300 Subject: [PATCH 01/11] adds no std support --- src/uint.rs | 54 ++++++++++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/src/uint.rs b/src/uint.rs index a86826f..20043a5 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -430,7 +430,7 @@ macro_rules! construct_uint { use core::cmp; use rustc_hex::ToHex;; - if self.is_zero() { return "0".to_owned(); } // special case. + if self.is_zero() { return "0".to_owned(); } // construct_uintspecial case. let mut bytes = [0u8; 8 * $n_words]; self.to_big_endian(&mut bytes); let bp7 = self.bits() + 7; @@ -910,34 +910,35 @@ macro_rules! construct_uint { } } - #[cfg(feature="std")] impl ::core::fmt::Debug for $name { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { ::core::fmt::Display::fmt(self, f) } } - #[cfg(feature="std")] impl ::core::fmt::Display for $name { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { if self.is_zero() { return write!(f, "0"); } - let mut s = String::new(); + let mut buf = [0_u8, $n_words*8]; + let mut i = buf.len() - 1; let mut current = *self; let ten = $name::from(10); while !current.is_zero() { - s = format!("{}{}", (current % ten).low_u32(), s); + let digit = (current % ten).low_u32() as u8; + buf[i] = digit + b'0'; current = current / ten; + i -= 1; } - write!(f, "{}", s) + let s = unsafe {::core::str::from_utf8_unchecked(&buf[i..])}; + f.write_str(s) } } - #[cfg(feature="std")] impl ::core::fmt::LowerHex for $name { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { let &$name(ref data) = self; @@ -955,13 +956,6 @@ macro_rules! construct_uint { Ok(()) } } - - #[cfg(feature="std")] - impl From<&'static str> for $name { - fn from(s: &'static str) -> Self { - s.parse().unwrap() - } - } ); } @@ -1997,25 +1991,25 @@ mod tests { let (result, _) = U256([1, 0, 0, 0]).overflowing_mul(U256([0, 0, 0, u64::max_value()])); assert_eq!(U256([0, 0, 0, u64::max_value()]), result); - let x1: U256 = "0000000000000000000000000000000000000000000000000000012365124623".into(); - let x2sqr_right: U256 = "000000000000000000000000000000000000000000014baeef72e0378e2328c9".into(); + let x1: U256 = "0000000000000000000000000000000000000000000000000000012365124623".parse().unwrap(); + let x2sqr_right: U256 = "000000000000000000000000000000000000000000014baeef72e0378e2328c9".parse().unwrap(); let x1sqr = x1 * x1; assert_eq!(x2sqr_right, x1sqr); let x1cube = x1sqr * x1; - let x1cube_right: U256 = "0000000000000000000000000000000001798acde139361466f712813717897b".into(); + let x1cube_right: U256 = "0000000000000000000000000000000001798acde139361466f712813717897b".parse().unwrap(); assert_eq!(x1cube_right, x1cube); let x1quad = x1cube * x1; - let x1quad_right: U256 = "000000000000000000000001adbdd6bd6ff027485484b97f8a6a4c7129756dd1".into(); + let x1quad_right: U256 = "000000000000000000000001adbdd6bd6ff027485484b97f8a6a4c7129756dd1".parse().unwrap(); assert_eq!(x1quad_right, x1quad); let x1penta = x1quad * x1; - let x1penta_right: U256 = "00000000000001e92875ac24be246e1c57e0507e8c46cc8d233b77f6f4c72993".into(); + let x1penta_right: U256 = "00000000000001e92875ac24be246e1c57e0507e8c46cc8d233b77f6f4c72993".parse().unwrap(); assert_eq!(x1penta_right, x1penta); let x1septima = x1penta * x1; - let x1septima_right: U256 = "00022cca1da3f6e5722b7d3cc5bbfb486465ebc5a708dd293042f932d7eee119".into(); + let x1septima_right: U256 = "00022cca1da3f6e5722b7d3cc5bbfb486465ebc5a708dd293042f932d7eee119".parse().unwrap(); assert_eq!(x1septima_right, x1septima); } @@ -2028,7 +2022,7 @@ mod tests { #[test] fn little_endian() { - let number: U256 = "00022cca1da3f6e5722b7d3cc5bbfb486465ebc5a708dd293042f932d7eee119".into(); + let number: U256 = "00022cca1da3f6e5722b7d3cc5bbfb486465ebc5a708dd293042f932d7eee119".parse().unwrap(); let expected = [ 0x19, 0xe1, 0xee, 0xd7, 0x32, 0xf9, 0x42, 0x30, @@ -2111,7 +2105,7 @@ mod tests { #[test] fn fixed_arrays_roundtrip() { - let raw: U256 = "7094875209347850239487502394881".into(); + let raw: U256 = "7094875209347850239487502394881".parse().unwrap(); let array: [u8; 32] = raw.into(); let new_raw = array.into(); @@ -2148,18 +2142,18 @@ mod tests { #[test] fn leading_zeros() { - assert_eq!(U256::from("000000000000000000000001adbdd6bd6ff027485484b97f8a6a4c7129756dd1").leading_zeros(), 95); - assert_eq!(U256::from("f00000000000000000000001adbdd6bd6ff027485484b97f8a6a4c7129756dd1").leading_zeros(), 0); - assert_eq!(U256::from("0000000000000000000000000000000000000000000000000000000000000001").leading_zeros(), 255); - assert_eq!(U256::from("0000000000000000000000000000000000000000000000000000000000000000").leading_zeros(), 256); + assert_eq!("000000000000000000000001adbdd6bd6ff027485484b97f8a6a4c7129756dd1".parse::().unwrap().leading_zeros(), 95); + assert_eq!("f00000000000000000000001adbdd6bd6ff027485484b97f8a6a4c7129756dd1".parse::().unwrap().leading_zeros(), 0); + assert_eq!("0000000000000000000000000000000000000000000000000000000000000001".parse::().unwrap().leading_zeros(), 255); + assert_eq!("0000000000000000000000000000000000000000000000000000000000000000".parse::().unwrap().leading_zeros(), 256); } #[test] fn trailing_zeros() { - assert_eq!(U256::from("1adbdd6bd6ff027485484b97f8a6a4c7129756dd100000000000000000000000").trailing_zeros(), 92); - assert_eq!(U256::from("1adbdd6bd6ff027485484b97f8a6a4c7129756dd10000000000000000000000f").trailing_zeros(), 0); - assert_eq!(U256::from("8000000000000000000000000000000000000000000000000000000000000000").trailing_zeros(), 255); - assert_eq!(U256::from("0000000000000000000000000000000000000000000000000000000000000000").trailing_zeros(), 256); + assert_eq!("1adbdd6bd6ff027485484b97f8a6a4c7129756dd100000000000000000000000".parse::().unwrap().trailing_zeros(), 92); + assert_eq!("1adbdd6bd6ff027485484b97f8a6a4c7129756dd10000000000000000000000f".parse::().unwrap().trailing_zeros(), 0); + assert_eq!("8000000000000000000000000000000000000000000000000000000000000000".parse::().unwrap().trailing_zeros(), 255); + assert_eq!("0000000000000000000000000000000000000000000000000000000000000000".parse::().unwrap().trailing_zeros(), 256); } mod laws { From 6fc5c22799016ad6c54b0e500504fefec7d750ff Mon Sep 17 00:00:00 2001 From: Psilon Date: Mon, 23 Jul 2018 11:52:26 +0300 Subject: [PATCH 02/11] typos --- src/uint.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/uint.rs b/src/uint.rs index 20043a5..e62a2d3 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -430,7 +430,7 @@ macro_rules! construct_uint { use core::cmp; use rustc_hex::ToHex;; - if self.is_zero() { return "0".to_owned(); } // construct_uintspecial case. + if self.is_zero() { return "0".to_owned(); } // special case. let mut bytes = [0u8; 8 * $n_words]; self.to_big_endian(&mut bytes); let bp7 = self.bits() + 7; @@ -934,6 +934,7 @@ macro_rules! construct_uint { i -= 1; } + // sequence of `'0'..'9'` chars are guaranteed to be a valid UTF8 string let s = unsafe {::core::str::from_utf8_unchecked(&buf[i..])}; f.write_str(s) } @@ -1167,7 +1168,7 @@ known_heap_size!(0, U128, U256); #[cfg(test)] #[cfg(feature="std")] -mod tests { +mod std_tests { use uint::{U128, U256, U512}; use std::str::FromStr; use super::FromDecStrErr; From 8753e8c122fe15cf4c7a86c72c027aa5a0eecb9e Mon Sep 17 00:00:00 2001 From: Psilon Date: Mon, 23 Jul 2018 12:45:42 +0300 Subject: [PATCH 03/11] overflow issue --- src/uint.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/uint.rs b/src/uint.rs index e62a2d3..bdc1530 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -927,15 +927,18 @@ macro_rules! construct_uint { let mut current = *self; let ten = $name::from(10); - while !current.is_zero() { + loop { let digit = (current % ten).low_u32() as u8; buf[i] = digit + b'0'; current = current / ten; + if !current.is_zero() { + break; + } i -= 1; } // sequence of `'0'..'9'` chars are guaranteed to be a valid UTF8 string - let s = unsafe {::core::str::from_utf8_unchecked(&buf[i..])}; + let s = ::core::str::from_utf8(&buf[i..]).unwrap(); f.write_str(s) } } @@ -2016,8 +2019,7 @@ mod std_tests { #[test] fn example() { - let mut val: U256 = 1023.into(); - for _ in 0..200 { val = val * 2.into() } + let val = (0..200).fold(U256::from(1023), |acc, _| acc * 2.into()); assert_eq!(&format!("{}", val), "1643897619276947051879427220465009342380213662639797070513307648"); } From 3188c1666a2479f3efbd8cc2d82e5d13460bc9be Mon Sep 17 00:00:00 2001 From: Psilon Date: Mon, 23 Jul 2018 13:12:12 +0300 Subject: [PATCH 04/11] buffer fix --- src/uint.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uint.rs b/src/uint.rs index bdc1530..06ec4fa 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -922,7 +922,7 @@ macro_rules! construct_uint { return write!(f, "0"); } - let mut buf = [0_u8, $n_words*8]; + let mut buf = [0_u8; $n_words*16]; let mut i = buf.len() - 1; let mut current = *self; let ten = $name::from(10); @@ -931,7 +931,7 @@ macro_rules! construct_uint { let digit = (current % ten).low_u32() as u8; buf[i] = digit + b'0'; current = current / ten; - if !current.is_zero() { + if current.is_zero() { break; } i -= 1; From 2cba077589ac7ad04c30d75ca528cb3f45eda5f9 Mon Sep 17 00:00:00 2001 From: Psilon Date: Mon, 23 Jul 2018 13:22:56 +0300 Subject: [PATCH 05/11] Fixes quickcheck --- src/uint.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uint.rs b/src/uint.rs index 06ec4fa..7a6526a 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -922,7 +922,7 @@ macro_rules! construct_uint { return write!(f, "0"); } - let mut buf = [0_u8; $n_words*16]; + let mut buf = [0_u8; $n_words*20]; let mut i = buf.len() - 1; let mut current = *self; let ten = $name::from(10); @@ -938,7 +938,7 @@ macro_rules! construct_uint { } // sequence of `'0'..'9'` chars are guaranteed to be a valid UTF8 string - let s = ::core::str::from_utf8(&buf[i..]).unwrap(); + let s = unsafe {::core::str::from_utf8_unchecked(&buf[i..])}; f.write_str(s) } } From 817ea95e24a8b7367919b92d60d56cfe910cac73 Mon Sep 17 00:00:00 2001 From: Psilon Date: Mon, 23 Jul 2018 13:29:06 +0300 Subject: [PATCH 06/11] typo --- src/uint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uint.rs b/src/uint.rs index 7a6526a..9b4c9d9 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -937,7 +937,7 @@ macro_rules! construct_uint { i -= 1; } - // sequence of `'0'..'9'` chars are guaranteed to be a valid UTF8 string + // sequence of `'0'..'9'` chars is guaranteed to be a valid UTF8 string let s = unsafe {::core::str::from_utf8_unchecked(&buf[i..])}; f.write_str(s) } From d91191dd2b656eff3bb5011bbf1378fd6166c7c8 Mon Sep 17 00:00:00 2001 From: Psilon Date: Mon, 23 Jul 2018 13:37:46 +0300 Subject: [PATCH 07/11] Removes extra cast --- src/uint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uint.rs b/src/uint.rs index 9b4c9d9..645f302 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -928,7 +928,7 @@ macro_rules! construct_uint { let ten = $name::from(10); loop { - let digit = (current % ten).low_u32() as u8; + let digit = (current % ten).low_u64() as u8; buf[i] = digit + b'0'; current = current / ten; if current.is_zero() { From b7817e516ad11bfdd57770e41440ebc275b84c19 Mon Sep 17 00:00:00 2001 From: Psilon Date: Mon, 23 Jul 2018 19:39:07 +0300 Subject: [PATCH 08/11] Returns `From` trait (it's better to create a separate PR). Adds fmt tests --- src/uint.rs | 141 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 82 insertions(+), 59 deletions(-) diff --git a/src/uint.rs b/src/uint.rs index 645f302..a3a9665 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -270,6 +270,8 @@ macro_rules! construct_uint { pub struct $name(pub [u64; $n_words]); impl $name { + pub const MAX_VALUE: $name = $name([u64::max_value(); $n_words]); + /// Convert from a decimal string. pub fn from_dec_str(value: &str) -> Result { if !value.bytes().all(|b| b >= 48 && b <= 57) { @@ -960,6 +962,13 @@ macro_rules! construct_uint { Ok(()) } } + + #[cfg(feature="std")] + impl From<&'static str> for $name { + fn from(s: &'static str) -> Self { + s.parse().unwrap() + } + } ); } @@ -1169,6 +1178,19 @@ impl From for [u8; 64] { #[cfg(feature="heapsizeof")] known_heap_size!(0, U128, U256); +#[cfg(test)] +mod tests { + use uint::U256; + + #[test] + pub fn display() { + let value = U256::MAX_VALUE; + let mut buf = [b'0'; 64]; + write!(&buf, "{}", value); + assert_eq!(string, ""); + } +} + #[cfg(test)] #[cfg(feature="std")] mod std_tests { @@ -1451,9 +1473,9 @@ mod std_tests { pub fn uint128_add_overflow() { assert_eq!( U128::from_str("ffffffffffffffffffffffffffffffff").unwrap() - .overflowing_add( - U128::from_str("ffffffffffffffffffffffffffffffff").unwrap() - ), + .overflowing_add( + U128::from_str("ffffffffffffffffffffffffffffffff").unwrap() + ), (U128::from_str("fffffffffffffffffffffffffffffffe").unwrap(), true) ); } @@ -1478,8 +1500,8 @@ mod std_tests { pub fn uint512_mul() { assert_eq!( U512::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap() - * - U512::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), + * + U512::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), U512::from_str("3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000001").unwrap() ); } @@ -1488,9 +1510,9 @@ mod std_tests { pub fn uint256_mul_overflow() { assert_eq!( U256::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap() - .overflowing_mul( - U256::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap() - ), + .overflowing_mul( + U256::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap() + ), (U256::from_str("1").unwrap(), true) ); } @@ -1507,11 +1529,11 @@ mod std_tests { pub fn uint256_sub_overflow() { assert_eq!( U256::from_str("0").unwrap() - .overflowing_sub( - U256::from_str("1").unwrap() - ), + .overflowing_sub( + U256::from_str("1").unwrap() + ), (U256::from_str("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), true) - ); + ); } #[test] @@ -1526,7 +1548,7 @@ mod std_tests { pub fn uint256_shl() { assert_eq!( U256::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap() - << 4, + << 4, U256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0").unwrap() ); } @@ -1535,12 +1557,12 @@ mod std_tests { pub fn uint256_shl_words() { assert_eq!( U256::from_str("0000000000000001ffffffffffffffffffffffffffffffffffffffffffffffff").unwrap() - << 64, + << 64, U256::from_str("ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000").unwrap() ); assert_eq!( U256::from_str("0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff").unwrap() - << 64, + << 64, U256::from_str("ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000").unwrap() ); } @@ -1549,10 +1571,10 @@ mod std_tests { pub fn uint256_mul() { assert_eq!( U256::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap() - * - U256::from_str("2").unwrap(), + * + U256::from_str("2").unwrap(), U256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe").unwrap() - ); + ); } #[test] @@ -1587,8 +1609,8 @@ mod std_tests { assert_eq!(format!("{}", U256::from(0)), "0"); } - #[test] - fn u512_multi_adds() { + #[test] + fn u512_multi_adds() { let (result, _) = U512([0, 0, 0, 0, 0, 0, 0, 0]).overflowing_add(U512([0, 0, 0, 0, 0, 0, 0, 0])); assert_eq!(result, U512([0, 0, 0, 0, 0, 0, 0, 0])); @@ -1613,32 +1635,32 @@ mod std_tests { let (_, overflow) = U512([0, 0, 0, 0, 0, 0, 0, MAX]) .overflowing_add(U512([0, 0, 0, 0, 0, 0, 0, MAX])); - assert!(overflow); + assert!(overflow); let (_, overflow) = U512([0, 0, 0, 0, 0, 0, 0, MAX]) .overflowing_add(U512([0, 0, 0, 0, 0, 0, 0, 0])); assert!(!overflow); } - #[test] - fn u256_multi_adds() { - let (result, _) = U256([0, 0, 0, 0]).overflowing_add(U256([0, 0, 0, 0])); - assert_eq!(result, U256([0, 0, 0, 0])); + #[test] + fn u256_multi_adds() { + let (result, _) = U256([0, 0, 0, 0]).overflowing_add(U256([0, 0, 0, 0])); + assert_eq!(result, U256([0, 0, 0, 0])); - let (result, _) = U256([0, 0, 0, 1]).overflowing_add(U256([0, 0, 0, 1])); - assert_eq!(result, U256([0, 0, 0, 2])); + let (result, _) = U256([0, 0, 0, 1]).overflowing_add(U256([0, 0, 0, 1])); + assert_eq!(result, U256([0, 0, 0, 2])); - let (result, overflow) = U256([0, 0, 2, 1]).overflowing_add(U256([0, 0, 3, 1])); - assert_eq!(result, U256([0, 0, 5, 2])); - assert!(!overflow); + let (result, overflow) = U256([0, 0, 2, 1]).overflowing_add(U256([0, 0, 3, 1])); + assert_eq!(result, U256([0, 0, 5, 2])); + assert!(!overflow); - let (_, overflow) = U256([MAX, MAX, MAX, MAX]) + let (_, overflow) = U256([MAX, MAX, MAX, MAX]) .overflowing_add(U256([MAX, MAX, MAX, MAX])); - assert!(overflow); + assert!(overflow); - let (_, overflow) = U256([0, 0, 0, MAX]).overflowing_add(U256([0, 0, 0, MAX])); - assert!(overflow); - } + let (_, overflow) = U256([0, 0, 0, MAX]).overflowing_add(U256([0, 0, 0, MAX])); + assert!(overflow); + } #[test] @@ -1787,8 +1809,8 @@ mod std_tests { assert_eq!(U256([0, 0, 0, MAX]), result); } - #[test] - fn u256_multi_muls_overflow() { + #[test] + fn u256_multi_muls_overflow() { let (_, overflow) = U256([1, 0, 0, 0]).overflowing_mul(U256([0, 0, 0, 0])); assert!(!overflow); @@ -1815,7 +1837,7 @@ mod std_tests { let (_, overflow) = U256([0, 0, 8, 0]).overflowing_mul(U256([0, 0, 7, 0])); assert!(overflow); - } + } #[test] fn big_endian() { @@ -1827,7 +1849,7 @@ mod std_tests { source.to_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, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8], + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8], target); let source = U256([512, 0, 0, 0]); @@ -1836,7 +1858,7 @@ mod std_tests { source.to_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, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8], + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8], target); let source = U256([0, 512, 0, 0]); @@ -1845,14 +1867,14 @@ mod std_tests { source.to_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, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8], + 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8], target); let source = U256::from_str("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20").unwrap(); source.to_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, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20], + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20], target); } @@ -1995,37 +2017,38 @@ mod std_tests { let (result, _) = U256([1, 0, 0, 0]).overflowing_mul(U256([0, 0, 0, u64::max_value()])); assert_eq!(U256([0, 0, 0, u64::max_value()]), result); - let x1: U256 = "0000000000000000000000000000000000000000000000000000012365124623".parse().unwrap(); - let x2sqr_right: U256 = "000000000000000000000000000000000000000000014baeef72e0378e2328c9".parse().unwrap(); + let x1: U256 = "0000000000000000000000000000000000000000000000000000012365124623".into(); + let x2sqr_right: U256 = "000000000000000000000000000000000000000000014baeef72e0378e2328c9".into(); let x1sqr = x1 * x1; assert_eq!(x2sqr_right, x1sqr); let x1cube = x1sqr * x1; - let x1cube_right: U256 = "0000000000000000000000000000000001798acde139361466f712813717897b".parse().unwrap(); + let x1cube_right: U256 = "0000000000000000000000000000000001798acde139361466f712813717897b".into(); assert_eq!(x1cube_right, x1cube); let x1quad = x1cube * x1; - let x1quad_right: U256 = "000000000000000000000001adbdd6bd6ff027485484b97f8a6a4c7129756dd1".parse().unwrap(); + let x1quad_right: U256 = "000000000000000000000001adbdd6bd6ff027485484b97f8a6a4c7129756dd1".into(); assert_eq!(x1quad_right, x1quad); let x1penta = x1quad * x1; - let x1penta_right: U256 = "00000000000001e92875ac24be246e1c57e0507e8c46cc8d233b77f6f4c72993".parse().unwrap(); + let x1penta_right: U256 = "00000000000001e92875ac24be246e1c57e0507e8c46cc8d233b77f6f4c72993".into(); assert_eq!(x1penta_right, x1penta); let x1septima = x1penta * x1; - let x1septima_right: U256 = "00022cca1da3f6e5722b7d3cc5bbfb486465ebc5a708dd293042f932d7eee119".parse().unwrap(); + let x1septima_right: U256 = "00022cca1da3f6e5722b7d3cc5bbfb486465ebc5a708dd293042f932d7eee119".into(); assert_eq!(x1septima_right, x1septima); } #[test] fn example() { - let val = (0..200).fold(U256::from(1023), |acc, _| acc * 2.into()); + let mut val: U256 = 1023.into(); + for _ in 0..200 { val = val * 2.into() } assert_eq!(&format!("{}", val), "1643897619276947051879427220465009342380213662639797070513307648"); } #[test] fn little_endian() { - let number: U256 = "00022cca1da3f6e5722b7d3cc5bbfb486465ebc5a708dd293042f932d7eee119".parse().unwrap(); + let number: U256 = "00022cca1da3f6e5722b7d3cc5bbfb486465ebc5a708dd293042f932d7eee119".into(); let expected = [ 0x19, 0xe1, 0xee, 0xd7, 0x32, 0xf9, 0x42, 0x30, @@ -2108,7 +2131,7 @@ mod std_tests { #[test] fn fixed_arrays_roundtrip() { - let raw: U256 = "7094875209347850239487502394881".parse().unwrap(); + let raw: U256 = "7094875209347850239487502394881".into(); let array: [u8; 32] = raw.into(); let new_raw = array.into(); @@ -2145,18 +2168,18 @@ mod std_tests { #[test] fn leading_zeros() { - assert_eq!("000000000000000000000001adbdd6bd6ff027485484b97f8a6a4c7129756dd1".parse::().unwrap().leading_zeros(), 95); - assert_eq!("f00000000000000000000001adbdd6bd6ff027485484b97f8a6a4c7129756dd1".parse::().unwrap().leading_zeros(), 0); - assert_eq!("0000000000000000000000000000000000000000000000000000000000000001".parse::().unwrap().leading_zeros(), 255); - assert_eq!("0000000000000000000000000000000000000000000000000000000000000000".parse::().unwrap().leading_zeros(), 256); + assert_eq!(U256::from("000000000000000000000001adbdd6bd6ff027485484b97f8a6a4c7129756dd1").leading_zeros(), 95); + assert_eq!(U256::from("f00000000000000000000001adbdd6bd6ff027485484b97f8a6a4c7129756dd1").leading_zeros(), 0); + assert_eq!(U256::from("0000000000000000000000000000000000000000000000000000000000000001").leading_zeros(), 255); + assert_eq!(U256::from("0000000000000000000000000000000000000000000000000000000000000000").leading_zeros(), 256); } #[test] fn trailing_zeros() { - assert_eq!("1adbdd6bd6ff027485484b97f8a6a4c7129756dd100000000000000000000000".parse::().unwrap().trailing_zeros(), 92); - assert_eq!("1adbdd6bd6ff027485484b97f8a6a4c7129756dd10000000000000000000000f".parse::().unwrap().trailing_zeros(), 0); - assert_eq!("8000000000000000000000000000000000000000000000000000000000000000".parse::().unwrap().trailing_zeros(), 255); - assert_eq!("0000000000000000000000000000000000000000000000000000000000000000".parse::().unwrap().trailing_zeros(), 256); + assert_eq!(U256::from("1adbdd6bd6ff027485484b97f8a6a4c7129756dd100000000000000000000000").trailing_zeros(), 92); + assert_eq!(U256::from("1adbdd6bd6ff027485484b97f8a6a4c7129756dd10000000000000000000000f").trailing_zeros(), 0); + assert_eq!(U256::from("8000000000000000000000000000000000000000000000000000000000000000").trailing_zeros(), 255); + assert_eq!(U256::from("0000000000000000000000000000000000000000000000000000000000000000").trailing_zeros(), 256); } mod laws { From 024a0fdf055a90136d8312b5905321bd8ea0f492 Mon Sep 17 00:00:00 2001 From: Psilon Date: Mon, 23 Jul 2018 19:48:14 +0300 Subject: [PATCH 09/11] Fixes tests --- src/lib.rs | 5 +++++ src/uint.rs | 26 +++++++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index dc66a93..1e8b23b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,7 @@ //! Efficient large, fixed-size big integers and hashes. #![cfg_attr(not(feature="std"), no_std)] +#![cfg_attr(all(not(feature="std"), test), feature(alloc))] extern crate byteorder; @@ -35,5 +36,9 @@ extern crate core; #[macro_use] extern crate quickcheck; +#[cfg(all(not(feature = "std"), test))] +#[macro_use] +extern crate alloc; + pub mod uint; pub use ::uint::*; diff --git a/src/uint.rs b/src/uint.rs index a3a9665..289a15a 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -1180,14 +1180,30 @@ known_heap_size!(0, U128, U256); #[cfg(test)] mod tests { - use uint::U256; + use uint::{U128, U256, U512}; + + #[test] + pub fn display_u128() { + let expected = "340282366920938463463374607431768211455"; + let value = U128::MAX_VALUE; + assert_eq!(format!("{}", value), expected); + assert_eq!(format!("{:?}", value), expected); + } #[test] - pub fn display() { + pub fn display_u256() { + let expected = "115792089237316195423570985008687907853269984665640564039457584007913129639935"; let value = U256::MAX_VALUE; - let mut buf = [b'0'; 64]; - write!(&buf, "{}", value); - assert_eq!(string, ""); + assert_eq!(format!("{}", value), expected); + assert_eq!(format!("{:?}", value), expected); + } + + #[test] + pub fn display_u512() { + let expected = "13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095"; + let value = U512::MAX_VALUE; + assert_eq!(format!("{}", value), expected); + assert_eq!(format!("{:?}", value), expected); } } From 84aa05838500bd26ab6e8fa074738ebfeb883a05 Mon Sep 17 00:00:00 2001 From: Psilon Date: Mon, 23 Jul 2018 19:55:20 +0300 Subject: [PATCH 10/11] Fixes naming issue --- src/uint.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/uint.rs b/src/uint.rs index 289a15a..d9a4998 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -270,7 +270,7 @@ macro_rules! construct_uint { pub struct $name(pub [u64; $n_words]); impl $name { - pub const MAX_VALUE: $name = $name([u64::max_value(); $n_words]); + pub const MAX: $name = $name([u64::max_value(); $n_words]); /// Convert from a decimal string. pub fn from_dec_str(value: &str) -> Result { @@ -1185,7 +1185,7 @@ mod tests { #[test] pub fn display_u128() { let expected = "340282366920938463463374607431768211455"; - let value = U128::MAX_VALUE; + let value = U128::MAX; assert_eq!(format!("{}", value), expected); assert_eq!(format!("{:?}", value), expected); } @@ -1193,7 +1193,7 @@ mod tests { #[test] pub fn display_u256() { let expected = "115792089237316195423570985008687907853269984665640564039457584007913129639935"; - let value = U256::MAX_VALUE; + let value = U256::MAX; assert_eq!(format!("{}", value), expected); assert_eq!(format!("{:?}", value), expected); } @@ -1201,7 +1201,7 @@ mod tests { #[test] pub fn display_u512() { let expected = "13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095"; - let value = U512::MAX_VALUE; + let value = U512::MAX; assert_eq!(format!("{}", value), expected); assert_eq!(format!("{:?}", value), expected); } From fca8052a6dd8821095156452a2609758460318e4 Mon Sep 17 00:00:00 2001 From: Psilon Date: Mon, 23 Jul 2018 20:00:27 +0300 Subject: [PATCH 11/11] Fixes formatting --- src/uint.rs | 84 ++++++++++++++++++++++++++--------------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/src/uint.rs b/src/uint.rs index d9a4998..fc11fda 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -1489,9 +1489,9 @@ mod std_tests { pub fn uint128_add_overflow() { assert_eq!( U128::from_str("ffffffffffffffffffffffffffffffff").unwrap() - .overflowing_add( - U128::from_str("ffffffffffffffffffffffffffffffff").unwrap() - ), + .overflowing_add( + U128::from_str("ffffffffffffffffffffffffffffffff").unwrap() + ), (U128::from_str("fffffffffffffffffffffffffffffffe").unwrap(), true) ); } @@ -1516,8 +1516,8 @@ mod std_tests { pub fn uint512_mul() { assert_eq!( U512::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap() - * - U512::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), + * + U512::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), U512::from_str("3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000001").unwrap() ); } @@ -1526,9 +1526,9 @@ mod std_tests { pub fn uint256_mul_overflow() { assert_eq!( U256::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap() - .overflowing_mul( - U256::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap() - ), + .overflowing_mul( + U256::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap() + ), (U256::from_str("1").unwrap(), true) ); } @@ -1545,11 +1545,11 @@ mod std_tests { pub fn uint256_sub_overflow() { assert_eq!( U256::from_str("0").unwrap() - .overflowing_sub( - U256::from_str("1").unwrap() - ), + .overflowing_sub( + U256::from_str("1").unwrap() + ), (U256::from_str("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap(), true) - ); + ); } #[test] @@ -1564,7 +1564,7 @@ mod std_tests { pub fn uint256_shl() { assert_eq!( U256::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap() - << 4, + << 4, U256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0").unwrap() ); } @@ -1573,12 +1573,12 @@ mod std_tests { pub fn uint256_shl_words() { assert_eq!( U256::from_str("0000000000000001ffffffffffffffffffffffffffffffffffffffffffffffff").unwrap() - << 64, + << 64, U256::from_str("ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000").unwrap() ); assert_eq!( U256::from_str("0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff").unwrap() - << 64, + << 64, U256::from_str("ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000").unwrap() ); } @@ -1587,10 +1587,10 @@ mod std_tests { pub fn uint256_mul() { assert_eq!( U256::from_str("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap() - * - U256::from_str("2").unwrap(), + * + U256::from_str("2").unwrap(), U256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe").unwrap() - ); + ); } #[test] @@ -1625,8 +1625,8 @@ mod std_tests { assert_eq!(format!("{}", U256::from(0)), "0"); } - #[test] - fn u512_multi_adds() { + #[test] + fn u512_multi_adds() { let (result, _) = U512([0, 0, 0, 0, 0, 0, 0, 0]).overflowing_add(U512([0, 0, 0, 0, 0, 0, 0, 0])); assert_eq!(result, U512([0, 0, 0, 0, 0, 0, 0, 0])); @@ -1651,32 +1651,32 @@ mod std_tests { let (_, overflow) = U512([0, 0, 0, 0, 0, 0, 0, MAX]) .overflowing_add(U512([0, 0, 0, 0, 0, 0, 0, MAX])); - assert!(overflow); + assert!(overflow); let (_, overflow) = U512([0, 0, 0, 0, 0, 0, 0, MAX]) .overflowing_add(U512([0, 0, 0, 0, 0, 0, 0, 0])); assert!(!overflow); } - #[test] - fn u256_multi_adds() { - let (result, _) = U256([0, 0, 0, 0]).overflowing_add(U256([0, 0, 0, 0])); - assert_eq!(result, U256([0, 0, 0, 0])); + #[test] + fn u256_multi_adds() { + let (result, _) = U256([0, 0, 0, 0]).overflowing_add(U256([0, 0, 0, 0])); + assert_eq!(result, U256([0, 0, 0, 0])); - let (result, _) = U256([0, 0, 0, 1]).overflowing_add(U256([0, 0, 0, 1])); - assert_eq!(result, U256([0, 0, 0, 2])); + let (result, _) = U256([0, 0, 0, 1]).overflowing_add(U256([0, 0, 0, 1])); + assert_eq!(result, U256([0, 0, 0, 2])); - let (result, overflow) = U256([0, 0, 2, 1]).overflowing_add(U256([0, 0, 3, 1])); - assert_eq!(result, U256([0, 0, 5, 2])); - assert!(!overflow); + let (result, overflow) = U256([0, 0, 2, 1]).overflowing_add(U256([0, 0, 3, 1])); + assert_eq!(result, U256([0, 0, 5, 2])); + assert!(!overflow); - let (_, overflow) = U256([MAX, MAX, MAX, MAX]) + let (_, overflow) = U256([MAX, MAX, MAX, MAX]) .overflowing_add(U256([MAX, MAX, MAX, MAX])); - assert!(overflow); + assert!(overflow); - let (_, overflow) = U256([0, 0, 0, MAX]).overflowing_add(U256([0, 0, 0, MAX])); - assert!(overflow); - } + let (_, overflow) = U256([0, 0, 0, MAX]).overflowing_add(U256([0, 0, 0, MAX])); + assert!(overflow); + } #[test] @@ -1825,8 +1825,8 @@ mod std_tests { assert_eq!(U256([0, 0, 0, MAX]), result); } - #[test] - fn u256_multi_muls_overflow() { + #[test] + fn u256_multi_muls_overflow() { let (_, overflow) = U256([1, 0, 0, 0]).overflowing_mul(U256([0, 0, 0, 0])); assert!(!overflow); @@ -1853,7 +1853,7 @@ mod std_tests { let (_, overflow) = U256([0, 0, 8, 0]).overflowing_mul(U256([0, 0, 7, 0])); assert!(overflow); - } + } #[test] fn big_endian() { @@ -1865,7 +1865,7 @@ mod std_tests { source.to_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, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8], + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8], target); let source = U256([512, 0, 0, 0]); @@ -1874,7 +1874,7 @@ mod std_tests { source.to_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, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8], + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8], target); let source = U256([0, 512, 0, 0]); @@ -1883,14 +1883,14 @@ mod std_tests { source.to_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, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8], + 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8], target); let source = U256::from_str("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20").unwrap(); source.to_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, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20], + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20], target); }