Skip to content

Commit c4a1f45

Browse files
lanfeimayew005MWDZYenyun035rajathkotyal
authored
Harnesses for carrying_mul (rust-lang#114)
## Towards: Issue rust-lang#59 ### Parent branch: main --- ### Changes - Added macros for generating `carrying_mul` harnesses - Added harnesses for `carrying_mul` for the following integer types: - `u8`, `u16`, `u32`, `u64` --------- Co-authored-by: yew005 <[email protected]> Co-authored-by: MWDZ <[email protected]> Co-authored-by: Yenyun035 <[email protected]> Co-authored-by: Rajath <[email protected]> Co-authored-by: Rajath Kotyal <[email protected]>
1 parent 61f68cf commit c4a1f45

File tree

1 file changed

+80
-4
lines changed

1 file changed

+80
-4
lines changed

library/core/src/num/mod.rs

+80-4
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)