<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Cradicle Explorer</title>
    <link href="/css/bootstrap/bootstrap.min.css" rel="stylesheet">
    <style>
      .form-control-dark::placeholder {
          color: #aaa;
          opacity: 1;
      }
    </style>
    <link rel="stylesheet" href="/assets/fontawesome/css/all.min.css">
    <link rel="icon" type="image/png" href="/favicon.png">


                <link href="/css/dashboard.css" rel="stylesheet">
                </head>
                <body>
                <header class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
                  <a class="navbar-brand col-md-3 col-lg-2 me-0 px-3 fs-6" href="/">Cradicle Explorer</a>
                  <button class="navbar-toggler position-absolute d-md-none collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                  </button>
                  <form method="get" action="/cgi-bin/main" style="width:100%;"><input class="form-control form-control-dark w-100 rounded-0 border-0" type="text" name="q" placeholder="Search repos" aria-label="Search"></form>
                  <div class="navbar-nav flex-row">
                    <div class="nav-item text-nowrap">
                      <a class="nav-link px-3 active" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX">abzu</a>
                    </div>
                  </div>
                </header>
                <div class="container-fluid">
                  <div class="row">
                    <nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-dark sidebar collapse">
                      <div class="position-sticky pt-3 sidebar-sticky">
                        <ul class="nav flex-column">
                          <li class="nav-item">
                            <a class="nav-link" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX">
                              <i class="align-text-bottom fa-solid fa-info"></i>
                              Info
                            </a>
                          </li>
                          <li class="nav-item">
                            <a class="nav-link" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&issue=list">
                              <i class="align-text-bottom fa-solid fa-layer-group"></i>
                              Issues
                            </a>
                          </li>
                          <li class="nav-item">
                            <a class="nav-link" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&patch=list">
                              <i class="align-text-bottom fa-solid fa-vest-patches"></i>
                              Patches
                            </a>
                          </li>
                          <li class="nav-item">
                            <a class="nav-link" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&wallet=list">
                              <i class="align-text-bottom fa-solid fa-wallet"></i>
                              Wallets
                            </a>
                          </li>
                          <li class="nav-item">
                            <a class="nav-link active" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=.">
                              <i class="align-text-bottom fa-solid fa-code"></i>
                              Source
                            </a>
                          </li>
                        <h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted text-uppercase">
                          <span></span>
                        </h6>
                        <ul class="nav flex-column mb-2">
                        
    <h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-1 mb-1 text-muted text-uppercase">
      <span>Source</span>
    </h6>
    <li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=.agent"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> .agent</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=.library_data"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> .library_data</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=.seeker_data"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> .seeker_data</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=.test_data"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> .test_data</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=_vendor"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> _vendor</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=abzu-account"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> abzu-account</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=abzu-chameleon"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> abzu-chameleon</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=abzu-core"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> abzu-core</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=abzu-daemon"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> abzu-daemon</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=abzu-dht"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> abzu-dht</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=abzu-ffi"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> abzu-ffi</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=abzu-inference"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> abzu-inference</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=abzu-router"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> abzu-router</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=abzu-sdk"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> abzu-sdk</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=abzu-token"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> abzu-token</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=abzu-transport"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> abzu-transport</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=apps"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> apps</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=docs"><i class="fa-solid fa-folder-open" style="color:#f0c040;"></i> docs</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=docs%2F.context"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> .context</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=docs%2Fabzu_handbook"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> abzu_handbook</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=docs%2Farchive"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> archive</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=docs%2Fassets"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> assets</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=docs%2Fdeep-dive"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> deep-dive</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=docs%2Fhuman"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> human</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=docs%2Fnotebooklm"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> notebooklm</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=docs%2Ftests"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> tests</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=docs%2FAGENT_BRIEFING.md"><i class="fa-solid fa-file" style="color:#888;"></i> AGENT_BRIEFING.md</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=docs%2FCODEBASE_GUIDE.md"><i class="fa-solid fa-file" style="color:#888;"></i> CODEBASE_GUIDE.md</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=docs%2FCOMPONENT_REFERENCE.md"><i class="fa-solid fa-file" style="color:#888;"></i> COMPONENT_REFERENCE.md</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=docs%2FCRATE_MAP.md"><i class="fa-solid fa-file" style="color:#888;"></i> CRATE_MAP.md</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=docs%2FFAULT_TOLERANCE_IMPLEMENTATION.md"><i class="fa-solid fa-file" style="color:#888;"></i> FAULT_TOLERANCE_IMPLEMENTATION.md</a></li><li><a class="nav-link py-0 active" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=docs%2FGhost_Mode_Security_Audit.md"><i class="fa-solid fa-file" style="color:#888;"></i> Ghost_Mode_Security_Audit.md</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=docs%2FINDEX.md"><i class="fa-solid fa-file" style="color:#888;"></i> INDEX.md</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=docs%2FMEMORY.md"><i class="fa-solid fa-file" style="color:#888;"></i> MEMORY.md</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=docs%2FMULTI_TENANT_ARCHITECTURE.md"><i class="fa-solid fa-file" style="color:#888;"></i> MULTI_TENANT_ARCHITECTURE.md</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=docs%2FSDK_API_REFERENCE.md"><i class="fa-solid fa-file" style="color:#888;"></i> SDK_API_REFERENCE.md</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=docs%2FTOKEN_ARCHITECTURE.md"><i class="fa-solid fa-file" style="color:#888;"></i> TOKEN_ARCHITECTURE.md</a></li><li><a class="nav-link py-0" style="padding-left:32px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=docs%2FWIRE_PROTOCOL_API.md"><i class="fa-solid fa-file" style="color:#888;"></i> WIRE_PROTOCOL_API.md</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=network"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> network</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=packages"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> packages</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=scripts"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> scripts</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=sovereign-agent"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> sovereign-agent</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=sovereign-wallet"><i class="fa-solid fa-folder" style="color:#f0c040;"></i> sovereign-wallet</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=.gitignore"><i class="fa-solid fa-file" style="color:#888;"></i> .gitignore</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=.markdownlintrc"><i class="fa-solid fa-file" style="color:#888;"></i> .markdownlintrc</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=AGENTS.md"><i class="fa-solid fa-file" style="color:#888;"></i> AGENTS.md</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=CLAUDE.md"><i class="fa-solid fa-file" style="color:#888;"></i> CLAUDE.md</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=CONTRIBUTING.md"><i class="fa-solid fa-file" style="color:#888;"></i> CONTRIBUTING.md</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=Cargo.lock"><i class="fa-solid fa-file" style="color:#888;"></i> Cargo.lock</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=Cargo.toml"><i class="fa-solid fa-file" style="color:#888;"></i> Cargo.toml</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=Gemini_Generated_Image_b955xfb955xfb955.jpg"><i class="fa-solid fa-file" style="color:#888;"></i> Gemini_Generated_Image_b955xfb955xfb955.jpg</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=LICENSE"><i class="fa-solid fa-file" style="color:#888;"></i> LICENSE</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=NOTICE"><i class="fa-solid fa-file" style="color:#888;"></i> NOTICE</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=README.md"><i class="fa-solid fa-file" style="color:#888;"></i> README.md</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=deny.toml"><i class="fa-solid fa-file" style="color:#888;"></i> deny.toml</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=following.json"><i class="fa-solid fa-file" style="color:#888;"></i> following.json</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=moltbook.json"><i class="fa-solid fa-file" style="color:#888;"></i> moltbook.json</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=prepare_nlm.sh"><i class="fa-solid fa-file" style="color:#888;"></i> prepare_nlm.sh</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=prepare_nlm_full.sh"><i class="fa-solid fa-file" style="color:#888;"></i> prepare_nlm_full.sh</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=profile.json"><i class="fa-solid fa-file" style="color:#888;"></i> profile.json</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=sovereign_agent.db"><i class="fa-solid fa-file" style="color:#888;"></i> sovereign_agent.db</a></li><li><a class="nav-link py-0" style="padding-left:16px;" href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&file=teleport_test.sh"><i class="fa-solid fa-file" style="color:#888;"></i> teleport_test.sh</a></li>
    
                        </ul>
                      </div>
                    </nav>
                <main class="col-md-9 ms-sm-auto col-lg-10">
                  <div class="container px-1 py-3">
        
