Skip to content
This repository has been archived by the owner on Dec 18, 2023. It is now read-only.

Add test and fix for non-canonical point at infinity #157

Closed

Conversation

kevaundray
Copy link
Contributor

Description

closes: #XXXX


Before we can merge this PR, please make sure that all the following items have been
checked off. If any of the checklist items are not applicable, please leave them but
write a little note why.

  • Targeted PR against correct branch (master)
  • Linked to Github issue with discussion and accepted design OR have an explanation in the PR that describes this work.
  • Wrote unit tests
  • Updated relevant documentation in the code
  • Added a relevant changelog entry to the Pending section in CHANGELOG.md
  • Re-reviewed Files changed in the Github PR explorer

@kevaundray kevaundray marked this pull request as draft April 15, 2023 21:37
@kevaundray kevaundray marked this pull request as ready for review April 15, 2023 22:02
@kevaundray kevaundray changed the title Add test for non-canonical point at infinity Add test and fix for non-canonical point at infinity Apr 15, 2023
if !flags.is_compressed {
return Err(SerializationError::UnexpectedFlags);
}

// Attempt to obtain the x-coordinate
let x = read_fq_with_offset(&bytes, 0, true)?;
Copy link
Member

Choose a reason for hiding this comment

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

Should we make this a byte-based check? i.e. directly on the bytes that we've read?

Copy link
Member

Choose a reason for hiding this comment

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

Good catch, I've PRed to @kevaundray's fork, if not merged there soon I'll open a PR directly here.

Comment on lines +18 to 19
/// Fetches the flags from the byte-string
pub fn get_flags(bytes: &[u8]) -> Self {

Choose a reason for hiding this comment

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

I think some extra validation here is needed to catch another, more subtle class of non-canonical infinity point encodings: some flag combinations are nonsensical. Here's a failing test to show you what I mean:

#[test]
fn bad_flag_combination() {
    // See https://github.com/zkcrypto/pairing/tree/fa8103764a07bd273927447d434de18aace252d3/src/bls12_381#serialization
    // - Bit 1 is compressed/uncompressed
    // - Bit 2 is infinity
    // - Bit 3 is lexicographical order for compressed point deserialization
    // Hence `0b1110` ("e" in hex) or `0b0110` ("6" in hex") are both nonsensical.
    let non_canonical_hex = "e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
    let non_canonical_bytes = hex::decode(non_canonical_hex).unwrap();
    assert_eq!(non_canonical_bytes.len(), 48);

    let maybe_affine_point: Result<G1Affine, ark_serialize::SerializationError> =
        CanonicalDeserialize::deserialize_compressed(&non_canonical_bytes[..]);

    assert!(maybe_affine_point.is_err())
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants