<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.43 (Ruby 3.4.9) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-bryce-cose-receipts-mmr-profile-03" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.34.1 -->
  <front>
    <title abbrev="COSE Receipts for MMRs">COSE Receipts for MMRs</title>
    <seriesInfo name="Internet-Draft" value="draft-bryce-cose-receipts-mmr-profile-03"/>
    <author fullname="Robin Bryce">
      <organization/>
      <address>
        <email>robinbryce@proton.me</email>
      </address>
    </author>
    <author fullname="Jon Geater">
      <organization/>
      <address>
        <email>jonathan@bowball-tech.com</email>
      </address>
    </author>
    <date year="2026" month="September" day="19"/>
    <area>Security</area>
    <workgroup>TBD</workgroup>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <?line 67?>

<t>This document defines a new verifiable data structure type for COSE Receipts <xref target="I-D.ietf-cose-merkle-tree-proofs"/> specifically for use with ledgers based on post-order traversal binary Merkle trees and which are designed for high throughput, ease of replication and compatibility with commodity cloud storage.</t>
      <t>Post-order traversal binary Merkle trees, also known as history trees, are more commonly known as Merkle Mountain Ranges.</t>
    </abstract>
  </front>
  <middle>
    <?line 73?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>The COSE Receipts document <xref target="I-D.ietf-cose-merkle-tree-proofs"/> defines a common framework for defining different types of proofs, such as proof of inclusion, about verifiable data structures (VDS). For instance, inclusion proofs guarantee to a verifier that a given serializable element is recorded at a given state of the VDS, while consistency proofs are used to establish that an inclusion proof is still consistent with the new state of the VDS at a later time.</t>
      <t>In this document, we define a new type of VDS: a post ordered binary merkle tree <xref target="KnuthTBT"/> is, logically, the unique series of perfect binary merkle trees required to commit its leaves. Such structures are also commonly known as Merkle Mountain Ranges <xref target="PeterTodd"/>.</t>
      <t>Example,</t>
      <artwork><![CDATA[
   6
 2   5
0 1 3 4 7
]]></artwork>
      <t>This illustrates <tt>MMR(8)</tt>, which is comprised of two perfect trees rooted at 6 and 7.
7 is the root of a tree comprised of a single element.</t>
      <t>The peaks of the perfect trees form the accumulator.</t>
      <t>The storage of a tree maintained in this way is addressed as a linear array, and additions to the tree are always appends.</t>
      <t>Proving and verifying are defined in terms of the cryptographic asynchronous accumulator described by <xref target="ReyzinYakoubov"/>.
The technical advantages of post-order traversal binary Merkle trees are discussed in <xref target="CrosbyWallach"/> (Section 3.3, "Storing the log on secondary storage") and <xref target="PostOrderTlog"/>.</t>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
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>
      <?line -18?>

<ul spacing="normal">
        <li>
          <t>A complete MMR(n) defines an mmr with n nodes where no equal height sibling trees exist.</t>
        </li>
        <li>
          <t><tt>i</tt> shall be the zero-based index of any node, including leaf nodes, in the MMR. Nodes are assigned indices in the order they are appended to the linear array.</t>
        </li>
        <li>
          <t><tt>pos</tt> shall be the one-based position of a node, <tt>pos = i + 1</tt>. The position is included in the hash of each interior node (see hash_pospair64), binding the node's value to its location in the tree, guaranteeing uniqueness in the tree without imposing constraints on inputs.</t>
        </li>
        <li>
          <t>g shall be the zero-based height of a node in the tree.</t>
        </li>
        <li>
          <t><tt>H(x)</tt> shall be the SHA-256 digest of any value x</t>
        </li>
        <li>
          <t><tt>||</tt> shall mean concatenation of raw byte representations of the referenced values.</t>
        </li>
      </ul>
      <t>In this specification, all numbers are unsigned 64 bit integers.
The maximum height of a single tree is 64 (which will have <tt>g=63</tt> for its peak).</t>
    </section>
    <section anchor="description-of-the-verifiable-data-structure">
      <name>Description of the Verifiable Data Structure</name>
      <t>This documents extends the verifiable data structure registry of <xref target="I-D.ietf-cose-merkle-tree-proofs"/> with the following value:</t>
      <table align="left" anchor="verifiable-data-structure-values">
        <name>Verifiable Data Structure Algorithms</name>
        <thead>
          <tr>
            <th align="left">Name</th>
            <th align="left">Value</th>
            <th align="left">Description</th>
            <th align="left">Reference</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td align="left">MMR_SHA256</td>
            <td align="left">TBD_1 (requested assignment 3)</td>
            <td align="left">Linearly addressed, position committing, MMR implementations, such as the MMR ledger</td>
            <td align="left">This document</td>
          </tr>
        </tbody>
      </table>
    </section>
    <section anchor="inclusion-proofs">
      <name>Inclusion Proofs</name>
      <t>The CBOR representation of an inclusion proof is</t>
      <sourcecode type="cddl"><![CDATA[
inclusion-proof = bstr .cbor [

  ; zero-based index of a tree node
  index: uint

  ; path proving the node's inclusion
  inclusion-path: [ + bstr ]
]
]]></sourcecode>
      <t>Note that the inclusion path for the index leads to a single permanent node in the tree.
This node will initially be a peak in the accumulator, as the tree grows it will eventually be "buried" by a new peak.</t>
      <section anchor="inclusionproofpath">
        <name>inclusion_proof_path</name>
        <t><tt>inclusion_proof_path(i, c)</tt> is used to produce the verification paths for inclusion proofs and consistency proofs.</t>
        <t>Given:</t>
        <ul spacing="normal">
          <li>
            <t><tt>c</tt> the index of the last node in any tree which contains <tt>i</tt>.</t>
          </li>
          <li>
            <t><tt>i</tt> the index of the mmr node whose verification path is required.</t>
          </li>
        </ul>
        <t>And the methods:</t>
        <ul spacing="normal">
          <li>
            <t><xref target="indexheight">index_height</xref> which obtains the zero-based height <tt>g</tt> of any node.</t>
          </li>
        </ul>
        <t>And the constraints:</t>
        <ul spacing="normal">
          <li>
            <t><tt>i &lt;= c</tt></t>
          </li>
        </ul>
        <t>We define <tt>inclusion_proof_path</tt> as</t>
        <sourcecode type="python"><![CDATA[
  def inclusion_proof_path(i, c):

    path = []

    g = index_height(i)

    while True:

      # The sibling of i is at i +/- 2^(g+1)
      siblingoffset = (2 << g)

      # If the index after i is higher, it is the left parent,
      # and i is the right sibling
      if index_height(i+1) > g:

        # The witness to the right sibling is offset behind i
        isibling = i - siblingoffset + 1

        # The parent of a right sibling is stored immediately
        # after
        i += 1
      else:

        # The witness to a left sibling is offset ahead of i
        isibling = i + siblingoffset - 1

        # The parent of a left sibling is stored immediately after
        # its right sibling
        i += siblingoffset

      # When the computed sibling exceeds the range of MMR(C+1),
      # we have completed the path
      if isibling > c:
          return path

      path.append(isibling)

      # Set g to the height of the next item in the path.
      g += 1
]]></sourcecode>
      </section>
    </section>
    <section anchor="cose-receipt-of-inclusion">
      <name>COSE Receipt of Inclusion</name>
      <t>The cbor representation of an inclusion proof is:</t>
      <sourcecode type="cddl"><![CDATA[
protected-header-map = {
  &(alg: 1) => int
  &(vds: 395) => TBD_1
  * cose-label => cose-value
}
]]></sourcecode>
      <ul spacing="normal">
        <li>
          <t>alg (label: 1): <bcp14>REQUIRED</bcp14>. Signature algorithm identifier. Value type: int.</t>
        </li>
        <li>
          <t>vds (label: 395): <bcp14>REQUIRED</bcp14>. verifiable data structure algorithm identifier. Value type: int.</t>
        </li>
      </ul>
      <t>The unprotected header for an inclusion proof signature is:</t>
      <sourcecode type="cddl"><![CDATA[
inclusion-proofs = [ + inclusion-proof ]

verifiable-proofs = {
  &(inclusion-proof: -1) => inclusion-proofs
}

unprotected-header-map = {
  &(vdp: 396) => verifiable-proofs
  * cose-label => cose-value
}
]]></sourcecode>
      <t>The payload of an inclusion proof signature is the tree peak committing to the nodes inclusion, or the node itself where the proof path is empty.
