@@ -1657,6 +1657,51 @@ mod verify {
1657
1657
}
1658
1658
}
1659
1659
}
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
+
1660
1705
1661
1706
// Part 2 : Nested unsafe functions Generation Macros --> https://github.com/verify-rust-std/blob/main/doc/src/challenges/0011-floats-ints.md
1662
1707
@@ -1741,7 +1786,7 @@ mod verify {
1741
1786
generate_unchecked_neg_harness ! ( i128 , checked_unchecked_neg_i128) ;
1742
1787
generate_unchecked_neg_harness ! ( isize , checked_unchecked_neg_isize) ;
1743
1788
1744
- // unchecked_mul proofs
1789
+ // ` unchecked_mul` proofs
1745
1790
//
1746
1791
// Target types:
1747
1792
// 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 {
1892
1937
generate_unchecked_math_harness ! ( u128 , unchecked_sub, checked_unchecked_sub_u128) ;
1893
1938
generate_unchecked_math_harness ! ( usize , unchecked_sub, checked_unchecked_sub_usize) ;
1894
1939
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
+
1895
1969
1896
- // Part 2 : Proof harnesses
1970
+ // Part_2 `widening_mul` proofs
1897
1971
1898
1972
// ====================== u8 Harnesses ======================
1899
1973
generate_widening_mul_intervals ! ( u8 , u16 , widening_mul_u8, 0u8 , u8 :: MAX ) ;
@@ -1919,7 +1993,7 @@ mod verify {
1919
1993
widening_mul_u64_mid_edge, ( u64 :: MAX / 2 ) - 10u64 , ( u64 :: MAX / 2 ) + 10u64
1920
1994
) ;
1921
1995
1922
- // `wrapping_shl` proofs
1996
+ // Part_2 `wrapping_shl` proofs
1923
1997
//
1924
1998
// Target types:
1925
1999
// 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 {
1944
2018
generate_wrapping_shift_harness ! ( u128 , wrapping_shl, checked_wrapping_shl_u128) ;
1945
2019
generate_wrapping_shift_harness ! ( usize , wrapping_shl, checked_wrapping_shl_usize) ;
1946
2020
1947
- // `wrapping_shr` proofs
2021
+ // Part_2 `wrapping_shr` proofs
1948
2022
//
1949
2023
// Target types:
1950
2024
// 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 {
1967
2041
generate_wrapping_shift_harness ! ( u64 , wrapping_shr, checked_wrapping_shr_u64) ;
1968
2042
generate_wrapping_shift_harness ! ( u128 , wrapping_shr, checked_wrapping_shr_u128) ;
1969
2043
generate_wrapping_shift_harness ! ( usize , wrapping_shr, checked_wrapping_shr_usize) ;
2044
+
1970
2045
}
2046
+
0 commit comments