Conversation
Co-Authored-By: Marcin Rataj <lidel@lidel.org>
lidel
left a comment
There was a problem hiding this comment.
I believe we need to explicitly require deterministic CBOR variant (details inline)
| #### COSE Key | ||
|
|
||
| The Data field is defined by [Section 7 of RFC | ||
| 9052](https://www.rfc-editor.org/rfc/rfc9052#section-7). |
There was a problem hiding this comment.
Something I realized in the context of libp2p is that PeerID is a hash of this protobuf.
RFC 9052 COSE_Key is plain CBOR; no deterministic encoding is required. But this spec requires deterministic protobuf encoding so peer IDs are stable.
Problem: Two conformant COSE encoders can produce different Data bytes for the same key, yielding different peer IDs.
Fix: unsure, maybe require RFC 8949 §4.2 Core Deterministic Encoding for COSEKEY*, and reject non-deterministic encodings on decode?
| #### COSE Key | |
| The Data field is defined by [Section 7 of RFC | |
| 9052](https://www.rfc-editor.org/rfc/rfc9052#section-7). | |
| #### COSE Key | |
| The Data field is defined by [Section 7 of RFC | |
| 9052](https://www.rfc-editor.org/rfc/rfc9052#section-7). | |
| The `COSE_Key` MUST be encoded using [CBOR Core Deterministic Encoding (RFC 8949 §4.2)](https://www.rfc-editor.org/rfc/rfc8949#section-4.2). Implementations MUST reject non-deterministic encodings. | |
| Signing and verification for each member are defined by that member's COSE `alg` parameter. |
There was a problem hiding this comment.
Yes. 9052 has encoding restrictions, but they don't apply to the keys.
There was a problem hiding this comment.
I also found this RFC: https://datatracker.ietf.org/doc/html/rfc9679 which sounds like what we should use instead of trying to define this.
| #### COSE KeySet | ||
|
|
||
| The Data field is defined by [Section 7 of RFC | ||
| 9052](https://www.rfc-editor.org/rfc/rfc9052#section-7). |
There was a problem hiding this comment.
PeerID semantics feel undefined?
Fix: spell out identity and verification rules, or drop COSE_KEY_SET from this PR until the use case is settled.
I think it may be beneficial to keep it to support hybrid keys and signatures, for example when we have both ed25519+something post-quantum secure, and requiring both sigs/handshakes etc.
so maybe:
| #### COSE KeySet | |
| The Data field is defined by [Section 7 of RFC | |
| 9052](https://www.rfc-editor.org/rfc/rfc9052#section-7). | |
| #### COSE KeySet | |
| The Data field is defined by [Section 7 of RFC | |
| 9052](https://www.rfc-editor.org/rfc/rfc9052#section-7). | |
| `COSE_KeySet` is intended for hybrid keys and signatures, for example pairing Ed25519 with a post-quantum scheme so that handshakes and signatures combine both. The following rules apply: | |
| - The `COSE_KeySet` MUST be encoded using [CBOR Core Deterministic Encoding (RFC 8949 §4.2)](https://www.rfc-editor.org/rfc/rfc8949#section-4.2). Implementations MUST reject non-deterministic encodings. | |
| - Members MUST be ordered in ascending lexicographic order of their deterministic CBOR encoding. This ensures independent encoders produce identical bytes for the same set, so the resulting PeerID is stable. | |
| - A `COSE_KeySet` MUST contain at least two members. A single-member set MUST be encoded as `COSE_Key` instead, so the same identity has exactly one on-the-wire representation. | |
| - Each COSE `alg` (and key-type family) MUST appear at most once in the set, removing ambiguity about which member is expected to produce a given signature or handshake component. | |
| - A signature or handshake over a `COSE_KeySet` identity is valid only if **every** member validates its corresponding component. Peers MUST NOT accept proofs that cover only a subset; doing so would defeat the purpose of the hybrid. | |
| Signing and verification for each member are defined by that member's COSE `alg` parameter. |
There was a problem hiding this comment.
I think it makes sense to back out the cose keyset changes. It only gives us an array of cose keys. You could imagine having a array of these protobufs instead.
There was a problem hiding this comment.
How do you mean? Current wire format for libp2p-key does not have repeatable fields, we don't have a spec for libp2p-key[], that is something you would have to invent, and add a new multicodec for it.
RFC for COSE_KeySet already exists, and could provide a backward-compatible way for hardening things with multiple keys (e.g. hybrid ed25519 + post-quantum).
Of course this is just an option, we dont have to support o require hybrid signatures this way, or at all, and can defer to future codes, but feels sensible to preregister COSE_KeySet here to allow libp2p ecosystem to experiment and evolve without gatekeepers.
There was a problem hiding this comment.
I mean using multiple protobuf messages instead of a COSE array. Maybe this doesn't work and the COSE array is better. I'm not sure. We'd also need to define how to hash the key set properly.
| COSE_KEY = 0x42; | ||
| COSE_KEY_SET = 0x43; |
There was a problem hiding this comment.
| COSE_KEY = 0x42; | |
| COSE_KEY_SET = 0x43; | |
| COSE_Key = 0x42; | |
| COSE_KeySet = 0x43; |
Other ones look like Secp256k1 and RFC 9052 uses COSE_KeySet.
Perhaps rename to match the RFC?
Co-authored-by: Marcin Rataj <lidel@lidel.org>
|
Doesn't this PR allow to e.g. represent an RSA key in three different ways? All of which would result in a differently encoded PeerID while all use the same key. The same is true when one peer uses COSE and the other PKIX with the same key. Why is such flexibility needed? The last change to the PeerID spec was three years ago. The rate of change doesn't really signal that fast iterations with new key types is required. |
See multiformats/multicodec#400 for a detailed motivation.
cc @lidel