The algorithm <xref target="includedroot">included_root</xref> obtains this value.</t>
      <t>The payload <bcp14>MUST</bcp14> be detached.
Detaching the payload forces verifiers to recompute the root from the inclusion proof,
this protects against implementation errors where the signature is verified but the payload merkle root does not match the inclusion proof.</t>
      <section anchor="verifying-the-receipt-of-inclusion">
        <name>Verifying the Receipt of inclusion</name>
        <t>The inclusion proof and signature are verified in order.
First the verifiers applies the inclusion proof to a possible entry (set member) bytes.
The result is the merkle root implied by the inclusion proof path for the candidate value.
The COSE Sign1 payload <bcp14>MUST</bcp14> be set to this value.
Second the verifier checks the signature of the COSE Sign1.
If the resulting signature verifies, the Receipt has proved inclusion of the entry in the verifiable data structure.
If the resulting signature does not verify, the signature may have been tampered with.</t>
        <t>It is recommended that implementations return a single boolean result for Receipt verification operations, to reduce the chance of accepting a valid signature over an invalid inclusion proof.</t>
        <t>As the proof must be processed prior to signature verification the implementation <bcp14>SHOULD</bcp14> check the lengths of the proof paths are appropriate for the provided tree sizes.</t>
      </section>
      <section anchor="includedroot">
        <name>included_root</name>
        <t>The algorithm <tt>included_root</tt> calculates the accumulator peak for the provided proof and node value.</t>
        <t>Given:</t>
        <ul spacing="normal">
          <li>
            <t><tt>i</tt> is the index the <tt>nodeHash</tt> is to be shown at</t>
          </li>
          <li>
            <t><tt>nodehash</tt> the value whose inclusion is to be shown</t>
          </li>
          <li>
            <t><tt>proof</tt> is the path of sibling values committing i.</t>
          </li>
        </ul>
        <t>And the methods:</t>
        <ul spacing="normal">
          <li>
            <t><xref target="indexheight">index_height</xref> which obtains the zero-based height <tt>g</tt> of any node.</t>
          </li>
          <li>
            <t><xref target="hashpospair64">hash_pospair64</xref> which applies <tt>H</tt> to the new node position and its children.</t>
          </li>
        </ul>
        <t>We define <tt>included_root</tt> as</t>
        <sourcecode type="python"><![CDATA[
  def included_root(i, nodehash, proof):

    root = nodehash

    g = index_height(i)

    for sibling in proof:

      # If the index after i is higher, it is the left parent,
      # and i is the right sibling

      if index_height(i + 1) > g:

        # The parent of a right sibling is stored immediately after

        i = i + 1

        # Set `root` to `H(i+1 || sibling || root)`
        root = hash_pospair64(i + 1, sibling, root)
      else:

        # The parent of a left sibling is stored immediately after
        # its right sibling.

        i = i + (2 << g)

        # Set `root` to `H(i+1 || root || sibling)`
        root = hash_pospair64(i + 1, root, sibling)

      # Set g to the height of the next item in the path.
      g = g + 1

    # If the path length was zero, the original nodehash is returned
    return root
]]></sourcecode>
      </section>
    </section>
    <section anchor="consistency-proof">
      <name>Consistency Proof</name>
      <t>A consistency proof shows that the accumulator, defined in <xref target="ReyzinYakoubov"/>,
