Skip to content

Comments

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Challenge 12: Safety of NonZero

1 participant