Skip to content

fix: overflow-safe activation interval validation in key_gen#45

Merged
tcoratger merged 3 commits intoleanEthereum:mainfrom
latifkasuli:fix/keygen-overflow-safe-validation
Apr 3, 2026
Merged

fix: overflow-safe activation interval validation in key_gen#45
tcoratger merged 3 commits intoleanEthereum:mainfrom
latifkasuli:fix/keygen-overflow-safe-validation

Conversation

@latifkasuli
Copy link
Copy Markdown
Contributor

Summary

The bounds check in key_gen() had two defects:

  1. usize wrapping: activation_epoch + num_active_epochs can wrap in release builds, silently passing the check (e.g. usize::MAX + 2 wraps to 1).

  2. 32-bit truncation: Self::LIFETIME as usize truncates when LOG_LIFETIME == 32 on 32-bit targets (1u64 << 32 becomes 0), making the validation vacuous.

This PR fixes both by performing the entire validation in u64 space via checked_add, comparing directly against Self::LIFETIME without any usize cast.

Also adds:

  • Compile-time assertion that LOG_LIFETIME <= 32, since sign() and verify() take epoch: u32.
  • Explicit rejection of num_active_epochs == 0, which previously passed validation but caused expand_activation_time() to silently invent a non-empty key range.

Partially addresses #37.

Test plan

  • cargo +nightly test — 119 passed, 0 failed, 1 ignored (pre-existing)
  • cargo +nightly clippy --all-targets — zero warnings
  • cargo +nightly fmt --check — clean

The previous bounds check `activation_epoch + num_active_epochs <= Self::LIFETIME as usize`
had two defects:

1. The usize addition can wrap in release builds, silently passing the
   check with bogus values (e.g. usize::MAX + 2 wraps to 1).

2. `Self::LIFETIME as usize` truncates on 32-bit targets when
   LOG_LIFETIME == 32 (1u64 << 32 becomes 0), making the check vacuous.

Fix both by performing the entire validation in u64 space via checked_add,
comparing directly against Self::LIFETIME without any usize cast.

Also adds:
- Compile-time assertion that LOG_LIFETIME <= 32, since sign() and
  verify() take epoch as u32.
- Explicit rejection of num_active_epochs == 0, which previously passed
  validation but caused expand_activation_time() to silently invent a
  non-empty key range.

Partially addresses leanEthereum#37.
Copy link
Copy Markdown
Contributor

@tcoratger tcoratger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just small comment

tcoratger and others added 2 commits April 3, 2026 16:38
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tcoratger tcoratger merged commit a616b34 into leanEthereum:main Apr 3, 2026
2 checks passed
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.

2 participants