<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE rfc [
  <!ENTITY nbsp "&#160;">
]>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     category="info" docName="draft-singh-psi-02" ipr="trust200902"
     submissionType="IETF" version="3" xml:lang="en"
     consensus="false">
  <front>
    <title abbrev="PSI">Proof of Stateful Integrity (PSI): Signed, Merkle-Committed Receipts for Digital Records</title>
    <seriesInfo name="Internet-Draft" value="draft-singh-psi-02"/>
    <author fullname="Kawaljeet Singh" initials="K." surname="Singh">
      <organization>APEX Infrastructure</organization>
      <address>
        <postal><city>Melbourne</city><region>Victoria</region><country>Australia</country></postal>
        <email>kawaljeet.singh3008@gmail.com</email>
        <uri>https://ai-governance-standard.com</uri>
      </address>
    </author>
    <date year="2026" month="October" day="13"/>
    <keyword>integrity</keyword>
    <keyword>provenance</keyword>
    <keyword>receipt</keyword>
    <keyword>transparency log</keyword>
    <abstract>
      <t>This document specifies Proof of Stateful Integrity (PSI), a
      format and procedure for issuing signed receipts over digital
      records.  A PSI receipt binds the SHA-256 digest of a canonical
      JSON record to an issuer signature, a monotonic sequence number,
      and a Merkle tree root computed with the RFC 6962 hashing profile,
      and may reference an external timestamp anchor.  Any party holding
      the record, the receipt, and the issuer public key can verify the
      receipt offline.  PSI provides evidence of integrity, origin, and
      ordering only.  It does not establish that a record is true,
      lawful, safe, or compliant with any regulation.</t>
      <t>This revision replaces revision 01.  It withdraws all claims of
      zero-knowledge proofs, multi-party computation, and inclusion
      proofs, which the reference implementation does not provide.</t>
    </abstract>
  </front>
  <middle>
    <section anchor="intro"><name>Introduction</name>
      <t>Automated systems, including software agents, produce records
      whose later integrity is disputed.  Ordinary logs can be edited by
      anyone with storage access.  PSI defines a small receipt that makes
      later modification of a record detectable and that can be checked
      without contacting the issuer.</t>
      <t>PSI is deliberately narrow.  It composes existing primitives:
      JSON Canonicalization Scheme <xref target="RFC8785"/>, SHA-256
      <xref target="FIPS180-4"/>, Ed25519 <xref target="RFC8032"/>, and
      the Merkle tree hashing of <xref target="RFC6962"/>.</t>
      <section><name>Requirements Language</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&nbsp;14 <xref target="RFC2119"/>
        <xref target="RFC8174"/> when, and only when, they appear in all
        capitals, as shown here.</t>
      </section>
      <section><name>Changes from Revision 01</name>
        <ul>
          <li>Title changed; the term "Sovereign" is removed.</li>
          <li>Zero-knowledge (Groth16/BN128) proof generation is removed.
          No such proving system is part of PSI.</li>
          <li>"Multi-party computation consensus" is removed.  Any policy
          checks an issuer runs before sealing are application logic and
          out of scope.</li>
          <li>The Merkle construction is replaced by the RFC 6962 profile,
          and inclusion proofs are no longer claimed.</li>
          <li>Claims that PSI demonstrates regulatory compliance are
          removed.</li>
        </ul>
      </section>
    </section>

    <section anchor="terms"><name>Terminology</name>
      <dl>
        <dt>Record:</dt><dd>A JSON value supplied by a submitter.</dd>
        <dt>Record digest:</dt><dd>SHA-256 over the RFC 8785 canonical
        UTF-8 encoding of the record, as lowercase hexadecimal.</dd>
        <dt>Issuer:</dt><dd>The party that signs receipts.</dd>
        <dt>Receipt:</dt><dd>A signed JSON object defined in
        <xref target="receipt"/>.</dd>
        <dt>Ledger:</dt><dd>The issuer's append-only, ordered sequence of
        record digests.</dd>
      </dl>
    </section>

    <section anchor="receipt"><name>Receipt Format</name>
      <t>A receipt is a JSON object with the following members:</t>
      <dl>
        <dt>schema:</dt><dd>The string "PSI-SEAL/1.0.0".</dd>
        <dt>receipt_id:</dt><dd>An issuer-unique identifier.</dd>
        <dt>decision_hash:</dt><dd>The record digest.</dd>
        <dt>sequence_number:</dt><dd>A non-negative integer, strictly
        increasing per issuer.</dd>
        <dt>prev_hash:</dt><dd>The decision_hash of the previous ledger
        entry, or 64 zero characters for the first entry.</dd>
        <dt>merkle_profile:</dt><dd>The string "RFC6962-SHA256".</dd>
        <dt>merkle_root:</dt><dd>Lowercase hex of the tree head computed
        per <xref target="merkle"/>.</dd>
        <dt>issued_at:</dt><dd>An RFC 3339 UTC timestamp asserted by the
        issuer.</dd>
        <dt>key_id:</dt><dd>Identifier of the issuer signing key.</dd>
        <dt>signature:</dt><dd>Ed25519 signature, lowercase hex, computed
        per <xref target="sig"/>.</dd>
        <dt>anchor:</dt><dd>OPTIONAL.  An object describing an external
        timestamp commitment (<xref target="anchor"/>).</dd>
      </dl>
      <t>Records SHOULD NOT contain personal or confidential data.
      Submitters SHOULD send only the record digest to the issuer.</t>
    </section>

    <section anchor="merkle"><name>Merkle Tree Profile</name>
      <t>Leaves are the record digests of ledger entries, in ascending
      sequence_number order; a leaf's index never changes once
      assigned.  The tree head is computed as the Merkle Tree Hash
      (MTH) of <xref target="RFC6962" section="2.1"/>, using SHA-256:</t>
      <artwork><![CDATA[
  leaf_hash(d)  = SHA-256(0x00 || d)
  node_hash(l,r)= SHA-256(0x01 || l || r)
  MTH({})       = SHA-256()
  MTH(D[n])     = node_hash(MTH(D[0:k]), MTH(D[k:n]))
                  where k is the largest power of two < n
]]></artwork>
      <t>Here d is the 32-byte binary record digest.  Odd nodes are not
      duplicated.  This revision defines tree heads only; inclusion and
      consistency proofs are left to a future revision.  Receipts issued
      before this profile was adopted carry no merkle_profile member and
      MUST NOT be verified against it.</t>
    </section>

    <section anchor="sig"><name>Signature</name>
      <t>The signature input is the RFC 8785 canonical encoding of the
      receipt object with the signature member removed.  The issuer
      signs it with Ed25519.  An issuer that cannot produce a valid
      signature MUST fail the request and MUST NOT emit a receipt with a
      substitute value.</t>
      <t>An issuer MAY additionally attach a hash-based signature
      <xref target="RFC8554"/> as defined in a separate post-quantum
      profile document.  Such signatures use one-time keys and MUST be
      allocated from a strictly increasing counter so that no key is
      ever used twice.</t>
      <t>Issuer public keys are published at
      /.well-known/apex-psi-trust-anchor.json on the issuer's origin as a
      list of key_id, algorithm, public key, and validity period.</t>
    </section>

    <section anchor="anchor"><name>External Anchoring</name>
      <t>An issuer MAY periodically commit a tree head to a public
      timestamping system such as OpenTimestamps
      <xref target="OTS"/>.  The anchor object then carries the system
      name, the committed root, and the proof data.  An anchor shows that
      the root existed no later than the anchored time; it does not show
      when a record was created.</t>
    </section>

    <section anchor="verify"><name>Verification</name>
      <t>A verifier holding a record and a receipt:</t>
      <ol>
        <li>Computes the record digest and compares it to
        decision_hash.</li>
        <li>Obtains the public key for key_id from the trust anchor
        document.</li>
        <li>Verifies the Ed25519 signature over the canonical receipt
        without its signature member.</li>
        <li>OPTIONALLY verifies the anchor proof.</li>
      </ol>
      <t>Verification returns only: digest match, signature validity,
      and anchor validity.  It never returns a judgement about the truth,
      legality, or compliance of the record.</t>
    </section>

    <section anchor="security"><name>Security Considerations</name>
      <ul>
        <li>PSI does not validate source data.  An issuer will seal a
        false record as readily as a true one.</li>
        <li>A single issuer is a central operator.  Receipts show what
        that issuer signed; they do not make it independent.  Ledger
        tampering by the issuer is detectable only by parties who retain
        earlier tree heads or anchors.</li>
        <li>issued_at is an issuer assertion.  Only an external anchor
        bounds time independently.</li>
        <li>Ed25519 is not resistant to large-scale quantum computers.
        Long-lived evidence SHOULD carry an external anchor and MAY carry
        a hash-based signature.</li>
        <li>Reuse of a one-time hash-based signing key destroys its
        security; see <xref target="sig"/>.</li>
        <li>Digests of low-entropy records can be brute-forced.  Records
        SHOULD include a random salt when confidentiality matters.</li>
      </ul>
    </section>

    <section anchor="iana"><name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
  </middle>
  <back>
    <references><name>References</name>
      <references><name>Normative References</name>
        <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/rfc2119">
          <front><title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author initials="S." surname="Bradner"/><date year="1997" month="March"/></front>
          <seriesInfo name="BCP" value="14"/><seriesInfo name="RFC" value="2119"/>
        </reference>
        <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/rfc8174">
          <front><title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author initials="B." surname="Leiba"/><date year="2017" month="May"/></front>
          <seriesInfo name="BCP" value="14"/><seriesInfo name="RFC" value="8174"/>
        </reference>
        <reference anchor="RFC8785" target="https://www.rfc-editor.org/info/rfc8785">
          <front><title>JSON Canonicalization Scheme (JCS)</title>
          <author initials="A." surname="Rundgren"/><author initials="B." surname="Jordan"/>
          <author initials="S." surname="Erdtman"/><date year="2020" month="June"/></front>
          <seriesInfo name="RFC" value="8785"/>
        </reference>
        <reference anchor="RFC8032" target="https://www.rfc-editor.org/info/rfc8032">
          <front><title>Edwards-Curve Digital Signature Algorithm (EdDSA)</title>
          <author initials="S." surname="Josefsson"/><author initials="I." surname="Liusvaara"/>
          <date year="2017" month="January"/></front>
          <seriesInfo name="RFC" value="8032"/>
        </reference>
        <reference anchor="RFC6962" target="https://www.rfc-editor.org/info/rfc6962">
          <front><title>Certificate Transparency</title>
          <author initials="B." surname="Laurie"/><author initials="A." surname="Langley"/>
          <author initials="E." surname="Kasper"/><date year="2013" month="June"/></front>
          <seriesInfo name="RFC" value="6962"/>
        </reference>
        <reference anchor="FIPS180-4" target="https://doi.org/10.6028/NIST.FIPS.180-4">
          <front><title>Secure Hash Standard (SHS)</title>
          <author><organization>NIST</organization></author><date year="2015" month="August"/></front>
          <seriesInfo name="FIPS PUB" value="180-4"/>
        </reference>
      </references>
      <references><name>Informative References</name>
        <reference anchor="RFC8554" target="https://www.rfc-editor.org/info/rfc8554">
          <front><title>Leighton-Micali Hash-Based Signatures</title>
          <author initials="D." surname="McGrew"/><author initials="M." surname="Curcio"/>
          <author initials="S." surname="Fluhrer"/><date year="2019" month="April"/></front>
          <seriesInfo name="RFC" value="8554"/>
        </reference>
        <reference anchor="OTS" target="https://opentimestamps.org">
          <front><title>OpenTimestamps</title>
          <author><organization>OpenTimestamps project</organization></author><date/></front>
        </reference>
      </references>
    </references>
  </back>
</rfc>