for tree-size-1 is a prefix of the accumulator for tree-size-2.</t>
      <t>The signature is over the complete accumulator for tree-size-2 obtained using the proof and the, supplied, possibly empty, list of <tt>right-peaks</tt> which complete the accumulator for tree-size-2.</t>
      <t>The receipt of consistency is defined so that a chain of cumulative consistency proofs can be verified together.</t>
      <t>The cbor representation of a consistency proof is:</t>
      <sourcecode type="cddl"><![CDATA[
consistency-path = [ * bstr ]

consistency-proof =  bstr .cbor [

  ; previous tree size
  tree-size-1: uint

  ; latest tree size
  tree-size-2: uint

  ; the inclusion path from each accumulator peak in
  ; tree-size-1 to its new peak in tree-size-2.
  consistency-paths: [ + consistency-path ]

  ; the additional peaks that
  ; complete the accumulator for tree-size-2,
  ; when appended to those produced by the consistency paths
  right-peaks: [ *bstr ]
]
]]></sourcecode>
      <section anchor="consistencyproofpath">
        <name>consistency_proof_path</name>
        <t>Produces the verification paths for inclusion of the peaks of tree-size-1 under the peaks of tree-size-2.</t>
        <t>right-peaks are obtained by invoking <tt>peaks(tree-size-2 - 1)</tt>, and discarding length(proofs) from the left.</t>
        <t>Given:</t>
        <ul spacing="normal">
          <li>
            <t><tt>ifrom</tt> is the last index of tree-size-1</t>
          </li>
          <li>
            <t><tt>ito</tt> is the last index of tree-size-2</t>
          </li>
        </ul>
        <t>And the methods:</t>
        <ul spacing="normal">
          <li>
            <t><xref target="inclusionproofpath">inclusion_proof_path</xref></t>
          </li>
          <li>
            <t><xref target="peaks"/></t>
          </li>
        </ul>
        <t>And the constraints:</t>
        <ul spacing="normal">
          <li>
            <t><tt>ifrom &lt;= ito</tt></t>
          </li>
        </ul>
        <t>We define <tt>consistency_proof_paths</tt> as</t>
        <sourcecode type="python"><![CDATA[
  def consistency_proof_paths(ifrom, ito):

    proof = []

    for i in peaks(ifrom):
      proof.append(inclusion_proof_path(i, ito))

    return proof
]]></sourcecode>
      </section>
    </section>
    <section anchor="cose-receipt-of-consistency">
      <name>COSE Receipt of Consistency</name>
      <t>The cbor representation of an inclusion proof is:</t>
      <sourcecode type="cddl"><![CDATA[
protected-header-map = {
  &(alg: 1) => int
  &(vds: 395) => TBD_1
  * cose-label => cose-value
}
]]></sourcecode>
      <ul spacing="normal">
        <li>
          <t>alg (label: 1): <bcp14>REQUIRED</bcp14>. Signature algorithm identifier. Value type: int.</t>
        </li>
        <li>
          <t>vds (label: 395): <bcp14>REQUIRED</bcp14>. verifiable data structure algorithm identifier. Value type: int.</t>
        </li>
      </ul>
      <t>The unprotected header for an inclusion proof signature is:</t>
      <sourcecode type="cddl"><![CDATA[
consistency-proofs = [ + consistency-proof ]

verifiable-proofs = {
  &(consistency-proof: -2) => consistency-proofs
}

unprotected-header-map = {
  &(vdp: 396) => verifiable-proofs
  * cose-label => cose-value
}
]]></sourcecode>
      <t>The payload <bcp14>MUST</bcp14> be detached.
