@@ -1657,6 +1657,51 @@ mod verify {
16571657 }
16581658 }
16591659 }
1660+
1661+ /// A macro to generate Kani proof harnesses for the `carrying_mul` method,
1662+ ///
1663+ /// The macro creates multiple harnesses for different ranges of input values,
1664+ /// allowing testing of both small and large inputs.
1665+ ///
1666+ /// # Parameters:
1667+ /// - `$type`: The integer type (e.g., u8, u16) for which the `carrying_mul` function is being tested.
1668+ /// - `$wide_type`: A wider type to simulate the multiplication (e.g., u16 for u8, u32 for u16).
1669+ /// - `$harness_name`: The name of the Kani harness to be generated.
1670+ /// - `$min`: The minimum value for the range of inputs for `lhs`, `rhs`, and `carry_in`.
1671+ /// - `$max`: The maximum value for the range of inputs for `lhs`, `rhs`, and `carry_in`.
1672+ macro_rules! generate_carrying_mul_intervals {
1673+ ( $type: ty, $wide_type: ty, $( $harness_name: ident, $min: expr, $max: expr) ,+) => {
1674+ $(
1675+ #[ kani:: proof]
1676+ pub fn $harness_name( ) {
1677+ let lhs: $type = kani:: any:: <$type>( ) ;
1678+ let rhs: $type = kani:: any:: <$type>( ) ;
1679+ let carry_in: $type = kani:: any:: <$type>( ) ;
1680+
1681+ kani:: assume( lhs >= $min && lhs <= $max) ;
1682+ kani:: assume( rhs >= $min && rhs <= $max) ;
1683+ kani:: assume( carry_in >= $min && carry_in <= $max) ;
1684+
1685+ // Perform the carrying multiplication
1686+ let ( result, carry_out) = lhs. carrying_mul( rhs, carry_in) ;
1687+
1688+ // Manually compute the expected result and carry using wider type
1689+ let wide_result = ( lhs as $wide_type)
1690+ . wrapping_mul( rhs as $wide_type)
1691+ . wrapping_add( carry_in as $wide_type) ;
1692+
1693+ let expected_result = wide_result as $type;
1694+ let expected_carry = ( wide_result >> <$type>:: BITS ) as $type;
1695+
1696+ // Assert the result and carry are correct
1697+ assert_eq!( result, expected_result) ;
1698+ assert_eq!( carry_out, expected_carry) ;
1699+ }
1700+ ) +
1701+ }
1702+ }
1703+
1704+
16601705
16611706 // Part 2 : Nested unsafe functions Generation Macros --> https://github.com/verify-rust-std/blob/main/doc/src/challenges/0011-floats-ints.md
16621707
@@ -1741,7 +1786,7 @@ mod verify {
17411786 generate_unchecked_neg_harness ! ( i128 , checked_unchecked_neg_i128) ;
17421787 generate_unchecked_neg_harness ! ( isize , checked_unchecked_neg_isize) ;
17431788
1744- // unchecked_mul proofs
1789+ // ` unchecked_mul` proofs
17451790 //
17461791 // Target types:
17471792 // i{8,16,32,64,128,size} and u{8,16,32,64,128,size} -- 12 types in total, with different interval checks for each.
@@ -1892,8 +1937,37 @@ mod verify {
18921937 generate_unchecked_math_harness ! ( u128 , unchecked_sub, checked_unchecked_sub_u128) ;
18931938 generate_unchecked_math_harness ! ( usize , unchecked_sub, checked_unchecked_sub_usize) ;
18941939
1940+
1941+ // Part_2 `carrying_mul` proofs
1942+ //
1943+ // ====================== u8 Harnesses ======================
1944+ /// Kani proof harness for `carrying_mul` on `u8` type with full range of values.
1945+ generate_carrying_mul_intervals ! ( u8 , u16 ,
1946+ carrying_mul_u8_full_range, 0u8 , u8 :: MAX
1947+ ) ;
1948+
1949+ // ====================== u16 Harnesses ======================
1950+ /// Kani proof harness for `carrying_mul` on `u16` type with full range of values.
1951+ generate_carrying_mul_intervals ! ( u16 , u32 ,
1952+ carrying_mul_u16_full_range, 0u16 , u16 :: MAX
1953+ ) ;
1954+
1955+ // ====================== u32 Harnesses ======================
1956+ generate_carrying_mul_intervals ! ( u32 , u64 ,
1957+ carrying_mul_u32_small, 0u32 , 10u32 ,
1958+ carrying_mul_u32_large, u32 :: MAX - 10u32 , u32 :: MAX ,
1959+ carrying_mul_u32_mid_edge, ( u32 :: MAX / 2 ) - 10u32 , ( u32 :: MAX / 2 ) + 10u32
1960+ ) ;
1961+
1962+ // ====================== u64 Harnesses ======================
1963+ generate_carrying_mul_intervals ! ( u64 , u128 ,
1964+ carrying_mul_u64_small, 0u64 , 10u64 ,
1965+ carrying_mul_u64_large, u64 :: MAX - 10u64 , u64 :: MAX ,
1966+ carrying_mul_u64_mid_edge, ( u64 :: MAX / 2 ) - 10u64 , ( u64 :: MAX / 2 ) + 10u64
1967+ ) ;
1968+
18951969
1896- // Part 2 : Proof harnesses
1970+ // Part_2 `widening_mul` proofs
18971971
18981972 // ====================== u8 Harnesses ======================
18991973 generate_widening_mul_intervals ! ( u8 , u16 , widening_mul_u8, 0u8 , u8 :: MAX ) ;
@@ -1919,7 +1993,7 @@ mod verify {
19191993 widening_mul_u64_mid_edge, ( u64 :: MAX / 2 ) - 10u64 , ( u64 :: MAX / 2 ) + 10u64
19201994 ) ;
19211995
1922- // `wrapping_shl` proofs
1996+ // Part_2 `wrapping_shl` proofs
19231997 //
19241998 // Target types:
19251999 // i{8,16,32,64,128,size} and u{8,16,32,64,128,size} -- 12 types in total
@@ -1944,7 +2018,7 @@ mod verify {
19442018 generate_wrapping_shift_harness ! ( u128 , wrapping_shl, checked_wrapping_shl_u128) ;
19452019 generate_wrapping_shift_harness ! ( usize , wrapping_shl, checked_wrapping_shl_usize) ;
19462020
1947- // `wrapping_shr` proofs
2021+ // Part_2 `wrapping_shr` proofs
19482022 //
19492023 // Target types:
19502024 // i{8,16,32,64,128,size} and u{8,16,32,64,128,size} -- 12 types in total
@@ -1967,4 +2041,6 @@ mod verify {
19672041 generate_wrapping_shift_harness ! ( u64 , wrapping_shr, checked_wrapping_shr_u64) ;
19682042 generate_wrapping_shift_harness ! ( u128 , wrapping_shr, checked_wrapping_shr_u128) ;
19692043 generate_wrapping_shift_harness ! ( usize , wrapping_shr, checked_wrapping_shr_usize) ;
2044+
19702045}
2046+
0 commit comments