---
# System prepended metadata

title: Gordian CBOR Tags Update

---

# Gordian CBOR Tags Update

## Wolf McNally, Blockchain Commons

### ⚠️ NOTE: The codepoints listed below are no longer authoritative. This document is now of historical interest only.

Refer to [the `CBORTags.swift` file in `BCSwiftFoundation`](https://github.com/BlockchainCommons/BCSwiftSecureComponents/blob/master/Sources/SecureComponents/Implementation/CBORTags.swift) for their authoritative assignments.

## Envelope-Related Tags as They Currently Exist

Due to the accidents of the development process, how we're currently occupying the tag namespace is not as neatly organized as we might want for the purpose of pursuing IANA registration. The purpose of this document is to illustrate the current situation and spark discussion/decision about how to proceed.

I have categorized the tags we're using as follows:

* `core`: Essential to basic envelope functioning.
* `ext`: Extended envelope features: signing, public key encryption, sskr, etc.
* `dfc`: Distributed function calls.

There are seven tags in the `core` category, but they are not contiguous. These are all documented in the I-D.

There are an additional eight in the `ext` category, also not contiguous. These are documented in the Secure Components docs. They are referred to in the I-D but not documented there.

The `dfc` category contains seven tags, and they are contiguous but not blocked with other tags we're using. These are not formally documented although we have sample code that uses them.

All of the tags listed below are "1+1", i.e., one CBOR header byte and one value byte, with the exception of `sskr-share`, which is 1+2.

Here are some possible courses of action:

* Re-group the tags below so they are more contiguous and grouped by category. This is a breaking change, of course, and we need to take have a strategy for possible future expansion.
* Register the `core` tags (and possibly other categories) at their current code points, and not worry about reorganization.
* Attempt to reserve the whole range from 200-230.
* Reorganize now but defer IANA registration.
* Defer any reorganization or IANA registration.

| code point | name | category
|:-|:-|:-
| 24 | `leaf` | core
| ... |
| 200 | `envelope` | core
| 201 | `crypto-message` | core
| 202 | `common-identifier` | ext
| 203 | `digest` | core
| 204 | `symmetric key` | ext
| 205 | `private-key-base` | ext
| 206 | `public-key-base` | ext
| 207 | `sealed-message` | ext
| 208 |
| 209 |
| 210 |
| 211 |
| 212 |
| 213 | `function` | dfc
| 214 | `parameter` | dfc
| 215 | `request` | dfc
| 216 | `response` | dfc
| 217 | `placeholder` | dfc
| 218 | `replacement` | dfc
| 219 |
| 220 |
| 221 | 
| 222 | `assertion` | core
| 222 | `signature` | ext
| 223 | `known-value` | core
| 224 | `wrapped-envelope` | core
| 225 |
| 226 |
| 227 |
| 228 |
| 229 |
| 230 | `agreement-public-key` | ext
| ... |
| 309 | `crypto-sskr` | ext

There are other tags we've defined in the 3xx range, but `crypto-sskr` is the only one that concerns functionality we've actually currently incorporated into the Envelope API. But nothing about SSKR requires this: it could be moved to a seperate package that depends on envelope. So could pretty much everything in the `ext` category for that matter. Even `crypto-message` and the ability to encrypt could be theoretically made optional, although there is structure-level support for encryption, so the actual support for encryption would have to become a sort of plugin, and without it the encryption API would need to throw errors.

## Analysis of Tag Frequency in Examples

* If we could pick a single 1-byte tag, it would obviously be `envelope`. It is ubiquitous because "envelopes are made up out of envelopes".
* `leaf` is the second-most frequently used, but it is already a 1-byte tag because its semantics are exactly the same as the [IANA registry](https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml) entry.
* `assertion` is the next-most frequently used tag, as I suspected.

### Verifiable Credential

| Name | Count |
|:-|:-
| envelope | 48
| leaf | 26
| assertion | 15
| known-value | 5
| crypto-cid | 1
| signature | 1
| wrapped-envelope | 1

### Warranty (redacted credential + signature)

| Name | Count |
|:-|:-
| envelope | 48
| leaf | 19
| assertion | 12
| crypto-digest | 7
| known-value | 6
| wrapped-envelope | 3
| signature | 2
| crypto-cid | 1

### Book Metadata

| Name | Count |
|:-|:-
| envelope | 45
| leaf | 18
| assertion | 13
| known-value | 9
| crypto-cid | 2
| crypto-digest | 1

## Proposed New CBOR Tag Codepoints

* Needless to say, this is a breaking change. However, some things *won't* break, e.g., existing URs like `crypto-seed` and `crypto-sskr`. This is because URs do *not* include the top-level CBOR tag, letting the type name field handle that, and none of the type name assignments are changing here. But URs that nest tagged CBOR structures with any of the renumbered tags *will* break.
* Within a category, in the absence of other sorting criteria, I have sorted the tags alphabetically by name, with corresponding numbering.
* Tag 24, and all the tags in the 200-255 range are 1+1 tags: they use two bytes, one for the CBOR header and one for the actual value.
* In the [IANA Registry](https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml) all the 1+1 tags from 128-255 are currently unassigned. In this proposal, we'd be asking for six of them right now, and squatting on six more.
* Tags above 255 are 1+2. All the 1+2 tags in the 279-1000 range are currently unassigned.

### Envelope Core

* With the exception of #6.24 `leaf`, these are the tags we would register with IANA.
* Despite the nice aesthetics of using a sequential tag for the next version, I'm assuming IANA probably won't let us register a tag without a spec, so selecting a tag code point for a future version of envelope should probably be deferred to when we actually produce the spec. Personally, I'd be happy with any 1+1 tag for a major revision to envelope, but if you want to pick one to squat on anyway, let me know.
* `crypto-message` and `digest` are speced in SecureComponents.
* `envelope`, `assertion`, `known-value`, and `wrapped-envelope` are speced in the envelope docs.
* All of these are also speced in the envelope I-D.

| code point | name
|:-|:-
| 24 | `leaf`
| 200 | `envelope`
| 201 | `assertion`
| 202 | `known-value`
| 203 | `wrapped-envelope`
| 204 | `digest`
| 205 | `crypto-message`
| 206 | `compressed`

### Distributed Function Calls

* Inasmuch as we'd like envelopes to be commonly used for this application, I propose giving its related tags the next higher range.
* This is still in the 1+1 tag space, so it's pretty valuable real-estate.
* The ordering here was chosen primarily to group semantics.
* We have reference code and examples for the first four of these tags, and some informal writing about the last two, but no definitive specs for any of them yet.

| code point | name
|:-|:-
| 207 | `request`
| 208 | `response`
| 209 | `function`
| 210 | `parameter`
| 211 | `placeholder`
| 212 | `replacement`

### Extensions

* These are the utility structures we've identified and speced related to other various applications that aren't specifically Bitcoin-related.
* This is where I recommend we start using 1+2 tags, so as not to get greedy in the 1+1 tag space.
* These are all speced in the SecureComponents documentation.

| code point | name
|:-|:-
| 300 | `agreement-private-key`
| 301 | `agreement-public-key`
| 302 | `common-identifier`
| 303 | `crypto-eckey`
| 304 | `crypto-seed`
| 305 | `crypto-sskr`
| 306 | `nonce`
| 307 | `password`
| 308 | `private-key-base`
| 309 | `public-key-base`
| 310 | `salt`
| 311 | `sealed-message`
| 312 | `signature`
| 313 | `signing-private-key`
| 314 | `signing-public-key`
| 315 | `symmetric-key`

### Bitcoin-Related

* Skipping up to #6.350 gives us room to add new tags to the previous category.
* I've ordered these alphabetically.
* These all have running code for them in BCFoundation, and some of them have specs in the research repo.

| code point | name
|:-|:-
| 350 | `crypto-account`
| 351 | `crypto-address`
| 352 | `crypto-coin-info`
| 353 | `crypto-hdKey`
| 354 | `crypto-keypath`
| 355 | `crypto-psbt`

### Crypto-Output

* This section is for `crypto-output` (output descriptor) and its subtypes.
* Skipped up to #6.370 to start with a round number, and leave additional code points in the Bitcoin category.
* These all have running code for them in BCFoundation, but I don't think we have formal specs.

| code point | name
|:-|:-
| 370 | `crypto-output`
| 371 | `output-combo`
| 372 | `output-cosigner`
| 373 | `output-multisig`
| 374 | `output-public-key`
| 375 | `output-public-key-hash`
| 376 | `output-raw-script`
| 377 | `output-script-hash`
| 378 | `output-sorted-multisig`
| 379 | `output-taproot`
| 380 | `output-witness-public-key-hash`
| 381 | `output-witness-script-hash`

### Experimental

* Tags in the #6.400 range are for demos or other experiments we don't have or plan to write specs for.

| code point | name
|:-|:-
| 400 | `receipt`