Detaching the payload forces verifiers to recompute the roots from the consistency proofs.
This protects against implementation errors where the signature is verified but the payload is not genuinely produced by the included proof.</t>
      <section anchor="verifying-the-receipt-of-consistency">
        <name>Verifying the Receipt of consistency</name>
        <t>Verification accommodates verifying the result of a cumulative series of consistency proofs.</t>
        <t>Perform the following for each consistency-proof in the list, verifying the signature with the output of the last.</t>
        <ol spacing="normal" type="1"><li>
            <t>Initialize current proof as the first consistency-proof.</t>
          </li>
          <li>
            <t>Initialize accumulatorfrom to the peaks of tree-size-1 in the current proof.</t>
          </li>
          <li>
            <t>Initialize ifrom to tree-size-1 - 1 from the current proof.</t>
          </li>
          <li>
            <t>Initialize proofs to the consistency-paths from the current proof.</t>
          </li>
          <li>
            <t>Apply the algorithm <xref target="consistentroots">consistent_roots</xref></t>
          </li>
          <li>
            <t>Apply the peaks algorithm to obtain the accumulator for tree-size-2</t>
          </li>
          <li>
            <t>From the peaks for tres-size-2, discard from the left the number of roots returned by consistent_roots.</t>
          </li>
          <li>
            <t>Create the consistent accumulator by appending the remaining peaks to the consistent roots.</t>
          </li>
          <li>
            <t>If there are no remaining proofs, use the consistent accumulator as the detached payload and verify the signature of the COSE Sign1.</t>
          </li>
        </ol>
        <t>It is recommended that implementations return a single boolean result for Receipt verification operations, to reduce the chance of accepting a valid signature over an invalid consistency proof.</t>
        <t>As the proof must be processed prior to signature verification the implementation <bcp14>SHOULD</bcp14> check the lengths of the proof paths are appropriate for the provided tree sizes.</t>
        <section anchor="consistentroots">
          <name>consistent_roots</name>
          <t><tt>consistent_roots</tt> returns the descending height ordered list of elements from the accumulator for the consistent future state.</t>
          <t>Implementations <bcp14>MUST</bcp14> require that the number of peaks returned by <xref target="peaks"/><tt>(ifrom)</tt> equals the number of entries in <tt>accumulatorfrom</tt>.</t>
          <t>Given:</t>
          <ul spacing="normal">
            <li>
              <t><tt>ifrom</tt> the last index in the complete MMR from which consistency was proven.</t>
            </li>
            <li>
              <t><tt>accumulatorfrom</tt> the node values corresponding to the peaks of the accumulator for tree-size-1</t>
            </li>
            <li>
              <t><tt>proofs</tt> the inclusion proofs for each node in <tt>accumulatorfrom</tt> for tree-size-2</t>
            </li>
          </ul>
          <t>And the methods:</t>
          <ul spacing="normal">
            <li>
              <t><xref target="includedroot">included_root</xref></t>
            </li>
            <li>
              <t><xref target="peaks"/></t>
            </li>
          </ul>
          <t>We define <tt>consistent_roots</tt> as</t>
          <sourcecode type="python"><![CDATA[
  def consistent_roots(ifrom, accumulatorfrom, proofs):

    frompeaks = peaks(ifrom)

    # if length(frompeaks) != length(proofs) -> ERROR

    roots = []
    for i in range(len(accumulatorfrom)):
      root = included_root(
          frompeaks[i], accumulatorfrom[i], proofs[i])

      if roots and roots[-1] == root:
          continue
      roots.append(root)

    return roots
]]></sourcecode>
        </section>
      </section>
    </section>
    <section anchor="appending-a-leaf">
      <name>Appending a leaf</name>
      <t>An algorithm for appending to a tree maintained in post order layout is provided.</t>
      <section anchor="addleafhash">
        <name>add_leaf_hash</name>
        <t>When a new node is appended, if its height matches the height of its immediate predecessor, then the two equal height siblings <bcp14>MUST</bcp14> be merged.
