diff --git a/fuzz/fuzz_targets/uint128_fuzz.rs b/fuzz/fuzz_targets/uint128_fuzz.rs index 9b8b2afa..6a34e2ab 100644 --- a/fuzz/fuzz_targets/uint128_fuzz.rs +++ b/fuzz/fuzz_targets/uint128_fuzz.rs @@ -27,7 +27,7 @@ fn do_test(data: &[u8]) { } } } - if data.len() != 16*2 + 1 { return; } + if data.len() != 16*2 { return; } let (a_native, a) = read_ints!(0); // Checks using only a: @@ -40,6 +40,10 @@ fn do_test(data: &[u8]) { assert_eq!(128 - a_native.leading_zeros() as usize, a.bits()); assert_eq!(a_native as u64, bitcoin::util::uint::Uint128::from_u64(a_native as u64).unwrap().low_u64()); + let mut a_inc = a.clone(); + a_inc.increment(); + check_eq!(a_native.wrapping_add(1), a_inc); + // Checks with two numbers: let (b_native, b) = read_ints!(16); diff --git a/src/util/uint.rs b/src/util/uint.rs index d5a894cc..3559c1b6 100644 --- a/src/util/uint.rs +++ b/src/util/uint.rs @@ -162,6 +162,16 @@ macro_rules! construct_uint { ($name(ret), sub_copy) } + + /// Increment by 1 + #[inline] + pub fn increment(&mut self) { + let &mut $name(ref mut arr) = self; + for i in 0..$n_words { + arr[i] = arr[i].wrapping_add(1); + if arr[i] != 0 { break; } + } + } } impl PartialOrd for $name { @@ -516,22 +526,6 @@ impl ::core::fmt::Display for ParseLengthError { impl ::std::error::Error for ParseLengthError {} impl Uint256 { - /// Increment by 1 - #[inline] - pub fn increment(&mut self) { - let &mut Uint256(ref mut arr) = self; - arr[0] += 1; - if arr[0] == 0 { - arr[1] += 1; - if arr[1] == 0 { - arr[2] += 1; - if arr[2] == 0 { - arr[3] += 1; - } - } - } - } - /// Decay to a uint128 #[inline] pub fn low_128(&self) -> Uint128 { @@ -693,6 +687,53 @@ mod tests { 0x4AFCFF6F0375C608u64, 0x928D92B4D7F5DF33u64])); } + #[test] + pub fn increment_test() { + let mut val = Uint256([ + 0xFFFFFFFFFFFFFFFEu64, + 0xFFFFFFFFFFFFFFFFu64, + 0xFFFFFFFFFFFFFFFFu64, + 0xEFFFFFFFFFFFFFFFu64, + ]); + val.increment(); + assert_eq!( + val, + Uint256([ + 0xFFFFFFFFFFFFFFFFu64, + 0xFFFFFFFFFFFFFFFFu64, + 0xFFFFFFFFFFFFFFFFu64, + 0xEFFFFFFFFFFFFFFFu64, + ]) + ); + val.increment(); + assert_eq!( + val, + Uint256([ + 0x0000000000000000u64, + 0x0000000000000000u64, + 0x0000000000000000u64, + 0xF000000000000000u64, + ]) + ); + + let mut val = Uint256([ + 0xFFFFFFFFFFFFFFFFu64, + 0xFFFFFFFFFFFFFFFFu64, + 0xFFFFFFFFFFFFFFFFu64, + 0xFFFFFFFFFFFFFFFFu64, + ]); + val.increment(); + assert_eq!( + val, + Uint256([ + 0x0000000000000000u64, + 0x0000000000000000u64, + 0x0000000000000000u64, + 0x0000000000000000u64, + ]) + ); + } + #[test] pub fn uint256_bitslice_test() { let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();