Permanent link to this page

Registration information

   Tag             296 (sharedref-namespace)
   Data Item       any
   Semantics       isolate shared values within this scope
   Reference       https://cbor.is4.site/sharedref-namespace
   Contact         IS4 <is4.site@gmail.com>

Summary

This tag is used to restrict the visibility of shareable values (using tag 28) to the scope of the value in this tag, similarly to how tag 256 (stringref-namespace) can be used to isolate string references.

Rationale

Existing tags 28 (shareable) and 29 (sharedref) are used to refer to an identical object from multiple places by identifying a value using an auto-incremented index.

The issue with this mechanism is that a single space of identifiers is used for all marked values during the decoding process, which requires adjusting the references when CBOR objects are composed or sequenced, and prevents simple binary concatenation of CBOR values.

By explicitly establishing a namespace of shared values, references within such names do not depend on any previous marked values in the CBOR stream, and marking shareable values within it does not affect the rest of the CBOR stream after the namespace.

Description

The sharedref-namespace tag (value 296) establishes an explicit scope of shared values, affecting any value tagged as shareable (value 28) or sharedref (value 29) within the tag. The modification to the behaviour of these two tags is as follows:

In practical terms, this means that any arbitrary sharedref-namespace-tagged value may be inserted in the CBOR stream (while maintaining well-formedness) without any effect on the decoding of any shared values that follow it, and without previous shared values affecting those within the sharedref-namespace tag. That is, the tag fully isolates its content from any external data in terms of value sharing (tags 28 and 29).

The interpretational value of this tag is the same as that of the value stored within it. Wrapping the whole CBOR stream in sharedref-namespace, i.e. replacing the implicit scope of shared values with an explicit one, should have no observable effect on the interpretation of such a stream. Likewise, removing all sharedref-namespace tags in a CBOR stream, while ensuring shared references in previously isolated namespaces do not overlap and still refer to identical values, should have no observable effect on the interpretation of such a stream.

Implementation note

As these tags may be arbitrarily nested within each other, decoders need to preserve information about namespaces enclosing the current scope in order to restore them when the scope ends. Architecturally, the implementation should be similar to that of stringref-namespace (value 256). Unlike that tag, however, using the sharedref-namespace in a CBOR stream containing shareable values or references thereto is completely optional, and only serves to establish isolated scopes within such stream.

Examples

The following is an example of 3 arrays stored alongside each other, each containing an object in its first index shared to the second index.

[
  [28({}), 29(0)],
  [28({}), 29(1)],
  [28({}), 29(2)]
]
83          # array(3)
   82       # array(2)
      D8 1C # tag(28)
         A0 # map(0)
      D8 1D # tag(29)
         00 # unsigned(0)
   82       # array(2)
      D8 1C # tag(28)
         A0 # map(0)
      D8 1D # tag(29)
         01 # unsigned(1)
   82       # array(2)
      D8 1C # tag(28)
         A0 # map(0)
      D8 1D # tag(29)
         02 # unsigned(2)

Even though these arrays are fundamentally equivalent, their binary encoding is not interchangeable. However, wrapping each of them in its individual namespace fixes this issue:

[
  296([28({}), 29(0)]),
  296([28({}), 29(0)]),
  296([28({}), 29(0)])
]
83             # array(3)
   D9 0128     # tag(296)
      82       # array(2)
         D8 1C # tag(28)
            A0 # map(0)
         D8 1D # tag(29)
            00 # unsigned(0)
   D9 0128     # tag(296)
      82       # array(2)
         D8 1C # tag(28)
            A0 # map(0)
         D8 1D # tag(29)
            00 # unsigned(0)
   D9 0128     # tag(296)
      82       # array(2)
         D8 1C # tag(28)
            A0 # map(0)
         D8 1D # tag(29)
            00 # unsigned(0)

Each occurrence of 29(0) identifies the map preceding it, as it is the first marked value in its respective namespace.

Security considerations

As this tag is usable only in combination with tags 28 and 29, the same security considerations as for those tags apply. Establishing isolated scopes of shared values does not have any impact on the security of these tags.