Merging is defined as the append of a new node which takes the adjacent peaks as its left and right children.
This process <bcp14>MUST</bcp14> proceed until there are no more completable sub trees.</t>
        <t><tt>add_leaf_hash(f)</tt> adds the leaf hash value f to the tree.</t>
        <t>Given:</t>
        <ul spacing="normal">
          <li>
            <t><tt>f</tt> the leaf value resulting from <tt>H(x)</tt> for the caller defined leaf value <tt>x</tt></t>
          </li>
          <li>
            <t><tt>db</tt> an interface supporting <tt>append(entry) -&gt; index</tt> and <tt>get(index) -&gt; entry</tt> methods.</t>
          </li>
        </ul>
        <t>And the methods:</t>
        <ul spacing="normal">
          <li>
            <t><xref target="indexheight">index_height</xref></t>
          </li>
          <li>
            <t><xref target="hashpospair64"/></t>
          </li>
        </ul>
        <t>We define <tt>add_leaf_hash</tt> as</t>
        <sourcecode type="python"><![CDATA[
  def add_leaf_hash(db, f: bytes):

    # Set g to 0, the height of the leaf item f
    g = 0

    # Set i to the result of invoking Append(f)
    i = db.append(f)

    # If index_height(i) is greater than g (#looptarget)
    while index_height(i) > g:

      # Set ileft to the index of the left child of i,
      # which is i - 2^(g+1)

      ileft = i - (2 << g)

      # Set iright to the index of the the right child of i,
      # which is i - 1

      iright = i - 1

      # Set v to H(i + 1 || Get(ileft) || Get(iright))
      # Set i to the result of invoking Append(v)

      i = db.append(
        hash_pospair64(i+1, db.get(ileft), db.get(iright)))

      # Set g to the height of the new i, which is g + 1
      g += 1

    return i
]]></sourcecode>
      </section>
      <section anchor="node-values">
        <name>Node values</name>
        <t>Interior nodes in the tree <bcp14>MUST</bcp14> prefix the value provided to <tt>H(x)</tt> with <tt>pos</tt>.</t>
        <t>The value <tt>v</tt> for any interior node <bcp14>MUST</bcp14> be <tt>H(pos || Get(LEFT_CHILD) || Get(RIGHT_CHILD))</tt></t>
        <t>The algorithm for leaf addition is provided the result of <tt>H(x)</tt> directly.</t>
        <section anchor="hashpospair64">
          <name>hash_pospair64</name>
          <t>Returns <tt>H(pos || a || b)</tt></t>
          <t>Given:</t>
          <ul spacing="normal">
            <li>
              <t><tt>pos</tt> the one-based position of the node being computed</t>
            </li>
            <li>
              <t><tt>a</tt> the first value to include in the hash after <tt>pos</tt></t>
            </li>
            <li>
              <t><tt>b</tt> the second value to include in the hash after <tt>pos</tt></t>
            </li>
          </ul>
          <t>And the constraints:</t>
          <ul spacing="normal">
            <li>
              <t><tt>pos &lt; 2^64</tt></t>
            </li>
            <li>
              <t><tt>a</tt> and <tt>b</tt> <bcp14>MUST</bcp14> be hashes produced by the appropriate hash algorithm.</t>
            </li>
          </ul>
          <t>We define <tt>hash_pospair64</tt> as</t>
          <sourcecode type="python"><![CDATA[
  def hash_pospair64(pos, a, b):

    # Note: Hash algorithm agility is tbd, this example uses SHA-256
    h = hashlib.sha256()

    # Take the big endian representation of pos
    h.update(pos.to_bytes(8, byteorder="big", signed=False))
    h.update(a)
    h.update(b)
    return h.digest()
]]></sourcecode>
        </section>
      </section>
    </section>
    <section anchor="essential-supporting-algorithms">
      <name>Essential supporting algorithms</name>
      <section anchor="indexheight">
        <name>index_height</name>
        <t><tt>index_height(i)</tt> returns the zero-based height <tt>g</tt> of the node index <tt>i</tt></t>
        <t>Given:</t>
        <ul spacing="normal">
          <li>
            <t><tt>i</tt> the index of any mmr node.</t>
          </li>
        </ul>
        <t>We define <tt>index_height</tt> as</t>
        <sourcecode type="python"><![CDATA[
  def index_height(i) -> int:
    pos = i + 1
    while not all_ones(pos):
      pos = pos - most_sig_bit(pos) + 1

    return bit_length(pos) - 1
]]></sourcecode>
      </section>
      <section anchor="peaks">
        <name>peaks</name>
        <t><tt>peaks(i)</tt> returns the peak indices for <tt>MMR(i+1)</tt>, which is also its accumulator.</t>
        <t>Assumes MMR(i+1) is complete, implementations can check for this condition by
testing the height of i+1</t>
        <t>Given:</t>
        <ul spacing="normal">
          <li>
            <t><tt>i</tt> the index of any mmr node.</t>
          </li>
        </ul>
        <t>We define <tt>peaks</tt></t>
        <sourcecode type="python"><![CDATA[
  def peaks(i):
    peak = 0
    peaks = []
    s = i+1
    while s != 0:
      # find the highest peak size in the current MMR(s)
      highest_size = (1 << log2floor(s+1)) - 1
      peak = peak + highest_size
      peaks.append(peak-1)
      s -= highest_size

    return peaks
]]></sourcecode>
      </section>
    </section>
    <section anchor="privacy-considerations">
      <name>Privacy Considerations</name>
      <t>See the privacy considerations section of <xref target="I-D.ietf-cose-merkle-tree-proofs"/>.</t>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>The security considerations of <xref target="I-D.ietf-cose-merkle-tree-proofs"/> apply. See also the security considerations section of <xref target="RFC9053"/>.</t>
      <section anchor="detection-of-improper-inclusion">
        <name>Detection of improper inclusion</name>
        <t>A receipt of inclusion shows only that the element is included in the ledger.
