<?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.39 (Ruby 3.4.9) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-bryce-cose-receipts-mmr-profile-02" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.33.0 -->
  <front>
    <title abbrev="COSE Receipts for MMRs">COSE Receipts for MMRs</title>
    <seriesInfo name="Internet-Draft" value="draft-bryce-cose-receipts-mmr-profile-02"/>
    <author fullname="Robin Bryce">
      <organization/>
      <address>
        <email>robinbryce@gmail.com</email>
      </address>
    </author>
    <date year="2026" month="June" day="14"/>
    <area>Security</area>
    <workgroup>TBD</workgroup>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <?line 32?>

<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 38?>

<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 is, logically, the unique series of perfect binary merkle trees required to commit its leaves.</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 <eref target="https://eprint.iacr.org/2015/718.pdf">ReyzinYakoubov</eref>.
The technical advantages of post-order traversal binary Merkle trees are discussed in <eref target="https://static.usenix.org/event/sec09/tech/full_papers/crosby.pdf">CrosbyWallachStorage</eref> and <eref target="https://research.swtch.com/tlog#appendix_a">PostOrderTlog</eref>.</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 index of any node, including leaf nodes, in the MMR</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) => 3
  * 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 <eref target="https://eprint.iacr.org/2015/718.pdf">ReyzinYakoubov</eref>,
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) => 3
  * 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-proof
}

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>, which is the value for the node identified by index <tt>pos - 1</tt></t>
          <t>Editors note: How this draft accommodates hash alg agility is tbd.</t>
          <t>Given:</t>
          <ul spacing="normal">
            <li>
              <t><tt>pos</tt> the size of the MMR whose last node index is <tt>pos - 1</tt></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 alg.</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="security-considerations">
      <name>Security Considerations</name>
      <t>See the security considerations section of:</t>
      <ul spacing="normal">
        <li>
          <t><xref target="RFC9053"/></t>
        </li>
      </ul>
      <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>
      <t>Editors note: Hash agility is desired.
We can start with SHA-256.
Two of the referenced implementations use BLAKE2b-256,
We would like to add support for SHA3-256, SHA3-512, and possibly Keccak and Pedersen.</t>
      <section anchor="additions-to-existing-registries">
        <name>Additions to Existing Registries</name>
        <t>Editors note: todo registry requests</t>
      </section>
      <section anchor="new-registries">
        <name>New Registries</name>
      </section>
    </section>
  </middle>
  <back>
    <references anchor="sec-normative-references">
      <name>Normative References</name>
      <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>
      <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>
    </references>
    <?line 627?>

<section anchor="references">
      <name>References</name>
      <section anchor="informative-references">
        <name>Informative References</name>
        <ul spacing="normal">
          <li>
            <t><eref target="https://eprint.iacr.org/2015/718.pdf">ReyzinYakoubov</eref></t>
          </li>
          <li>
            <t><eref target="https://static.usenix.org/event/sec09/tech/full_papers/crosby.pdf">CrosbyWallach</eref></t>
          </li>
          <li>
            <t><eref target="https://static.usenix.org/event/sec09/tech/full_papers/crosby.pdf">CrosbyWallachStorage</eref> 3.3 Storing the log on secondary storage</t>
          </li>
          <li>
            <t><eref target="https://research.swtch.com/tlog#appendix_a">PostOrderTlog</eref></t>
          </li>
          <li>
            <t><eref target="https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-May/012715.html">PeterTodd</eref></t>
          </li>
          <li>
            <t><eref target="https://www-cs-faculty.stanford.edu/~knuth/taocp.html">KnuthTBT</eref> 2.3.1 Traversing Binary Trees</t>
          </li>
          <li>
            <t><eref target="https://eprint.iacr.org/2021/038.pdf">BNT</eref></t>
          </li>
        </ul>
      </section>
    </section>
    <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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
OhJClFAAAA==

-->

</rfc>
