Skip to content

Verify safety of NonZero operations (Challenge 12)#544

Open
jrey8343 wants to merge 4 commits intomodel-checking:mainfrom
jrey8343:challenge-12-nonzero
Open

Verify safety of NonZero operations (Challenge 12)#544
jrey8343 wants to merge 4 commits intomodel-checking:mainfrom
jrey8343:challenge-12-nonzero

Conversation

@jrey8343
Copy link

@jrey8343 jrey8343 commented Feb 8, 2026

Summary

Resolves #71 (Challenge 12: Safety of NonZero)

Adds 376 new Kani verification harnesses for all remaining NonZero functions specified in the challenge, covering:

  • Bit operations: count_ones, swap_bytes, reverse_bits, rotate_left, rotate_right (12 types each)
  • Byte order: from_be, from_le, to_be, to_le (12 types each)
  • Bitor: all 3 implementations — NonZero|NonZero, NonZero|T, T|NonZero (12 types each)
  • Checked/saturating arithmetic: checked_mul, saturating_mul, checked_add, saturating_add (unsigned-only for add)
  • Power operations: checked_pow, saturating_pow (12 types each)
  • Unsigned-only: checked_next_power_of_two, midpoint, isqrt
  • Signed-only: neg, abs, checked_abs, overflowing_abs, saturating_abs, wrapping_abs, unsigned_abs, checked_neg, overflowing_neg, wrapping_neg
  • Reference: from_mut

Changes

  • library/core/src/num/nonzero.rs: 376 new verification harnesses in mod verify
  • library/core/src/num/uint_macros.rs: Remove trivial #[safety::loop_invariant(true)] from checked_pow that caused CBMC assigns check interference with NonZero::new_unchecked verification
  • library/core/src/num/int_macros.rs: Same loop_invariant removal for signed types

Verification

All 385 harnesses pass (376 new + 9 existing):

Manual Harness Summary:
Complete - 385 successfully verified harnesses, 0 failures, 385 total.

Run with:

./scripts/run-kani.sh --kani-args --harness nonzero_check -p core --features core/kani

Add verification harnesses for all remaining NonZero functions:
bit operations (count_ones, swap_bytes, reverse_bits, rotate_left,
rotate_right), byte order (from_be, from_le, to_be, to_le), bitor
(all 3 impls), checked/saturating arithmetic (checked_mul,
saturating_mul, checked_add, saturating_add, checked_pow,
saturating_pow), power of two (checked_next_power_of_two), midpoint,
isqrt, signed operations (neg, abs, checked_abs, overflowing_abs,
saturating_abs, wrapping_abs, unsigned_abs, checked_neg,
overflowing_neg, wrapping_neg), and from_mut.

Remove trivial loop_invariant(true) annotations from primitive
checked_pow that caused CBMC assigns check interference with
NonZero::new_unchecked verification.

Total: 385 harnesses pass (376 new + 9 existing).
@jrey8343 jrey8343 requested a review from a team as a code owner February 8, 2026 03:37
The 128-bit saturating_pow harnesses with unbounded u32 exponents hit
CBMC's 10-minute timeout because 128-bit bitvector multiplication is
extremely expensive. Add a dedicated macro that constrains exp <= 10
with unwind(5), sufficient to cover both the non-saturating and
saturating code paths while keeping verification tractable.
…sion

Same fix as saturating_pow_128: use a dedicated macro with exp <= 10
and #[kani::unwind(5)] for the 128-bit checked_pow harnesses.
@jrey8343 jrey8343 force-pushed the challenge-12-nonzero branch from d41f3ea to 9d26114 Compare February 21, 2026 23:57
@jrey8343
Copy link
Author

CI is passing — ready for review.

@feliperodri feliperodri added the Challenge Used to tag a challenge label Mar 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Challenge Used to tag a challenge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Challenge 12: Safety of NonZero

2 participants