mirror of
https://github.com/saymrwulf/proof-aware-crypto-tooling-agent.git
synced 2026-09-06 20:20:36 +00:00
course refresh: the notebooks enter the SLH-DSA era
The 14-notebook course predated the post-quantum campaign entirely (coherence findings 10, 11). Now, authored in the GENERATOR and regenerated (AGENTS.md rule): - notebook 06: new section 'The second signature that actually shipped: SLH-DSA' — the deterministic co-signature since tree size 14, chosen because the log attests its own parameter set's verify path (leaf 18, 11 certs); absent-not-failed for older heads; determinism as an audit primitive; verify-only always. Plus a runnable keygen/sign/verify/ re-sign-byte-equality demo (honest skip below OpenSSL 3.5) and the --slhdsa-public-key consumer flag in the policy list. - notebook 09: the 'post-quantum line' is now three-legged — Ed25519 proven-verify dogfood, SLH-DSA shipped-and-attested, ML-DSA required- but-honest-unavailable — with the closing point that a slot stops being aspirational the day its verify path enters the log; stale 16/16 provenance count -> 44/44 (leaf 13 re-attestation). - notebook 07: policy exercise extended with the co-signature question; 00 course map goal updated; README course listing for 06/09. - GENERATOR DRIFT REPAIRED in passing: notebook 10's cockpit cell had been added to the .ipynb but never backported to the generator — regeneration would have silently dropped it; the cell is now IN the generator and round-trips (19 cells, content identical). Suite 157 green.
This commit is contained in:
parent
31a9dee10a
commit
1086a3ba02
8 changed files with 893 additions and 801 deletions
|
|
@ -125,11 +125,11 @@ The `notebooks/` directory contains a zero-to-hero teaching sequence for undergr
|
||||||
- `03_lean_replay_and_axiom_audit.ipynb`: replay versus transpilation, Lean invocation, axiom audits.
|
- `03_lean_replay_and_axiom_audit.ipynb`: replay versus transpilation, Lean invocation, axiom audits.
|
||||||
- `04_proof_hygiene_and_boundaries.ipynb`: `sorry`, local axioms, trivial targets, manifest coverage.
|
- `04_proof_hygiene_and_boundaries.ipynb`: `sorry`, local axioms, trivial targets, manifest coverage.
|
||||||
- `05_third_party_attestation_provider.ipynb`: provider trust transformation and signed attestations.
|
- `05_third_party_attestation_provider.ipynb`: provider trust transformation and signed attestations.
|
||||||
- `06_merkle_transparency_logs.ipynb`: RFC 9162-style Merkle proofs, STHs, Ed25519/ML-DSA policy.
|
- `06_merkle_transparency_logs.ipynb`: RFC 9162-style Merkle proofs, STHs, the dual-signature head policy (Ed25519 + the shipped SLH-DSA co-signature) and the fail-closed ML-DSA slot.
|
||||||
- `06a_provider_build_the_log.ipynb` / `06b_agent_verify_inclusion.ipynb`: the MIRRORED PAIR - one provider (builds, Lean-verifies, signs with the merkleized library, self-checks its own inclusion), many agents (verify inclusion from scratch in ~25 lines, no Lean); the domain separation is the design and the lecture structure mirrors it.
|
- `06a_provider_build_the_log.ipynb` / `06b_agent_verify_inclusion.ipynb`: the MIRRORED PAIR - one provider (builds, Lean-verifies, signs with the merkleized library, self-checks its own inclusion), many agents (verify inclusion from scratch in ~25 lines, no Lean); the domain separation is the design and the lecture structure mirrors it.
|
||||||
- `07_agent_consequences.ipynb`: receipt-gated artifact builds and wallet-denial policy.
|
- `07_agent_consequences.ipynb`: receipt-gated artifact builds and wallet-denial policy.
|
||||||
- `08_capstone_research_program.ipynb`: audit the shipped R4 evidence; design the R5 discharge plan.
|
- `08_capstone_research_program.ipynb`: audit the shipped R4 evidence; design the R5 discharge plan.
|
||||||
- `09_dogfood_verified_crypto.ipynb`: the proven-path verifier in the agent's own loop; hybrid-PQC posture.
|
- `09_dogfood_verified_crypto.ipynb`: the proven-path verifier in the agent's own loop; the three-legged PQ posture (Ed25519 dogfood, shipped SLH-DSA, honest ML-DSA slot).
|
||||||
- `10_verified_custody_wallet.ipynb`: warden - the quorum custody boundary and signing firewall, ratchet-rule (toy 3-of-3, then the real four proven forks), plus the counterparty recomputing a custody card's inclusion proof.
|
- `10_verified_custody_wallet.ipynb`: warden - the quorum custody boundary and signing firewall, ratchet-rule (toy 3-of-3, then the real four proven forks), plus the counterparty recomputing a custody card's inclusion proof.
|
||||||
- `11_the_customers_eye_view.ipynb`: the counterparty's seat - what a customer can and cannot recompute about someone else's wallet from its custody card and the public log.
|
- `11_the_customers_eye_view.ipynb`: the counterparty's seat - what a customer can and cannot recompute about someone else's wallet from its custody card and the public log.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
"- Perform a proof hygiene scan and explain why `sorry`, local axioms, and trivial theorem targets are dangerous.\n",
|
"- Perform a proof hygiene scan and explain why `sorry`, local axioms, and trivial theorem targets are dangerous.\n",
|
||||||
"- Explain how a third-party proof-checking provider changes the trusted base.\n",
|
"- Explain how a third-party proof-checking provider changes the trusted base.\n",
|
||||||
"- Implement and verify RFC 9162-style Merkle inclusion and consistency proofs.\n",
|
"- Implement and verify RFC 9162-style Merkle inclusion and consistency proofs.\n",
|
||||||
"- Explain why Signed Tree Heads need accountable signatures, why Ed25519 is useful here, and why ML-DSA requires a real backend.\n",
|
"- Explain why Signed Tree Heads need accountable signatures, why Ed25519 is useful here, why ML-DSA requires a real backend, and how the shipped SLH-DSA co-signature differs from both.\n",
|
||||||
"- Design policy gates that convert verification evidence into consequences.\n",
|
"- Design policy gates that convert verification evidence into consequences.\n",
|
||||||
"- Read R4 four-tier apex evidence, name its residual blockers, and write a research plan toward R5 production assurance.\n"
|
"- Read R4 four-tier apex evidence, name its residual blockers, and write a research plan toward R5 production assurance.\n"
|
||||||
]
|
]
|
||||||
|
|
@ -150,26 +150,6 @@
|
||||||
"- NIST FIPS 204, Module-Lattice-Based Digital Signature Standard: https://csrc.nist.gov/pubs/fips/204/final\n",
|
"- NIST FIPS 204, Module-Lattice-Based Digital Signature Standard: https://csrc.nist.gov/pubs/fips/204/final\n",
|
||||||
"- PACTA README: `../README.md`\n"
|
"- PACTA README: `../README.md`\n"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"## The course's operational twin: the cockpit and the lab manual\n",
|
|
||||||
"\n",
|
|
||||||
"These notebooks are the *code-level* track: you build the machinery with your own hands.\n",
|
|
||||||
"Two sibling surfaces teach the *operational* track on the very same system:\n",
|
|
||||||
"\n",
|
|
||||||
"- **The custody cockpit** — `pacta wallet cockpit --demo` serves a read-only bridge of six\n",
|
|
||||||
" role stations (proposer, quorum bench, operator, cryptographer, architect, newcomer) over\n",
|
|
||||||
" live evidence, with a tmux-style deck (`/deck`) showing every station in parallel.\n",
|
|
||||||
"- **The lab manual** (`docs/warden-lab-manual.md`, served at `/manual`) — a study-club course\n",
|
|
||||||
" that teaches each *role* hands-on: labs with checkpoints, a safe ledger-tamper drill,\n",
|
|
||||||
" self-tests, and a capstone incident walked through all six chairs.\n",
|
|
||||||
"\n",
|
|
||||||
"Recommended weave: notebooks 00–09 first (build it), then the lab manual (run it as a crew),\n",
|
|
||||||
"with notebook 10 and the manual's warden sessions read side by side."
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,8 @@
|
||||||
"Policy matters:\n",
|
"Policy matters:\n",
|
||||||
"\n",
|
"\n",
|
||||||
"- `require-signatures ed25519`: verify Ed25519 and allow ML-DSA to be unavailable.\n",
|
"- `require-signatures ed25519`: verify Ed25519 and allow ML-DSA to be unavailable.\n",
|
||||||
"- `require-signatures both`: require Ed25519 and ML-DSA verified. If ML-DSA is unavailable, fail closed.\n"
|
"- `require-signatures both`: require Ed25519 and ML-DSA verified. If ML-DSA is unavailable, fail closed.\n",
|
||||||
|
"- `--slhdsa-public-key <pem>`: additionally verify the second (post-quantum) SLH-DSA co-signature on the head; heads before tree size 14 report `absent` (allowed), a present-but-wrong signature fails closed.\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -156,6 +157,59 @@
|
||||||
"ML-DSA adds post-quantum robustness for the accumulator signature layer. But it must be a real signature, not an aspirational label. If a host lacks ML-DSA, the correct result is an explicit blocker.\n"
|
"ML-DSA adds post-quantum robustness for the accumulator signature layer. But it must be a real signature, not an aspirational label. If a host lacks ML-DSA, the correct result is an explicit blocker.\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## The second signature that actually shipped: SLH-DSA\n",
|
||||||
|
"\n",
|
||||||
|
"Since tree size 14, every head of the LIVE log carries a second,\n",
|
||||||
|
"deterministic **SLH-DSA-SHA2-128s** (FIPS 205) signature beside the\n",
|
||||||
|
"required Ed25519 one. This is not the ML-DSA slot above - it is a\n",
|
||||||
|
"hash-based scheme, and it was chosen because the estate has PROVEN\n",
|
||||||
|
"its verify path (eleven certificates, log leaf 18): the log\n",
|
||||||
|
"co-signs with the parameter set whose verification path it itself\n",
|
||||||
|
"attests. Three design facts worth internalizing:\n",
|
||||||
|
"\n",
|
||||||
|
"1. Heads published before size 14 carry no co-signature, and\n",
|
||||||
|
" verifiers report them `ABSENT` rather than failing them - an\n",
|
||||||
|
" append-only log keeps the history of its own signature-scheme\n",
|
||||||
|
" upgrades.\n",
|
||||||
|
"2. The co-signature is deterministic on purpose: re-signing the\n",
|
||||||
|
" same payload is byte-comparable, so \"same input, same\n",
|
||||||
|
" signature\" becomes a diff you can run, not an assurance you\n",
|
||||||
|
" must trust.\n",
|
||||||
|
"3. Signing is still never proven - here, as everywhere in this\n",
|
||||||
|
" estate, certificates cover the VERIFY path only.\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Runnable where OpenSSL >= 3.5 is present; honest skip otherwise.\n",
|
||||||
|
"import tempfile\n",
|
||||||
|
"from pathlib import Path\n",
|
||||||
|
"\n",
|
||||||
|
"from pacta import slhdsa\n",
|
||||||
|
"\n",
|
||||||
|
"tmp = Path(tempfile.mkdtemp(prefix=\"nb06-slhdsa-\"))\n",
|
||||||
|
"try:\n",
|
||||||
|
" slhdsa.generate_slhdsa_keypair(tmp / \"slh.key\", tmp / \"slh.pub\")\n",
|
||||||
|
"except Exception as exc:\n",
|
||||||
|
" print(\"SLH-DSA unavailable on this host (OpenSSL >= 3.5 needed):\", exc)\n",
|
||||||
|
"else:\n",
|
||||||
|
" payload = b\"canonical STH payload bytes\"\n",
|
||||||
|
" block = slhdsa.slh_dsa_signature_block(payload, tmp / \"slh.key\", tmp / \"slh.pub\")\n",
|
||||||
|
" ok, err = slhdsa.verify_payload_slhdsa(payload, block[\"signature_base64\"], tmp / \"slh.pub\")\n",
|
||||||
|
" print(\"co-signature verifies:\", ok, err or \"\")\n",
|
||||||
|
" block2 = slhdsa.slh_dsa_signature_block(payload, tmp / \"slh.key\", tmp / \"slh.pub\")\n",
|
||||||
|
" print(\"deterministic (byte-equal re-sign):\",\n",
|
||||||
|
" block[\"signature_base64\"] == block2[\"signature_base64\"])\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,7 @@
|
||||||
"- Modify a claim card to R2 and show that `build-library` is refused.\n",
|
"- Modify a claim card to R2 and show that `build-library` is refused.\n",
|
||||||
"- Explain why a denial artifact is useful for auditability.\n",
|
"- Explain why a denial artifact is useful for auditability.\n",
|
||||||
"- Design a policy where an agent requires `both` Ed25519 and ML-DSA signatures for production deployment but allows Ed25519-only in a local lab.\n",
|
"- Design a policy where an agent requires `both` Ed25519 and ML-DSA signatures for production deployment but allows Ed25519-only in a local lab.\n",
|
||||||
|
"- Extend it: when should the agent also require the SLH-DSA co-signature, given that heads before tree size 14 legitimately lack it?\n",
|
||||||
"- Write a downstream Rust pseudo-code snippet that imports the generated capsule before enabling a code path.\n"
|
"- Write a downstream Rust pseudo-code snippet that imports the generated capsule before enabling a code path.\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
"- State precisely which parts of the dogfood verifier are certificate-covered and which are its trusted base.\n",
|
"- State precisely which parts of the dogfood verifier are certificate-covered and which are its trusted base.\n",
|
||||||
"- Extract a raw Ed25519 key from an OpenSSL PEM by hand (napkin) and mechanically (real).\n",
|
"- Extract a raw Ed25519 key from an OpenSSL PEM by hand (napkin) and mechanically (real).\n",
|
||||||
"- Demonstrate backend dispatch and the fail-closed `--require-verified-verifier` policy.\n",
|
"- Demonstrate backend dispatch and the fail-closed `--require-verified-verifier` policy.\n",
|
||||||
"- Defend the hybrid post-quantum posture: one proven-classical signature plus one required-but-honest ML-DSA slot.\n"
|
"- Defend the three-legged post-quantum posture: proven-classical Ed25519, the shipped SLH-DSA co-signature with its attested verify path, and a required-but-honest ML-DSA slot.\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -122,7 +122,8 @@
|
||||||
"leaf, against the very tree it is about to sign. The verdict is\n",
|
"leaf, against the very tree it is about to sign. The verdict is\n",
|
||||||
"embedded in the signature block (`signing_provenance`: backend,\n",
|
"embedded in the signature block (`signing_provenance`: backend,\n",
|
||||||
"library commit, leaf index, `self_inclusion: verified`,\n",
|
"library commit, leaf index, `self_inclusion: verified`,\n",
|
||||||
"certificates 16/16). Lectures 6a/6b walk both sides of this.\n",
|
"certificates 44/44 - the signer's source family was re-attested at 44\n",
|
||||||
|
"certificates as leaf 13). Lectures 6a/6b walk both sides of this.\n",
|
||||||
"Honesty note unchanged: the library's VERIFY path is\n",
|
"Honesty note unchanged: the library's VERIFY path is\n",
|
||||||
"certificate-covered; the signing path is declared trusted base -\n",
|
"certificate-covered; the signing path is declared trusted base -\n",
|
||||||
"but it is the attested artifact, not an un-attested third\n",
|
"but it is the attested artifact, not an un-attested third\n",
|
||||||
|
|
@ -130,12 +131,13 @@
|
||||||
"\n",
|
"\n",
|
||||||
"## The post-quantum line, held honestly\n",
|
"## The post-quantum line, held honestly\n",
|
||||||
"\n",
|
"\n",
|
||||||
"The dogfood loop deliberately does NOT extend to ML-DSA. There is no formally verified ML-DSA implementation in this corpus, and pretending otherwise would poison the whole posture. The hybrid strategy is therefore asymmetric on purpose:\n",
|
"The posture has three legs now, and each is exactly as strong as it claims:\n",
|
||||||
"\n",
|
"\n",
|
||||||
"- **Ed25519 (classical): proven path.** The signature everyone can check today runs on certificate-covered code.\n",
|
"- **Ed25519 (classical): proven verify path, dogfooded.** The signature everyone can check today runs on certificate-covered code.\n",
|
||||||
"- **ML-DSA-65 (post-quantum): required, honest, unavailable-until-real.** The tree-head slot exists in every signed structure; `--require-signatures both` fails CLOSED on hosts without a real FIPS 204 backend; and when a real backend lands, the policy flips on without a schema change.\n",
|
"- **SLH-DSA-SHA2-128s (post-quantum): shipped and attested.** Since tree size 14 every live head carries a second, deterministic SLH-DSA co-signature. The estate proved the VERIFY path of a pinned Rust FIPS 205 implementation (eleven certificates) and appended that attestation as leaf 18 - so the co-signature uses exactly the parameter set the log itself attests. Consumers check it with `pacta receipt-verify ... --slhdsa-public-key provider.slhdsa.pub` or the mirror's `verify.py`. Signing remains unproven - verify paths only, always.\n",
|
||||||
|
"- **ML-DSA-65 (lattice PQ): required, honest, unavailable-until-real.** The tree-head slot exists in every signed structure; `--require-signatures both` fails CLOSED on hosts without a real FIPS 204 backend; when a real backend lands, the policy flips on without a schema change.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"A migration strategy that records \"we cannot do this yet\" as a deployment blocker is strictly stronger than one that ships a placeholder. Blockers get fixed; placeholders get trusted.\n"
|
"A migration strategy that records \"we cannot do this yet\" as a deployment blocker is strictly stronger than one that ships a placeholder. Blockers get fixed; placeholders get trusted. And the SLH-DSA leg shows the endgame: a slot stops being aspirational the day its verify path enters the log.\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@
|
||||||
"## Why a quorum, when one proof would do?\n",
|
"## Why a quorum, when one proof would do?\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Each member is *proven* to decide the same predicate,\n",
|
"Each member is *proven* to decide the same predicate,\n",
|
||||||
"`accept(A,m,R,s) ⇔ decompress(R) = [k](−A) + [s]B`. So on the\n",
|
"`accept(A,m,R,s) \u21d4 decompress(R) = [k](\u2212A) + [s]B`. So on the\n",
|
||||||
"proven domain they cannot disagree about *meaning*. Classic\n",
|
"proven domain they cannot disagree about *meaning*. Classic\n",
|
||||||
"N-version programming hopes independent code won't share a bug;\n",
|
"N-version programming hopes independent code won't share a bug;\n",
|
||||||
"we do not hope - we know the semantics coincide, so a runtime\n",
|
"we do not hope - we know the semantics coincide, so a runtime\n",
|
||||||
|
|
@ -343,8 +343,8 @@
|
||||||
"\n",
|
"\n",
|
||||||
"Open `/deck` for all six role stations live in parallel (the quorum bench you built is the\n",
|
"Open `/deck` for all six role stations live in parallel (the quorum bench you built is the\n",
|
||||||
"indigo pane; the ledger you hash-chained is re-verified on every page load), and `/manual`\n",
|
"indigo pane; the ledger you hash-chained is re-verified on every page load), and `/manual`\n",
|
||||||
"for the lab-manual sessions that teach each role — Session 4's tamper drill breaks a *copy*\n",
|
"for the lab-manual sessions that teach each role \u2014 Session 4's tamper drill breaks a *copy*\n",
|
||||||
"of a ledger exactly like this notebook's and watches two independent surfaces catch it."
|
"of a ledger exactly like this notebook's and watches two independent surfaces catch it.\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,12 @@
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# Lecture 11: The Customer's-Eye View — You Hold the Ruler\n",
|
"# Lecture 11: The Customer's-Eye View \u2014 You Hold the Ruler\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Every earlier lecture looked at the log from the *operator's*\n",
|
"Every earlier lecture looked at the log from the *operator's*\n",
|
||||||
"side: replaying proofs, signing attestations, building the\n",
|
"side: replaying proofs, signing attestations, building the\n",
|
||||||
"tree. This one flips the telescope. You are now a customer — an\n",
|
"tree. This one flips the telescope. You are now a customer \u2014 an\n",
|
||||||
"agent, a wallet, a developer — who wants to trust one of the\n",
|
"agent, a wallet, a developer \u2014 who wants to trust one of the\n",
|
||||||
"four verified Ed25519 forks and has no theorem prover, no Lean,\n",
|
"four verified Ed25519 forks and has no theorem prover, no Lean,\n",
|
||||||
"no desire to spend hours re-checking anything. What actually\n",
|
"no desire to spend hours re-checking anything. What actually\n",
|
||||||
"happens on your side? The answer reframes the whole system, and\n",
|
"happens on your side? The answer reframes the whole system, and\n",
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
"\n",
|
"\n",
|
||||||
"- Separate the three roles that a verification touches:\n",
|
"- Separate the three roles that a verification touches:\n",
|
||||||
" *measurement* (operator), *publication* (the log), and\n",
|
" *measurement* (operator), *publication* (the log), and\n",
|
||||||
" *judgment* (you) — and see that only the last is yours.\n",
|
" *judgment* (you) \u2014 and see that only the last is yours.\n",
|
||||||
"- Understand the \"allowed axioms\" list as a **requirements\n",
|
"- Understand the \"allowed axioms\" list as a **requirements\n",
|
||||||
" card** you own, can read, and could write yourself.\n",
|
" card** you own, can read, and could write yourself.\n",
|
||||||
"- Explain why a self-written card meeting the supply *exactly*\n",
|
"- Explain why a self-written card meeting the supply *exactly*\n",
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## The card is a requirements card — and ideally you write it\n",
|
"## The card is a requirements card \u2014 and ideally you write it\n",
|
||||||
"\n",
|
"\n",
|
||||||
"The list of axioms a certificate is *allowed* to rest on is not\n",
|
"The list of axioms a certificate is *allowed* to rest on is not\n",
|
||||||
"handed to you by the operator at verification time. It ships\n",
|
"handed to you by the operator at verification time. It ships\n",
|
||||||
|
|
@ -85,12 +85,12 @@
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Wish meets supply — and it is no accident\n",
|
"## Wish meets supply \u2014 and it is no accident\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Now compare your self-written card against what the four forks\n",
|
"Now compare your self-written card against what the four forks\n",
|
||||||
"actually declare. They match. That convergence is *engineered*:\n",
|
"actually declare. They match. That convergence is *engineered*:\n",
|
||||||
"the supply was deliberately shrunk — every axiom made to justify\n",
|
"the supply was deliberately shrunk \u2014 every axiom made to justify\n",
|
||||||
"its existence — so that any reasonable person's independently\n",
|
"its existence \u2014 so that any reasonable person's independently\n",
|
||||||
"written card lands on the same minimal list. When the wish meets\n",
|
"written card lands on the same minimal list. When the wish meets\n",
|
||||||
"the supply exactly, it is because the supplier spent months\n",
|
"the supply exactly, it is because the supplier spent months\n",
|
||||||
"making the supply as small as honesty allows.\n"
|
"making the supply as small as honesty allows.\n"
|
||||||
|
|
@ -131,20 +131,20 @@
|
||||||
"\n",
|
"\n",
|
||||||
"Only judgment is yours, and it is the only step that involves an\n",
|
"Only judgment is yours, and it is the only step that involves an\n",
|
||||||
"opinion. The operator is trusted to *copy down what the kernel\n",
|
"opinion. The operator is trusted to *copy down what the kernel\n",
|
||||||
"printed* — never to interpret it.\n"
|
"printed* \u2014 never to interpret it.\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## If you are happy — you are already finished\n",
|
"## If you are happy \u2014 you are already finished\n",
|
||||||
"\n",
|
"\n",
|
||||||
"If your card covers the observed cone, verification is: check\n",
|
"If your card covers the observed cone, verification is: check\n",
|
||||||
"one signature, walk ~4 hashes to the signed root, compare cones\n",
|
"one signature, walk ~4 hashes to the signed root, compare cones\n",
|
||||||
"to your card. Milliseconds, standard library, no Lean. Done.\n",
|
"to your card. Milliseconds, standard library, no Lean. Done.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"## If you are NOT happy — there is nothing to negotiate\n",
|
"## If you are NOT happy \u2014 there is nothing to negotiate\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Suppose your card is stricter: *\"I require SHA-512 itself\n",
|
"Suppose your card is stricter: *\"I require SHA-512 itself\n",
|
||||||
"proven, not an oracle.\"* The system has no sales pitch for you.\n",
|
"proven, not an oracle.\"* The system has no sales pitch for you.\n",
|
||||||
|
|
@ -152,7 +152,7 @@
|
||||||
"*not in supply; SHA-512-proven is the R5 frontier; here is the\n",
|
"*not in supply; SHA-512-proven is the R5 frontier; here is the\n",
|
||||||
"exact list of what you would be accepting if you proceed\n",
|
"exact list of what you would be accepting if you proceed\n",
|
||||||
"anyway.* Your decision is never \"lower my standards\" in the\n",
|
"anyway.* Your decision is never \"lower my standards\" in the\n",
|
||||||
"abstract — it is a named line item: *SHA-512 as oracle: yes/no.*\n",
|
"abstract \u2014 it is a named line item: *SHA-512 as oracle: yes/no.*\n",
|
||||||
"Informed compromise, not diffuse trust.\n"
|
"Informed compromise, not diffuse trust.\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -180,7 +180,7 @@
|
||||||
"\n",
|
"\n",
|
||||||
"The gap between anyone's dream card and today's supply is a\n",
|
"The gap between anyone's dream card and today's supply is a\n",
|
||||||
"to-do list, not a wall. Prove SHA-512, certify the wire\n",
|
"to-do list, not a wall. Prove SHA-512, certify the wire\n",
|
||||||
"parsers, and the new certificates enter the same log — and\n",
|
"parsers, and the new certificates enter the same log \u2014 and\n",
|
||||||
"stricter cards start passing. The log is additive in exactly\n",
|
"stricter cards start passing. The log is additive in exactly\n",
|
||||||
"the way requirements are.\n",
|
"the way requirements are.\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
|
@ -211,19 +211,6 @@
|
||||||
" card and the supply)? What single action by a customer\n",
|
" card and the supply)? What single action by a customer\n",
|
||||||
" settles the argument in their favor?\n"
|
" settles the argument in their favor?\n"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"## Do it in the cockpit: the Inspect instrument\n",
|
|
||||||
"\n",
|
|
||||||
"The recomputation this notebook performs by hand is exactly what the cockpit's **Inspect**\n",
|
|
||||||
"instrument (`/inspect`) runs on paste — same deployed verifier, verbatim diagnostics —\n",
|
|
||||||
"and what the lab manual's Cryptographer session drills: verify the sample evidence, then\n",
|
|
||||||
"deliberately corrupt one character and learn the distinct failure surfaces.\n",
|
|
||||||
"`pacta wallet cockpit --demo`, then Inspect → “Load the sample evidence”."
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ COURSE = {
|
||||||
- Perform a proof hygiene scan and explain why `sorry`, local axioms, and trivial theorem targets are dangerous.
|
- Perform a proof hygiene scan and explain why `sorry`, local axioms, and trivial theorem targets are dangerous.
|
||||||
- Explain how a third-party proof-checking provider changes the trusted base.
|
- Explain how a third-party proof-checking provider changes the trusted base.
|
||||||
- Implement and verify RFC 9162-style Merkle inclusion and consistency proofs.
|
- Implement and verify RFC 9162-style Merkle inclusion and consistency proofs.
|
||||||
- Explain why Signed Tree Heads need accountable signatures, why Ed25519 is useful here, and why ML-DSA requires a real backend.
|
- Explain why Signed Tree Heads need accountable signatures, why Ed25519 is useful here, why ML-DSA requires a real backend, and how the shipped SLH-DSA co-signature differs from both.
|
||||||
- Design policy gates that convert verification evidence into consequences.
|
- Design policy gates that convert verification evidence into consequences.
|
||||||
- Read R4 four-tier apex evidence, name its residual blockers, and write a research plan toward R5 production assurance.
|
- Read R4 four-tier apex evidence, name its residual blockers, and write a research plan toward R5 production assurance.
|
||||||
"""
|
"""
|
||||||
|
|
@ -1029,6 +1029,7 @@ COURSE = {
|
||||||
|
|
||||||
- `require-signatures ed25519`: verify Ed25519 and allow ML-DSA to be unavailable.
|
- `require-signatures ed25519`: verify Ed25519 and allow ML-DSA to be unavailable.
|
||||||
- `require-signatures both`: require Ed25519 and ML-DSA verified. If ML-DSA is unavailable, fail closed.
|
- `require-signatures both`: require Ed25519 and ML-DSA verified. If ML-DSA is unavailable, fail closed.
|
||||||
|
- `--slhdsa-public-key <pem>`: additionally verify the second (post-quantum) SLH-DSA co-signature on the head; heads before tree size 14 report `absent` (allowed), a present-but-wrong signature fails closed.
|
||||||
"""
|
"""
|
||||||
),
|
),
|
||||||
code(
|
code(
|
||||||
|
|
@ -1050,6 +1051,53 @@ COURSE = {
|
||||||
ML-DSA adds post-quantum robustness for the accumulator signature layer. But it must be a real signature, not an aspirational label. If a host lacks ML-DSA, the correct result is an explicit blocker.
|
ML-DSA adds post-quantum robustness for the accumulator signature layer. But it must be a real signature, not an aspirational label. If a host lacks ML-DSA, the correct result is an explicit blocker.
|
||||||
"""
|
"""
|
||||||
),
|
),
|
||||||
|
md(
|
||||||
|
"""
|
||||||
|
## The second signature that actually shipped: SLH-DSA
|
||||||
|
|
||||||
|
Since tree size 14, every head of the LIVE log carries a second,
|
||||||
|
deterministic **SLH-DSA-SHA2-128s** (FIPS 205) signature beside the
|
||||||
|
required Ed25519 one. This is not the ML-DSA slot above - it is a
|
||||||
|
hash-based scheme, and it was chosen because the estate has PROVEN
|
||||||
|
its verify path (eleven certificates, log leaf 18): the log
|
||||||
|
co-signs with the parameter set whose verification path it itself
|
||||||
|
attests. Three design facts worth internalizing:
|
||||||
|
|
||||||
|
1. Heads published before size 14 carry no co-signature, and
|
||||||
|
verifiers report them `ABSENT` rather than failing them - an
|
||||||
|
append-only log keeps the history of its own signature-scheme
|
||||||
|
upgrades.
|
||||||
|
2. The co-signature is deterministic on purpose: re-signing the
|
||||||
|
same payload is byte-comparable, so "same input, same
|
||||||
|
signature" becomes a diff you can run, not an assurance you
|
||||||
|
must trust.
|
||||||
|
3. Signing is still never proven - here, as everywhere in this
|
||||||
|
estate, certificates cover the VERIFY path only.
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
code(
|
||||||
|
"""
|
||||||
|
# Runnable where OpenSSL >= 3.5 is present; honest skip otherwise.
|
||||||
|
import tempfile
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from pacta import slhdsa
|
||||||
|
|
||||||
|
tmp = Path(tempfile.mkdtemp(prefix="nb06-slhdsa-"))
|
||||||
|
try:
|
||||||
|
slhdsa.generate_slhdsa_keypair(tmp / "slh.key", tmp / "slh.pub")
|
||||||
|
except Exception as exc:
|
||||||
|
print("SLH-DSA unavailable on this host (OpenSSL >= 3.5 needed):", exc)
|
||||||
|
else:
|
||||||
|
payload = b"canonical STH payload bytes"
|
||||||
|
block = slhdsa.slh_dsa_signature_block(payload, tmp / "slh.key", tmp / "slh.pub")
|
||||||
|
ok, err = slhdsa.verify_payload_slhdsa(payload, block["signature_base64"], tmp / "slh.pub")
|
||||||
|
print("co-signature verifies:", ok, err or "")
|
||||||
|
block2 = slhdsa.slh_dsa_signature_block(payload, tmp / "slh.key", tmp / "slh.pub")
|
||||||
|
print("deterministic (byte-equal re-sign):",
|
||||||
|
block["signature_base64"] == block2["signature_base64"])
|
||||||
|
"""
|
||||||
|
),
|
||||||
md(
|
md(
|
||||||
"""
|
"""
|
||||||
## Two domains, two notebooks - by design
|
## Two domains, two notebooks - by design
|
||||||
|
|
@ -1749,6 +1797,7 @@ COURSE = {
|
||||||
- Modify a claim card to R2 and show that `build-library` is refused.
|
- Modify a claim card to R2 and show that `build-library` is refused.
|
||||||
- Explain why a denial artifact is useful for auditability.
|
- Explain why a denial artifact is useful for auditability.
|
||||||
- Design a policy where an agent requires `both` Ed25519 and ML-DSA signatures for production deployment but allows Ed25519-only in a local lab.
|
- Design a policy where an agent requires `both` Ed25519 and ML-DSA signatures for production deployment but allows Ed25519-only in a local lab.
|
||||||
|
- Extend it: when should the agent also require the SLH-DSA co-signature, given that heads before tree size 14 legitimately lack it?
|
||||||
- Write a downstream Rust pseudo-code snippet that imports the generated capsule before enabling a code path.
|
- Write a downstream Rust pseudo-code snippet that imports the generated capsule before enabling a code path.
|
||||||
"""
|
"""
|
||||||
),
|
),
|
||||||
|
|
@ -1770,7 +1819,7 @@ COURSE = {
|
||||||
- State precisely which parts of the dogfood verifier are certificate-covered and which are its trusted base.
|
- State precisely which parts of the dogfood verifier are certificate-covered and which are its trusted base.
|
||||||
- Extract a raw Ed25519 key from an OpenSSL PEM by hand (napkin) and mechanically (real).
|
- Extract a raw Ed25519 key from an OpenSSL PEM by hand (napkin) and mechanically (real).
|
||||||
- Demonstrate backend dispatch and the fail-closed `--require-verified-verifier` policy.
|
- Demonstrate backend dispatch and the fail-closed `--require-verified-verifier` policy.
|
||||||
- Defend the hybrid post-quantum posture: one proven-classical signature plus one required-but-honest ML-DSA slot.
|
- Defend the three-legged post-quantum posture: proven-classical Ed25519, the shipped SLH-DSA co-signature with its attested verify path, and a required-but-honest ML-DSA slot.
|
||||||
"""
|
"""
|
||||||
),
|
),
|
||||||
md(
|
md(
|
||||||
|
|
@ -1858,7 +1907,8 @@ COURSE = {
|
||||||
leaf, against the very tree it is about to sign. The verdict is
|
leaf, against the very tree it is about to sign. The verdict is
|
||||||
embedded in the signature block (`signing_provenance`: backend,
|
embedded in the signature block (`signing_provenance`: backend,
|
||||||
library commit, leaf index, `self_inclusion: verified`,
|
library commit, leaf index, `self_inclusion: verified`,
|
||||||
certificates 16/16). Lectures 6a/6b walk both sides of this.
|
certificates 44/44 - the signer's source family was re-attested at 44
|
||||||
|
certificates as leaf 13). Lectures 6a/6b walk both sides of this.
|
||||||
Honesty note unchanged: the library's VERIFY path is
|
Honesty note unchanged: the library's VERIFY path is
|
||||||
certificate-covered; the signing path is declared trusted base -
|
certificate-covered; the signing path is declared trusted base -
|
||||||
but it is the attested artifact, not an un-attested third
|
but it is the attested artifact, not an un-attested third
|
||||||
|
|
@ -1866,12 +1916,13 @@ COURSE = {
|
||||||
|
|
||||||
## The post-quantum line, held honestly
|
## The post-quantum line, held honestly
|
||||||
|
|
||||||
The dogfood loop deliberately does NOT extend to ML-DSA. There is no formally verified ML-DSA implementation in this corpus, and pretending otherwise would poison the whole posture. The hybrid strategy is therefore asymmetric on purpose:
|
The posture has three legs now, and each is exactly as strong as it claims:
|
||||||
|
|
||||||
- **Ed25519 (classical): proven path.** The signature everyone can check today runs on certificate-covered code.
|
- **Ed25519 (classical): proven verify path, dogfooded.** The signature everyone can check today runs on certificate-covered code.
|
||||||
- **ML-DSA-65 (post-quantum): required, honest, unavailable-until-real.** The tree-head slot exists in every signed structure; `--require-signatures both` fails CLOSED on hosts without a real FIPS 204 backend; and when a real backend lands, the policy flips on without a schema change.
|
- **SLH-DSA-SHA2-128s (post-quantum): shipped and attested.** Since tree size 14 every live head carries a second, deterministic SLH-DSA co-signature. The estate proved the VERIFY path of a pinned Rust FIPS 205 implementation (eleven certificates) and appended that attestation as leaf 18 - so the co-signature uses exactly the parameter set the log itself attests. Consumers check it with `pacta receipt-verify ... --slhdsa-public-key provider.slhdsa.pub` or the mirror's `verify.py`. Signing remains unproven - verify paths only, always.
|
||||||
|
- **ML-DSA-65 (lattice PQ): required, honest, unavailable-until-real.** The tree-head slot exists in every signed structure; `--require-signatures both` fails CLOSED on hosts without a real FIPS 204 backend; when a real backend lands, the policy flips on without a schema change.
|
||||||
|
|
||||||
A migration strategy that records "we cannot do this yet" as a deployment blocker is strictly stronger than one that ships a placeholder. Blockers get fixed; placeholders get trusted.
|
A migration strategy that records "we cannot do this yet" as a deployment blocker is strictly stronger than one that ships a placeholder. Blockers get fixed; placeholders get trusted. And the SLH-DSA leg shows the endgame: a slot stops being aspirational the day its verify path enters the log.
|
||||||
"""
|
"""
|
||||||
),
|
),
|
||||||
code(
|
code(
|
||||||
|
|
@ -2310,6 +2361,23 @@ COURSE = {
|
||||||
trusted for after you do.
|
trusted for after you do.
|
||||||
"""
|
"""
|
||||||
),
|
),
|
||||||
|
md(
|
||||||
|
"""
|
||||||
|
## The human surface: see this wallet through the cockpit
|
||||||
|
|
||||||
|
Everything this notebook built programmatically has a read-only human console:
|
||||||
|
|
||||||
|
```
|
||||||
|
pacta wallet cockpit --demo # throwaway demo wallet, zero setup
|
||||||
|
pacta wallet cockpit --wallet DIR # the wallet you just sealed here
|
||||||
|
```
|
||||||
|
|
||||||
|
Open `/deck` for all six role stations live in parallel (the quorum bench you built is the
|
||||||
|
indigo pane; the ledger you hash-chained is re-verified on every page load), and `/manual`
|
||||||
|
for the lab-manual sessions that teach each role — Session 4's tamper drill breaks a *copy*
|
||||||
|
of a ledger exactly like this notebook's and watches two independent surfaces catch it.
|
||||||
|
"""
|
||||||
|
),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
"11_the_customers_eye_view.ipynb": notebook(
|
"11_the_customers_eye_view.ipynb": notebook(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue