From 6a3c64ff606a287f1a645ebf0c84c14d8f91a01e Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sun, 10 Jul 2016 20:18:23 +0200 Subject: [PATCH] Some obvious evm & uint optimizations (#1576) * fix name and tests for endians * using renamed func * zero and sign opt --- src/uint.rs | 57 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/src/uint.rs b/src/uint.rs index 2f58061..8e08e59 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -524,9 +524,8 @@ pub trait Uint: Sized + Default + FromStr + From + fmt::Debug + fmt::Displa fn bit(&self, index: usize) -> bool; /// Return single byte fn byte(&self, index: usize) -> u8; - /// Get this Uint as slice of bytes - fn to_raw_bytes(&self, bytes: &mut[u8]); - + /// Convert U256 to the sequence of bytes with a big endian + fn to_big_endian(&self, bytes: &mut[u8]); /// Create `Uint(10**n)` fn exp10(n: usize) -> Self; /// Return eponentation `self**other`. Panic on overflow. @@ -551,6 +550,9 @@ pub trait Uint: Sized + Default + FromStr + From + fmt::Debug + fmt::Displa /// Returns negation of this `Uint` and overflow (always true) fn overflowing_neg(self) -> (Self, bool); + + /// Returns + fn is_zero(&self) -> bool; } macro_rules! construct_uint { @@ -616,6 +618,13 @@ macro_rules! construct_uint { arr[0] } + #[inline] + fn is_zero(&self) -> bool { + let &$name(ref arr) = self; + for i in 0..$n_words { if arr[i] != 0 { return false; } } + return true; + } + /// Return the least number of bits needed to represent the number #[inline] fn bits(&self) -> usize { @@ -638,7 +647,7 @@ macro_rules! construct_uint { (arr[index / 8] >> (((index % 8)) * 8)) as u8 } - fn to_raw_bytes(&self, bytes: &mut[u8]) { + fn to_big_endian(&self, bytes: &mut[u8]) { assert!($n_words * 8 == bytes.len()); let &$name(ref arr) = self; for i in 0..bytes.len() { @@ -1454,7 +1463,7 @@ mod tests { let hex = "8090a0b0c0d0e0f00910203040506077583a2cf8264910e1436bda32571012f0"; let uint = U256::from_str(hex).unwrap(); let mut bytes = [0u8; 32]; - uint.to_raw_bytes(&mut bytes); + uint.to_big_endian(&mut bytes); let uint2 = U256::from(&bytes[..]); assert_eq!(uint, uint2); } @@ -2021,6 +2030,44 @@ mod tests { assert!(overflow); } + #[test] + fn big_endian() { + let source = U256([1, 0, 0, 0]); + let mut target = vec![0u8; 32]; + + assert_eq!(source, U256::from(1)); + + 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], + target); + + let source = U256([512, 0, 0, 0]); + let mut target = vec![0u8; 32]; + + 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], + target); + + let source = U256([0, 512, 0, 0]); + let mut target = vec![0u8; 32]; + + 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], + 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], + target); + } #[test] #[cfg_attr(feature="dev", allow(cyclomatic_complexity))]