<?xml version="1.0" encoding="UTF-8"?>

<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     category="exp"
     docName="draft-bellis-unheaded-pqc-authentication-00"
     ipr="trust200902"
     submissionType="independent"
     xml:lang="en"
     tocInclude="true"
     symRefs="true"
     sortRefs="true"
     version="3">

  <front>
    <title abbrev="Unheaded PQC Authentication">Post-Quantum Packet Authentication for the Unheaded Protocol</title>

    <seriesInfo name="Internet-Draft" value="draft-bellis-unheaded-pqc-authentication-00"/>
    <author fullname="Stevie Bellis" initials="S." surname="Bellis">
      <organization>Unheaded</organization>
      <address>
        <email>stevie@bellis.tech</email>
      </address>
    </author>

    <date year="2026" month="March" day="19"/>

    <area>Applications</area>
    <workgroup>Unheaded Kingdom</workgroup>

    <abstract>
      <t>This document specifies a post-quantum cryptographic (PQC)
      authentication mechanism for the Unheaded Protocol Foundation.
      It defines a multi-algorithm, dual-layer, tiered authentication
      architecture integrating three NIST PQC digital signature
      standards -- FIPS 205 (SLH-DSA), FIPS 204 (ML-DSA), and FIPS
      206 (FN-DSA) -- plus two NIST PQC key-encapsulation mechanisms
      -- FIPS 203 (ML-KEM) and FIPS 207 (HQC) -- with the Monad wire
      format, Sophia BPF map dictionaries, and Wotan per-flow memory
      model.</t>

      <t>Layer 1 (Wire-Level, REQUIRED): Full PQC signatures are
      stored in Sophia BPF maps via a "signature-by-reference" scheme.
      The Monad register carries compact 12-byte references (SigRef,
      KeyRef, SeqNum, HashPfx).  Shield verifies signatures at the
      network perimeter and strips Monad Hop-by-Hop headers at
      ingress -- internal kingdom traffic never carries PQC wire
      overhead.</t>

      <t>Layer 2 (Application-Level, OPTIONAL): User applications MAY
      define verification requirements in Sophia application policy
      dictionaries.  After wire-level authentication succeeds, the
      application reads Wotan per-flow PQC state and matches it
      against its own policy.</t>

      <t>Four PQC compliance tiers -- NONE, STANDARD, ENHANCED, and
      SOVEREIGN -- are signaled via Kingdom Mode bits in the Monad
      flags byte.</t>
    </abstract>

    <note removeInRFC="false">
      <name>Status of This Memo</name>
      <t>This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.</t>
      <t>Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.</t>
      <t>Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them except as reference to a "work in progress."</t>
      <t>This Internet-Draft will expire on September 19, 2026.</t>
    </note>

    <note removeInRFC="false">
      <name>Copyright Notice</name>
      <t>Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.</t>
      <t>This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info/) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.</t>
    </note>

  </front>

  <middle>

    <section anchor="introduction" numbered="true" toc="include">
      <name>Introduction</name>
      <t>The Unheaded Protocol Foundation <xref target="MONAD"/> defines a 20-byte register
      carried in an IPv6 Hop-by-Hop extension header <xref target="RFC8200"/>.  This register
      provides per-packet metadata for service mesh operations including
      tracing, QoS classification, circuit breaking, and deployment ring
      isolation.</t>

      <t>As quantum computing advances threaten existing cryptographic
      assumptions, infrastructure systems MUST prepare for post-quantum
      cryptographic migration.  NIST has finalized five PQC standards:
      three digital signature algorithms -- FIPS 205 (SLH-DSA) <xref target="FIPS205"/>,
      FIPS 204 (ML-DSA) <xref target="FIPS204"/>, and FIPS 206 (FN-DSA) <xref target="FIPS206"/> -- and
      two key-encapsulation mechanisms -- FIPS 203 (ML-KEM) <xref target="FIPS203"/> and
      FIPS 207 (HQC) <xref target="FIPS207"/>.</t>

      <t>PQC signature sizes range from 666 bytes (FN-DSA-512) to 49,856
      bytes (SLH-DSA-SHAKE-256f), all far exceeding the Monad register's
      12-byte value field.  This document defines a "signature-by-reference"
      scheme that stores full PQC signatures and public keys in Sophia BPF
      maps while carrying compact references in the Monad register.  Sophia
      <xref target="SOPHIA"/> dictionaries provide the BPF map structures for
      signature and key storage.  The scheme is algorithm-agnostic -- the
      same 12-byte wire layout supports all three signature standards.</t>

      <t>This approach provides:</t>

      <ol type="(%c)" spacing="normal">
        <li>Post-quantum packet authentication at the wire level (Layer 1).</li>
        <li>Zero increase in per-packet wire overhead (Monad remains 20 bytes).</li>
        <li>Amortized verification cost across flow lifetime (first-packet
        verification, subsequent packets use cached result).</li>
        <li>Configurable verification policy per trust boundary.</li>
        <li>Optional application-level policy verification (Layer 2) via
        Sophia dictionaries, enabling enterprises to define custom
        authentication requirements without modifying the wire protocol.</li>
        <li>Clean perimeter isolation -- Shield strips Monad HbH headers at
        ingress, so internal kingdom traffic carries zero PQC wire
        overhead.  Wire-level PQC is exclusively a perimeter concern.</li>
        <li>Algorithm agility -- the algo_id field and signature-by-reference
        design support all five NIST PQC standards with zero wire format
        changes.  New algorithms require only a registry entry and a
        verifier implementation.</li>
        <li>Tiered compliance -- four PQC compliance tiers (NONE, STANDARD,
        ENHANCED, SOVEREIGN) enable graduated deployment from development
        environments (zero overhead) to government-grade multi-algorithm
        cross-verification.</li>
      </ol>
    </section>

    <section anchor="requirements-language" numbered="true" toc="include">
      <name>Requirements Language</name>
      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
      NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED",
      "MAY", and "OPTIONAL" in this document are to be interpreted as
      described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
      appear in all capitals, as shown here.</t>
    </section>

    <section anchor="terminology" numbered="true" toc="include">
      <name>Terminology</name>

      <dl>
        <dt>SLH-DSA:</dt>
        <dd>Stateless Hash-Based Digital Signature Algorithm, as
        defined in FIPS 205 <xref target="FIPS205"/>.  Formerly known as SPHINCS+.
        Hash-based construction.  eBPF-native (integer-only operations).</dd>

        <dt>ML-DSA:</dt>
        <dd>Module-Lattice-Based Digital Signature Algorithm, as
        defined in FIPS 204 <xref target="FIPS204"/>.  Formerly known as CRYSTALS-Dilithium.
        Lattice-based construction.  eBPF-native (integer NTT modular arithmetic).</dd>

        <dt>FN-DSA:</dt>
        <dd>FFT over NTRU-Lattice-Based Digital Signature Algorithm,
        as defined in FIPS 206 <xref target="FIPS206"/>.  Formerly known as FALCON.
        Lattice-based construction.  NOT eBPF-native: signing requires
        IEEE-754 binary64 floating-point arithmetic (FFT, LDL tree
        decomposition, discrete Gaussian sampling).  Verification is
        integer-only and MAY be performed in eBPF.</dd>

        <dt>ML-KEM:</dt>
        <dd>Module-Lattice-Based Key-Encapsulation Mechanism, as
        defined in FIPS 203 <xref target="FIPS203"/>.  Formerly known as CRYSTALS-Kyber.
        Used for key establishment, not per-packet authentication.</dd>

        <dt>HQC:</dt>
        <dd>Hamming Quasi-Cyclic Key-Encapsulation Mechanism, as defined
        in FIPS 207 <xref target="FIPS207"/>.  Code-based KEM providing non-lattice
        diversity for key establishment.</dd>

        <dt>Compliance Tier:</dt>
        <dd>One of four PQC enforcement levels (NONE, STANDARD, ENHANCED,
        SOVEREIGN) signaled via Kingdom Mode bits K1|K0 in the Monad flags
        byte.  Tiers govern Shield verification behavior, algorithm selection,
        and Layer 2 enforcement policy.</dd>

        <dt>Signature-by-Reference:</dt>
        <dd>A scheme where a compact reference (index) is carried in
        the packet header, pointing to a full cryptographic signature
        stored in a kernel-resident data structure (Sophia BPF map).</dd>

        <dt>SigRef:</dt>
        <dd>A 24-bit unsigned integer indexing into the Sophia PQC
        Signature Map.</dd>

        <dt>KeyRef:</dt>
        <dd>A 24-bit unsigned integer indexing into the Sophia PQC
        Public Key Map.</dd>

        <dt>SeqNum:</dt>
        <dd>A 32-bit per-flow sequence number providing replay
        resistance.  Monotonically increasing within a flow lifetime.</dd>

        <dt>HashPfx:</dt>
        <dd>A 16-bit integrity tag derived from SHA-256 of the
        full SLH-DSA signature, truncated to 2 bytes.</dd>

        <dt>Pseudo-Header:</dt>
        <dd>The set of immutable packet fields over which
        the SLH-DSA signature is computed (<xref target="pseudo-header"/>).</dd>

        <dt>Verification Policy:</dt>
        <dd>A per-trust-boundary configuration determining whether
        packets are forwarded before (OPTIMISTIC) or after (PESSIMISTIC)
        signature verification completes (<xref target="verification-policies"/>).</dd>

        <dt>Layer 1 (Wire-Level Authentication):</dt>
        <dd>Infrastructure-grade PQC verification performed by Shield/XDP
        at the network perimeter.  Operates on Monad HbH headers.
        REQUIRED for all PQC-enabled flows.  Transparent to applications.</dd>

        <dt>Layer 2 (Application-Level Policy):</dt>
        <dd>Optional verification where user applications read Wotan
        per-flow PQC state and match it against requirements defined in
        Sophia application policy dictionaries (<xref target="application-level-policy"/>).
        Operates AFTER Layer 1 succeeds and Monad headers have been stripped.</dd>

        <dt>Application Policy Dictionary:</dt>
        <dd>A Sophia dictionary defining per-application PQC requirements:
        minimum security level, allowed algorithm set, key pinning requirements,
        maximum key age.  Consumed by Layer 2 verification.</dd>

        <dt>Header Stripping:</dt>
        <dd>The removal of Monad Hop-by-Hop extension headers at Shield
        ingress.  Internal kingdom traffic operates without PQC wire
        overhead; Wotan per-flow state preserves the authentication result
        for application consumption.</dd>
      </dl>
    </section>

    <section anchor="protocol-overview" numbered="true" toc="include">
      <name>Protocol Overview</name>
      <t>The PQC authentication scheme operates in four phases:</t>

      <t>Phase 1 - Key and Signature Provisioning:</t>
      <t>The control plane generates SLH-DSA key pairs and pre-computes
      signatures over expected pseudo-headers.  Full signatures and
      public keys are loaded into Sophia BPF maps.  SigRef and KeyRef
      indices are assigned.</t>

      <t>Phase 2 - Packet Marking:</t>
      <t>When a packet enters the Unheaded network at Shield ingress,
      the Monad register's value field is populated with the SigRef,
      KeyRef, SeqNum, and HashPfx corresponding to the flow's
      authentication context.  The S (Signed) flag in byte 0x01 is
      set to 1.</t>

      <t>Phase 3 - Wire-Level Verification (Layer 1):</t>
      <t>At the Shield ingress from an untrusted network, the eBPF
      program at XDP reads the SigRef and KeyRef from the Monad
      register, retrieves the full signature and public key from
      Sophia maps, and either:</t>
      <ol type="(%c)" spacing="normal">
        <li>Checks a cached verification result (fast path), or</li>
        <li>Submits the signature to the userspace verifier via ring
        buffer for asynchronous SLH-DSA verification (slow path,
        first packet of flow only).</li>
      </ol>

      <t>Upon successful verification, Shield strips the Monad HbH
      extension header.  The verification result is persisted in
      Wotan per-flow PQC state (<xref target="wotan-integration"/>).  Internal kingdom
      traffic proceeds without PQC wire overhead.</t>

      <t>Phase 4 - Application-Level Policy (Layer 2, OPTIONAL):</t>
      <t>After Shield ingress strips Monad headers and forwards the
      packet into the kingdom, user applications MAY perform a
      second verification pass.  The application reads the flow's
      PQC state from Wotan memory (algo_id, key_epoch, verified
      status, key fingerprint) and matches it against requirements
      defined in a Sophia application policy dictionary.</t>

      <t>If the flow's PQC state does not satisfy the application's
      policy (e.g., algorithm too weak, key too old, fingerprint
      not pinned), the application MAY reject the flow at the
      application layer.  This provides defense-in-depth and
      enables per-application security posture without modifying
      the wire protocol.</t>
    </section>

    <section anchor="monad-value-layout" numbered="true" toc="include">
      <name>Monad Value Layout for PQC Authentication</name>
      <t>When the S (Signed) flag is set in the Monad flags byte, the
      12-byte value region of the Monad register (bytes specific to
      the flow action and QoS fields as defined in <xref target="MONAD"/>) SHALL be
      interpreted as follows:</t>

      <artwork type="ascii-art"><![CDATA[
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    SigRef (24 bits)           | KeyRef[23:16] |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         KeyRef[15:0] (16 bits)                |HashPfx(16 bits)|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       SeqNum (32 bits)                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      ]]></artwork>

      <t>Field definitions:</t>

      <dl>
        <dt>SigRef (3 octets, unsigned, big-endian):</dt>
        <dd>Index into the Sophia PQC Signature Map.  Range: 0 to 16,777,215.
        Value 0 is reserved (indicates "no signature").  Implementations MUST
        reject packets where S flag is set but SigRef is 0.</dd>

        <dt>KeyRef (3 octets, unsigned, big-endian):</dt>
        <dd>Index into the Sophia PQC Public Key Map.  Range: 0 to 16,777,215.
        Value 0 is reserved.  Implementations MUST reject packets where S flag
        is set but KeyRef is 0.</dd>

        <dt>HashPfx (2 octets, unsigned, big-endian):</dt>
        <dd>First two bytes of SHA-256(signature_blob).  Provides a fast
        integrity check binding the SigRef to a specific signature.  Collision
        probability: 1/65,536 per SigRef pair (see Security Considerations).</dd>

        <dt>SeqNum (4 octets, unsigned, big-endian):</dt>
        <dd>Per-flow sequence number.  MUST be monotonically increasing within
        a flow lifetime.  Provides replay resistance (see <xref target="pseudo-header"/>).
        The signed pseudo-header includes SeqNum; therefore replayed packets
        with stale sequence numbers will fail verification.</dd>
      </dl>

      <t>Note: When PQC compliance tiers are active (K1|K0 != 00), the
      S flag (bit 3 of the flags byte) is repurposed from its SAMPLED
      semantics defined in <xref target="MONAD"/> to indicate Signed
      status.  This dual-use is signaled by the Kingdom Mode bits;
      implementations MUST check the K1|K0 field before interpreting
      the S flag.  The Monad Flags Registry update for this extended
      semantics is specified in <xref target="monad-flags-update"/>.</t>
    </section>

    <section anchor="sophia-pqc-maps" numbered="true" toc="include">
      <name>Sophia PQC Map Structures</name>

      <section anchor="pqc-signature-map" numbered="true" toc="include">
        <name>PQC Signature Map</name>
        <t>A new Sophia BPF hash map SHALL be created for PQC signature
        storage:</t>

        <artwork type="ascii-art"><![CDATA[
   Map name:      sophia_pqc_sigs
   Key type:      uint32 (SigRef, zero-extended from 24 bits)
   Value type:    struct sophia_pqc_sig_entry
   Max entries:   Configurable (RECOMMENDED: 1,048,576)
   Flags:         BPF_F_RDONLY_PROG (data plane read-only)
   Pinning:       /sys/fs/bpf/sophia/pqc_sigs
        ]]></artwork>

        <t>The value structure:</t>

        <sourcecode type="c"><![CDATA[
   struct sophia_pqc_sig_entry {
       uint8_t  algo_id;           /* SLH-DSA parameter set ID    */
       uint8_t  verified;          /* 0=pending, 1=valid, 2=invalid */
       uint16_t sig_len;           /* Signature length in bytes    */
       uint32_t flow_label;        /* Owning flow label            */
       uint64_t verify_timestamp;  /* Nanosecond timestamp of verification */
       uint8_t  signature[];       /* Variable-length SLH-DSA signature */
   };
        ]]></sourcecode>

        <t>The algo_id field SHALL use values from the PQC Algorithm
        Registry (<xref target="iana-considerations"/>):</t>

        <t>SLH-DSA Parameter Sets (FIPS 205 -- hash-based, eBPF-native):</t>

        <table>
          <thead>
            <tr><th>Value</th><th>Parameter Set</th><th>Sig Size</th><th>Security</th><th>eBPF?</th></tr>
          </thead>
          <tbody>
            <tr><td>0x00</td><td>Reserved</td><td>N/A</td><td>N/A</td><td>N/A</td></tr>
            <tr><td>0x01</td><td>SLH-DSA-SHA2-128s</td><td>7,856 B</td><td>Level 1</td><td>YES</td></tr>
            <tr><td>0x02</td><td>SLH-DSA-SHA2-128f</td><td>17,088 B</td><td>Level 1</td><td>YES</td></tr>
            <tr><td>0x03</td><td>SLH-DSA-SHA2-192s</td><td>16,224 B</td><td>Level 3</td><td>YES</td></tr>
            <tr><td>0x04</td><td>SLH-DSA-SHA2-192f</td><td>35,664 B</td><td>Level 3</td><td>YES</td></tr>
            <tr><td>0x05</td><td>SLH-DSA-SHA2-256s</td><td>29,792 B</td><td>Level 5</td><td>YES</td></tr>
            <tr><td>0x06</td><td>SLH-DSA-SHA2-256f</td><td>49,856 B</td><td>Level 5</td><td>YES</td></tr>
            <tr><td>0x07</td><td>SLH-DSA-SHAKE-128s</td><td>7,856 B</td><td>Level 1</td><td>YES</td></tr>
            <tr><td>0x08</td><td>SLH-DSA-SHAKE-128f</td><td>17,088 B</td><td>Level 1</td><td>YES</td></tr>
            <tr><td>0x09</td><td>SLH-DSA-SHAKE-192s</td><td>16,224 B</td><td>Level 3</td><td>YES</td></tr>
            <tr><td>0x0A</td><td>SLH-DSA-SHAKE-192f</td><td>35,664 B</td><td>Level 3</td><td>YES</td></tr>
            <tr><td>0x0B</td><td>SLH-DSA-SHAKE-256s</td><td>29,792 B</td><td>Level 5</td><td>YES</td></tr>
            <tr><td>0x0C</td><td>SLH-DSA-SHAKE-256f</td><td>49,856 B</td><td>Level 5</td><td>YES</td></tr>
          </tbody>
        </table>

        <t>ML-DSA Parameter Sets (FIPS 204 -- lattice-based, eBPF-native):</t>

        <table>
          <thead>
            <tr><th>Value</th><th>Parameter Set</th><th>Sig Size</th><th>Security</th><th>eBPF?</th></tr>
          </thead>
          <tbody>
            <tr><td>0x10</td><td>ML-DSA-44</td><td>2,420 B</td><td>Level 2</td><td>YES</td></tr>
            <tr><td>0x11</td><td>ML-DSA-65</td><td>3,309 B</td><td>Level 3</td><td>YES</td></tr>
            <tr><td>0x12</td><td>ML-DSA-87</td><td>4,627 B</td><td>Level 5</td><td>YES</td></tr>
          </tbody>
        </table>

        <t>FN-DSA Parameter Sets (FIPS 206 -- lattice-based, userspace verify):</t>

        <table>
          <thead>
            <tr><th>Value</th><th>Parameter Set</th><th>Sig Size</th><th>Security</th><th>eBPF?</th></tr>
          </thead>
          <tbody>
            <tr><td>0x20</td><td>FN-DSA-512</td><td>666 B</td><td>Level 1</td><td>NO*</td></tr>
            <tr><td>0x21</td><td>FN-DSA-1024</td><td>1,280 B</td><td>Level 5</td><td>NO*</td></tr>
          </tbody>
        </table>

        <t>*FN-DSA verification uses integer NTT and MAY be implemented in
        eBPF.  However, FN-DSA signing requires IEEE-754 binary64
        floating-point (FFT, LDL tree, Gaussian sampling) and MUST NOT
        execute in eBPF.  See <xref target="multi-algorithm-considerations"/>
        (Multi-Algorithm Considerations).</t>

        <t>KEM Algorithm Identifiers (key establishment only, not per-packet):</t>

        <table>
          <thead>
            <tr><th>Value</th><th>Algorithm</th><th>CT Size</th><th>Security</th><th>Use</th></tr>
          </thead>
          <tbody>
            <tr><td>0x80</td><td>ML-KEM-512</td><td>768 B</td><td>Level 1</td><td>Tunnel key</td></tr>
            <tr><td>0x81</td><td>ML-KEM-768</td><td>1,088 B</td><td>Level 3</td><td>Tunnel key</td></tr>
            <tr><td>0x82</td><td>ML-KEM-1024</td><td>1,568 B</td><td>Level 5</td><td>Tunnel key</td></tr>
            <tr><td>0x90</td><td>HQC-128</td><td>4,497 B</td><td>Level 1</td><td>Tunnel key</td></tr>
            <tr><td>0x91</td><td>HQC-192</td><td>9,042 B</td><td>Level 3</td><td>Tunnel key</td></tr>
          </tbody>
        </table>

        <t>Reserved Ranges:</t>

        <table>
          <thead>
            <tr><th>Value</th><th>Description</th></tr>
          </thead>
          <tbody>
            <tr><td>0x0D-0x0F</td><td>Reserved (SLH-DSA future)</td></tr>
            <tr><td>0x13-0x1F</td><td>Reserved (ML-DSA future)</td></tr>
            <tr><td>0x22-0x7F</td><td>Reserved (signature algos)</td></tr>
            <tr><td>0x83-0x8F</td><td>Reserved (ML-KEM future)</td></tr>
            <tr><td>0x92-0xFE</td><td>Unassigned</td></tr>
            <tr><td>0xFF</td><td>Reserved</td></tr>
          </tbody>
        </table>

        <t>The sophia_pqc_sigs map MUST be created with the BPF_F_RDONLY_PROG
        flag.  Data plane eBPF programs (XDP, TC) MUST NOT have write
        access.  Only the control plane (userspace) SHALL write to this
        map.</t>
      </section>

      <section anchor="pqc-public-key-map" numbered="true" toc="include">
        <name>PQC Public Key Map</name>
        <t>A new Sophia BPF hash map SHALL be created for PQC public key
        storage:</t>

        <artwork type="ascii-art"><![CDATA[
   Map name:      sophia_pqc_keys
   Key type:      uint32 (KeyRef, zero-extended from 24 bits)
   Value type:    struct sophia_pqc_key_entry
   Max entries:   Configurable (RECOMMENDED: 65,536)
   Flags:         BPF_F_RDONLY_PROG
   Pinning:       /sys/fs/bpf/sophia/pqc_keys
        ]]></artwork>

        <t>The value structure:</t>

        <sourcecode type="c"><![CDATA[
   struct sophia_pqc_key_entry {
       uint8_t  algo_id;           /* Must match sig entry algo_id */
       uint8_t  key_epoch;         /* Key rotation epoch counter   */
       uint16_t key_len;           /* Public key length in bytes   */
       uint8_t  fingerprint[32];   /* SHA-256 of full public key   */
       uint8_t  public_key[];      /* Variable-length SLH-DSA pubkey */
   };
        ]]></sourcecode>
      </section>
    </section>

    <section anchor="pseudo-header" numbered="true" toc="include">
      <name>Signed Pseudo-Header</name>
      <t>The SLH-DSA signature MUST be computed over a pseudo-header
      constructed from immutable packet fields.  The pseudo-header
      ensures that the signature binds to a specific flow, destination,
      and sequence position.</t>

      <t>The pseudo-header is constructed as follows (52 bytes):</t>

      <artwork type="ascii-art"><![CDATA[
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                   Source IPv6 Address                          +
|                           (128 bits)                          |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                Destination IPv6 Address                       +
|                           (128 bits)                          |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    IPv6 Flow Label (20 bits) |    Reserved     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Source Port           |       Destination Port         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Sequence Number                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      ]]></artwork>

      <t>Fields:</t>

      <dl>
        <dt>Source IPv6 Address (16 octets):</dt>
        <dd>Copied from the IPv6 header.  MUST NOT change in transit.</dd>

        <dt>Destination IPv6 Address (16 octets):</dt>
        <dd>Copied from the IPv6 header.  MUST NOT change in transit.</dd>

        <dt>IPv6 Flow Label (20 bits):</dt>
        <dd>Copied from the IPv6 header.  The remaining 12 bits of this
        4-byte field MUST be set to zero.</dd>

        <dt>Source Port (2 octets):</dt>
        <dd>Transport layer source port.  Set to zero if the transport
        protocol does not use ports.</dd>

        <dt>Destination Port (2 octets):</dt>
        <dd>Transport layer destination port.  Set to zero if the transport
        protocol does not use ports.</dd>

        <dt>Sequence Number (4 octets):</dt>
        <dd>Copied from the SeqNum field of the Monad PQC value layout
        (<xref target="monad-value-layout"/>).  This field provides replay resistance.</dd>
      </dl>

      <t>Implementations MUST construct the pseudo-header identically at
      both the signing and verification endpoints.  Any difference in
      construction will cause verification to fail.</t>

      <t>Note: The pseudo-header intentionally excludes mutable fields
      such as hop_count, the Monad flags byte, and the CRC-16 checksum.
      Including mutable fields would invalidate the signature at each
      hop.</t>
    </section>

    <section anchor="verification-pipeline" numbered="true" toc="include">
      <name>Verification Pipeline</name>

      <section anchor="fast-path" numbered="true" toc="include">
        <name>Fast Path (Cached Verification)</name>
        <t>When a packet arrives at an XDP verification point and the S flag
        is set:</t>

        <ol spacing="normal">
          <li>Parse SigRef from the Monad value field.</li>
          <li>Look up SigRef in sophia_pqc_sigs map.</li>
          <li><t>If entry exists and verified == 1 (valid):</t>
            <ol type="(%c)" spacing="normal">
              <li>Compare entry.flow_label with packet flow label.  If
              mismatch, proceed to slow path (possible SigRef reuse
              attack).</li>
              <li>Read HashPfx from Monad register.  Compare with stored
              SHA-256(signature)[0:2].  If mismatch, DROP and emit
              Anamnesis ERROR event.</li>
              <li>Check SeqNum &gt; last_seen_seq for this flow in Wotan
              memory.  If not, DROP (replay detected) and emit
              Anamnesis ERROR event.</li>
              <li>Update last_seen_seq in Wotan memory.</li>
              <li>Forward packet (XDP_PASS).</li>
            </ol>
          </li>
          <li><t>If entry exists and verified == 2 (invalid):</t>
            <ol type="(%c)" spacing="normal">
              <li>DROP packet (XDP_DROP).  Emit Anamnesis ERROR event.</li>
            </ol>
          </li>
          <li><t>If entry does not exist or verified == 0 (pending):</t>
            <ol type="(%c)" spacing="normal">
              <li>Proceed to slow path (<xref target="slow-path"/>).</li>
            </ol>
          </li>
        </ol>
      </section>

      <section anchor="slow-path" numbered="true" toc="include">
        <name>Slow Path (Asynchronous Verification)</name>
        <t>When cached verification is not available:</t>

        <ol spacing="normal">
          <li>Write packet metadata to the Anamnesis ring buffer:
          flow key, SigRef, KeyRef, SeqNum, timestamp.</li>
          <li>Apply verification policy (<xref target="verification-policies"/>) to determine
          whether to forward or hold the packet.</li>
          <li><t>The userspace PQC verifier daemon reads from the ring
          buffer and performs:</t>
            <ol type="(%c)" spacing="normal">
              <li>Retrieve full signature from sophia_pqc_sigs[SigRef].</li>
              <li>Retrieve full public key from sophia_pqc_keys[KeyRef].</li>
              <li>Construct pseudo-header from packet metadata.</li>
              <li>Execute SLH-DSA.Verify(public_key, pseudo_header,
              signature).</li>
              <li>Update sophia_pqc_sigs[SigRef].verified to 1 (valid)
              or 2 (invalid) via control plane map update.</li>
            </ol>
          </li>
          <li><t>If verification fails, the control plane MUST:</t>
            <ol type="(%c)" spacing="normal">
              <li>Set verified = 2 in the signature map entry.</li>
              <li>Emit an Anamnesis ERROR event with event details.</li>
              <li>Optionally tear down the flow via Wotan state update.</li>
            </ol>
          </li>
        </ol>
      </section>

      <section anchor="verifier-daemon-health" numbered="true" toc="include">
        <name>Verifier Daemon Health</name>
        <t>The PQC verifier daemon MUST implement a health check
        mechanism.  If the daemon becomes unresponsive:</t>

        <ol spacing="normal">
          <li>The control plane MUST detect failure within 10 seconds
          (RECOMMENDED: 5-second health check interval with 2
          missed checks triggering failure).</li>
          <li>All flows with verified == 0 (pending) entries that are
          older than the configured timeout (default: 10 seconds)
          MUST be treated as verification failures.</li>
          <li>The daemon MUST be automatically restarted.</li>
          <li>An Anamnesis event of type ERROR MUST be emitted.</li>
        </ol>
      </section>
    </section>

    <section anchor="verification-policies" numbered="true" toc="include">
      <name>Verification Policies</name>
      <t>The verification policy determines packet handling during the
      asynchronous verification window (typically 1-5 milliseconds
      for first packet of a new flow).</t>

      <section anchor="pessimistic-policy" numbered="true" toc="include">
        <name>PESSIMISTIC Policy</name>
        <t>Packets are held until verification completes.</t>
        <ul spacing="normal">
          <li>First packet of flow: buffered in BPF ring buffer.</li>
          <li>Released only after verified == 1.</li>
          <li>If verification fails or times out: DROP.</li>
          <li>Added latency: 1-5ms on flow establishment.</li>
          <li>RECOMMENDED for: ingress from untrusted networks.</li>
        </ul>
      </section>

      <section anchor="optimistic-policy" numbered="true" toc="include">
        <name>OPTIMISTIC Policy</name>
        <t>Packets are forwarded immediately; verification occurs
        asynchronously.</t>
        <ul spacing="normal">
          <li>First packet of flow: forwarded with UNVERIFIED status.</li>
          <li>If verification subsequently fails: tear down flow, DROP
          all subsequent packets.</li>
          <li>Risk window: 1-5ms of potentially unauthenticated traffic.</li>
          <li>RECOMMENDED for: internal east-west traffic where mTLS
          provides additional authentication.</li>
        </ul>
      </section>

      <section anchor="policy-selection" numbered="true" toc="include">
        <name>Policy Selection</name>
        <t>The verification policy MUST be configurable per trust
        boundary.  Policy is configured out-of-band via the control
        plane (see <xref target="compliance-tiers"/>).  The compliance tier
        determines the default policy: SOVEREIGN defaults to PESSIMISTIC;
        STANDARD and ENHANCED default to OPTIMISTIC.</t>

        <t>Implementations MUST default to PESSIMISTIC when no explicit
        policy is configured.</t>
      </section>
    </section>

    <section anchor="compliance-tiers" numbered="true" toc="include">
      <name>Compliance Tiers</name>
      <t>Four PQC compliance tiers govern Shield processing behavior.
      Tiers are signaled via the Kingdom Mode bits (K1|K0) in the
      Monad flags byte:</t>

      <table>
        <thead>
          <tr><th>K1</th><th>K0</th><th>Tier</th><th>Algorithms</th><th>Layer 2</th><th>Multi-Algo</th></tr>
        </thead>
        <tbody>
          <tr><td>0</td><td>0</td><td>NONE</td><td>--</td><td>--</td><td>--</td></tr>
          <tr><td>0</td><td>1</td><td>STANDARD</td><td>SLH-DSA only</td><td>OFF</td><td>NO</td></tr>
          <tr><td>1</td><td>0</td><td>ENHANCED</td><td>SLH-DSA+ML-DSA+FN-DSA</td><td>OPT</td><td>NO</td></tr>
          <tr><td>1</td><td>1</td><td>SOVEREIGN</td><td>All three, 2-of-3</td><td>MANDATORY</td><td>YES</td></tr>
        </tbody>
      </table>

      <section anchor="tier-none" numbered="true" toc="include">
        <name>Tier NONE (K1=0, K0=0)</name>
        <t>Shield performs no PQC processing.  Monad S flag is ignored.
        No Sophia PQC maps are loaded.  No Wotan PQC state is allocated.
        Wire overhead: zero.</t>

        <t>Use: development, staging, internal microservices behind a trusted
        perimeter where PQC is not required.</t>
      </section>

      <section anchor="tier-standard" numbered="true" toc="include">
        <name>Tier STANDARD (K1=0, K0=1)</name>
        <t>Shield verifies Layer 1 using SLH-DSA only.  The primary signature
        standard (FIPS 205) provides the most conservative security
        posture: hash-based construction with no lattice assumptions,
        fully eBPF-native verification.</t>

        <t>Sophia maps loaded: sophia_pqc_sigs, sophia_pqc_keys.
        Wotan state: basic PQC fields (0x0000FF00-0x0000FF0F).
        Layer 2: disabled.  Default policy: OPTIMISTIC.</t>

        <t>RECOMMENDED for: standard SaaS deployments requiring baseline
        post-quantum compliance.</t>
      </section>

      <section anchor="tier-enhanced" numbered="true" toc="include">
        <name>Tier ENHANCED (K1=1, K0=0)</name>
        <t>Shield verifies Layer 1 using any of the three signature algorithms
        (SLH-DSA, ML-DSA, FN-DSA).  Applications MAY enable Layer 2
        Sophia policy dictionaries for per-application verification
        requirements.</t>

        <t>Sophia maps loaded: all PQC maps including sophia_pqc_app_policy.
        Wotan state: full PQC fields (0x0000FF00-0x0000FF27).
        Layer 2: optional (applications opt in via policy dictionary).
        Default policy: OPTIMISTIC.</t>

        <t>RECOMMENDED for: enterprise deployments requiring algorithm
        flexibility and application-level security policy (SOC2, HIPAA,
        FedRAMP).</t>
      </section>

      <section anchor="tier-sovereign" numbered="true" toc="include">
        <name>Tier SOVEREIGN (K1=1, K0=1)</name>
        <t>Shield verifies Layer 1 using ALL THREE signature algorithms in
        a 2-of-3 multi-algorithm cross-verification scheme.  Layer 2 is
        MANDATORY -- every application MUST have a Sophia policy dictionary.
        Pinned key enforcement is REQUIRED.</t>

        <t>For each incoming packet, Shield:</t>

        <ol spacing="normal">
          <li>Verifies the primary signature (algo indicated by algo_id).</li>
          <li>Retrieves a secondary signature (different algorithm family)
          from the Sophia map using an extended SigRef (<xref target="sovereign-multi-sig"/>).</li>
          <li>If any 2 of 3 algorithms confirm the signature, verification
          succeeds.  If fewer than 2 verify, DROP.</li>
        </ol>

        <t>Sophia maps loaded: all PQC maps, plus sophia_pqc_sovereign_sigs
        for secondary/tertiary signature entries.
        Wotan state: full PQC fields plus sovereign audit fields.
        Layer 2: mandatory.  Default policy: PESSIMISTIC.
        Anamnesis: every verification result emits an audit event.</t>

        <t>RECOMMENDED for: government, defense, classified environments
        requiring FIPS 140-3 Level 4 compliance and crypto-agility
        against single-algorithm compromise.</t>
      </section>

      <section anchor="tier-transitions" numbered="true" toc="include">
        <name>Tier Transitions</name>
        <t>Tier changes are effected via the control plane API:</t>

        <ol spacing="normal">
          <li>Control plane updates the Kingdom Mode bits in the Monad
          configuration.</li>
          <li>Shield hot-reloads Sophia maps appropriate for the new tier.</li>
          <li>Wotan PQC state addresses are allocated or deallocated as
          required.</li>
          <li>Transition is effective on the next packet -- zero downtime.</li>
        </ol>

        <t>Tier downgrades (e.g., SOVEREIGN to STANDARD) MUST emit an
        Anamnesis WARNING event.  Tier upgrades are silent.</t>
      </section>
    </section>

    <section anchor="key-lifecycle" numbered="true" toc="include">
      <name>Key Lifecycle Management</name>

      <section anchor="key-generation" numbered="true" toc="include">
        <name>Key Generation</name>
        <t>SLH-DSA key pairs MUST be generated using a CSPRNG conforming
        to NIST SP 800-90A <xref target="SP80090A"/>.  For deployments requiring
        FIPS 140-3 validation, key generation SHOULD be performed
        within a validated Hardware Security Module (HSM).</t>
      </section>

      <section anchor="key-rotation" numbered="true" toc="include">
        <name>Key Rotation</name>
        <t>Key rotation is signaled via the key_epoch field in the Sophia
        PQC Public Key Map entry.  When a key is rotated:</t>

        <ol spacing="normal">
          <li>New key pair is generated and loaded into sophia_pqc_keys
          under a new KeyRef with incremented key_epoch.</li>
          <li>New signatures are computed for active flows and loaded
          into sophia_pqc_sigs under new SigRef values.</li>
          <li>A grace period (RECOMMENDED: 60 seconds) allows in-flight
          packets signed with the old key to complete verification.</li>
          <li>After the grace period, old key and signature entries MAY
          be evicted from Sophia maps.</li>
        </ol>
      </section>

      <section anchor="key-revocation" numbered="true" toc="include">
        <name>Key Revocation</name>
        <t>Immediate key revocation is supported via the key_revoke flow
        action (action ID 0x12).  When a key_revoke action is
        triggered:</t>

        <ol spacing="normal">
          <li>All signature map entries referencing the revoked KeyRef
          MUST have their verified field set to 2 (invalid).</li>
          <li>All subsequent packets referencing the revoked KeyRef
          MUST be dropped.</li>
          <li>An Anamnesis event MUST be emitted.</li>
        </ol>
      </section>
    </section>

    <section anchor="wotan-integration" numbered="true" toc="include">
      <name>Wotan Integration</name>
      <t>The Wotan per-flow memory model <xref target="WOTAN"/> provides storage for
      PQC authentication state:</t>

      <section anchor="per-flow-pqc-state" numbered="true" toc="include">
        <name>Per-Flow PQC State</name>
        <t>Within each flow's 64KB Wotan address space, the following
        addresses are reserved for PQC state:</t>

        <artwork type="ascii-art"><![CDATA[
   Address     Size    Field
   0x0000FF00  4       last_seen_seq (last verified sequence number)
   0x0000FF04  1       pqc_verified (0=no, 1=yes, 2=failed)
   0x0000FF05  1       pqc_algo_id (SLH-DSA parameter set)
   0x0000FF06  1       pqc_key_epoch (current key epoch)
   0x0000FF07  1       reserved
   0x0000FF08  4       pqc_verify_count (number of verifications)
   0x0000FF0C  4       pqc_fail_count (number of failures)
   0x0000FF10  8       pqc_key_fp (truncated SHA-256 of public key)
   0x0000FF18  8       pqc_verify_ts (verification timestamp, nanos)
   0x0000FF20  4       pqc_key_created (key creation epoch seconds)
   0x0000FF24  4       pqc_app_policy_id (Layer 2 policy ref, 0=none)
        ]]></artwork>

        <t>The addresses 0x0000FF10-0x0000FF27 support Layer 2 application
        policy verification (<xref target="application-level-policy"/>).  pqc_key_fp and pqc_verify_ts
        are written by Shield at ingress after successful Layer 1
        verification.  pqc_app_policy_id is written by the application
        to record which policy was applied (audit trail).</t>

        <t>These fields persist after Monad header stripping, providing
        the authoritative PQC state for internal kingdom operations.</t>
      </section>

      <section anchor="seqnum-management" numbered="true" toc="include">
        <name>Sequence Number Management</name>
        <t>The SeqNum field provides replay resistance.  Wotan stores
        the last verified sequence number per flow at address
        0x0000FF00.</t>

        <t>For each packet with S flag set:</t>

        <ol spacing="normal">
          <li>Read last_seen_seq via bpf_wotan_read(flow_label,
          0x0000FF00, &amp;last_seq, 4).</li>
          <li>If packet.SeqNum &lt;= last_seen_seq: DROP (replay).</li>
          <li>If packet.SeqNum &gt; last_seen_seq: update via
          bpf_wotan_cas(flow_label, 0x0000FF00, last_seen_seq,
          packet.SeqNum).</li>
          <li>If CAS fails (concurrent update): re-read and retry
          (maximum 3 attempts before DROP).</li>
        </ol>
      </section>
    </section>

    <section anchor="shield-processing" numbered="true" toc="include">
      <name>Shield Processing Rules (Header Stripping)</name>
      <t>Shield operates as the perimeter gateway between untrusted
      external networks and the internal kingdom.  PQC wire-level
      authentication is EXCLUSIVELY a perimeter concern.  Monad
      Hop-by-Hop extension headers are stripped at ingress and
      re-stamped at egress.  Internal kingdom traffic carries
      zero PQC wire overhead.</t>

      <section anchor="shield-ingress" numbered="true" toc="include">
        <name>Ingress (Untrusted to Kingdom)</name>
        <t>When Shield receives a packet from an untrusted source with
        the S flag set:</t>

        <ol spacing="normal">
          <li>Validate Monad CRC-16 per <xref target="MONAD"/>.</li>
          <li>Extract SigRef, KeyRef, SeqNum, HashPfx from value field.</li>
          <li>Execute verification pipeline (<xref target="verification-pipeline"/>).</li>
          <li><t>If verification succeeds or policy is OPTIMISTIC:</t>
            <ol type="(%c)" spacing="normal">
              <li>Persist verification result to Wotan per-flow PQC
              state (<xref target="wotan-integration"/>): pqc_verified, pqc_algo_id,
              pqc_key_epoch, last_seen_seq.</li>
              <li>Pin the key fingerprint from sophia_pqc_keys[KeyRef]
              into Wotan address 0x0000FF10 (8 bytes, truncated
              SHA-256).</li>
              <li>Strip the Monad Hop-by-Hop extension header from
              the packet.  The internal kingdom network does not
              process or forward PQC wire metadata.</li>
              <li>Forward the stripped packet into the kingdom.</li>
            </ol>
          </li>
          <li>If verification fails: DROP, emit DEATH event.</li>
        </ol>
      </section>

      <section anchor="shield-egress" numbered="true" toc="include">
        <name>Egress (Kingdom to External)</name>
        <t>When Shield transmits a packet to an external network:</t>

        <ol spacing="normal">
          <li><t>Read Wotan per-flow PQC state.  If pqc_verified == 1:</t>
            <ol type="(%c)" spacing="normal">
              <li>Re-stamp a fresh Monad Hop-by-Hop extension header
              with current SigRef, KeyRef, incremented SeqNum,
              and recomputed HashPfx.</li>
              <li>Set the S flag in the Monad flags byte.</li>
            </ol>
          </li>
          <li>Kingdom Mode bits MUST be zeroed (per <xref target="MONAD"/>).</li>
          <li>External receivers without Unheaded support will ignore
          the S flag and Monad value field.</li>
        </ol>
      </section>

      <section anchor="internal-transit" numbered="true" toc="include">
        <name>Internal Transit (No PQC Wire Overhead)</name>
        <t>Within the kingdom, after Shield ingress header stripping:</t>

        <ol spacing="normal">
          <li>Packets do NOT carry Monad HbH extension headers.</li>
          <li>PQC verification is NOT repeated at internal hops.</li>
          <li>The authoritative PQC authentication state resides in
          Wotan per-flow memory.  Applications and internal
          services read Wotan state -- not wire headers -- to
          determine authentication status.</li>
          <li><t>This design ensures:</t>
            <ol type="(%c)" spacing="normal">
              <li>Zero per-packet PQC overhead on internal links.</li>
              <li>Threat surface for PQC-specific attacks (SigRef
              exhaustion, cache poisoning, timing oracles) is
              confined to the Shield perimeter.</li>
              <li>Internal lateral movement cannot exploit PQC wire
              attack vectors -- the headers do not exist.</li>
            </ol>
          </li>
        </ol>
      </section>
    </section>

    <section anchor="application-level-policy" numbered="true" toc="include">
      <name>Application-Level Policy Verification (Layer 2)</name>
      <t>Layer 2 verification is OPTIONAL.  It enables user applications
      to define and enforce their own PQC authentication requirements
      independently of the wire-level infrastructure.</t>

      <section anchor="sophia-app-policy" numbered="true" toc="include">
        <name>Sophia Application Policy Dictionary</name>
        <t>Applications MAY define a Sophia dictionary containing PQC
        policy fields.  The dictionary is loaded into a Sophia BPF map
        and consumed by the application at runtime.</t>

        <artwork type="ascii-art"><![CDATA[
   Map name:      sophia_pqc_app_policy
   Key type:      uint32 (application_id)
   Value type:    struct sophia_pqc_policy
   Max entries:   Configurable (RECOMMENDED: 4,096)
   Flags:         BPF_F_RDONLY_PROG
   Pinning:       /sys/fs/bpf/sophia/pqc_app_policy
        ]]></artwork>

        <t>The policy structure:</t>

        <sourcecode type="c"><![CDATA[
   struct sophia_pqc_policy {
       uint8_t  min_security_level;  /* NIST level: 1, 3, or 5        */
       uint8_t  require_pinned_key;  /* 0=no, 1=yes                   */
       uint8_t  num_allowed_algos;   /* Count of allowed algo_ids     */
       uint8_t  reserved;
       uint32_t max_key_age_sec;     /* Maximum key epoch age         */
       uint8_t  allowed_algos[12];   /* Up to 12 allowed algo_id vals */
       uint8_t  pinned_fp[32];       /* Expected key fingerprint      */
                                     /* (if require_pinned_key == 1)  */
   };
        ]]></sourcecode>

        <t>Field definitions:</t>

        <dl>
          <dt>min_security_level (1 octet):</dt>
          <dd>Minimum NIST post-quantum security level the application
          requires.  Flows authenticated with a weaker parameter set MUST
          be rejected by the application.  Mapping: algo_id
          0x01-0x02,0x07-0x08 to Level 1; 0x03-0x04,0x09-0x0A to Level 3;
          0x05-0x06,0x0B-0x0C to Level 5.</dd>

          <dt>require_pinned_key (1 octet):</dt>
          <dd>If set to 1, the application MUST compare the flow's key
          fingerprint (from Wotan address 0x0000FF10) against pinned_fp.
          Mismatch leads to rejection.</dd>

          <dt>num_allowed_algos (1 octet):</dt>
          <dd>Number of valid entries in the allowed_algos array.  If 0,
          all algorithms are accepted (policy only checks
          min_security_level).</dd>

          <dt>max_key_age_sec (4 octets):</dt>
          <dd>Maximum age of the key epoch in seconds.  The application
          reads pqc_key_epoch from Wotan and compares against the key's
          creation timestamp in sophia_pqc_keys.  Keys older than this
          value lead to rejection.</dd>

          <dt>allowed_algos (12 octets):</dt>
          <dd>Array of acceptable algo_id values.  If the flow's
          pqc_algo_id (Wotan 0x0000FF05) is not in this set, the
          application rejects the flow.</dd>

          <dt>pinned_fp (32 octets):</dt>
          <dd>Expected SHA-256 fingerprint of the public key.  Only
          checked when require_pinned_key == 1.</dd>
        </dl>
      </section>

      <section anchor="layer2-verification-procedure" numbered="true" toc="include">
        <name>Layer 2 Verification Procedure</name>
        <t>When an application performs Layer 2 verification:</t>

        <ol spacing="normal">
          <li>Read pqc_verified from Wotan address 0x0000FF04.
          If not 1 (valid), reject.  Layer 1 MUST succeed first.</li>
          <li>Read pqc_algo_id from Wotan address 0x0000FF05.</li>
          <li>Look up the application's policy from sophia_pqc_app_policy
          using the application_id as key.</li>
          <li>If policy.num_allowed_algos &gt; 0: verify pqc_algo_id is in
          policy.allowed_algos[].  If not found, reject.</li>
          <li>Map pqc_algo_id to NIST security level.  If level &lt;
          policy.min_security_level, reject.</li>
          <li>If policy.require_pinned_key == 1: read key fingerprint
          from Wotan address 0x0000FF10 (8 bytes).  Compare against
          policy.pinned_fp[0:8].  If mismatch, reject.</li>
          <li>If policy.max_key_age_sec &gt; 0: read pqc_key_epoch from
          Wotan address 0x0000FF06.  Look up key creation timestamp
          from sophia_pqc_keys.  If (now - creation) &gt; max_key_age_sec,
          reject.</li>
          <li>All checks pass: accept flow at application layer.</li>
        </ol>
      </section>

      <section anchor="layer2-independence" numbered="true" toc="include">
        <name>Layer 2 Independence</name>
        <t>Layer 2 operates entirely on Wotan per-flow state and Sophia
        policy dictionaries.  It has NO dependency on Monad wire headers
        (which have been stripped at Shield ingress).  This means:</t>

        <ol type="(%c)" spacing="normal">
          <li>Layer 2 can be added or modified without any wire protocol
          changes.</li>
          <li>Different applications on the same host MAY enforce
          different policies for the same flow.</li>
          <li>Layer 2 is a pure application-space concern.  The
          infrastructure (Shield, XDP, Monad) is unaware of it.</li>
          <li>Enterprise customers can define arbitrarily strict policies
          without affecting the performance of Layer 1 wire-level
          authentication.</li>
        </ol>
      </section>

      <section anchor="sophia-dict-format" numbered="true" toc="include">
        <name>Sophia Dictionary Definition Format</name>
        <t>Applications define their policy using standard Sophia dictionary
        syntax.  Example enterprise policy:</t>

        <sourcecode><![CDATA[
   dictionary "enterprise-auth-policy" {
       field pqc_min_security_level  uint8   = 3;
       field pqc_require_pinned_key  uint8   = 1;
       field pqc_max_key_age_sec     uint32  = 86400;
       field pqc_allowed_algos       uint8[] = [0x03, 0x04, 0x09, 0x0A];
       field pqc_pinned_fp           bytes32 = 0xa1b2c3...;
   }
        ]]></sourcecode>

        <t>This policy requires: NIST Level 3 minimum, specific SHA2/SHAKE-192
        algorithms only, key rotation within 24 hours, and a pinned key
        fingerprint.  Any flow not meeting ALL requirements is rejected at
        the application layer, even if Layer 1 wire authentication passed.</t>
      </section>
    </section>

    <section anchor="multi-algorithm-considerations" numbered="true" toc="include">
      <name>Multi-Algorithm Considerations</name>
      <t>The inclusion of three distinct signature algorithm families
      introduces architectural constraints that implementations MUST
      address.</t>

      <section anchor="ebpf-compat-matrix" numbered="true" toc="include">
        <name>eBPF Compatibility Matrix</name>
        <t>Not all PQC algorithms can execute entirely within the eBPF/XDP
        verification pipeline.  The following matrix governs where
        verification occurs:</t>

        <table>
          <thead>
            <tr><th>Algorithm</th><th>Verify in eBPF?</th><th>Sign in eBPF?</th><th>Constraint</th></tr>
          </thead>
          <tbody>
            <tr><td>SLH-DSA</td><td>YES</td><td>NO</td><td>Hash-only, integer</td></tr>
            <tr><td>ML-DSA</td><td>YES</td><td>NO</td><td>Integer NTT mod q</td></tr>
            <tr><td>FN-DSA</td><td>PARTIAL*</td><td>NO</td><td>Float in signing</td></tr>
          </tbody>
        </table>

        <t>*FN-DSA verification performs integer NTT modular arithmetic
        (mod q=12289) plus L2-norm and infinity-norm checks.  These
        operations are integer-only and fit within the BPF verifier's
        <xref target="RFC9669"/> 1,000,000 instruction budget (~21,000 instructions estimated).
        However, implementations MAY choose to route FN-DSA verification
        to userspace via bpf_kfunc upcall for simplicity.</t>

        <t>FN-DSA signing requires IEEE-754 binary64 floating-point for:
        FFT expansion of private basis, LDL tree decomposition, and
        discrete Gaussian sampling.  eBPF does not support floating-point
        operations.  FN-DSA signing MUST occur in a dedicated userspace
        daemon.</t>
      </section>

      <section anchor="fndsa-signing-daemon" numbered="true" toc="include">
        <name>FN-DSA Signing Daemon</name>
        <t>When FN-DSA is enabled (Tier ENHANCED or SOVEREIGN), a dedicated
        signing daemon MUST be deployed:</t>

        <ol type="(%c)" spacing="normal">
          <li>The daemon MUST run with process isolation (separate cgroup,
          network namespace, dedicated CPU cores via isolcpus).</li>
          <li>The daemon MUST use a constant-time FN-DSA implementation
          to mitigate timing side channels (see Security Considerations
          <xref target="fndsa-side-channels"/>).</li>
          <li>FN-DSA mandates randomized signing only (NIST FIPS 206).
          Deterministic signing is PROHIBITED due to floating-point
          reproducibility concerns that could leak private key
          information.</li>
          <li>The daemon MUST validate entropy source quality at startup.
          If system entropy is insufficient (&lt; 256 bits available),
          the daemon MUST refuse to start and emit an Anamnesis
          CRITICAL event.</li>
          <li>Communication between Shield and the signing daemon MUST
          use an authenticated channel (Unix domain socket with
          SO_PEERCRED verification).</li>
        </ol>
      </section>

      <section anchor="algorithm-negotiation" numbered="true" toc="include">
        <name>Algorithm Negotiation</name>
        <t>When multiple algorithms are available (Tier ENHANCED or
        SOVEREIGN), the control plane selects the algorithm per flow
        based on:</t>

        <ol spacing="normal">
          <li>Peer capability advertisement (if Unheaded-to-Unheaded).</li>
          <li>Administrative policy (Sophia app policy dictionary).</li>
          <li>Performance preference (FN-DSA for minimum bandwidth,
          ML-DSA for fastest verification, SLH-DSA for maximum
          conservatism).</li>
        </ol>

        <t>The selected algo_id is written to the Sophia signature map
        entry and persisted in Wotan per-flow state.  Algorithm
        selection MUST NOT change mid-flow.</t>
      </section>

      <section anchor="sovereign-multi-sig" numbered="true" toc="include">
        <name>Sovereign Multi-Signature Layout</name>
        <t>In Tier SOVEREIGN, each flow carries signatures from at least
        two distinct algorithm families.  The Sophia signature map
        entry is extended:</t>

        <sourcecode type="c"><![CDATA[
   struct sophia_pqc_sovereign_entry {
       uint8_t  primary_algo_id;     /* Primary algorithm            */
       uint8_t  secondary_algo_id;   /* Secondary (different family) */
       uint8_t  tertiary_algo_id;    /* Tertiary (0x00 if 2-of-3)   */
       uint8_t  consensus;           /* Bitfield: b0=pri b1=sec b2=ter */
       uint32_t primary_sigref;      /* SigRef for primary sig       */
       uint32_t secondary_sigref;    /* SigRef for secondary sig     */
       uint32_t tertiary_sigref;     /* SigRef for tertiary sig      */
   };
        ]]></sourcecode>

        <t>The consensus field tracks which algorithms have verified
        successfully.  When popcount(consensus) &gt;= 2, the packet is
        authenticated.  This ensures that compromise of any single
        algorithm family does not break authentication.</t>
      </section>
    </section>

    <section anchor="kem-integration" numbered="true" toc="include">
      <name>KEM Integration (Key Establishment)</name>
      <t>The KEM algorithms (ML-KEM, HQC) are used for key establishment
      between Shield instances, NOT for per-packet authentication.</t>

      <section anchor="shield-tunnel-keys" numbered="true" toc="include">
        <name>Shield-to-Shield Tunnel Keys</name>
        <t>When two Shield instances establish a PQC-authenticated tunnel:</t>

        <ol spacing="normal">
          <li>Initiator generates an ML-KEM or HQC encapsulation using
          the responder's public KEM key.</li>
          <li>Ciphertext is transmitted via the Sophia control channel
          (not in Monad HbH headers -- ciphertexts are too large).</li>
          <li>Responder decapsulates to derive a shared secret.</li>
          <li>Shared secret is used to derive per-flow signing keys via
          HKDF-SHA256.</li>
        </ol>
      </section>

      <section anchor="kem-algorithm-selection" numbered="true" toc="include">
        <name>KEM Algorithm Selection</name>
        <t>ML-KEM (FIPS 203) is RECOMMENDED as the primary KEM due to its
        small ciphertext (768-1,568 bytes) and fast performance.</t>

        <t>HQC (FIPS 207) SHOULD be available as a non-lattice backup.
        If lattice-based assumptions are compromised (affecting both
        ML-KEM and ML-DSA), HQC provides code-based diversity.</t>

        <t>KEM algorithm identifiers use the 0x80-0x9F range in the algo_id
        registry (<xref target="iana-considerations"/>).  KEM entries appear in Sophia key maps
        but do NOT appear in per-packet Monad headers.</t>
      </section>
    </section>

    <section anchor="iana-considerations" numbered="true" toc="include">
      <name>IANA Considerations</name>

      <section anchor="pqc-algo-registry" numbered="true" toc="include">
        <name>PQC Algorithm Registry</name>
        <t>This document requests IANA to create a new registry:
        "Unheaded PQC Algorithm Identifiers"</t>

        <t>Registration Policy: Specification Required <xref target="RFC8126"/></t>

        <table>
          <thead>
            <tr><th>Value</th><th>Description</th><th>FIPS</th><th>Reference</th></tr>
          </thead>
          <tbody>
            <tr><td>0x00</td><td>Reserved</td><td>--</td><td>This document</td></tr>
            <tr><td>0x01</td><td>SLH-DSA-SHA2-128s</td><td>205</td><td>This document</td></tr>
            <tr><td>0x02</td><td>SLH-DSA-SHA2-128f</td><td>205</td><td>This document</td></tr>
            <tr><td>0x03</td><td>SLH-DSA-SHA2-192s</td><td>205</td><td>This document</td></tr>
            <tr><td>0x04</td><td>SLH-DSA-SHA2-192f</td><td>205</td><td>This document</td></tr>
            <tr><td>0x05</td><td>SLH-DSA-SHA2-256s</td><td>205</td><td>This document</td></tr>
            <tr><td>0x06</td><td>SLH-DSA-SHA2-256f</td><td>205</td><td>This document</td></tr>
            <tr><td>0x07</td><td>SLH-DSA-SHAKE-128s</td><td>205</td><td>This document</td></tr>
            <tr><td>0x08</td><td>SLH-DSA-SHAKE-128f</td><td>205</td><td>This document</td></tr>
            <tr><td>0x09</td><td>SLH-DSA-SHAKE-192s</td><td>205</td><td>This document</td></tr>
            <tr><td>0x0A</td><td>SLH-DSA-SHAKE-192f</td><td>205</td><td>This document</td></tr>
            <tr><td>0x0B</td><td>SLH-DSA-SHAKE-256s</td><td>205</td><td>This document</td></tr>
            <tr><td>0x0C</td><td>SLH-DSA-SHAKE-256f</td><td>205</td><td>This document</td></tr>
            <tr><td>0x0D-0x0F</td><td>Reserved (SLH-DSA)</td><td>205</td><td>This document</td></tr>
            <tr><td>0x10</td><td>ML-DSA-44</td><td>204</td><td>This document</td></tr>
            <tr><td>0x11</td><td>ML-DSA-65</td><td>204</td><td>This document</td></tr>
            <tr><td>0x12</td><td>ML-DSA-87</td><td>204</td><td>This document</td></tr>
            <tr><td>0x13-0x1F</td><td>Reserved (ML-DSA)</td><td>204</td><td>This document</td></tr>
            <tr><td>0x20</td><td>FN-DSA-512</td><td>206</td><td>This document</td></tr>
            <tr><td>0x21</td><td>FN-DSA-1024</td><td>206</td><td>This document</td></tr>
            <tr><td>0x22-0x7F</td><td>Reserved (sigs)</td><td>--</td><td>This document</td></tr>
            <tr><td>0x80</td><td>ML-KEM-512</td><td>203</td><td>This document</td></tr>
            <tr><td>0x81</td><td>ML-KEM-768</td><td>203</td><td>This document</td></tr>
            <tr><td>0x82</td><td>ML-KEM-1024</td><td>203</td><td>This document</td></tr>
            <tr><td>0x83-0x8F</td><td>Reserved (ML-KEM)</td><td>203</td><td>This document</td></tr>
            <tr><td>0x90</td><td>HQC-128</td><td>207</td><td>This document</td></tr>
            <tr><td>0x91</td><td>HQC-192</td><td>207</td><td>This document</td></tr>
            <tr><td>0x92-0xFE</td><td>Unassigned</td><td>--</td><td></td></tr>
            <tr><td>0xFF</td><td>Reserved</td><td>--</td><td>This document</td></tr>
          </tbody>
        </table>
      </section>

      <section anchor="monad-flags-update" numbered="true" toc="include">
        <name>Monad Flags Registry Update</name>
        <t>This document updates the Monad Flags Registry to formally
        define the semantics of the S (Signed) flag (bit 3) when used
        with PQC authentication:</t>

        <t>S = 1: The Monad value field contains PQC authentication
        references as defined in <xref target="monad-value-layout"/> of this document.</t>
      </section>

      <section anchor="sophia-map-type-update" numbered="true" toc="include">
        <name>Sophia Map Type Registry Update</name>
        <t>This document registers three new Sophia map types:</t>

        <table>
          <thead>
            <tr><th>Map Type</th><th>Name</th><th>Reference</th></tr>
          </thead>
          <tbody>
            <tr><td>0x10</td><td>PQC Signatures</td><td>This document</td></tr>
            <tr><td>0x11</td><td>PQC Public Keys</td><td>This document</td></tr>
            <tr><td>0x12</td><td>PQC App Policies</td><td>This document</td></tr>
            <tr><td>0x13</td><td>PQC Sovereign Sigs</td><td>This document</td></tr>
            <tr><td>0x14</td><td>PQC KEM Keys</td><td>This document</td></tr>
          </tbody>
        </table>
      </section>
    </section>

    <section anchor="security-considerations" numbered="true" toc="include">
      <name>Security Considerations</name>

      <section anchor="sig-by-ref-trust" numbered="true" toc="include">
        <name>Signature-by-Reference Trust Model</name>
        <t>The signature-by-reference scheme relocates the full signature
        from the wire to kernel-resident BPF maps.  The security of
        this scheme depends on:</t>

        <ol type="(%c)" spacing="normal">
          <li>The Sophia PQC maps being write-protected from the data
          plane (BPF_F_RDONLY_PROG).  If an attacker gains write
          access to the maps, they can substitute arbitrary
          signatures.</li>
          <li>The SigRef-to-signature binding being immutable for the
          lifetime of the flow.  SigRef values MUST NOT be reused
          within the same key epoch.</li>
          <li>The control plane being trusted.  The control plane is
          the sole writer to Sophia maps.  Compromise of the control
          plane compromises all authentication.</li>
        </ol>
      </section>

      <section anchor="replay-resistance" numbered="true" toc="include">
        <name>Replay Resistance</name>
        <t>The SeqNum field in the Monad register provides replay
        resistance.  Without SeqNum, an attacker who captures a
        legitimate packet could replay it indefinitely, as the SigRef
        would still reference a valid cached verification result.</t>

        <t>The SeqNum MUST be included in the signed pseudo-header.
        The Wotan per-flow last_seen_seq counter MUST be checked at
        each verification point.  Packets with SeqNum less than or
        equal to last_seen_seq MUST be dropped.</t>

        <t>Implementations SHOULD use a sliding window (RECOMMENDED:
        64 packets) rather than strict monotonic ordering to tolerate
        minor packet reordering.</t>
      </section>

      <section anchor="hashpfx-collision" numbered="true" toc="include">
        <name>HashPfx Collision Probability</name>
        <t>The 16-bit HashPfx provides a fast integrity check with
        collision probability of 1/65,536.  This is NOT a security
        mechanism -- it is an optimization to detect accidental SigRef
        corruption without performing a full map lookup.</t>

        <t>Deliberate attacks against HashPfx (preimage or collision)
        are trivial given its 16-bit size.  Security depends entirely
        on SLH-DSA verification, not on HashPfx.</t>
      </section>

      <section anchor="async-verification-window" numbered="true" toc="include">
        <name>Asynchronous Verification Window</name>
        <t>The OPTIMISTIC verification policy creates a window of 1-5
        milliseconds during which unverified packets may be forwarded.
        Deployments with strict authentication requirements MUST use
        the PESSIMISTIC policy.</t>

        <t>The OPTIMISTIC policy is acceptable when additional
        authentication mechanisms (e.g., mTLS) are in place and the
        PQC authentication serves as a defense-in-depth layer.</t>
      </section>

      <section anchor="memory-exhaustion" numbered="true" toc="include">
        <name>Memory Exhaustion</name>
        <t>An attacker may attempt to exhaust Sophia map capacity by
        generating flows with unique SigRef values.  Implementations
        MUST:</t>

        <ol type="(%c)" spacing="normal">
          <li>Enforce a maximum map size.</li>
          <li>Implement LRU eviction for verified entries.</li>
          <li>Rate-limit new SigRef allocations from untrusted sources.</li>
          <li>Monitor map utilization and alert when approaching
          capacity (RECOMMENDED: alert at 80%).</li>
        </ol>
      </section>

      <section anchor="crc16-not-crypto" numbered="true" toc="include">
        <name>CRC-16 Is Not Cryptographic</name>
        <t>As noted in <xref target="MONAD"/>, the CRC-16/CCITT checksum detects
        accidental corruption, not deliberate tampering.  PQC
        authentication via SLH-DSA provides tamper detection.  The
        two mechanisms are complementary: CRC-16 catches transmission
        errors; SLH-DSA catches deliberate modification.</t>
      </section>

      <section anchor="side-channel" numbered="true" toc="include">
        <name>Side-Channel Considerations</name>
        <t>SLH-DSA verification timing may vary based on signature
        content.  Implementations MUST use constant-time comparison
        for HashPfx and fingerprint checks.  The asynchronous
        verification architecture inherently mitigates timing side
        channels in the data plane, as verification occurs off the
        packet forwarding path.</t>
      </section>

      <section anchor="quantum-security-level" numbered="true" toc="include">
        <name>Quantum Security Level Selection</name>
        <t>The choice of SLH-DSA parameter set determines the quantum
        security level.  NIST Level 1 (SLH-DSA-128s) is RECOMMENDED
        for most deployments as it provides 128-bit security against
        quantum attacks with the smallest signature size (7,856 bytes).</t>

        <t>Deployments handling classified or long-term sensitive data
        SHOULD use Level 3 (SLH-DSA-192s) or Level 5 (SLH-DSA-256s).</t>
      </section>

      <section anchor="header-stripping-security" numbered="true" toc="include">
        <name>Header Stripping and Perimeter Isolation</name>
        <t>The header stripping design confines PQC wire-level attack
        vectors to the Shield perimeter.  This fundamentally limits
        the blast radius of several attack classes:</t>

        <ol type="(%c)" spacing="normal">
          <li>SigRef exhaustion (PQC-001): Only external traffic
          carries SigRef values.  Internal lateral movement cannot
          exploit SigRef-based amplification -- the headers are
          stripped.</li>
          <li>Cache poisoning (PQC-002): SigRef prediction attacks are
          only possible from external sources.  Internal services
          never reference the signature cache via wire headers.</li>
          <li>Timing oracles (PQC-003): Verification timing differences
          are only observable from outside the perimeter.  Internal
          paths see constant-time Wotan reads.</li>
        </ol>

        <t>However, header stripping does NOT mitigate:</t>

        <ol type="(%c)" start="4" spacing="normal">
          <li>Control plane compromise (PQC-008): A compromised control
          plane can poison Wotan state directly, bypassing wire-level
          authentication entirely.  Defense-in-depth measures (key
          pinning, audit trails, HSM integration) remain critical.</li>
        </ol>
      </section>

      <section anchor="dual-layer-security" numbered="true" toc="include">
        <name>Dual-Layer Verification Security Properties</name>
        <t>The dual-layer model provides defense-in-depth:</t>

        <ol type="(%c)" spacing="normal">
          <li>Layer 1 alone is sufficient for infrastructure-grade
          authentication.  Layer 2 is additive security.</li>
          <li>Layer 2 cannot weaken Layer 1.  A flow rejected by Layer 1
          never reaches the application.  Layer 2 can only further
          restrict what Layer 1 has already accepted.</li>
          <li>Layer 2 policy dictionaries are stored in BPF_F_RDONLY_PROG
          maps.  Applications cannot modify their own policies at
          runtime via the data plane.  Policy changes require control
          plane intervention.</li>
          <li>Different applications MAY enforce different Layer 2
          policies on the same flow.  Application A may accept a
          Level 1 authenticated flow while Application B on the same
          host rejects it for not meeting Level 3 requirements.  This
          is by design -- applications own their security posture.</li>
          <li>Layer 2 verification adds negligible overhead: Wotan reads
          (~50ns each) plus Sophia policy map lookup (~50-100ns).
          Total Layer 2 cost: ~200-300ns per flow establishment.</li>
        </ol>
      </section>

      <section anchor="fndsa-side-channels" numbered="true" toc="include">
        <name>FN-DSA Floating-Point Side Channels (PQC-009)</name>
        <t>FN-DSA signing requires IEEE-754 binary64 floating-point
        operations for FFT expansion, LDL tree decomposition, and
        discrete Gaussian sampling.  The "Do Not Disturb a Sleeping
        Falcon" paper (Eurocrypt 2025) demonstrates that timing
        variations in these operations can leak private key bits after
        approximately 2^26 observed signatures.</t>

        <t>Mitigations:</t>

        <ol type="(%c)" spacing="normal">
          <li>The FN-DSA signing daemon MUST use a constant-time
          implementation as specified in FIPS 206.</li>
          <li>The signing daemon MUST run on isolated CPU cores (isolcpus)
          with FPU state pinned (no context-switch FPU save/restore
          observable by other processes).</li>
          <li>Memory used by the signing daemon MUST be mlocked to prevent
          swapping.</li>
          <li>NIST requires randomized signing for FN-DSA.  This prevents
          the deterministic signature patterns that enable the
          Eurocrypt 2025 attack.</li>
        </ol>

        <t>Header stripping does NOT mitigate this finding -- the signing
        daemon is internal to the kingdom.</t>
      </section>

      <section anchor="userspace-kernel-boundary" numbered="true" toc="include">
        <name>Userspace-Kernel Boundary Attacks (PQC-010)</name>
        <t>When FN-DSA verification is routed to userspace via bpf_kfunc
        upcall, a time-of-check-to-time-of-use (TOCTOU) window exists
        between eBPF verification and application consumption.</t>

        <t>Mitigations:</t>

        <ol type="(%c)" spacing="normal">
          <li>Signature verification results MUST be pinned to the flow
          via a SHA-256 hash stored in Wotan per-flow state.
          Applications compare the pinned hash, not the raw result.</li>
          <li>The bpf_kfunc interface MUST authenticate the calling BPF
          program via BTF type verification.</li>
          <li>Ring buffer communication between kernel and userspace MUST
          use monotonic sequence numbers to prevent replay.</li>
        </ol>

        <t>Header stripping partially mitigates this -- the TOCTOU window
        exists only at the Shield perimeter.</t>
      </section>

      <section anchor="algo-confusion-downgrade" numbered="true" toc="include">
        <name>Algorithm Confusion and Downgrade (PQC-011)</name>
        <t>With three signature algorithm families, an attacker may attempt
        to force use of a weaker or compromised algorithm by manipulating
        the algo_id field in the Monad register.</t>

        <t>Mitigations:</t>

        <ol type="(%c)" spacing="normal">
          <li>Shield MUST validate that algo_id matches the algo_id stored
          in the Sophia signature map entry.  Mismatch leads to DROP.</li>
          <li>The compliance tier MUST restrict which algo_id values are
          accepted.  Tier STANDARD accepts only SLH-DSA (0x01-0x0C).
          Packets with ML-DSA or FN-DSA algo_id values at Tier STANDARD
          MUST be dropped.</li>
          <li>Algorithm selection MUST NOT change mid-flow.  If a packet
          arrives with a different algo_id than the flow's established
          algorithm, DROP and emit Anamnesis ERROR.</li>
          <li>Tier SOVEREIGN requires 2-of-3 consensus across different
          algorithm families, preventing single-algorithm downgrade.</li>
        </ol>

        <t>Header stripping mitigates this at the perimeter -- algo_id
        manipulation is only possible from external sources.</t>
      </section>

      <section anchor="entropy-requirements" numbered="true" toc="include">
        <name>Entropy Requirements for FN-DSA (PQC-013)</name>
        <t>FN-DSA signing requires approximately 40,448 bits of randomness
        per signature (79 bits x 512 coefficients).  Insufficient
        entropy in the discrete Gaussian sampling process can cause
        signatures to leak private key information.</t>

        <t>Mitigations:</t>

        <ol type="(%c)" spacing="normal">
          <li>The signing daemon MUST verify entropy source quality at
          startup using RDSEED or equivalent hardware RNG.</li>
          <li>If the kernel entropy pool drops below 256 bits, the signing
          daemon MUST pause signing and emit an Anamnesis CRITICAL event.</li>
          <li>Deployments in virtual machines or containers MUST ensure
          virtio-rng or equivalent entropy passthrough is configured.</li>
          <li>SLH-DSA does not have this vulnerability -- its hash-based
          construction uses deterministic derivation from the message
          and secret key.  This is one reason SLH-DSA is the RECOMMENDED
          default at Tier STANDARD.</li>
        </ol>
      </section>

      <section anchor="tier-security-boundaries" numbered="true" toc="include">
        <name>Compliance Tier Security Boundaries</name>
        <t>Each compliance tier establishes distinct security guarantees:</t>

        <ol type="(%c)" spacing="normal">
          <li>Tier NONE: No PQC guarantees.  Packets are not authenticated.
          Suitable only for environments where PQC is not required.</li>
          <li>Tier STANDARD: Single-algorithm (SLH-DSA) authentication at
          Layer 1.  Vulnerable to SLH-DSA-specific compromise but
          provides baseline post-quantum protection.</li>
          <li>Tier ENHANCED: Multi-algorithm availability but single-algorithm
          enforcement per flow.  Provides algorithm agility
          but not simultaneous cross-verification.</li>
          <li>Tier SOVEREIGN: Multi-algorithm cross-verification (2-of-3).
          Survives compromise of any single algorithm family.  MANDATORY
          Layer 2 enforcement and audit trail.  Maximum assurance.</li>
        </ol>

        <t>Tier downgrades MUST be treated as security events.  A downgrade
        from SOVEREIGN to STANDARD removes multi-algorithm protection.</t>
      </section>
    </section>

  </middle>

  <back>

    <references>
      <name>References</name>

      <references>
        <name>Normative References</name>

        <reference anchor="FIPS203">
          <front>
            <title>Module-Lattice-Based Key-Encapsulation Mechanism Standard</title>
            <author>
              <organization>National Institute of Standards and Technology</organization>
            </author>
            <date year="2024" month="August"/>
          </front>
          <seriesInfo name="FIPS" value="203"/>
        </reference>

        <reference anchor="FIPS204">
          <front>
            <title>Module-Lattice-Based Digital Signature Standard</title>
            <author>
              <organization>National Institute of Standards and Technology</organization>
            </author>
            <date year="2024" month="August"/>
          </front>
          <seriesInfo name="FIPS" value="204"/>
        </reference>

        <reference anchor="FIPS205">
          <front>
            <title>Stateless Hash-Based Digital Signature Standard</title>
            <author>
              <organization>National Institute of Standards and Technology</organization>
            </author>
            <date year="2024" month="August"/>
          </front>
          <seriesInfo name="FIPS" value="205"/>
        </reference>

        <reference anchor="FIPS206">
          <front>
            <title>FFT over NTRU-Lattice-Based Digital Signature Standard</title>
            <author>
              <organization>National Institute of Standards and Technology</organization>
            </author>
            <date year="2025"/>
          </front>
          <seriesInfo name="FIPS" value="206"/>
        </reference>

        <reference anchor="FIPS207">
          <front>
            <title>HQC Key-Encapsulation Mechanism Standard</title>
            <author>
              <organization>National Institute of Standards and Technology</organization>
            </author>
            <date year="2025"/>
          </front>
          <seriesInfo name="FIPS" value="207"/>
        </reference>

        <reference anchor="MONAD">
          <front>
            <title>The Unheaded Protocol Foundation</title>
            <author initials="S." surname="Bellis" fullname="Stevie Bellis"/>
            <date year="2026" month="March"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-bellis-unheaded-protocol-foundation-00"/>
        </reference>

        <reference anchor="SOPHIA">
          <front>
            <title>Sophia Dictionary Specification for the Unheaded Protocol</title>
            <author initials="S." surname="Bellis" fullname="Stevie Bellis"/>
            <date year="2026" month="March"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-bellis-unheaded-sophia-dictionary-00"/>
        </reference>

        <reference anchor="WOTAN">
          <front>
            <title>Wotan Memory Model for the Unheaded Protocol</title>
            <author initials="S." surname="Bellis" fullname="Stevie Bellis"/>
            <date year="2026" month="March"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-bellis-unheaded-wotan-memory-00"/>
        </reference>

        <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="RFC8126" target="https://www.rfc-editor.org/info/rfc8126">
          <front>
            <title>Guidelines for Writing an IANA Considerations Section in RFCs</title>
            <author initials="M." surname="Cotton"/>
            <author initials="B." surname="Leiba"/>
            <author initials="T." surname="Narten"/>
            <date year="2017" month="June"/>
          </front>
          <seriesInfo name="BCP" value="26"/>
          <seriesInfo name="RFC" value="8126"/>
        </reference>

        <reference anchor="RFC8200" target="https://www.rfc-editor.org/info/rfc8200">
          <front>
            <title>Internet Protocol, Version 6 (IPv6) Specification</title>
            <author initials="S." surname="Deering"/>
            <author initials="R." surname="Hinden"/>
            <date year="2017" month="July"/>
          </front>
          <seriesInfo name="STD" value="86"/>
          <seriesInfo name="RFC" value="8200"/>
        </reference>
      </references>

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

        <reference anchor="SP80090A">
          <front>
            <title>Recommendation for Random Number Generation Using Deterministic Random Bit Generators</title>
            <author>
              <organization>National Institute of Standards and Technology</organization>
            </author>
            <date year="2015" month="June"/>
          </front>
          <seriesInfo name="NIST SP" value="800-90A Rev. 1"/>
        </reference>

        <reference anchor="RFC9669" target="https://www.rfc-editor.org/info/rfc9669">
          <front>
            <title>BPF Instruction Set Architecture (ISA)</title>
            <author initials="D." surname="Thaler" role="editor"/>
            <date year="2024" month="October"/>
          </front>
          <seriesInfo name="RFC" value="9669"/>
        </reference>
      </references>
    </references>

    <section anchor="appendix-a" numbered="true" toc="include">
      <name>Algorithm Parameter Set Selection Guide</name>
      <t>Cross-algorithm comparison for deployment planning:</t>

      <table>
        <thead>
          <tr><th>Requirement</th><th>Recommended Algo</th><th>Sig Size</th><th>Verify Time</th><th>Tier</th></tr>
        </thead>
        <tbody>
          <tr><td>Most conservative</td><td>SLH-DSA-SHA2-128s</td><td>7,856 B</td><td>~2ms</td><td>STANDARD</td></tr>
          <tr><td>Fast verification</td><td>ML-DSA-44</td><td>2,420 B</td><td>~0.1ms</td><td>ENHANCED</td></tr>
          <tr><td>Minimum bandwidth</td><td>FN-DSA-512</td><td>666 B</td><td>~0.2ms</td><td>ENHANCED</td></tr>
          <tr><td>High security (hash)</td><td>SLH-DSA-SHA2-256s</td><td>29,792 B</td><td>~5ms</td><td>STANDARD</td></tr>
          <tr><td>High security (lattice)</td><td>ML-DSA-87</td><td>4,627 B</td><td>~0.3ms</td><td>ENHANCED</td></tr>
          <tr><td>Government / CNSA 2.0</td><td>SLH-DSA-SHA2-192s+</td><td>16,224 B</td><td>~3ms</td><td>SOVEREIGN</td></tr>
          <tr><td>Maximum assurance</td><td>2-of-3 (all algos)</td><td>varies</td><td>~5-7ms</td><td>SOVEREIGN</td></tr>
        </tbody>
      </table>

      <t>Algorithm family trade-offs:</t>

      <t>SLH-DSA (FIPS 205): Most conservative.  Hash-based -- no lattice
      assumptions.  Largest signatures but simplest trust model.  Fully
      eBPF-native.  RECOMMENDED for Tier STANDARD.</t>

      <t>ML-DSA (FIPS 204): Best performance/size ratio.  Lattice-based with
      integer NTT.  Fully eBPF-native.  If lattice assumptions hold, this
      is the optimal choice for high-throughput deployments.</t>

      <t>FN-DSA (FIPS 206): Smallest signatures (666-1,280B).  Lattice-based
      with floating-point signing.  Requires userspace signing daemon.
      Best for bandwidth-constrained links.  Carries additional side-channel
      risk (see <xref target="fndsa-side-channels"/>).</t>

      <t>For the signature-by-reference scheme, signature size impacts Sophia
      map memory, not wire overhead.  All algorithms use the same 12-byte
      Monad value layout.</t>
    </section>

    <section anchor="appendix-b" numbered="true" toc="include">
      <name>Performance Analysis</name>
      <t>Estimated per-packet overhead at XDP:</t>

      <table>
        <thead>
          <tr><th>Operation</th><th>Time</th><th>Notes</th></tr>
        </thead>
        <tbody>
          <tr><td>Sophia map lookup</td><td>50-100ns</td><td>Hash map, kernel memory</td></tr>
          <tr><td>Cached verification read</td><td>~10ns</td><td>Single byte read</td></tr>
          <tr><td>HashPfx comparison</td><td>~5ns</td><td>2-byte constant-time</td></tr>
          <tr><td>SeqNum Wotan read</td><td>~50ns</td><td>bpf_wotan_read</td></tr>
          <tr><td>SeqNum Wotan CAS</td><td>~100ns</td><td>bpf_wotan_cas</td></tr>
          <tr><td>Total fast path</td><td>~215-265ns</td><td>Per packet, cached</td></tr>
        </tbody>
      </table>

      <t>First-packet slow path (async, one-time per flow):</t>

      <table>
        <thead>
          <tr><th>Operation</th><th>Time</th><th>Notes</th></tr>
        </thead>
        <tbody>
          <tr><td>Ring buffer write</td><td>~200ns</td><td>Zero-copy to userspace</td></tr>
          <tr><td>SLH-DSA verification</td><td>0.5-5ms</td><td>Parameter set dependent</td></tr>
          <tr><td>Map update with result</td><td>~100ns</td><td>Control plane write</td></tr>
          <tr><td>Total slow path</td><td>~1-5ms</td><td>One-time per flow</td></tr>
        </tbody>
      </table>

      <t>Memory overhead per concurrent flow (SLH-DSA-SHA2-128s):</t>

      <table>
        <thead>
          <tr><th>Component</th><th>Size per flow</th><th>100K flows</th><th>1M flows</th></tr>
        </thead>
        <tbody>
          <tr><td>Signature entry</td><td>~8 KB</td><td>~800 MB</td><td>~8 GB</td></tr>
          <tr><td>Key entry</td><td>~100 B</td><td>~10 MB</td><td>~100 MB</td></tr>
          <tr><td>Wotan PQC state</td><td>16 B</td><td>~1.6 MB</td><td>~16 MB</td></tr>
          <tr><td>Total</td><td>~8.1 KB</td><td>~812 MB</td><td>~8.1 GB</td></tr>
        </tbody>
      </table>
    </section>

    <section anchor="appendix-c" numbered="true" toc="include">
      <name>Test Vectors</name>
      <t>(To be provided in a future revision with complete SLH-DSA
      signing and verification examples using the pseudo-header
      format defined in <xref target="pseudo-header"/>.)</t>
    </section>

  </back>

</rfc>
