Skip to content

Commit dc862c4

Browse files
authored
Contracts & Harnesses for widening_mul (#111)
Towards : issue #59 Parent branch : main Revalidation : Per the discussion in #59, we have to build and run Kani from feature/verify-rust-std branch. To revalidate the verification results, run the following command. <harness_to_run> can be either num::verify to run all harnesses or num::verify::<harness_name> (e.g. widening_mul_u16_small) to run a specific harness. ``` kani verify-std "path/to/library" \ --harness <harness_to_run> \ -Z unstable-options \ -Z function-contracts \ -Z mem-predicates ```
1 parent 32e0cf9 commit dc862c4

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

library/core/src/num/mod.rs

+56
Original file line numberDiff line numberDiff line change
@@ -1658,6 +1658,35 @@ mod verify {
16581658
}
16591659
}
16601660

1661+
// Part 2 : Nested unsafe functions Generation Macros --> https://github.com/verify-rust-std/blob/main/doc/src/challenges/0011-floats-ints.md
1662+
1663+
// Verify `widening_mul`, which internally uses `unchecked_mul`
1664+
macro_rules! generate_widening_mul_intervals {
1665+
($type:ty, $wide_type:ty, $($harness_name:ident, $min:expr, $max:expr),+) => {
1666+
$(
1667+
#[kani::proof]
1668+
pub fn $harness_name() {
1669+
let lhs: $type = kani::any::<$type>();
1670+
let rhs: $type = kani::any::<$type>();
1671+
1672+
kani::assume(lhs >= $min && lhs <= $max);
1673+
kani::assume(rhs >= $min && rhs <= $max);
1674+
1675+
let (result_low, result_high) = lhs.widening_mul(rhs);
1676+
1677+
// Compute expected result using wider type
1678+
let expected = (lhs as $wide_type) * (rhs as $wide_type);
1679+
1680+
let expected_low = expected as $type;
1681+
let expected_high = (expected >> <$type>::BITS) as $type;
1682+
1683+
assert_eq!(result_low, expected_low);
1684+
assert_eq!(result_high, expected_high);
1685+
}
1686+
)+
1687+
}
1688+
}
1689+
16611690
// `unchecked_add` proofs
16621691
//
16631692
// Target types:
@@ -1849,4 +1878,31 @@ mod verify {
18491878
generate_unchecked_math_harness!(u64, unchecked_sub, checked_unchecked_sub_u64);
18501879
generate_unchecked_math_harness!(u128, unchecked_sub, checked_unchecked_sub_u128);
18511880
generate_unchecked_math_harness!(usize, unchecked_sub, checked_unchecked_sub_usize);
1881+
1882+
1883+
// Part 2 : Proof harnesses
1884+
1885+
// ====================== u8 Harnesses ======================
1886+
generate_widening_mul_intervals!(u8, u16, widening_mul_u8, 0u8, u8::MAX);
1887+
1888+
// ====================== u16 Harnesses ======================
1889+
generate_widening_mul_intervals!(u16, u32,
1890+
widening_mul_u16_small, 0u16, 10u16,
1891+
widening_mul_u16_large, u16::MAX - 10u16, u16::MAX,
1892+
widening_mul_u16_mid_edge, (u16::MAX / 2) - 10u16, (u16::MAX / 2) + 10u16
1893+
);
1894+
1895+
// ====================== u32 Harnesses ======================
1896+
generate_widening_mul_intervals!(u32, u64,
1897+
widening_mul_u32_small, 0u32, 10u32,
1898+
widening_mul_u32_large, u32::MAX - 10u32, u32::MAX,
1899+
widening_mul_u32_mid_edge, (u32::MAX / 2) - 10u32, (u32::MAX / 2) + 10u32
1900+
);
1901+
1902+
// ====================== u64 Harnesses ======================
1903+
generate_widening_mul_intervals!(u64, u128,
1904+
widening_mul_u64_small, 0u64, 10u64,
1905+
widening_mul_u64_large, u64::MAX - 10u64, u64::MAX,
1906+
widening_mul_u64_mid_edge, (u64::MAX / 2) - 10u64, (u64::MAX / 2) + 10u64
1907+
);
18521908
}

0 commit comments

Comments
 (0)