Skip to content

fix: add canonical range check to MontyField31 deserialization#155

Merged
TomWambsgans merged 1 commit intoleanEthereum:mainfrom
jiayaoqijia:fix/monty-field31-canonical-deserialize
Feb 28, 2026
Merged

fix: add canonical range check to MontyField31 deserialization#155
TomWambsgans merged 1 commit intoleanEthereum:mainfrom
jiayaoqijia:fix/monty-field31-canonical-deserialize

Conversation

@jiayaoqijia
Copy link
Contributor

Summary

Severity: CRITICAL (F-01)

The Deserialize impl for MontyField31 at crates/backend/koala-bear/src/monty_31/monty_31.rs:159-164 accepts any u32 and passes it directly to new_monty() without verifying val < PRIME. An attacker can craft a serialized value >= FP::PRIME that gets stored as-is in Montgomery form, creating a non-canonical field element.

This breaks the field invariant (value < P) and can cause:

  • Incorrect field arithmetic (addition, multiplication produce wrong results)
  • Forged proofs accepted by verifiers
  • Consensus divergence between nodes that check canonicality and those that do not

Fix

Add a range check before new_monty():

if val >= FP::PRIME {
    return Err(serde::de::Error::custom("non-canonical MontyField31 value"));
}

Test plan

  • Verify existing tests pass (serialization round-trip still works for canonical values)
  • Verify that deserializing a value >= PRIME now returns an error
  • Fuzz deserialization with random u32 values to confirm only canonical values are accepted

Found during security audit of leanEthereum repositories.

The Deserialize impl for MontyField31 accepts any u32 and passes it
directly to new_monty() without verifying val < PRIME. An attacker can
supply a value >= PRIME that is stored as-is in Montgomery form,
creating a non-canonical field element. This breaks the field invariant
(value < P) and can cause incorrect arithmetic, forged proofs, or
consensus divergence.

Add a range check that rejects values >= FP::PRIME with a descriptive
serde error.

Severity: CRITICAL (F-01)
@TomWambsgans TomWambsgans merged commit e755ba1 into leanEthereum:main Feb 28, 2026
2 of 3 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