<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     submissionType="independent"
     category="info"
     tocDepth="3"
     docName="draft-rundgren-deterministic-cbor-07"
     ipr="trust200902"
     obsoletes=""
     updates=""
     xml:lang="en"
     tocInclude="true"
     symRefs="true"
     sortRefs="true"
     version="3">
    <front>
      <title abbrev="D-CBOR">
        Deterministically Encoded CBOR (D-CBOR)
      </title>
      <author fullname="Anders Rundgren" initials="A." surname="Rundgren" role="editor">
          <organization>Independent</organization>
          <address>
              <postal>
                  <city>Montpellier</city>
                  <country>France</country>
              </postal>
              <email>anders.rundgren.net@gmail.com</email>
              <uri>https://www.linkedin.com/in/andersrundgren/</uri>
          </address>
      </author>
      <date year="2023"/>
      <area>Application</area>
      <workgroup>CBOR</workgroup>
      <keyword>CBOR</keyword>
      <keyword>Encoding</keyword>
      <keyword>Deterministic</keyword>

      <abstract>
        <t>
          This document describes a deterministic encoding scheme for CBOR
          intended for usage in high-end computing platforms like mobile
          phones, Web browsers, and Web servers.  In addition to enhancing
          interoperability, deterministic encoding can also support
          cryptographic operations like signing CBOR data items.
          Using this specification, the latter can achieved without wrapping
          such data in byte strings or depend on non-standard canonicalization procedures.
        </t>
      </abstract>
    </front>
    <middle>
      <section anchor="d-cbor.intro" numbered="true" toc="default">
        <name>Introduction</name>
        <t>
          This specification introduces a deterministic encoding scheme for data expressed in the
          CBOR <xref target="RFC8949" format="default"/> format.  This scheme is subsequently
          referred to as D&nbhy;CBOR.
        </t>
        <t>
          Note that this document is not on the IETF standards track. However, a
          conformant implementation is supposed to adhere to the specified behavior for
          security and interoperability reasons.
        </t>
        <section anchor="d-cbor.background" numbered="true" toc="default">
          <name>Background</name>
          <t>
            <xref target="RFC8949" format="default"/> supports a number of deterministic encoding
            options that are <em>mutually incompatible</em>, like Rule 1-3 in Section 4.2.2.
            This complicates large scale rollout of applications needing deterministic CBOR encoding.
          </t>
        </section>
        <section anchor="d-cbor.objectives" numbered="true" toc="default">
          <name>Objectives</name>
          <t>
            The primary objective of D&nbhy;CBOR is providing an interoperable
            CBOR profile, <em>primarily</em> targeting high-end computing platforms
            like mobile phones, Web browsers, and Web servers.
            In addition, due to the underpinning deterministic encoding scheme,
            D&nbhy;CBOR also enables performing cryptographic operations like
            signatures over "raw" (unwrapped) CBOR data items since signatures
            depend on a <em>unified</em> representation of the data to be signed.
            Furthermore, building on the same foundation, D&nbhy;CBOR also permits
            decoded CBOR data to be subjected to simple and secure 
            <em>transformation</em> and <em>reencoding</em> operations.
          </t>
          <t>
            The deterministic encoding scheme described in this document is
            characterized by being <em>bidirectional</em> also when CBOR is provided
            in <em>diagnostic notation</em> (Section 8 of <xref target="RFC8949" format="default"/>),
            making D&nbhy;CBOR comparatively easy to understand, debug, and implement.
          </t>
          <t>
            In spite of the enhanced functionality, this specification retains full 
            compatibility with <xref target="RFC8949" format="default"/>.
          </t>
          <t>
            See also <xref target="I-D.mcnally-deterministic-cbor" format="default"/> which represents
            an alternative approach to deterministic encoding.
          </t>
        </section>
        <section anchor="d-cbor.terms" numbered="true" toc="default">
          <name>Terminology</name>
          <t>
            The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST&nbsp;NOT</bcp14>",
            "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>
              SHALL&nbsp;NOT
            </bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", 
            "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
            "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" 
            in this document are to be interpreted as
            described in BCP 14 <xref target="RFC2119"/> 
            <xref target="RFC8174"/> when, and only when, they
            appear in all capitals, as shown here.
          </t>
        </section>
      </section>

      <section anchor="d-cbor.spec" numbered="true" toc="default">
        <name>Specification</name>
        <t>
          The deterministic encoding scheme used by D&nbhy;CBOR builds on
          Section 4.2 of <xref target="RFC8949" format="default"/>.
          However, to achieve a <em>fixed and bidirectional</em> representation
          of numbers, Rule 2 in Section 4.2.2 MUST also be adhered to.
          <xref target="d-cbor.numbers" format="default"/> provides
          additional information regarding numbers in D&nbhy;CBOR.
        </t>
        <t>
          Occurrences of unknown or malformed CBOR data items MUST be rejected.
        </t>
        <t>
          Map keys MUST only be compared and sorted based on their
          bytewise lexicographic order of their deterministic encoding.
        </t>
        <t>
          For applications that depend on <em>deterministic reencoding</em> of CBOR data items,
          compliant decoder implementations MUST be able to recreate such data
          in its original form.  This means for example that the string component
          of date items (<tt>tag&nbsp;0</tt>) MUST be preserved "as&nbsp;is" in order
          to maintain consistency.
        </t>
        <t>
          The <em>optional</em> numerical extensions described in
          Section 3.4.4. of <xref target="RFC8949" format="default"/> MUST be
          treated as <em>distinct</em> data items as well as not be subjected to
          any transformations at the encoding level.
        </t>
        <t>
          A compliant D&nbhy;CBOR implementation SHOULD as a <em>minimum</em> support the following
          CBOR data items:
        </t>
        <table anchor="d-cbor.types-table">
          <name>Supported CBOR Data Items</name>
          <thead>
            <tr>
              <th align="center">Data Item</th>
              <th align="center">Encoding</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>
                <tt>integer</tt>
              </td>
              <td>
                Major type <tt>0</tt> and <tt>1</tt>
            </td>
            </tr>
            <tr>
              <td>
                <tt>bignum</tt>
              </td>
              <td>
                <tt>0xc2</tt> and <tt>0xc3</tt>
              </td>
            </tr>
            <tr>
              <td>
                <tt>floating&nbsp;point</tt>
              </td>
              <td>
                <tt>0xf9</tt>, <tt>0xfa</tt> and <tt>0xfb</tt>
              </td>
            </tr>
            <tr>
              <td>
                <tt>byte&nbsp;string</tt>
              </td>
              <td>Major type <tt>2</tt></td>
            </tr>
            <tr>
              <td>
                <tt>text&nbsp;string</tt>
              </td>
              <td>Major type <tt>3</tt></td>
            </tr>
            <tr>
              <td>
                <tt>false</tt>
              </td>
              <td>
                <tt>0xf4</tt>
              </td>
            </tr>
            <tr>
              <td>
                <tt>true</tt>
              </td>
              <td>
                <tt>0xf5</tt>
              </td>
            </tr>
            <tr>
              <td>
                <tt>null</tt>
              </td>
              <td>
                <tt>0xf6</tt>
              </td>
            </tr>
            <tr>
              <td>
                <tt>array</tt>
              </td>
              <td>Major type <tt>4</tt></td>
            </tr>
            <tr>
              <td>
                <tt>map</tt>
              </td>
              <td>Major type <tt>5</tt></td>
            </tr>
            <tr>
              <td>
                <tt>tag</tt>
              </td>
              <td>
                Major type <tt>6</tt>
              </td>
            </tr>
          </tbody>
        </table>
        <t>
          See also <xref target="d-cbor.constraints" format="default"/>.
        </t>
      </section>

      <section anchor="d-cbor.iana" numbered="true" toc="default">
        <name>IANA Considerations</name>
        <t>
          This document has no IANA actions.
        </t>
      </section>

      <section anchor="d-cbor.security" numbered="true" toc="default">
        <name>Security Considerations</name>
        <t>
          This specification inherits all the security considerations
          of CBOR <xref target="RFC8949" format="default"/>.
        </t>
        <t>
          Applications that exploit the uniqueness of deterministic encoding
          should verify that the used decoder actually flags incorrectly formatted
          CBOR data items.
        </t>
      </section>
    </middle>
    <back>
      <references>
        <name>References</name>
        <references>
            <name>Normative References</name>

            <xi:include
                href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
            <xi:include
                href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
            <xi:include
                href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8949.xml"/>

        </references>
        <references>
            <name>Informative References</name>

          <reference anchor="I-D.mcnally-deterministic-cbor">
            <front>
              <title>Gordian dCBOR: Deterministic CBOR Implementation Practices</title>
              <author fullname="Wolf McNally" initials="W." surname="McNally">
                <organization>Blockchain Commons</organization>
              </author>
              <author fullname="Christopher Allen" initials="C." surname="Allen">
                <organization>Blockchain Commons</organization>
              </author>
              <date day="4" month="May" year="2023"/>
 
            </front>
            <seriesInfo name="Internet-Draft" value="draft-mcnally-deterministic-cbor-01"/>
          </reference>
 
        </references>

      </references>

      <section anchor="d-cbor.numbers" numbered="true" toc="default">
        <name>Encoding of Numbers</name>
        <t>This section is normative.</t>
        <t>
          The following sub sections hold examples of numbers expressed
          in <em>diagnostic notation</em> (Section 8 of <xref target="RFC8949" format="default"/>)
          and their D&nbhy;CBOR encoded counterpart (expressed in hexadecimal).
        </t>
        <t>
          Note that the values and encodings are supposed to work in <em>both</em> directions.
        </t>
        <section anchor="d-cbor.integer" numbered="true" toc="default">
          <name>Integer Numbers</name>
          <t>
            The following table holds a set of integers highlighting the
            selection between <tt>integer</tt> and <tt>bignum</tt> data items.
          </t>
          <table anchor="d-cbor.integer-table">
            <name>Integer Numbers</name>
            <thead>
              <tr><th align="center">Value</th><th align="center">Encoding</th></tr>
            </thead>
            <tbody>
              <tr>
                <td align="right">
                  <tt>0</tt>
                </td>
                <td align="right">
                  <tt>00</tt>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <tt>-1</tt>
                </td>
                <td align="right">
                  <tt>20</tt>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <tt>23</tt>
                </td>
                <td align="right">
                  <tt>17</tt>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <tt>24</tt>
                </td>
                <td align="right">
                  <tt>1818</tt>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <tt>-24</tt>
                </td>
                <td align="right">
                  <tt>37</tt>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <tt>-25</tt>
                </td>
                <td align="right">
                  <tt>3818</tt>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <tt>255</tt>
                </td>
                <td align="right">
                  <tt>18ff</tt>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <tt>256</tt>
                </td>
                <td align="right">
                  <tt>190100</tt>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <tt>-256</tt>
                </td>
                <td align="right">
                  <tt>38ff</tt>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <tt>-257</tt>
                </td>
                <td align="right">
                  <tt>390100</tt>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <tt>65535</tt>
                </td>
                <td align="right">
                  <tt>19ffff</tt>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <tt>65536</tt>
                </td>
                <td align="right">
                  <tt>1a00010000</tt>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <tt>1099511627775</tt>
                </td>
                <td align="right">
                  <tt>1b000000ffffffffff</tt>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <tt>18446744073709551615</tt>
                </td>
                <td align="right">
                  <tt>1bffffffffffffffff</tt>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <tt>18446744073709551616</tt>
                </td>
                <td align="right">
                  <tt>c249010000000000000000</tt>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <tt>-18446744073709551616</tt>
                </td>
                <td align="right">
                  <tt>3bffffffffffffffff</tt>
                </td>
              </tr>
              <tr>
                <td align="right">
                  <tt>-18446744073709551617</tt>
                </td>
                <td align="right">
                  <tt>c349010000000000000000</tt>
                </td>
              </tr>
            </tbody>
          </table>
        </section>
        <section anchor="d-cbor.floating" numbered="true" toc="default">
          <name>Floating Point Numbers</name>
          <section anchor="d-cbor.float.dedicated" numbered="true" toc="default">
            <name>Dedicated Floating Point Numbers</name>
            <t>
              The following table holds the set of dedicated IEEE&nbsp;754 values.
              Note that <tt>NaN</tt> "signaling" MUST be flagged as an error. 
            </t>
            <table anchor="d-cbor.float.dedicated-table">
              <name>Dedicated Floating Point Numbers</name>
              <thead>
                <tr>
                  <th align="center">Value</th>
                  <th align="center">Encoding</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td align="right">
                    <tt>0.0</tt>
                  </td>
                  <td align="right">
                    <tt>f90000</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>-0.0</tt>
                  </td>
                  <td align="right">
                    <tt>f98000</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>Infinity</tt>
                  </td>
                  <td align="right">
                    <tt>f97c00</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>-Infinity</tt>
                  </td>
                  <td align="right">
                    <tt>f9fc00</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>NaN</tt>
                  </td>
                  <td align="right">
                    <tt>f97e00</tt>
                  </td>
                </tr>
              </tbody>
            </table>
          </section>
          <section anchor="d-cbor.float.assorted" numbered="true" toc="default">
            <name>Assorted Floating Point Numbers</name>
            <t>
              The following table holds a set of "ordinary" IEEE&nbsp;754 values
              including some edge cases.
              Note that subnormal floating point values MUST be supported.
            </t>
            <table anchor="d-cbor.float.assorted-table">
              <name>Assorted Floating Point Numbers</name>
              <thead>
                <tr>
                  <th align="center">Value</th>
                  <th align="center">Encoding</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td align="right">
                    <tt>-5.960464477539062e-8</tt>
                  </td>
                  <td align="right">
                    <tt>fbbe6fffffffffffff</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>-5.9604644775390625e-8</tt>
                  </td>
                  <td align="right">
                    <tt>f98001</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>-5.960464477539064e-8</tt>
                  </td>
                  <td align="right">
                    <tt>fbbe70000000000001</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>-5.960465188081798e-8</tt>
                  </td>
                  <td align="right">
                    <tt>fab3800001</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>0.00006097555160522461</tt>
                  </td>
                  <td align="right">
                    <tt>f903ff</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>65504.0</tt>
                  </td>
                  <td align="right">
                    <tt>f97bff</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>65504.00390625</tt>
                  </td>
                  <td align="right">
                    <tt>fa477fe001</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>65536.0</tt>
                  </td>
                  <td align="right">
                    <tt>fa47800000</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>10.559998512268066</tt>
                  </td>
                  <td align="right">
                    <tt>fa4128f5c1</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>10.559998512268068</tt>
                  </td>
                  <td align="right">
                    <tt>fb40251eb820000001</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>3.4028234663852886e+38</tt>
                  </td>
                  <td align="right">
                    <tt>fa7f7fffff</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>3.402823466385289e+38</tt>
                  </td>
                  <td align="right">
                    <tt>fb47efffffe0000001</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>1.401298464324817e-45</tt>
                  </td>
                  <td align="right">
                    <tt>fa00000001</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>1.1754942106924411e-38</tt>
                  </td>
                  <td align="right">
                    <tt>fa007fffff</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>5.0e-324</tt>
                  </td>
                  <td align="right">
                    <tt>fb0000000000000001</tt>
                  </td>
                </tr>
                <tr>
                  <td align="right">
                    <tt>-1.7976931348623157e+308</tt>
                  </td>
                  <td align="right">
                    <tt>fbffefffffffffffff</tt>
                  </td>
                </tr>
              </tbody>
            </table>
          </section>
        </section>
      </section>
      <section anchor="d-cbor.constraints">
        <name>Implementation Constraints</name>
        <t>This section is informative.</t>
        <t>
          Note that even if an application does not support (or need)
          <tt>bignum</tt> or <tt>floating&nbsp;point</tt> data items,
          you can still use D-CBOR since a strict subset is upwardly
          compatible with full-blown implementations.
          Low-end platforms typically also restrict CBOR <tt>map</tt> keys to
          <tt>integer</tt> and <tt>text&nbsp;string</tt> data items.
          Since these issues are application specific, they are out of scope
          for this specification.
        </t>
      </section>
      <section anchor="d-cbor.reference-implementations">
        <name>Reference Implementations</name>
        <t>This section is informative.</t>
        <t>Reference implementations that conform to this specification include:</t>
        <ul spacing="normal">
          <li>
            JavaScript: <eref
      target="https://github.com/cyberphone/CBOR.js#cborjs"
      brackets="angle"/>
          </li>
          <li>
              JDK 17+: <eref
      target="https://github.com/cyberphone/openkeystore#cbor-support"
      brackets="angle"/>
          </li>
          <li>
            Android/Java: <eref
      target="https://github.com/cyberphone/android-cbor#cbor-for-android"
      brackets="angle"/>
          </li>
        </ul>
      </section>
      <section anchor="d-cbor.online-tools">
        <name>Online Tools</name>
        <t>This section is informative.</t>
        <t>The following online tools enable testing D&nbhy;CBOR
        without installing any software:</t>
        <ul spacing="normal">
          <li>
            <eref
      target="https://cyberphone.github.io/CBOR.js/doc/playground.html"
      brackets="angle"/>
          </li>
          <li>
             <eref
      target="https://test.webpki.org/csf-lab/convert"
      brackets="angle"/>
          </li>
        </ul>
      </section>
      <section anchor="d-cbor.acknowledgements" numbered="false" toc="default">
        <name>Acknowledgements</name>
        <t>
          TBD
        </t>
      </section>

      <section anchor="d-cbor.document.history" numbered="false" toc="default">
        <name>Document History</name>
        <t>
            [[ This section to be removed by the RFC Editor before publication as
            an RFC ]]
        </t>
        <t>Version 00:</t>
        <ul spacing="normal">
          <li>
            Initial publication.
          </li>
        </ul>
        <t>Version 01:</t>
        <ul spacing="normal">
          <li>
            Added Table 1: Supported CBOR Data Types
          </li>
        </ul>
        <t>Version 02:</t>
        <ul spacing="normal">
          <li>
            Added bidirectional + reencoding to 2
          </li>
        </ul>      
        <t>Version 03:</t>
        <ul spacing="normal">
          <li>
            Added ref to 3.4.4. Decimal Fractions and Bigfloats.
          </li>
          <li>
            Type => Data Item (throughout the spec).
          </li>
        </ul>
        <t>Version 04-00:</t>
        <ul spacing="normal">
          <li>
            Document name spelling error.
          </li>
        </ul>
        <t>Version 01:</t>
        <ul spacing="normal">
          <li>
            Minor tweaks.
          </li>
        </ul>
        <t>Version 02:</t>
        <ul spacing="normal">
          <li>
            ISE submission and associated changes.
          </li>
        </ul>
        <t>Version 03:</t>
        <ul spacing="normal">
          <li>
            Number table clarifications.
          </li>
        </ul>
        <t>Version 04:</t>
        <ul spacing="normal">
          <li>
            Word-smithing.
          </li>
        </ul>      
        <t>Version 05:</t>
        <ul spacing="normal">
          <li>
            ISE input resulted in Background section.
          </li>
        </ul>      
        <t>Version 06:</t>
        <ul spacing="normal">
          <li>
            Word-smithing.
          </li>
        </ul>
        <t>Version 07:</t>
        <ul spacing="normal">
          <li>
            Word-smithing.
          </li>
        </ul>
      </section>
    </back>
</rfc>
