Skip to content

[Feature]: rfc8949 canonicalization #144

@hoxxep

Description

@hoxxep

Is there an existing issue for this?

  • I have searched the existing issues

Description

The current ciborium implementation follows RFC 7049 / RFC 8949 4.2.3 backwards compatible canonical CBOR output (length-first map key ordering).

I would quite like to output canonical CBOR in the more "modern" RFC 8949 4.2.1 spec (lexicographic byte ordering).

The change is as simple as modifying the cmp_value function, but toggling this functionality is tricky. It's really easy to implement as a crate feature, but then different libraries might cause the features to conflict (eg. two libs for different protocols using different scheme features in the same application project).

It would be nice to pass the canonicalisation scheme as an enum to the Serializer, into_reader, to_vec methods; but then how this makes it into the CanonicalValue struct would require a lot of work. An alternate suggestion of how canonicalisation/key ordering could be done is suggested below (albeit messily gated behind #[cfg(std)] flags for now).

I'm happy to continue with this work if it's something you're interested in.

Acceptance Criteria

No response

Suggestions for a technical implementation

The starts to a bodged alternative implementation, but would allow for RFC 7049, 8049, or no sorting for faster serialization. Only sorts keys once: #143

Lazy cmp_value implementation:

/// Compares two values using canonical comparison as defined in RFC 8949 4.2.1.
pub fn cmp_value_rfc8949(v1: &Value, v2: &Value) -> Ordering {
    let mut bytes1 = Vec::new();
    let _ = crate::ser::into_writer(v1, &mut bytes1);
    let mut bytes2 = Vec::new();
    let _ = crate::ser::into_writer(v2, &mut bytes2);
    bytes1.cmp(&bytes2)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions