Repository navigation
Conversation
…unchecked RFC 8032 section 5.2.3 says decoding fails when the cleared y is >= p. decompress_unchecked read only bit 455 and reduced y mod p, so an encoding with any of bits 448-454 set, and the encoding of y + p, both decoded. Wycheproof ed448 RustCrypto#63, RustCrypto#64 and RustCrypto#65 verified (3 invalid cases accepted of 70; none after this change; valid 17 of 17 both ways). The decoder now requires the unused bits to be zero and takes y from FieldElement::from_repr, folded into the returned CtOption. decompress, signature R decoding and VerifyingKey::from_bytes inherit the check. Tests: tests/wycheproof.rs over the vendored ed448_test.json (every valid case verifies, every invalid case is refused; fails on master with "tcId 63: invalid case accepted"); unit tests for each unused bit, for y = 1 + p, and for the generator and y = 1 still decoding. Closes RustCrypto#1970
Member
|
See #1972 |
Author
|
Pointing to #1972 is taken. I posted the survey for question 1 there. This PR today: On question 2, the PR is "implement RFC 8032 outright", applied everywhere. It could take these shapes:
Which do you want? The vector test fits all three. On #1462 and #1949, whichever lands second adapts. Happy to take that side. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1970.
Why
RFC 8032 section 5.2.3, step 1: "The y-coordinate is recovered simply by clearing this bit. If the resulting value is >= p, decoding fails."
CompressedEdwardsY::decompress_uncheckedread only bit 455 and reduced y mod p, so an encoding with any of bits 448 to 454 set, and the encoding of y + p, both decoded. Wycheproof ed448 tcId 63, 64 and 65 verified. Conformance, not forgery: only the key holder can produce such a signature, but two verifiers disagree on the same input and one key has two encodings.What
decompress_uncheckedrequiressign & 0x7f == 0and takes y fromFieldElement::from_repr(the checked decoder already in the crate), both folded into the returnedCtOption. Constant time, no early return.decompress, signature R decoding andVerifyingKey::from_bytesgo through it, so they inherit the check.ed448-goldilocks: don't reduce points during decompression #1462 switches this path tofrom_repras well (the y >= p half). This change also covers the unused bits and adds the vectors; whichever lands second rebases, happy to take that side.Tests
tests/wycheproof.rsover the vendoreded448_test.json(C2SP/wycheproof12fd3aaf, sha2563b3c7995...289a): everyvalidcase verifies, everyinvalidcase is refused, tcId 63 to 65 present. Fails on master with "tcId 63: invalid case accepted".decompress(y + p)true to false;VerifyingKey::from_bytes(y + p)Ok to Err.Gates
cargo test -p ed448-goldilocks --all-features: 74 + 1 + 3 passed.cargo fmt --checkclean.cargo clippy --all-features -- -D warningsclean on 1.89 (the workspace pin) and 1.95.0.Not in this PR
CompressedEdwardsY::IDENTITYencodes y = 0; #1949 fixes that.