Defining whether that inclusion was legitimate, or in some way valid,  is out of scope for this document.</t>
      </section>
      <section anchor="misbehaving-ledgers">
        <name>Misbehaving Ledgers</name>
        <t>A ledger can misbehave in several ways. Examples include the following: failing to incorporate a leaf entry in the MMR; presenting different, conflicting views of the MMR at different times and/or to different parties.</t>
        <t>Detection of a failure to include items in the first place is out of scope for
this document.</t>
        <t>Having included an element, ledger implementations using this draft <bcp14>MUST</bcp14> use consistency proofs as the basis for proving entries are not moved, modified or excluded in future states of the MMR.
Similarly, consistency proofs <bcp14>MUST</bcp14> be the basis for proving the unequivocal history of additions.</t>
      </section>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <section anchor="additions-to-existing-registries">
        <name>Additions to Existing Registries</name>
        <section anchor="cose-verifiable-data-structure-algorithms">
          <name>COSE Verifiable Data Structure Algorithms</name>
          <t>IANA is requested to add the following value to the "COSE Verifiable Data Structure Algorithms" registry established by <xref target="I-D.ietf-cose-merkle-tree-proofs"/>:</t>
          <ul spacing="normal">
            <li>
              <t>Name: MMR_SHA256</t>
            </li>
            <li>
              <t>Value: TBD_1 (requested assignment 3)</t>
            </li>
            <li>
              <t>Description: Linearly addressed, position-committing, append-only logs that are integrity-protected by a post-order traversal (Merkle Mountain Range) binary Merkle tree using SHA-256.</t>
            </li>
            <li>
              <t>Reference: RFCthis</t>
            </li>
          </ul>
          <t>Editors note: Hash agility. This document defines a single SHA-256-based identifier, MMR_SHA256, following the convention of binding the hash function into the algorithm identifier. Additional identifiers (for example using BLAKE2b-256, SHA3-256, or SHA3-512, both of which are used by existing implementations) are expected to be registered as separate values in a future revision, rather than negotiated within a single identifier.</t>
        </section>
      </section>
      <section anchor="new-registries">
        <name>New Registries</name>
        <t>This document requests no new registries.</t>
      </section>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
        <reference anchor="RFC9053">
          <front>
            <title>CBOR Object Signing and Encryption (COSE): Initial Algorithms</title>
            <author fullname="J. Schaad" initials="J." surname="Schaad"/>
            <date month="August" year="2022"/>
            <abstract>
              <t>Concise Binary Object Representation (CBOR) is a data format designed for small code size and small message size. There is a need to be able to define basic security services for this data format. This document defines a set of algorithms that can be used with the CBOR Object Signing and Encryption (COSE) protocol (RFC 9052).</t>
              <t>This document, along with RFC 9052, obsoletes RFC 8152.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9053"/>
          <seriesInfo name="DOI" value="10.17487/RFC9053"/>
        </reference>
        <reference anchor="I-D.ietf-cose-merkle-tree-proofs">
          <front>
            <title>COSE (CBOR Object Signing and Encryption) Receipts</title>
            <author fullname="Orie Steele" initials="O." surname="Steele">
              <organization>Tradeverifyd</organization>
            </author>
            <author fullname="Henk Birkholz" initials="H." surname="Birkholz">
              <organization>Fraunhofer SIT</organization>
            </author>
            <author fullname="Antoine Delignat-Lavaud" initials="A." surname="Delignat-Lavaud">
              <organization>Microsoft</organization>
            </author>
            <author fullname="Cedric Fournet" initials="C." surname="Fournet">
              <organization>Microsoft</organization>
            </author>
            <date day="2" month="December" year="2025"/>
            <abstract>
              <t>   COSE (CBOR Object Signing and Encryption) Receipts prove properties
   of a verifiable data structure to a verifier.  Verifiable data
   structures and associated proof types enable security properties,
   such as minimal disclosure, transparency and non-equivocation.
   Transparency helps maintain trust over time, and has been applied to
   certificates, end to end encrypted messaging systems, and supply
   chain security.  This specification enables concise transparency
   oriented systems, by building on CBOR (Concise Binary Object
   Representation) and COSE.  The extensibility of the approach is
   demonstrated by providing CBOR encodings for Merkle inclusion and
   consistency proofs.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-cose-merkle-tree-proofs-18"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="ReyzinYakoubov" target="https://eprint.iacr.org/2015/718.pdf">
          <front>
            <title>Efficient Asynchronous Accumulators for Distributed PKI</title>
            <author initials="L." surname="Reyzin" fullname="Leonid Reyzin">
              <organization/>
            </author>
            <author initials="S." surname="Yakoubov" fullname="Sophia Yakoubov">
              <organization/>
            </author>
            <date year="2015"/>
          </front>
        </reference>
        <reference anchor="CrosbyWallach" target="https://static.usenix.org/event/sec09/tech/full_papers/crosby.pdf">
          <front>
            <title>Efficient Data Structures for Tamper-Evident Logging</title>
            <author initials="S. A." surname="Crosby" fullname="Scott A. Crosby">
              <organization/>
            </author>
            <author initials="D. S." surname="Wallach" fullname="Dan S. Wallach">
              <organization/>
            </author>
            <date year="2009"/>
          </front>
        </reference>
        <reference anchor="PostOrderTlog" target="https://research.swtch.com/tlog#appendix_a">
          <front>
            <title>Transparent Logs for Skeptical Clients (Appendix A: Storing the Log)</title>
            <author initials="R." surname="Cox" fullname="Russ Cox">
              <organization/>
            </author>
            <date year="2019"/>
          </front>
        </reference>
        <reference anchor="PeterTodd" target="https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-May/012715.html">
          <front>
            <title>Merkle Mountain Ranges (bitcoin-dev mailing list)</title>
            <author initials="P." surname="Todd" fullname="Peter Todd">
              <organization/>
            </author>
            <date year="2016"/>
          </front>
        </reference>
        <reference anchor="KnuthTBT" target="https://www-cs-faculty.stanford.edu/~knuth/taocp.html">
          <front>
            <title>The Art of Computer Programming, Volume 1: Fundamental Algorithms, Section 2.3.1 Traversing Binary Trees</title>
            <author initials="D. E." surname="Knuth" fullname="Donald E. Knuth">
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
      </references>
    </references>
    <?line 669?>

