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

<t>This document defines a new verifiable data structure profile for the COSE Receipts document <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 39?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>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.
Implementation defined methods for interacting with storage are specified.</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 the <xref target="append"/> and <xref target="get"/> implementation defined storage 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="implementation-defined-storage-methods">
        <name>Implementation defined storage methods</name>
        <t>The following methods are assumed to be available to the implementation.
Very minimal requirements are specified.</t>
        <t>Informally, the storage must be array like and have no gaps.</t>
        <section anchor="get">
          <name>Get</name>
          <t>Reads the value from the tree at the supplied index.</t>
          <t>The read <bcp14>MUST</bcp14> be consistent with any other calls to Append or Get within the same algorithm invocation.</t>
          <t>Get <bcp14>MAY</bcp14> fail for transient reasons.</t>
        </section>
        <section anchor="append">
          <name>Append</name>
          <t>Appends new node to storage and returns the index that will be occupied by the node provided to the next call to append.</t>
          <t>The implementation <bcp14>MUST</bcp14> guarantee that the results of Append are immediately available to Get calls in the same invocation of the algorithm.</t>
          <t>Append <bcp14>MUST</bcp14> return the node <tt>i</tt> identifying the node location which comes next.</t>
          <t>The implementation <bcp14>MAY</bcp14> defer commitment to underlying persistent storage.</t>
          <t>Append <bcp14>MAY</bcp14> fail for transient reasons.</t>
        </section>
      </section>
      <section anchor="node-values">
        <name>Node values</name>
        <t>Interior nodes in the <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 Receipts</title>
          <author fullname="Orie Steele" initials="O." surname="Steele">
            <organization>Transmute</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="11" month="May" 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 RFC9162.

            </t>
          </abstract>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-ietf-cose-merkle-tree-proofs-14"/>
      </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 654?>

<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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
kRFVoKPo44jNBrL1PRLY3ufovwGrxln8qVIAAA==

-->

</rfc>
