Skip to content

x448: reject non-canonical encodings of low order points - #1947

Open
Bruce039 wants to merge 1 commit into
RustCrypto:masterfrom
Bruce039:x448-low-order-noncanonical
Open

Bruce039 wants to merge 1 commit into
RustCrypto:masterfrom
Bruce039:x448-low-order-noncanonical

Conversation

@Bruce039

@Bruce039 Bruce039 commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

MontgomeryPoint::is_low_order compares the raw 56 bytes against LOW_A/LOW_B/LOW_C, the canonical encodings of 0, 1 and p - 1. RFC 7748 has implementations accept non-canonical u values and reduce them, which the ladder does, so p and p + 1 decode to 0 and 1 but get past the check. x448::PublicKey::from_bytes accepts them and x448(sk, p) returns Some([0; 56]), although its docs say it never returns a low order result.

The check now reduces u before comparing. Only 0 and 1 have non-canonical encodings in 56 bytes, so this covers all of them.

Added test_non_canonical_low_order in x448, which fails on master for both values. #1306 moves this function to MontgomeryXpoint unchanged, so it would need the same change if that lands first.

is_low_order compared the raw bytes against the canonical encodings of 0, 1 and p - 1, so the non-canonical encodings p and p + 1 were not detected and x448() returned an all-zero shared secret for them.

This branch has not been deployed

No deployments
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.

1 participant