summaryrefslogtreecommitdiffstats
path: root/news/phase4-encryption-sealed
diff options
context:
space:
mode:
Diffstat (limited to 'news/phase4-encryption-sealed')
-rw-r--r--news/phase4-encryption-sealed/index.html178
-rw-r--r--news/phase4-encryption-sealed/index.html.gzbin4246 -> 0 bytes
2 files changed, 0 insertions, 178 deletions
diff --git a/news/phase4-encryption-sealed/index.html b/news/phase4-encryption-sealed/index.html
deleted file mode 100644
index dd7b5eb..0000000
--- a/news/phase4-encryption-sealed/index.html
+++ /dev/null
@@ -1,178 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>Phase 4: Encryption and Sealed Tesseras — Tesseras</title>
- <meta name="description" content="Tesseras now supports private and sealed memories with hybrid post-quantum encryption — AES-256-GCM, X25519 + ML-KEM-768, and time-lock key publication.">
- <!-- Open Graph -->
- <meta property="og:type" content="article">
- <meta property="og:title" content="Phase 4: Encryption and Sealed Tesseras">
- <meta property="og:description" content="Tesseras now supports private and sealed memories with hybrid post-quantum encryption — AES-256-GCM, X25519 + ML-KEM-768, and time-lock key publication.">
- <meta property="og:image" content="https://tesseras.net/images/social.jpg">
- <meta property="og:image:width" content="1200">
- <meta property="og:image:height" content="630">
- <meta property="og:site_name" content="Tesseras">
- <!-- Twitter Card -->
- <meta name="twitter:card" content="summary_large_image">
- <meta name="twitter:title" content="Phase 4: Encryption and Sealed Tesseras">
- <meta name="twitter:description" content="Tesseras now supports private and sealed memories with hybrid post-quantum encryption — AES-256-GCM, X25519 + ML-KEM-768, and time-lock key publication.">
- <meta name="twitter:image" content="https://tesseras.net/images/social.jpg">
- <link rel="stylesheet" href="https://tesseras.net/style.css?h=21f0f32121928ee5c690">
-
-
- <link rel="alternate" type="application/atom+xml" title="Tesseras" href="https://tesseras.net/atom.xml">
-
-
- <link rel="icon" type="image/png" sizes="32x32" href="https://tesseras.net/images/favicon.png?h=be4e123a23393b1a027d">
-
-</head>
-<body>
- <header>
- <h1>
- <a href="https:&#x2F;&#x2F;tesseras.net/">
- <img src="https://tesseras.net/images/logo-64.png?h=c1b8d0c4c5f93b49d40b" alt="Tesseras" width="40" height="40" class="logo">
- Tesseras
- </a>
- </h1>
- <nav>
-
- <a href="https://tesseras.net/about/">About</a>
- <a href="https://tesseras.net/news/">News</a>
- <a href="https://tesseras.net/releases/">Releases</a>
- <a href="https://tesseras.net/faq/">FAQ</a>
- <a href="https://tesseras.net/subscriptions/">Subscriptions</a>
- <a href="https://tesseras.net/contact/">Contact</a>
-
- </nav>
- <nav class="lang-switch">
-
- <strong>English</strong> | <a href="/pt-br&#x2F;news&#x2F;phase4-encryption-sealed&#x2F;">Português</a>
-
- </nav>
- </header>
-
- <main>
-
-<article>
- <h2>Phase 4: Encryption and Sealed Tesseras</h2>
- <p class="news-date">2026-02-14</p>
- <p>Some memories are not meant for everyone. A private journal, a letter to be
-opened in 2050, a family secret sealed until the grandchildren are old enough.
-Until now, every tessera on the network was open. Phase 4 changes that: Tesseras
-now encrypts private and sealed content with a hybrid cryptographic scheme
-designed to resist both classical and quantum attacks.</p>
-<p>The principle remains the same — encrypt as little as possible. Public memories
-need availability, not secrecy. But when someone creates a private or sealed
-tessera, the content is now locked behind AES-256-GCM encryption with keys
-protected by a hybrid key encapsulation mechanism combining X25519 and
-ML-KEM-768. Both algorithms must be broken to access the content.</p>
-<h2 id="what-was-built">What was built</h2>
-<p><strong>AES-256-GCM encryptor</strong> (<code>tesseras-crypto/src/encryption.rs</code>) — Symmetric
-content encryption with random 12-byte nonces and authenticated associated data
-(AAD). The AAD binds ciphertext to its context: for private tesseras, the
-content hash is included; for sealed tesseras, both the content hash and the
-<code>open_after</code> timestamp are bound into the AAD. This means moving ciphertext
-between tesseras with different open dates causes decryption failure — you
-cannot trick the system into opening a sealed memory early by swapping its
-ciphertext into a tessera with an earlier seal date.</p>
-<p><strong>Hybrid Key Encapsulation Mechanism</strong> (<code>tesseras-crypto/src/kem.rs</code>) — Key
-exchange using X25519 (classical elliptic curve Diffie-Hellman) combined with
-ML-KEM-768 (the NIST-standardized post-quantum lattice-based KEM, formerly
-Kyber). Both shared secrets are combined via <code>blake3::derive_key</code> with a fixed
-context string ("tesseras hybrid kem v1") to produce a single 256-bit content
-encryption key. This follows the same "dual from day one" philosophy as the
-project's dual signing (Ed25519 + ML-DSA): if either algorithm is broken in the
-future, the other still protects the content.</p>
-<p><strong>Sealed Key Envelope</strong> (<code>tesseras-crypto/src/sealed.rs</code>) — Wraps a content
-encryption key using the hybrid KEM, so only the tessera owner can recover it.
-The KEM produces a transport key, which is XORed with the content key to produce
-a wrapped key stored alongside the KEM ciphertext. On unsealing, the owner
-decapsulates the KEM ciphertext to recover the transport key, then XORs again to
-recover the content key.</p>
-<p><strong>Key Publication</strong> (<code>tesseras-crypto/src/sealed.rs</code>) — A standalone signed
-artifact for publishing a sealed tessera's content key after its <code>open_after</code>
-date has passed. The owner signs the content key, tessera hash, and publication
-timestamp with their dual keys (Ed25519, with ML-DSA placeholder). The manifest
-stays immutable — the key publication is a separate document. Other nodes verify
-the signature against the owner's public key before using the published key to
-decrypt the content.</p>
-<p><strong>EncryptionContext</strong> (<code>tesseras-core/src/enums.rs</code>) — A domain type that
-represents the AAD context for encryption. It lives in tesseras-core rather than
-tesseras-crypto because it's a domain concept (not a crypto implementation
-detail). The <code>to_aad_bytes()</code> method produces deterministic serialization: a tag
-byte (0x00 for Private, 0x01 for Sealed), followed by the content hash, and for
-Sealed, the <code>open_after</code> timestamp as little-endian i64.</p>
-<p><strong>Domain validation</strong> (<code>tesseras-core/src/service.rs</code>) —
-<code>TesseraService::create()</code> now rejects Sealed and Private tesseras that don't
-provide encryption keys. This is a domain-level validation: the service layer
-enforces that you cannot create a sealed memory without the cryptographic
-machinery to protect it. The error message is clear: "missing encryption keys
-for visibility sealed until 2050-01-01."</p>
-<p><strong>Core type updates</strong> — <code>TesseraIdentity</code> now includes an optional
-<code>encryption_public: Option&lt;HybridEncryptionPublic&gt;</code> field containing both the
-X25519 and ML-KEM-768 public keys. <code>KeyAlgorithm</code> gained <code>X25519</code> and <code>MlKem768</code>
-variants. The identity filesystem layout now supports <code>node.x25519.key</code>/<code>.pub</code>
-and <code>node.mlkem768.key</code>/<code>.pub</code>.</p>
-<p><strong>Testing</strong> — 8 unit tests for AES-256-GCM (roundtrip, wrong key, tampered
-ciphertext, wrong AAD, cross-context decryption failure, unique nonces, plus 2
-property-based tests for arbitrary payloads and nonce uniqueness). 5 unit tests
-for HybridKem (roundtrip, wrong keypair, tampered X25519, KDF determinism, plus
-1 property-based test). 4 unit tests for SealedKeyEnvelope and KeyPublication. 2
-integration tests covering the complete sealed and private tessera lifecycle:
-generate keys, create content key, encrypt, seal, unseal, decrypt, publish key,
-and verify — the full cycle.</p>
-<h2 id="architecture-decisions">Architecture decisions</h2>
-<ul>
-<li><strong>Hybrid KEM from day one</strong>: X25519 + ML-KEM-768 follows the same philosophy
-as dual signing. We don't know which cryptographic assumptions will hold over
-millennia, so we combine classical and post-quantum algorithms. The cost is
-~1.2 KB of additional key material per identity — trivial compared to the
-photos and videos in a tessera.</li>
-<li><strong>BLAKE3 for KDF</strong>: rather than adding <code>hkdf</code> + <code>sha2</code> as new dependencies, we
-use <code>blake3::derive_key</code> with a fixed context string. BLAKE3's key derivation
-mode is specifically designed for this use case, and the project already
-depends on BLAKE3 for content hashing.</li>
-<li><strong>Immutable manifests</strong>: when a sealed tessera's <code>open_after</code> date passes, the
-content key is published as a separate signed artifact (<code>KeyPublication</code>), not
-by modifying the manifest. This preserves the append-only, content-addressed
-nature of tesseras. The manifest was signed at creation time and never
-changes.</li>
-<li><strong>AAD binding prevents ciphertext swapping</strong>: the <code>EncryptionContext</code> binds
-both the content hash and (for sealed tesseras) the <code>open_after</code> timestamp
-into the AES-GCM authenticated data. An attacker who copies encrypted content
-from a "sealed until 2050" tessera into a "sealed until 2025" tessera will
-find that decryption fails — the AAD no longer matches.</li>
-<li><strong>XOR key wrapping</strong>: the sealed key envelope uses a simple XOR of the content
-key with the KEM-derived transport key, rather than an additional layer of
-AES-GCM. Since the transport key is a fresh random value from the KEM and is
-used exactly once, XOR is information-theoretically secure for this specific
-use case and avoids unnecessary complexity.</li>
-<li><strong>Domain validation, not storage validation</strong>: the "missing encryption keys"
-check lives in <code>TesseraService::create()</code>, not in the storage layer. This
-follows the hexagonal architecture pattern: domain rules are enforced at the
-service boundary, not scattered across adapters.</li>
-</ul>
-<h2 id="what-comes-next">What comes next</h2>
-<ul>
-<li><strong>Phase 4 continued: Resilience and Scale</strong> — Shamir's Secret Sharing for heir
-key distribution, advanced NAT traversal (STUN/TURN), performance tuning,
-security audits, OS packaging</li>
-<li><strong>Phase 5: Exploration and Culture</strong> — Public tessera browser by
-era/location/theme/language, institutional curation, genealogy integration,
-physical media export (M-DISC, microfilm, acid-free paper with QR)</li>
-</ul>
-<p>Sealed tesseras make Tesseras a true time capsule. A father can now record a
-message for his unborn grandchild, seal it until 2060, and know that the
-cryptographic envelope will hold — even if the quantum computers of the future
-try to break it open early.</p>
-
-</article>
-
- </main>
-
- <footer>
- <p>&copy; 2026 Tesseras Project. <a href="/atom.xml">News Feed</a> · <a href="https://git.sr.ht/~ijanc/tesseras">Source</a></p>
- </footer>
-</body>
-</html>
diff --git a/news/phase4-encryption-sealed/index.html.gz b/news/phase4-encryption-sealed/index.html.gz
deleted file mode 100644
index 817b650..0000000
--- a/news/phase4-encryption-sealed/index.html.gz
+++ /dev/null
Binary files differ