<div class="mb-2" style="font-size:1.1rem;"><a href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=.">/</a> <a href="/cgi-bin/repo?id=z3g8vEyv3XfBUnDq17xgVegmBvyFX&source=docs">docs</a> / Ghost_Mode_Security_Audit.md</div>
        <div class="list-group">
        <div class="list-group-item">
        <div class="mb-2" style="font-weight:bold;"><i class="fa-solid fa-file"></i> Ghost_Mode_Security_Audit.md</div>
        <pre style="margin:0; font-size:0.85rem; overflow-x:auto; color:#fafafa;"><span style="color:#666; user-select:none;">  1</span>  # Ghost Mode Security Audit &amp; Hardening
<span style="color:#666; user-select:none;">  2</span>  
<span style="color:#666; user-select:none;">  3</span>  **Date**: January 2026  
<span style="color:#666; user-select:none;">  4</span>  **Status**: ✅ Complete
<span style="color:#666; user-select:none;">  5</span>  
<span style="color:#666; user-select:none;">  6</span>  ---
<span style="color:#666; user-select:none;">  7</span>  
<span style="color:#666; user-select:none;">  8</span>  ## Executive Summary
<span style="color:#666; user-select:none;">  9</span>  
<span style="color:#666; user-select:none;"> 10</span>  External review identified two critical vulnerabilities in Ghost Mode&#x27;s cover traffic implementation. Both have been remediated. Cover traffic is now cryptographically indistinguishable from real traffic on the wire.
<span style="color:#666; user-select:none;"> 11</span>  
<span style="color:#666; user-select:none;"> 12</span>  ---
<span style="color:#666; user-select:none;"> 13</span>  
<span style="color:#666; user-select:none;"> 14</span>  ## Vulnerabilities Fixed
<span style="color:#666; user-select:none;"> 15</span>  
<span style="color:#666; user-select:none;"> 16</span>  ### 1. Serialization Overhead Leak
<span style="color:#666; user-select:none;"> 17</span>  
<span style="color:#666; user-select:none;"> 18</span>  **Issue**: Cover frames were sized *before* serialization. Postcard encoding adds overhead (variant tag + varint length prefix), causing cover packets to be 2-3 bytes larger than observed real traffic.
<span style="color:#666; user-select:none;"> 19</span>  
<span style="color:#666; user-select:none;"> 20</span>  **Attack**: DPI could filter packets by size, detecting cover traffic via consistent header offsets.
<span style="color:#666; user-select:none;"> 21</span>  
<span style="color:#666; user-select:none;"> 22</span>  **Fix** ([wire.rs](file:///Users/adrian/studio/abzu/abzu-transport/src/wire.rs#L144-L163)):
<span style="color:#666; user-select:none;"> 23</span>  
<span style="color:#666; user-select:none;"> 24</span>  ```rust
<span style="color:#666; user-select:none;"> 25</span>  pub fn cover(target_wire_size: usize) -&gt; Self {
<span style="color:#666; user-select:none;"> 26</span>      // Postcard overhead: 1 byte variant + varint length
<span style="color:#666; user-select:none;"> 27</span>      let length_prefix_size = if target_wire_size &lt; 128 { 1 } else { 2 };
<span style="color:#666; user-select:none;"> 28</span>      let overhead = 1 + length_prefix_size;
<span style="color:#666; user-select:none;"> 29</span>      
<span style="color:#666; user-select:none;"> 30</span>      let noise_len = target_wire_size.saturating_sub(overhead);
<span style="color:#666; user-select:none;"> 31</span>      // ... generate noise of noise_len bytes
<span style="color:#666; user-select:none;"> 32</span>  }
<span style="color:#666; user-select:none;"> 33</span>  ```
<span style="color:#666; user-select:none;"> 34</span>  
<span style="color:#666; user-select:none;"> 35</span>  **Result**: Encoded wire size now equals target exactly.
<span style="color:#666; user-select:none;"> 36</span>  
<span style="color:#666; user-select:none;"> 37</span>  ---
<span style="color:#666; user-select:none;"> 38</span>  
<span style="color:#666; user-select:none;"> 39</span>  ### 2. Echo Attack via Unique Sizes
<span style="color:#666; user-select:none;"> 40</span>  
<span style="color:#666; user-select:none;"> 41</span>  **Issue**: `PatternObserver` recorded exact packet sizes. An adversary could inject a unique-sized packet (e.g., 13337 bytes) and watch for cover traffic echoing that size.
<span style="color:#666; user-select:none;"> 42</span>  
<span style="color:#666; user-select:none;"> 43</span>  **Attack**: Send probe → wait → correlate cover traffic with matching size → deanonymize sender.
<span style="color:#666; user-select:none;"> 44</span>  
<span style="color:#666; user-select:none;"> 45</span>  **Fix** ([cover.rs](file:///Users/adrian/studio/abzu/abzu-transport/src/cover.rs#L121-L140)):
<span style="color:#666; user-select:none;"> 46</span>  
<span style="color:#666; user-select:none;"> 47</span>  ```rust
<span style="color:#666; user-select:none;"> 48</span>  pub fn record_size(&amp;mut self, size: usize) {
<span style="color:#666; user-select:none;"> 49</span>      // Fuzz to nearest 16-byte bucket
<span style="color:#666; user-select:none;"> 50</span>      let fuzzed_size = (size + 8) / 16 * 16;
<span style="color:#666; user-select:none;"> 51</span>      self.size_samples.push(fuzzed_size);
<span style="color:#666; user-select:none;"> 52</span>  }
<span style="color:#666; user-select:none;"> 53</span>  ```
<span style="color:#666; user-select:none;"> 54</span>  
<span style="color:#666; user-select:none;"> 55</span>  **Result**: Unique sizes collapse into common buckets. Probe sizes become indistinguishable from legitimate traffic.
<span style="color:#666; user-select:none;"> 56</span>  
<span style="color:#666; user-select:none;"> 57</span>  ---
<span style="color:#666; user-select:none;"> 58</span>  
<span style="color:#666; user-select:none;"> 59</span>  ## Test Verification
<span style="color:#666; user-select:none;"> 60</span>  
<span style="color:#666; user-select:none;"> 61</span>  ```
<span style="color:#666; user-select:none;"> 62</span>  test wire::tests::test_cover_roundtrip ... ok     # Wire size == target
<span style="color:#666; user-select:none;"> 63</span>  test cover::tests::test_histogram_sampling ... ok # Sizes fuzzed to buckets
<span style="color:#666; user-select:none;"> 64</span>  test result: ok. 17 passed; 0 failed
<span style="color:#666; user-select:none;"> 65</span>  ```
<span style="color:#666; user-select:none;"> 66</span>  
<span style="color:#666; user-select:none;"> 67</span>  ---
<span style="color:#666; user-select:none;"> 68</span>  
<span style="color:#666; user-select:none;"> 69</span>  ## Design Principle: Post-Decrypt Discrimination
<span style="color:#666; user-select:none;"> 70</span>  
<span style="color:#666; user-select:none;"> 71</span>  Cover traffic remains **indistinguishable on the wire**. Only after decryption can a node identify and discard `AbzuFrame::Cover`. This follows Kerckhoffs&#x27; Principle—security depends on keys, not obscurity of the protocol.
<span style="color:#666; user-select:none;"> 72</span>  
<span style="color:#666; user-select:none;"> 73</span>  ```
<span style="color:#666; user-select:none;"> 74</span>  Wire (encrypted)     → All frames same format
<span style="color:#666; user-select:none;"> 75</span>  Decrypt              → Identify Cover variant
<span style="color:#666; user-select:none;"> 76</span>  Switchboard          → Silently discard, log at TRACE
<span style="color:#666; user-select:none;"> 77</span>  ```
<span style="color:#666; user-select:none;"> 78</span>  
<span style="color:#666; user-select:none;"> 79</span>  ---
<span style="color:#666; user-select:none;"> 80</span>  
<span style="color:#666; user-select:none;"> 81</span>  ## Files Modified
<span style="color:#666; user-select:none;"> 82</span>  
<span style="color:#666; user-select:none;"> 83</span>  | File | Change |
<span style="color:#666; user-select:none;"> 84</span>  | ---- | ------ |
<span style="color:#666; user-select:none;"> 85</span>  | `abzu-transport/src/wire.rs` | Overhead compensation in `cover()` |
<span style="color:#666; user-select:none;"> 86</span>  | `abzu-transport/src/cover.rs` | 16-byte bucket fuzzing in `record_size()` |
<span style="color:#666; user-select:none;"> 87</span>  
<span style="color:#666; user-select:none;"> 88</span>  ---
<span style="color:#666; user-select:none;"> 89</span>  
<span style="color:#666; user-select:none;"> 90</span>  ## Remaining Considerations
<span style="color:#666; user-select:none;"> 91</span>  
<span style="color:#666; user-select:none;"> 92</span>  - **Bucket size tuning**: 16 bytes is a reasonable default. Consider adaptive sizing based on observed traffic entropy.
<span style="color:#666; user-select:none;"> 93</span>  - **Timing analysis**: Poisson timing is implemented but could be enhanced with traffic-adaptive jitter.
<span style="color:#666; user-select:none;"> 94</span>  - **Metrics isolation**: Cover traffic is excluded from node metrics to prevent debugging data leakage.
<span style="color:#666; user-select:none;"> 95</span>  
<span style="color:#666; user-select:none;"> 96</span>  ---
<span style="color:#666; user-select:none;"> 97</span>  
<span style="color:#666; user-select:none;"> 98</span>  ## P1 Fingerprint Mitigations (January 2026)
<span style="color:#666; user-select:none;"> 99</span>  
<span style="color:#666; user-select:none;">100</span>  Following the initial P0 hardening, additional P1 fingerprint mitigations were implemented:
<span style="color:#666; user-select:none;">101</span>  
<span style="color:#666; user-select:none;">102</span>  ### 3. Sticky TLS Profiles
<span style="color:#666; user-select:none;">103</span>  
<span style="color:#666; user-select:none;">104</span>  **Issue**: Random TLS profile selection per-connection creates a &quot;schizophrenic user&quot; fingerprint.
<span style="color:#666; user-select:none;">105</span>  
<span style="color:#666; user-select:none;">106</span>  **Fix** ([tls_profiles.rs](file:///Users/adrian/studio/abzu/abzu-transport/src/transports/tls_profiles.rs)):
<span style="color:#666; user-select:none;">107</span>  
<span style="color:#666; user-select:none;">108</span>  ```rust
<span style="color:#666; user-select:none;">109</span>  pub fn select_sticky_profile(node_identity: &amp;[u8; 32]) -&gt; TlsProfile {
<span style="color:#666; user-select:none;">110</span>      let hash = sha256(node_identity);
<span style="color:#666; user-select:none;">111</span>      BROWSER_PROFILES[hash[0] as usize % BROWSER_PROFILES.len()].clone()
<span style="color:#666; user-select:none;">112</span>  }
<span style="color:#666; user-select:none;">113</span>  ```
<span style="color:#666; user-select:none;">114</span>  
<span style="color:#666; user-select:none;">115</span>  **Result**: Node uses consistent TLS fingerprint across all connections.
<span style="color:#666; user-select:none;">116</span>  
<span style="color:#666; user-select:none;">117</span>  ---
<span style="color:#666; user-select:none;">118</span>  
<span style="color:#666; user-select:none;">119</span>  ### 4. Cold-Start Histogram Seeding
<span style="color:#666; user-select:none;">120</span>  
<span style="color:#666; user-select:none;">121</span>  **Issue**: New nodes emit statistically flat traffic (uniform distribution) until trained.
<span style="color:#666; user-select:none;">122</span>  
<span style="color:#666; user-select:none;">123</span>  **Fix** ([histogram_presets.rs](file:///Users/adrian/studio/abzu/abzu-chameleon/src/histogram_presets.rs)):
<span style="color:#666; user-select:none;">124</span>  
<span style="color:#666; user-select:none;">125</span>  ```rust
<span style="color:#666; user-select:none;">126</span>  // 5 presets derived from real traffic analysis
<span style="color:#666; user-select:none;">127</span>  pub static HISTOGRAM_PRESETS: [HistogramPreset; 5] = [...];
<span style="color:#666; user-select:none;">128</span>  
<span style="color:#666; user-select:none;">129</span>  // from_identity() selects preset deterministically from node identity
<span style="color:#666; user-select:none;">130</span>  pub fn from_identity(identity: &amp;[u8; 32]) -&gt; Self {
<span style="color:#666; user-select:none;">131</span>      let preset = &amp;HISTOGRAM_PRESETS[identity[0] as usize % 5];
<span style="color:#666; user-select:none;">132</span>      Self::from_preset(preset)
<span style="color:#666; user-select:none;">133</span>  }
<span style="color:#666; user-select:none;">134</span>  ```
<span style="color:#666; user-select:none;">135</span>  
<span style="color:#666; user-select:none;">136</span>  **Result**: New nodes immediately have realistic traffic patterns.
<span style="color:#666; user-select:none;">137</span>  
<span style="color:#666; user-select:none;">138</span>  ---
<span style="color:#666; user-select:none;">139</span>  
<span style="color:#666; user-select:none;">140</span>  ### 5. Edge GRU-Matched Distribution
<span style="color:#666; user-select:none;">141</span>  
<span style="color:#666; user-select:none;">142</span>  **Issue**: Mobile/Edge devices without ML still need GRU-equivalent traffic patterns.
<span style="color:#666; user-select:none;">143</span>  
<span style="color:#666; user-select:none;">144</span>  **Fix** ([edge_generator.rs](file:///Users/adrian/studio/abzu/abzu-chameleon/src/edge_generator.rs)):
<span style="color:#666; user-select:none;">145</span>  
<span style="color:#666; user-select:none;">146</span>  ```rust
<span style="color:#666; user-select:none;">147</span>  pub struct EdgeGenerator {
<span style="color:#666; user-select:none;">148</span>      delay_histogram: [u16; 20],  // Pre-computed from trained GRU
<span style="color:#666; user-select:none;">149</span>      size_histogram: [u16; 20],   // Static, embedded at compile time
<span style="color:#666; user-select:none;">150</span>  }
<span style="color:#666; user-select:none;">151</span>  ```
<span style="color:#666; user-select:none;">152</span>  
<span style="color:#666; user-select:none;">153</span>  **Result**: Edge nodes indistinguishable from Desktop GRU nodes.
<span style="color:#666; user-select:none;">154</span>  
<span style="color:#666; user-select:none;">155</span>  ---
<span style="color:#666; user-select:none;">156</span>  
<span style="color:#666; user-select:none;">157</span>  ### 6. 3σ Poisoning Resistance
<span style="color:#666; user-select:none;">158</span>  
<span style="color:#666; user-select:none;">159</span>  **Issue**: Adversary could inject abnormal sizes to watermark traffic patterns.
<span style="color:#666; user-select:none;">160</span>  
<span style="color:#666; user-select:none;">161</span>  **Fix** ([cover.rs](file:///Users/adrian/studio/abzu/abzu-transport/src/cover.rs)):
<span style="color:#666; user-select:none;">162</span>  
<span style="color:#666; user-select:none;">163</span>  ```rust
<span style="color:#666; user-select:none;">164</span>  pub fn record_size(&amp;mut self, size: usize) {
<span style="color:#666; user-select:none;">165</span>      // After 50-sample training phase, reject 3σ outliers
<span style="color:#666; user-select:none;">166</span>      if self.stats_count &gt;= 50 &amp;&amp; stddev &gt; 0.0 {
<span style="color:#666; user-select:none;">167</span>          let z_score = (fuzzed - mean).abs() / stddev;
<span style="color:#666; user-select:none;">168</span>          if z_score &gt; 3.0 { return; } // Reject poisoning attempt
<span style="color:#666; user-select:none;">169</span>      }
<span style="color:#666; user-select:none;">170</span>      // ... Welford&#x27;s algorithm for running statistics
<span style="color:#666; user-select:none;">171</span>  }
<span style="color:#666; user-select:none;">172</span>  ```
<span style="color:#666; user-select:none;">173</span>  
<span style="color:#666; user-select:none;">174</span>  **Result**: Adversarial watermarks rejected with statistical confidence.
<span style="color:#666; user-select:none;">175</span>  
<span style="color:#666; user-select:none;">176</span>  ---
<span style="color:#666; user-select:none;">177</span>  
<span style="color:#666; user-select:none;">178</span>  ## Files Modified (P1)
<span style="color:#666; user-select:none;">179</span>  
<span style="color:#666; user-select:none;">180</span>  | File | Change |
<span style="color:#666; user-select:none;">181</span>  | ---- | ------ |
<span style="color:#666; user-select:none;">182</span>  | `abzu-transport/src/transports/tls_profiles.rs` | Sticky profile selection |
<span style="color:#666; user-select:none;">183</span>  | `abzu-chameleon/src/histogram_presets.rs` | 5 traffic presets |
<span style="color:#666; user-select:none;">184</span>  | `abzu-chameleon/src/histogram_gen.rs` | `from_preset()`, `from_identity()` |
<span style="color:#666; user-select:none;">185</span>  | `abzu-chameleon/src/edge_generator.rs` | Static GRU-derived histograms |
<span style="color:#666; user-select:none;">186</span>  | `abzu-transport/src/cover.rs` | 3σ outlier rejection |
</pre>
        </div>
        </div>

</div>
</main>
</div>
</div>


</body>
</html>

