@@ -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
@@ -1687,6 +1732,19 @@ mod verify {
1687
1732
}
1688
1733
}
1689
1734
1735
+ // Verify `wrapping_{shl, shr}` which internally uses `unchecked_{shl,shr}`
1736
+ macro_rules! generate_wrapping_shift_harness {
1737
+ ( $type: ty, $method: ident, $harness_name: ident) => {
1738
+ #[ kani:: proof_for_contract( $type:: $method) ]
1739
+ pub fn $harness_name( ) {
1740
+ let num1: $type = kani:: any:: <$type>( ) ;
1741
+ let num2: u32 = kani:: any:: <u32 >( ) ;
1742
+
1743
+ let _ = num1. $method( num2) ;
1744
+ }
1745
+ }
1746
+ }
1747
+
1690
1748
// `unchecked_add` proofs
1691
1749
//
1692
1750
// Target types:
@@ -1728,7 +1786,7 @@ mod verify {
1728
1786
generate_unchecked_neg_harness ! ( i128 , checked_unchecked_neg_i128) ;
1729
1787
generate_unchecked_neg_harness ! ( isize , checked_unchecked_neg_isize) ;
1730
1788
1731
- // unchecked_mul proofs
1789
+ // ` unchecked_mul` proofs
1732
1790
//
1733
1791
// Target types:
1734
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.
@@ -1879,8 +1937,37 @@ mod verify {
1879
1937
generate_unchecked_math_harness ! ( u128 , unchecked_sub, checked_unchecked_sub_u128) ;
1880
1938
generate_unchecked_math_harness ! ( usize , unchecked_sub, checked_unchecked_sub_usize) ;
1881
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
+
1882
1969
1883
- // Part 2 : Proof harnesses
1970
+ // Part_2 `widening_mul` proofs
1884
1971
1885
1972
// ====================== u8 Harnesses ======================
1886
1973
generate_widening_mul_intervals ! ( u8 , u16 , widening_mul_u8, 0u8 , u8 :: MAX ) ;
@@ -1905,4 +1992,55 @@ mod verify {
1905
1992
widening_mul_u64_large, u64 :: MAX - 10u64 , u64 :: MAX ,
1906
1993
widening_mul_u64_mid_edge, ( u64 :: MAX / 2 ) - 10u64 , ( u64 :: MAX / 2 ) + 10u64
1907
1994
) ;
1995
+
1996
+ // Part_2 `wrapping_shl` proofs
1997
+ //
1998
+ // Target types:
1999
+ // i{8,16,32,64,128,size} and u{8,16,32,64,128,size} -- 12 types in total
2000
+ //
2001
+ // Target contracts:
2002
+ // #[ensures(|result| *result == self << (rhs & (Self::BITS - 1)))]
2003
+ //
2004
+ // Target function:
2005
+ // pub const fn wrapping_shl(self, rhs: u32) -> Self
2006
+ //
2007
+ // This function performs an panic-free bitwise left shift operation.
2008
+ generate_wrapping_shift_harness ! ( i8 , wrapping_shl, checked_wrapping_shl_i8) ;
2009
+ generate_wrapping_shift_harness ! ( i16 , wrapping_shl, checked_wrapping_shl_i16) ;
2010
+ generate_wrapping_shift_harness ! ( i32 , wrapping_shl, checked_wrapping_shl_i32) ;
2011
+ generate_wrapping_shift_harness ! ( i64 , wrapping_shl, checked_wrapping_shl_i64) ;
2012
+ generate_wrapping_shift_harness ! ( i128 , wrapping_shl, checked_wrapping_shl_i128) ;
2013
+ generate_wrapping_shift_harness ! ( isize , wrapping_shl, checked_wrapping_shl_isize) ;
2014
+ generate_wrapping_shift_harness ! ( u8 , wrapping_shl, checked_wrapping_shl_u8) ;
2015
+ generate_wrapping_shift_harness ! ( u16 , wrapping_shl, checked_wrapping_shl_u16) ;
2016
+ generate_wrapping_shift_harness ! ( u32 , wrapping_shl, checked_wrapping_shl_u32) ;
2017
+ generate_wrapping_shift_harness ! ( u64 , wrapping_shl, checked_wrapping_shl_u64) ;
2018
+ generate_wrapping_shift_harness ! ( u128 , wrapping_shl, checked_wrapping_shl_u128) ;
2019
+ generate_wrapping_shift_harness ! ( usize , wrapping_shl, checked_wrapping_shl_usize) ;
2020
+
2021
+ // Part_2 `wrapping_shr` proofs
2022
+ //
2023
+ // Target types:
2024
+ // i{8,16,32,64,128,size} and u{8,16,32,64,128,size} -- 12 types in total
2025
+ //
2026
+ // Target contracts:
2027
+ // #[ensures(|result| *result == self >> (rhs & (Self::BITS - 1)))]
2028
+ // Target function:
2029
+ // pub const fn wrapping_shr(self, rhs: u32) -> Self {
2030
+ //
2031
+ // This function performs an panic-free bitwise right shift operation.
2032
+ generate_wrapping_shift_harness ! ( i8 , wrapping_shr, checked_wrapping_shr_i8) ;
2033
+ generate_wrapping_shift_harness ! ( i16 , wrapping_shr, checked_wrapping_shr_i16) ;
2034
+ generate_wrapping_shift_harness ! ( i32 , wrapping_shr, checked_wrapping_shr_i32) ;
2035
+ generate_wrapping_shift_harness ! ( i64 , wrapping_shr, checked_wrapping_shr_i64) ;
2036
+ generate_wrapping_shift_harness ! ( i128 , wrapping_shr, checked_wrapping_shr_i128) ;
2037
+ generate_wrapping_shift_harness ! ( isize , wrapping_shr, checked_wrapping_shr_isize) ;
2038
+ generate_wrapping_shift_harness ! ( u8 , wrapping_shr, checked_wrapping_shr_u8) ;
2039
+ generate_wrapping_shift_harness ! ( u16 , wrapping_shr, checked_wrapping_shr_u16) ;
2040
+ generate_wrapping_shift_harness ! ( u32 , wrapping_shr, checked_wrapping_shr_u32) ;
2041
+ generate_wrapping_shift_harness ! ( u64 , wrapping_shr, checked_wrapping_shr_u64) ;
2042
+ generate_wrapping_shift_harness ! ( u128 , wrapping_shr, checked_wrapping_shr_u128) ;
2043
+ generate_wrapping_shift_harness ! ( usize , wrapping_shr, checked_wrapping_shr_usize) ;
2044
+
1908
2045
}
2046
+
0 commit comments