Skip to content

Commit 454379c

Browse files
committed
Merge rust-bitcoin#612: Fix Uint256::increment panics
5d71a9d Correct input length check for uin128 fuzzer (Matt Corallo) 9c256cc Add a fuzz check for `Uint128::increment` (Matt Corallo) a15f263 Move the `increment` fn into the uint macro to add it to Uint128 (Matt Corallo) d52b88b Fix increment of Uint256 with carry (carolcapps) Pull request description: This is rust-bitcoin#578 with review feedback addressed. ACKs for top commit: apoelstra: ACK 5d71a9d sanket1729: ACK 5d71a9d Tree-SHA512: 32e5ea6387943ecad8f190a0de336a545fda72b6ff7388d3479037a5f880434276a7d0607f5cf61710d45e984c01954f4e3199a60c542be48b397717afb3d406
2 parents e49cdbd + 5d71a9d commit 454379c

File tree

2 files changed

+62
-17
lines changed

2 files changed

+62
-17
lines changed

fuzz/fuzz_targets/uint128_fuzz.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ fn do_test(data: &[u8]) {
2727
} }
2828
}
2929

30-
if data.len() != 16*2 + 1 { return; }
30+
if data.len() != 16*2 { return; }
3131
let (a_native, a) = read_ints!(0);
3232

3333
// Checks using only a:
@@ -40,6 +40,10 @@ fn do_test(data: &[u8]) {
4040
assert_eq!(128 - a_native.leading_zeros() as usize, a.bits());
4141
assert_eq!(a_native as u64, bitcoin::util::uint::Uint128::from_u64(a_native as u64).unwrap().low_u64());
4242

43+
let mut a_inc = a.clone();
44+
a_inc.increment();
45+
check_eq!(a_native.wrapping_add(1), a_inc);
46+
4347
// Checks with two numbers:
4448
let (b_native, b) = read_ints!(16);
4549

src/util/uint.rs

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,16 @@ macro_rules! construct_uint {
162162

163163
($name(ret), sub_copy)
164164
}
165+
166+
/// Increment by 1
167+
#[inline]
168+
pub fn increment(&mut self) {
169+
let &mut $name(ref mut arr) = self;
170+
for i in 0..$n_words {
171+
arr[i] = arr[i].wrapping_add(1);
172+
if arr[i] != 0 { break; }
173+
}
174+
}
165175
}
166176

167177
impl PartialOrd for $name {
@@ -516,22 +526,6 @@ impl ::core::fmt::Display for ParseLengthError {
516526
impl ::std::error::Error for ParseLengthError {}
517527

518528
impl Uint256 {
519-
/// Increment by 1
520-
#[inline]
521-
pub fn increment(&mut self) {
522-
let &mut Uint256(ref mut arr) = self;
523-
arr[0] += 1;
524-
if arr[0] == 0 {
525-
arr[1] += 1;
526-
if arr[1] == 0 {
527-
arr[2] += 1;
528-
if arr[2] == 0 {
529-
arr[3] += 1;
530-
}
531-
}
532-
}
533-
}
534-
535529
/// Decay to a uint128
536530
#[inline]
537531
pub fn low_128(&self) -> Uint128 {
@@ -693,6 +687,53 @@ mod tests {
693687
0x4AFCFF6F0375C608u64, 0x928D92B4D7F5DF33u64]));
694688
}
695689

690+
#[test]
691+
pub fn increment_test() {
692+
let mut val = Uint256([
693+
0xFFFFFFFFFFFFFFFEu64,
694+
0xFFFFFFFFFFFFFFFFu64,
695+
0xFFFFFFFFFFFFFFFFu64,
696+
0xEFFFFFFFFFFFFFFFu64,
697+
]);
698+
val.increment();
699+
assert_eq!(
700+
val,
701+
Uint256([
702+
0xFFFFFFFFFFFFFFFFu64,
703+
0xFFFFFFFFFFFFFFFFu64,
704+
0xFFFFFFFFFFFFFFFFu64,
705+
0xEFFFFFFFFFFFFFFFu64,
706+
])
707+
);
708+
val.increment();
709+
assert_eq!(
710+
val,
711+
Uint256([
712+
0x0000000000000000u64,
713+
0x0000000000000000u64,
714+
0x0000000000000000u64,
715+
0xF000000000000000u64,
716+
])
717+
);
718+
719+
let mut val = Uint256([
720+
0xFFFFFFFFFFFFFFFFu64,
721+
0xFFFFFFFFFFFFFFFFu64,
722+
0xFFFFFFFFFFFFFFFFu64,
723+
0xFFFFFFFFFFFFFFFFu64,
724+
]);
725+
val.increment();
726+
assert_eq!(
727+
val,
728+
Uint256([
729+
0x0000000000000000u64,
730+
0x0000000000000000u64,
731+
0x0000000000000000u64,
732+
0x0000000000000000u64,
733+
])
734+
);
735+
}
736+
696737
#[test]
697738
pub fn uint256_bitslice_test() {
698739
let init = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();

0 commit comments

Comments
 (0)