<section anchor="assumed-bit-primitives">
      <name>Assumed bit primitives</name>
      <section anchor="log2floor">
        <name>log2floor</name>
        <t>Returns the floor of log base 2 x</t>
        <sourcecode type="python"><![CDATA[
  def log2floor(x):
    return x.bit_length() - 1
]]></sourcecode>
      </section>
      <section anchor="mostsigbit">
        <name>most_sig_bit</name>
        <t>Returns the mask for the the most significant bit in pos</t>
        <sourcecode type="python"><![CDATA[
  def most_sig_bit(pos) -> int:
    return 1 << (pos.bit_length() - 1)
]]></sourcecode>
        <t>The following primitives are assumed for working with bits as they commonly have library or hardware support.</t>
      </section>
      <section anchor="bitlength">
        <name>bit_length</name>
        <t>The minimum number of bits to represent pos. b011 would be 2, b010 would be 2, and b001 would be 1.</t>
        <sourcecode type="python"><![CDATA[
  def bit_length(pos):
    return pos.bit_length()
]]></sourcecode>
      </section>
      <section anchor="allones">
        <name>all_ones</name>
        <t>Tests if all bits, from the most significant that is set, are 1, b0111 would be true, b0101 would be false.</t>
        <sourcecode type="python"><![CDATA[
  def all_ones(pos) -> bool:
    msb = most_sig_bit(pos)
    mask = (1 << (msb + 1)) - 1
    return pos == mask
]]></sourcecode>
      </section>
      <section anchor="onescount">
        <name>ones_count</name>
        <t>Count of set bits.
For example <tt>ones_count(b101)</tt> is 2</t>
      </section>
      <section anchor="trailingzeros">
        <name>trailing_zeros</name>
        <sourcecode type="python"><![CDATA[
  (v & -v).bit_length() - 1
]]></sourcecode>
      </section>
    </section>
    <section anchor="acknowledgments">
      <name>Acknowledgments</name>
    </section>
  </back>
  <!-- ##markdown-source:
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
nLDayOxojxi29zn6L+jF7qNFVwAA

-->

</rfc>
