summaryrefslogtreecommitdiffstats
path: root/docs/FOG-PKI.md
diff options
context:
space:
mode:
authorGab <24553253+gabrix73@users.noreply.github.com>2026-08-18 21:43:48 +0200
committerGab <24553253+gabrix73@users.noreply.github.com>2026-08-18 21:43:48 +0200
commit25356debcce4118cdfa86842029278fde1e64518 (patch)
treee2b681576fb7163ee83006a74b62013e63706c29 /docs/FOG-PKI.md
parent6974e5459608feed48c611c76622226d2fc4fe26 (diff)
downloadfog-25356debcce4118cdfa86842029278fde1e64518.tar.gz
fog-25356debcce4118cdfa86842029278fde1e64518.tar.xz
fog-25356debcce4118cdfa86842029278fde1e64518.zip
Publish FOG design documentation and Merkle tree
Diffstat (limited to 'docs/FOG-PKI.md')
-rw-r--r--docs/FOG-PKI.md1814
1 files changed, 1814 insertions, 0 deletions
diff --git a/docs/FOG-PKI.md b/docs/FOG-PKI.md
new file mode 100644
index 0000000..4bc0ebd
--- /dev/null
+++ b/docs/FOG-PKI.md
@@ -0,0 +1,1814 @@
+# FOG Public Key Infrastructure
+
+Status: Draft 0.1
+
+Date: 2026-08-08
+
+## 1. Purpose
+
+This document defines `FOG-PKI-1`, the normative directory, admission,
+authority, consensus, revocation, topology, and transparency protocol for the
+FOG network.
+
+It refines the following baselines:
+
+- `FOG-THREAT-MODEL.md`, especially `TM-NET-06`, `TM-PKI-01`,
+ `TM-PKI-02`, `TM-PKI-03`, `TM-CRYPTO-01`, `TM-CRYPTO-02`, and
+ `TM-AVAIL-01`;
+- `FOG-ARCHITECTURE.md`, especially `ARC-005`, `ARC-007`, `ARC-008`,
+ `ARC-009`, `IF-03`, `IF-04`, and `IF-05`.
+
+FOG is not implemented. Requirements in this document are protocol targets,
+not statements about deployed security.
+
+The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, and MAY describe
+normative requirements in the sense of BCP 14 when they appear in uppercase.
+
+## 2. Security Goals
+
+FOG-PKI MUST provide:
+
+- one complete authenticated network view for a given epoch;
+- M-of-N authority approval over identical canonical consensus bytes;
+- public attribution of every authority signature;
+- deterministic topology and parameter derivation from public inputs;
+- permissioned admission and public role assignment;
+- purpose-separated current and future node public keys;
+- explicit validity, freshness, grace, and hard-expiry semantics;
+- monotonic state that detects rollback and same-epoch forks;
+- append-only consistency evidence for long-offline Composers;
+- bounded key overlap, rotation, revocation, and authority replacement;
+- public operator-family constraints for route selection;
+- bounded deterministic parsing and offline verification;
+- auditable evidence for authority, node, and checkpoint equivocation.
+
+FOG-PKI does not provide:
+
+- permissionless Sybil resistance;
+- proof that nominally different operators are independent;
+- availability after authority quorum loss;
+- trusted time to an endpoint with no reliable clock;
+- secrecy for public topology or node addresses;
+- safety after compromise of the configured authority threshold;
+- automatic recovery from loss of the pinned authority roots;
+- anonymity by itself.
+
+## 3. Protocol Invariants
+
+### PKI-INV-01: Independent quorum signatures
+
+A valid consensus carries at least M valid signatures from distinct active
+authorities over one identical canonical body. `FOG-PKI-1` does not use one
+shared threshold private key.
+
+### PKI-INV-02: Sign once per epoch
+
+An authority MUST sign at most one consensus body hash for one network and
+epoch. It MUST durably record that body hash before releasing its signature.
+
+### PKI-INV-03: Full view only
+
+Consumers MUST validate a full consensus. They MUST NOT merge descriptors,
+signatures, topology, parameters, or revocations from different consensus
+bodies.
+
+### PKI-INV-04: Monotonic acceptance
+
+A consumer MUST persist the highest accepted authority-set version, consensus
+epoch, consensus hash, and transparency checkpoint. Older or conflicting state
+MUST NOT replace it through an ordinary update.
+
+### PKI-INV-05: Offline roots, online voting keys
+
+Long-term authority root keys certify bounded-lifetime online voting keys.
+Online voting keys sign routine protocol objects. Root private keys MUST NOT be
+present on an online authority service.
+
+### PKI-INV-06: No self-authorized algorithms
+
+The signature and hash suite used to authenticate an object MUST be pinned by
+already trusted state. An object MUST NOT select the algorithm by which its own
+authenticity is decided.
+
+### PKI-INV-07: One node identity, one role
+
+One node identity has exactly one effective online role in an epoch. Layer
+assignment is made by consensus, not self-declared by a node.
+
+### PKI-INV-08: Fail closed at hard expiry
+
+After consensus hard expiry, consumers MUST stop constructing new routes and
+nodes MUST stop accepting new work under that consensus. Only explicitly
+bounded drain and packet-lifetime behavior may continue.
+
+### PKI-INV-09: Public decisions, minimal personal data
+
+Admissions, assignments, suspensions, revocations, authority transitions, and
+equivocation evidence are public. Personal names, private contact details,
+credentials, and sensitive supporting evidence MUST NOT enter public PKI
+objects.
+
+### PKI-INV-10: No trust on first use recovery
+
+Unknown authority, node, operator, mirror, witness, or replacement keys MUST
+NOT become trusted because they are the only reachable keys.
+
+## 4. Roles and Trust
+
+### 4.1 Authority root operator
+
+The root operator controls one authority root key in an offline ceremony. The
+root key certifies that authority's online vote keys and participates in
+authority-set transitions.
+
+### 4.2 Online authority
+
+`fog-authority` accepts descriptors, exchanges protocol messages, constructs
+deterministic proposals, signs one consensus body per epoch, and publishes
+public artifacts. It has no privileged data-plane route.
+
+### 4.3 Operator
+
+An operator controls an operator identity and one or more separately keyed
+nodes. The operator declares common control, infrastructure relationships, and
+role requests. Admission does not prove honesty or independence.
+
+### 4.4 Node
+
+A node signs its descriptor and proves possession of its node identity. It
+publishes only the role-specific public keys and endpoints needed by the
+network.
+
+### 4.5 Mirror
+
+A mirror distributes immutable public objects. It is untrusted for
+authenticity, freshness, completeness, and consistency.
+
+### 4.6 Witness or monitor
+
+A witness independently fetches, compares, archives, and republishes consensus
+and transparency checkpoints. Witnesses improve detection but do not replace
+the authority quorum.
+
+### 4.7 Consumer
+
+Consumers are Composers, blind relays, entries, mixes, couriers, storage
+replicas, services, and observers. Each maintains role-appropriate monotonic
+PKI state. The offline Composer is the final authority for user route
+construction.
+
+## 5. Authority Set and Quorum
+
+An authority set contains:
+
+- an exact authority-set version;
+- an odd number N of authority roots;
+- a quorum M where `floor(N / 2) + 1 <= M <= N`;
+- one stable identifier and root public key per authority;
+- the permitted online signing suites;
+- activation and retirement epochs;
+- the transparency-log identifier;
+- the hash of the previous authority-set manifest.
+
+The initial claim-bearing profile uses N = 3 and M = 2. A later preferred
+profile uses N = 5 and M = 3. A local PoC MAY use a simulated smaller set, but
+the resulting consensus is functional test data only.
+
+Consensus signatures are independent signatures. A signature record names its
+authority and certified online key. A verifier counts at most one valid
+signature per active authority.
+
+Signatures from unknown, duplicate, expired, revoked, not-yet-active, or
+wrong-set keys do not count. Extra invalid signatures MUST make the envelope
+invalid instead of being silently ignored, because inconsistent validation
+would create implementation fingerprints.
+
+## 6. `FOG-PKI-CBOR-1` Encoding
+
+FOG-PKI objects use a restricted deterministic CBOR profile based on RFC 8949.
+This profile is named `FOG-PKI-CBOR-1`.
+
+Every signed object has the form:
+
+```text
+SignedObject = [
+ magic,
+ encoding_version,
+ object_type,
+ body
+]
+```
+
+where:
+
+- `magic` is the byte string `FOGPKI1`;
+- `encoding_version` is unsigned integer `1`;
+- `object_type` is a registered unsigned integer;
+- `body` is an exact-length array defined by this specification.
+
+An authenticated envelope has the form:
+
+```text
+SignedEnvelope = [
+ signed_object_bytes,
+ signatures
+]
+
+SignatureRecord = [
+ authority_or_subject_id,
+ key_id,
+ signature_suite_id,
+ signature_bytes
+]
+```
+
+`signed_object_bytes` is a CBOR byte string containing the exact canonical
+encoding of `SignedObject`. A verifier MUST parse it, enforce this profile,
+re-encode it, and require byte-for-byte equality before checking signatures.
+
+The profile permits only:
+
+- unsigned integers in their shortest encoding;
+- definite-length byte strings;
+- definite-length UTF-8 text strings where a field explicitly permits text;
+- definite-length arrays with exact schema length.
+
+The profile forbids:
+
+- negative integers;
+- maps;
+- floating-point values;
+- tags;
+- simple values, including `null`, `true`, and `false`;
+- indefinite-length items;
+- duplicate set elements;
+- unsorted set-like arrays;
+- trailing bytes or concatenated objects.
+
+Boolean fields use unsigned integer `0` or `1`. Optional fields use an
+explicit variant discriminator and exact variant array, never `null`.
+
+Set-like arrays MUST be sorted by the canonical byte encoding of the complete
+element and MUST contain no duplicate element. Ordered protocol sequences MUST
+retain their specified order and MUST NOT be sorted.
+
+Unknown object types, versions, fields, enum values, key purposes, signature
+suites, hash suites, roles, parameters, or extensions are critical and MUST be
+rejected in version 1.
+
+## 7. Object Types
+
+`FOG-PKI-1` reserves the following object types:
+
+| Value | Object |
+| --- | --- |
+| 1 | `TrustAnchorManifest` |
+| 2 | `AuthorityOnlineKeyCertificate` |
+| 3 | `OperatorRecord` |
+| 4 | `AdmissionDecision` |
+| 5 | `NodeDescriptor` |
+| 6 | `AuthorityCommit` |
+| 7 | `AuthorityReveal` |
+| 8 | `AuthorityProposal` |
+| 9 | `ConsensusBody` |
+| 10 | `RevocationStatement` |
+| 11 | `AuthoritySetTransition` |
+| 12 | `EpochArchive` |
+| 13 | `LogCheckpoint` |
+| 14 | `EquivocationEvidence` |
+| 15 | `RecoveryManifest` |
+| 16 | `ProfileTransition` |
+| 17 | `AuthorityWireKeyCertificate` |
+| 18 | `StorageReplicaManifest` |
+
+Object type assignments never change meaning. Incompatible schemas require a
+new encoding or object version.
+
+## 8. Domain Separation and Identifiers
+
+The trusted PKI suite defines one approved hash construction and its output
+length. All hashes use a distinct ASCII domain string encoded as the first
+element of a canonical CBOR array.
+
+Examples:
+
+```text
+key_id = HASH(["FOG-PKI-KEY-ID-1", algorithm_id, public_key])
+authority_id = HASH(["FOG-PKI-AUTHORITY-ID-1", root_key_id])
+operator_id = HASH(["FOG-PKI-OPERATOR-ID-1", operator_key_id])
+node_id = HASH(["FOG-PKI-NODE-ID-1", node_identity_key_id])
+object_hash = HASH(["FOG-PKI-OBJECT-1", signed_object_bytes])
+consensus_hash = HASH(["FOG-PKI-CONSENSUS-1", consensus_body_bytes])
+descriptor_hash = HASH(["FOG-PKI-DESCRIPTOR-1", descriptor_bytes])
+storage_manifest_hash = HASH([
+ "FOG-PKI-STORAGE-MANIFEST-1",
+ storage_manifest_bytes
+])
+```
+
+Signature input is the canonical encoding of:
+
+```text
+[
+ "FOG-PKI-SIGNATURE-1",
+ network_id,
+ object_type,
+ signature_suite_id,
+ signed_object_bytes
+]
+```
+
+The exact strings above are part of version 1 and are case-sensitive. Binding
+`signature_suite_id` prevents a valid component from being rewrapped under a
+different signature suite over otherwise identical object bytes.
+
+`network_id` is a uniformly random 32-byte value created at genesis and pinned
+in the initial trust-anchor manifest. It is not derived from a DNS name,
+project title, mirror, or operator identity.
+
+Identifiers are public correlation handles inside PKI. They MUST NOT be reused
+as message identities, user accounts, storage capabilities, transport secrets,
+or release identities.
+
+## 9. Absolute Parser Limits
+
+All implementations MUST enforce these absolute version-1 limits before
+allocation proportional to attacker input:
+
+| Item | Limit |
+| --- | --- |
+| Any `SignedEnvelope` | 8 MiB |
+| One `PKIUpdateBundle` | 16 MiB |
+| One `NodeDescriptor` envelope | 128 KiB |
+| One `StorageReplicaManifest` envelope | 1 MiB |
+| One proof bundle | 1 MiB |
+| Nesting depth | 8 arrays |
+| Authorities | 9 |
+| Authority signatures | 9 |
+| Operators | 512 |
+| Nodes in one consensus | 1024 |
+| Endpoints per node | 4 |
+| Family or infrastructure groups per node | 16 |
+| Epoch public keys per node | 24 |
+| Active protocol profiles | 32 |
+| Storage manifests per consensus | 3 |
+| Replica records per storage manifest | 256 |
+| Revocation entries per consensus | 4096 |
+| Text field | 128 UTF-8 bytes |
+| One public key or signature component | 128 KiB |
+
+The initial deployment profile MAY set lower limits. Increasing an absolute
+limit requires a new PKI version and parser review. FOG-PKI uses no compression
+in version 1.
+
+## 10. Trust Bootstrap
+
+### 10.1 Genesis material
+
+A new Composer or node begins with:
+
+- the 32-byte `network_id`;
+- one exact genesis `TrustAnchorManifest` hash;
+- the full genesis manifest;
+- the release-verification trust anchor used for the software image;
+- the initial transparency checkpoint;
+- the accepted PKI encoding and cryptographic suite identifiers.
+
+The genesis manifest is a trust anchor. Self-signatures do not create its
+trust. Its hash MUST be pinned in the verified software release and SHOULD be
+available through at least one independent human-verifiable channel.
+
+DNS, TLS, a mirror, the blind relay, a QR label, or a reachable authority MUST
+NOT replace the pinned genesis hash.
+
+### 10.2 `TrustAnchorManifest`
+
+The manifest body is:
+
+```text
+[
+ network_id,
+ manifest_version,
+ previous_manifest_hash,
+ activation_epoch,
+ retirement_epoch,
+ quorum_m,
+ authority_roots,
+ pki_authentication_suite_id,
+ allowed_object_suite_ids,
+ transparency_log_id,
+ epoch_origin,
+ epoch_duration,
+ schedule_profile_id,
+ hard_limits_profile_id
+]
+```
+
+`authority_roots` is a sorted array of:
+
+```text
+[
+ authority_id,
+ root_key_id,
+ root_signature_algorithm_id,
+ root_public_key,
+ public_alias
+]
+```
+
+`public_alias` is an informational pseudonymous label. It is not an identity
+proof and MUST NOT contain private contact information. It is 1 to 64 bytes
+from ASCII letters, digits, `.`, `_`, and `-`; it need not be globally unique
+and MUST NOT be used in security decisions.
+
+Genesis uses an all-zero `previous_manifest_hash`. Later manifests are
+accepted only through the transition procedure in Section 22.
+
+`manifest_version` is the `authority_set_version` used by certificates,
+consensus, checkpoints, and transitions. The two terms describe the same
+monotonic unsigned integer.
+
+## 11. Authority Key Hierarchy
+
+### 11.1 Authority root key
+
+Each authority has one active offline root identity at a time. Its root private
+key:
+
+- certifies that authority's online voting keys;
+- certifies that authority's dedicated online FOG-WIRE keys;
+- signs authority-set transitions;
+- signs root-key replacement or retirement;
+- participates in authenticated disaster recovery.
+
+It MUST NOT sign routine consensus, descriptor, commit, reveal, proposal,
+checkpoint, or admission objects.
+
+The root private key MUST be generated and used in an offline ceremony. Backup
+material MUST be encrypted, authenticated, geographically separated where
+appropriate, and stored separately from its decryption or recovery secret.
+
+### 11.2 Online vote key
+
+An online voting key signs routine authority protocol objects. It is certified
+by its authority root in an `AuthorityOnlineKeyCertificate`:
+
+```text
+[
+ network_id,
+ authority_set_version,
+ authority_id,
+ online_key_generation,
+ online_key_id,
+ online_signature_suite_id,
+ online_public_key,
+ valid_from_epoch,
+ valid_until_epoch,
+ previous_certificate_hash
+]
+```
+
+The certificate is signed by the matching authority root. An online key
+certificate MUST cover no more than 32 epochs. One current and one next online
+key certificate MAY overlap for at most two epochs.
+
+Consensus validation uses the online key valid for the consensus epoch. A key
+outside its certified interval cannot sign that epoch even if its certificate
+has not been explicitly revoked.
+
+### 11.3 Authority wire key
+
+An authority uses a dedicated online wire key for mutually authenticated
+`FOG-WIRE` links with peer authorities and admitted descriptor submitters. It
+MUST NOT reuse the authority root key or online vote key for transport.
+
+The wire key is certified by the matching authority root in an
+`AuthorityWireKeyCertificate`:
+
+```text
+[
+ network_id,
+ authority_set_version,
+ authority_id,
+ wire_key_generation,
+ wire_key_id,
+ wire_algorithm_id,
+ wire_public_key,
+ supported_wire_profile_ids,
+ valid_from_epoch,
+ valid_until_epoch,
+ previous_certificate_hash
+]
+```
+
+`supported_wire_profile_ids` is sorted and duplicate-free. Every listed
+profile MUST already be trusted and MUST require the declared key algorithm.
+The certificate does not authorize its own algorithm or wire profile.
+
+The certificate is signed by the matching offline authority root. It MUST
+cover no more than 32 epochs. One current and one next authority wire-key
+certificate MAY overlap for at most two epochs. There MUST be exactly one
+valid wire key for one authority, profile, and epoch, unless one already
+trusted profile defines a composite key as one key record.
+
+An authority wire key authenticates only `NODE_AUTHORITY` and
+`AUTHORITY_AUTHORITY` contexts from `FOG-WIRE-1`. It MUST NOT sign votes,
+consensus, checkpoints, admission decisions, descriptors, releases, or user
+objects.
+
+### 11.4 Signature-suite composition
+
+A suite MAY require more than one signature component, including a classical
+and post-quantum component. A composite signature is valid only when every
+mandatory component in the already trusted suite validates over the same
+signature input.
+
+Components from different signature records, objects, keys, or authorities
+MUST NOT be combined to manufacture one valid composite signature.
+
+`FOG-PKI-HASH-CANDIDATE-SHA3-256-1` and
+`FOG-PKI-CANDIDATE-MLDSA65-ED25519-1` are the leading non-active candidates.
+The latter requires independently generated ML-DSA-65 and Ed25519 keys and
+requires both components over the exact suite-bound signature input. Their
+encoding, vectors, separability analysis, implementation, side-channel review,
+and numeric activation remain pre-PoC gates. Algorithm names or post-quantum
+labels alone do not satisfy review.
+
+## 12. Operator Identity and Family Records
+
+An operator uses one dedicated signing identity that is separate from node,
+authority, release, user, and infrastructure login keys.
+
+An `OperatorRecord` contains:
+
+```text
+[
+ network_id,
+ operator_id,
+ operator_key_id,
+ operator_signature_algorithm_id,
+ operator_public_key,
+ public_alias,
+ family_ids,
+ infrastructure_group_ids,
+ declared_provider_codes,
+ declared_as_numbers,
+ declared_country_codes,
+ record_sequence,
+ valid_from_epoch,
+ valid_until_epoch
+]
+```
+
+The operator signs the record, and admission authorities approve its hash.
+
+`family_ids` describe known common control or cooperation across operator
+identities. `infrastructure_group_ids` describe shared provider accounts,
+orchestration, management, backup, monitoring, corporate ownership, or other
+common compromise domains.
+
+Authorities MAY conservatively merge family or infrastructure groups when
+credible evidence indicates common control. They MUST NOT split an existing
+group without an ordinary threshold decision and a public rationale code.
+
+Provider, ASN, and country declarations are public routing inputs, not proof
+of operator independence. Route selection MUST reject reuse of one operator,
+family, or prohibited infrastructure group where the active profile requires
+diversity.
+
+Public records MUST NOT contain legal names, personal email addresses, phone
+numbers, billing identifiers, street addresses, login names, or private abuse
+reports. Authorities MAY maintain a separate access-controlled admission file,
+but its content is outside consensus and MUST NOT be required by clients.
+
+## 13. Permissioned Admission
+
+### 13.1 Application
+
+The initial network is permissioned. An operator applies with:
+
+- its signed `OperatorRecord`;
+- the node identity public key and proof of possession;
+- requested role and capabilities;
+- canonical endpoints;
+- future role-specific public keys;
+- declared family and infrastructure relationships;
+- operational and policy evidence required by governance.
+
+Private supporting evidence is not placed in the public application object.
+
+### 13.2 Decision
+
+An `AdmissionDecision` contains:
+
+```text
+[
+ network_id,
+ decision_sequence,
+ subject_type,
+ subject_id,
+ operator_record_hash,
+ requested_role,
+ disposition,
+ public_reason_code,
+ constraints,
+ effective_epoch,
+ expiry_epoch
+]
+```
+
+`disposition` is one of admit, deny, suspend, reinstate, or retire. It uses a
+registered unsigned integer, not text.
+
+Ordinary admission, role change, reinstatement, and retirement require M
+independent authority signatures. A single authority cannot admit a node.
+
+Admission binds one node identity to one operator and one eligible role. A
+role change requires a new decision. Admission does not assign a mix layer;
+the consensus topology does.
+
+### 13.3 Reapplication and replacement
+
+A revoked node identity MUST NOT be reused. A replacement generates a new node
+identity and follows ordinary admission. A changed endpoint or role-specific
+key does not require a new node identity if a valid monotonic descriptor and
+the existing admission constraints permit the change.
+
+## 14. Node Identity and Descriptor
+
+### 14.1 Node identity
+
+Every online node has one role-local node identity signing key. It signs
+descriptors and proves continuity across epoch-key rotation. It MUST NOT be
+used for Noise transport, KEMSphinx, entry capsules, storage envelopes,
+metrics, release signing, or operator administration.
+
+### 14.2 Descriptor body
+
+A `NodeDescriptor` contains:
+
+```text
+[
+ network_id,
+ descriptor_version,
+ descriptor_sequence,
+ node_id,
+ node_identity_key_id,
+ node_identity_algorithm_id,
+ node_identity_public_key,
+ operator_id,
+ operator_record_hash,
+ admitted_role,
+ capability_ids,
+ endpoints,
+ epoch_public_keys,
+ supported_profile_ids,
+ valid_from_epoch,
+ valid_until_epoch,
+ previous_descriptor_hash
+]
+```
+
+It is signed independently by the node identity and operator identity. Both
+signatures are required.
+
+`descriptor_sequence` starts at zero and increases by exactly one for each
+accepted replacement descriptor. A new descriptor names the previous accepted
+descriptor hash. A gap, rollback, duplicate sequence with a different hash, or
+broken chain is invalid.
+
+One descriptor MUST cover no more than four consecutive epochs. It MUST carry
+the public keys required for its current and next usable key periods without
+extending private-key overlap beyond the owning protocol profile.
+
+### 14.3 Endpoints
+
+An endpoint is:
+
+```text
+[
+ transport_profile_id,
+ address_type,
+ address_bytes,
+ port,
+ priority_class
+]
+```
+
+Only endpoint forms explicitly permitted by the active wire profile are
+valid. An endpoint MUST NOT contain a URL path, username, password, API token,
+query string, fragment, or unauthenticated redirect target.
+
+DNS-only identity is forbidden. If a profile permits DNS discovery, the
+descriptor still binds the node identity and authenticated endpoint behavior;
+DNS never authorizes a different node key.
+
+### 14.4 Epoch public keys
+
+Each public key entry is:
+
+```text
+[
+ purpose_id,
+ algorithm_id,
+ key_id,
+ public_key,
+ valid_from_epoch,
+ valid_until_epoch
+]
+```
+
+Purpose IDs distinguish at least:
+
+- node Noise transport;
+- entry submission capsule;
+- entry return KEMSphinx terminal processing where required;
+- mix KEMSphinx transformation;
+- courier or service terminal KEMSphinx processing;
+- replica envelope protection;
+- replica durable-result receipt authentication;
+- aggregate signing.
+
+A descriptor MUST contain exactly the key purposes required by its admitted
+role and MUST NOT contain keys for another role. The current and next key
+periods MUST be published before the descriptor deadline. More than one active
+key for the same purpose and epoch is invalid unless the active suite defines
+one composite key as a single key record.
+
+Private keys never enter a descriptor, vote, consensus, proof, log, example,
+fixture, or support artifact.
+
+## 15. Epoch and Time Model
+
+The genesis manifest pins:
+
+- `epoch_origin`, an unsigned Unix-time second;
+- `epoch_duration`, a whole number of seconds;
+- one schedule profile;
+- maximum clock uncertainty;
+- consensus freshness and hard-expiry offsets;
+- descriptor, commit, reveal, proposal, signature, and publication deadlines;
+- packet and key grace constraints supplied by the owning protocol profiles.
+
+Epoch number at time `t` is:
+
+```text
+floor((t - epoch_origin) / epoch_duration)
+```
+
+for `t >= epoch_origin`.
+
+The exact initial epoch duration and schedule offsets remain a pre-PoC
+operational selection. They MUST be identical for all participants, encoded in
+the trust manifest, and supported by fault-injection tests. Operators cannot
+override them locally.
+
+Changing epoch origin, duration, schedule, or maximum clock uncertainty
+requires an authority-set manifest transition with at least two epochs of
+advance notice. It is not an ordinary consensus parameter change.
+
+Consumers MUST evaluate time with an explicit local uncertainty interval. A
+relay-provided timestamp, mirror `Date` header, DNS response, or single time
+server is not trusted time. If the uncertainty interval cannot establish
+validity, the consumer fails closed for new work.
+
+## 16. Authority Protocol State Machine
+
+For target epoch E, each online authority executes these phases.
+
+### 16.1 Collect
+
+Authorities collect valid descriptors, operator records, admission decisions,
+revocations, online key certificates, and announced transitions before the
+descriptor deadline.
+
+Inputs arriving after the deadline are considered only for a later epoch.
+Authorities MUST NOT create different inclusion behavior based on requester
+latency after the public deadline.
+
+### 16.2 Commit
+
+Each authority generates a fresh uniformly random secret for epoch E and
+publishes a signed `AuthorityCommit`:
+
+```text
+[
+ network_id,
+ authority_set_version,
+ epoch,
+ authority_id,
+ commitment,
+ previous_consensus_epoch,
+ previous_consensus_hash
+]
+```
+
+The commitment is the suite hash of a domain-separated encoding containing
+the network, epoch, authority, random secret, and previous consensus hash.
+
+Exactly:
+
+```text
+commitment = HASH([
+ "FOG-PKI-COMMIT-1",
+ network_id,
+ authority_set_version,
+ epoch,
+ authority_id,
+ previous_consensus_epoch,
+ previous_consensus_hash,
+ random_secret
+])
+```
+
+### 16.3 Reveal
+
+After the commit deadline, each authority publishes a signed
+`AuthorityReveal` containing the secret corresponding to its prior commitment.
+Reveals without one valid timely commit, invalid reveals, duplicates, or early
+reveals are excluded and recorded.
+
+If fewer than M authorities provide valid commit/reveal pairs, no consensus is
+produced.
+
+The shared seed is derived from the previous consensus hash and the sorted
+valid authority reveals using the pinned hash suite:
+
+```text
+shared_seed = HASH([
+ "FOG-PKI-SHARED-SEED-1",
+ network_id,
+ authority_set_version,
+ epoch,
+ previous_consensus_epoch,
+ previous_consensus_hash,
+ sorted_reveals
+])
+
+sorted_reveals = [
+ [authority_id, random_secret],
+ ...
+]
+```
+
+The complete commit and reveal hashes are included in the consensus audit
+section. `sorted_reveals` is sorted by `authority_id` and contains no duplicate
+authority.
+
+Commit-reveal limits unilateral prediction but permits withholding and denial
+of service by a last revealer. FOG-PKI does not claim bias-free randomness from
+this construction. Topology stability and deterministic public auditing limit
+where the seed is security-critical.
+
+### 16.4 Propose
+
+Each authority independently applies the exact deterministic rules in this
+specification to the same eligible input set. It signs and exchanges an
+`AuthorityProposal` containing the resulting consensus body hash and sorted
+input object hashes.
+
+Authorities MUST NOT average, merge, or majority-vote individual fields from
+different proposals. A body is signable only when at least M authorities have
+published identical proposal body and input hashes.
+
+### 16.5 Sign
+
+Before signing, an authority:
+
+1. validates its active online key certificate;
+2. recomputes the complete canonical consensus body;
+3. verifies the previous consensus and authority-set chain;
+4. persists `(network_id, epoch, consensus_hash)` in durable sign-once state;
+5. refuses if any different hash is already stored for that epoch;
+6. signs the canonical `ConsensusBody` object.
+
+The sign-once record MUST survive restart, restore, and failover. Cloning an
+authority database into two active signers is forbidden.
+
+### 16.6 Publish
+
+Authorities exchange detached signatures. Any publisher can assemble a valid
+`ConsensusEnvelope` only by attaching at least M distinct valid signatures to
+the exact body bytes.
+
+Authorities publish the body, all signature records, relevant certificates,
+input hashes, epoch archive, and transparency material. Mirrors may copy these
+bytes but cannot modify them.
+
+Signature collection closes at the public signature deadline. The final
+sorted signature-record set is committed by the epoch archive before
+`valid_after`. A later signature over the same body remains evidence of that
+authority's statement but MUST NOT be inserted into the finalized consensus
+envelope for that epoch.
+
+## 17. Deterministic Eligibility and Topology
+
+### 17.1 Eligibility filtering
+
+A node is eligible for epoch E only if:
+
+- its admission is active for E;
+- its operator record is active and threshold-approved;
+- its descriptor chain and both descriptor signatures validate;
+- the descriptor covers E and has the required future key material;
+- it is not suspended or revoked;
+- every endpoint, key, capability, and profile is permitted;
+- its role does not conflict with another identity or active assignment;
+- its operator and infrastructure declarations meet the active profile.
+
+All filtering operates on canonical public data and deterministic reason
+codes. Private authority evidence may cause a signed public suspension or
+revocation decision, but it MUST NOT silently change deterministic evaluation.
+
+### 17.2 Effective roles
+
+The consensus assigns each eligible node exactly one of:
+
+- entry;
+- mix layer 1;
+- mix layer 2;
+- mix layer 3;
+- courier;
+- storage replica;
+- declared native service;
+- observer.
+
+The node requests an admitted role. Only mix layer number is assigned by the
+consensus topology algorithm. A node cannot self-place into a layer.
+
+### 17.3 Topology generation
+
+Layer assignment remains stable within one `topology_generation`. A new
+generation is created only for admission, removal, capacity change, diversity
+repair, or deliberate rebalance. Routine epoch key rotation MUST NOT reshuffle
+all mix layers.
+
+For a new generation:
+
+1. eligible nodes are grouped by role;
+2. each group is sorted by `node_id`;
+3. the shared seed drives a suite-defined deterministic pseudorandom shuffle
+ using unbiased sampling;
+4. mix nodes are assigned to three balanced layers;
+5. deterministic constraints maximize operator, family, provider, ASN,
+ country, and infrastructure-group diversity;
+6. a validation pass proves that the profile has at least one allowed complete
+ route and meets its minimum node counts;
+7. failure to satisfy hard constraints makes the proposal invalid.
+
+The exact deterministic shuffle and constraint solver require conformance
+vectors before the PoC. Different implementations MUST produce byte-identical
+topology from the same inputs and seed.
+
+### 17.4 Route constraints
+
+Consensus publishes the attributes needed by the Composer to reject routes
+that repeat one operator, family, or prohibited infrastructure group. The
+consensus MUST NOT precompute one user route or allow operators to choose user
+paths.
+
+## 18. Consensus Body
+
+The canonical `ConsensusBody` is:
+
+```text
+[
+ network_id,
+ pki_version,
+ authority_set_version,
+ epoch,
+ topology_generation,
+ valid_after,
+ fresh_until,
+ valid_until,
+ previous_consensus_epoch,
+ previous_consensus_hash,
+ trust_anchor_manifest_hash,
+ commit_reveal_summary,
+ operator_records,
+ node_descriptors,
+ topology,
+ revocations,
+ storage_manifests,
+ active_profile_ids,
+ network_parameters,
+ announced_transition_hashes
+]
+```
+
+`previous_consensus_epoch` and `previous_consensus_hash` identify the latest
+prior epoch that produced a valid consensus. They may skip scheduled epochs
+that ended without consensus. Each skipped epoch still receives a
+no-consensus transparency archive under Section 24.
+
+### 18.1 Validity times
+
+`valid_after`, `fresh_until`, and `valid_until` are derived exactly from the
+epoch schedule. Authorities do not choose them independently.
+
+- Before `valid_after`, the consensus may be staged but not used for new work.
+- After `fresh_until`, a consumer reports a stale-update condition but MAY
+ continue only until `valid_until` under the same profile.
+- At `valid_until`, new route construction and new work stop.
+
+No mirror, relay, node, operator, or single authority can extend these times.
+
+### 18.2 Full descriptors
+
+Version 1 consensus contains the complete accepted operator records and node
+descriptors needed for route and link validation. It does not use
+state-dependent descriptor deltas or fetch-on-demand partial views.
+
+Each embedded record or descriptor is a CBOR byte string containing its full
+canonical signed envelope. Arrays are sorted by the corresponding stable
+identifier, not by operator alias, endpoint, or arrival order. Consumers
+independently validate the embedded operator and node signatures after the
+authority quorum signature.
+
+`storage_manifests` contains the complete canonical previous, current, and
+announced next `StorageReplicaManifest` objects required by the active
+FOG-STORAGE retention and transition windows. The objects are sorted by
+storage epoch and manifest hash, duplicate-free, and validated under
+`FOG-PKI-CBOR-1` and the authority quorum. Consumers MUST NOT merge replica
+records or storage keys from different manifests. The exact object schema,
+sign-once state, shard inputs, and key windows are defined by
+`FOG-STORAGE.md`.
+
+### 18.3 Profiles and parameters
+
+`active_profile_ids` authorizes exact wire, packet, storage, entry, cover, and
+application protocol profiles. `network_parameters` contains only registered
+integer parameter IDs and bounded unsigned integer values.
+
+For KEMSphinx packet processing, consensus and the applicable
+`FOG-SPHINX-PROFILES` record MUST resolve exactly one packet profile for each
+tuple `(epoch, link_context, packet_class)`. During a transition, old and new
+packet profile IDs may both appear only with an unambiguous activation and
+drain mapping. A consumer MUST reject a consensus that makes profile selection
+ambiguous, requires packet-length detection, or maps one new-work tuple to
+more than one packet profile.
+
+Every node descriptor selected for a KEMSphinx route MUST contain the exact
+epoch KEM key purpose, role, layer, and packet profile required by that route.
+The consensus is invalid if its topology cannot supply a complete four-hop
+forward and reply shape required by the active packet profile.
+
+A parameter cannot select the suite used to authenticate its own consensus.
+Security-critical profile transition requires a preannounced bounded overlap
+and cannot silently downgrade an already accepted minimum.
+
+A `ProfileTransition` contains:
+
+```text
+[
+ network_id,
+ transition_sequence,
+ profile_class,
+ old_profile_ids,
+ new_profile_ids,
+ announcement_epoch,
+ activation_epoch,
+ retirement_epoch,
+ minimum_compatible_version
+]
+```
+
+It requires M independent authority signatures, at least two epochs of advance
+notice, a bounded old/new overlap, and inclusion of its hash in every
+intervening consensus. Parameters classified as profile-bound change only
+through this object. Parameters explicitly classified as dynamic MUST have
+hard minimum, maximum, and per-epoch change bounds in the active profile.
+
+### 18.4 Signature envelope
+
+A `ConsensusEnvelope` is a `SignedEnvelope` whose signed object type is
+`ConsensusBody`. Signature records are sorted by `authority_id` and contain no
+duplicates.
+
+The consensus hash covers the body bytes only. The valid consensus identity is
+the pair `(epoch, consensus_hash)`. Adding a valid signature does not create a
+different consensus identity.
+
+## 19. Consumer Consensus Validation
+
+A consumer MUST perform these checks in order:
+
+1. enforce the outer byte limit before parsing;
+2. decode one exact `SignedEnvelope` and reject trailing data;
+3. validate `FOG-PKI-CBOR-1` and canonical byte equality;
+4. require the pinned `network_id`, PKI version, and object type;
+5. load the already trusted authority-set manifest for the declared version;
+6. validate all required authority online vote-key and wire-key certificates
+ and revocation state;
+7. verify every included signature and require at least M distinct valid
+ active authorities;
+8. recompute the consensus hash;
+9. require exact epoch schedule times and acceptable local clock uncertainty;
+10. reject an epoch below the highest accepted epoch;
+11. reject a different hash for an already accepted epoch;
+12. verify the previous-consensus relationship or the offline consistency
+ bundle described in Section 25;
+13. validate all records, descriptors, key purposes, profile IDs, parameters,
+ revocations, limits, topology assignments, and diversity constraints;
+14. verify the epoch archive and transparency inclusion and consistency
+ evidence;
+15. atomically persist the new manifest version, epoch, consensus hash,
+ checkpoint, and minimum accepted profile state;
+16. only then expose the network view to route or link logic.
+
+Signature verification MUST occur before expensive validation proportional to
+the complete topology where practical, but canonical parsing and strict bounds
+always occur first.
+
+An implementation MUST NOT choose one of two valid-looking same-epoch bodies
+by timestamp, signature count above M, mirror order, lexicographic hash, or
+network reachability. It freezes and reports equivocation.
+
+## 20. Node Consumption and Key Acceptance
+
+Online nodes apply the same consensus authentication rules as Composers and
+also MUST:
+
+- confirm their own effective role and layer before serving traffic;
+- bind peer eligibility to the active consensus and link profile;
+- accept role-specific epoch keys only for their declared purpose;
+- validate root-certified current or staged authority wire keys before
+ `NODE_AUTHORITY` or `AUTHORITY_AUTHORITY` handshakes;
+- stage next-epoch connections without forwarding next-epoch traffic early;
+- close or reject peers removed by the next consensus at the specified
+ boundary;
+- retain previous packet-processing keys only for the exact bounded packet
+ grace period;
+- erase expired epoch private keys after all required replay and packet
+ windows close;
+- stop if local configuration attempts to activate a second role.
+
+An operator configuration cannot add a peer, key, profile, or role absent from
+consensus.
+
+## 21. Revocation and Suspension
+
+### 21.1 Scope
+
+A `RevocationStatement` may target:
+
+- one role-specific epoch key;
+- one node identity and all its keys;
+- one operator and all admitted nodes;
+- one authority online voting key;
+- one authority online wire key;
+- one authority root through an authority-set transition;
+- one protocol profile or suite through a preannounced transition.
+
+### 21.2 Body
+
+```text
+[
+ network_id,
+ revocation_sequence,
+ target_type,
+ target_id,
+ scope,
+ public_reason_code,
+ effective_epoch,
+ effective_time,
+ expiry_epoch,
+ replacement_policy,
+ previous_revocation_hash
+]
+```
+
+Ordinary suspension, revocation, expiry change, and reinstatement require M
+authority signatures.
+
+### 21.3 Self-revocation
+
+A node or operator MAY publish a self-revocation signed by the affected
+identity. Consumers treat a valid self-revocation as an immediate denial-of-
+service-safe removal of that identity. Self-revocation cannot authorize a
+replacement key, identity, operator, role, or authority.
+
+### 21.4 Emergency revocation
+
+Between normal consensuses, M authorities MAY sign one emergency revocation
+envelope. It MUST:
+
+- use a monotonic revocation sequence;
+- identify the last valid consensus hash;
+- have a short explicit expiry no later than the next normal consensus hard
+ expiry;
+- be included in the next epoch archive;
+- never add or reinstate an identity;
+- never change quorum, authority roots, profiles, or topology except by
+ removing the compromised subject.
+
+A single authority warning is public evidence but is not an effective network
+revocation.
+
+### 21.5 Compromise response
+
+After confirmed compromise:
+
+- stop new use of the affected private key;
+- publish self-revocation where safe;
+- issue threshold suspension or revocation;
+- remove affected objects from new consensus;
+- generate purpose-separated replacement keys;
+- use ordinary admission or transition for replacement;
+- preserve public evidence without publishing secret forensic material;
+- document which past and future properties may have failed.
+
+Revocation does not erase previously recorded traffic, signatures, or
+compromise effects.
+
+## 22. Authority-Set Transition
+
+Authority membership, quorum, root keys, PKI authentication suite, epoch
+schedule, and transparency-log identity change only through an
+`AuthoritySetTransition`.
+
+The transition body contains:
+
+```text
+[
+ network_id,
+ old_manifest_version,
+ old_manifest_hash,
+ new_manifest_version,
+ new_manifest_hash,
+ announcement_epoch,
+ activation_epoch,
+ transition_reason_code
+]
+```
+
+Acceptance requires:
+
+1. versions increase by exactly one;
+2. the old manifest is already trusted;
+3. activation is announced at least two epochs in advance;
+4. at least M old authority root signatures validate;
+5. at least the new quorum of new authority root signatures validate;
+6. the transition hash appears in every consensus during the overlap;
+7. the new manifest chains to the old manifest hash;
+8. the consumer persists the new manifest before its activation epoch;
+9. old roots stop authorizing ordinary new state at activation;
+10. a bounded verification overlap exists only for objects created before the
+ boundary.
+
+This dual-quorum procedure follows the principle that both the old trusted set
+and the new set authorize a root transition.
+
+The old quorum signs the exact new root keys and suite identifiers. A new
+authentication suite MUST already be supported and explicitly authorized as a
+transition suite by the old manifest during the overlap. A client MUST NOT
+jump directly from an old suite to an object that can be verified only by an
+algorithm named inside that object. Software support for a suite does not make
+the suite trusted without this chained authorization.
+
+If too many old roots are lost to reach the old quorum, the network has no
+automatic in-protocol recovery. Recovery requires a separately authenticated
+`RecoveryManifest`, explicit user or operator action, and a new trust anchor
+obtained through independent channels. It MUST NOT resemble an ordinary
+update or trust-on-first-use prompt.
+
+## 23. Topology and Profile Revocation Effects
+
+Removing one node MUST NOT cause consumers to bypass its layer. A new
+consensus recomputes a valid complete topology or fails.
+
+If revocation makes the minimum topology or operator diversity impossible:
+
+- no stronger privacy profile is advertised;
+- authorities may publish a lower claim profile only if it was already
+ supported, explicitly authorized, and not a silent downgrade;
+- consumers whose minimum accepted profile is stronger stop new work;
+- the local PoC profile may continue only as functional test mode.
+
+Profile removal is not a generic emergency revocation. It requires a
+preannounced `ProfileTransition`, or an authority-set transition when the PKI
+authentication suite itself changes, unless the profile already has an
+authenticated hard retirement epoch.
+
+## 24. Append-Only Transparency Log
+
+### 24.1 Purpose and limitation
+
+FOG-PKI maintains an append-only Merkle log so a long-offline Composer can
+verify that a new accepted view extends its stored checkpoint with a proof
+whose size grows logarithmically rather than linearly with missed epochs.
+
+The log detects inconsistent signed history when views are compared. It does
+not by itself guarantee that every client sees the same view. Independent
+retrieval, witnesses, and checkpoint gossip remain necessary.
+
+### 24.2 Epoch archive
+
+For every scheduled epoch E, authorities create one canonical `EpochArchive`
+once quorum can finalize either the successful or no-consensus outcome:
+
+```text
+[
+ network_id,
+ epoch,
+ archive_status,
+ failure_reason_code,
+ consensus_hash,
+ authority_manifest_hash,
+ online_key_certificate_hashes,
+ authority_wire_key_certificate_hashes,
+ authority_protocol_object_hashes,
+ consensus_signature_hashes,
+ operator_record_hashes,
+ admission_decision_hashes,
+ node_descriptor_hashes,
+ revocation_hashes,
+ transition_hashes,
+ equivocation_evidence_hashes
+]
+```
+
+All set-like lists are sorted and duplicate-free. The archive commits to the
+public protocol record without embedding private admission evidence.
+
+The archive is a canonical `SignedObject` byte string but needs no individual
+signature envelope. Its authenticity derives from inclusion in the Merkle tree
+identified by an M-of-N signed checkpoint.
+
+For a successful epoch, `archive_status` is unsigned integer `0`,
+`failure_reason_code` is zero, and `consensus_hash` identifies the threshold-
+valid consensus. For an epoch without consensus, `archive_status` is unsigned
+integer `1`, `consensus_hash` is the all-zero hash, and the registered failure
+code records the failed phase without private diagnostics.
+
+`authority_protocol_object_hashes` commits to authority commits, reveals, and
+proposals associated with the epoch.
+`consensus_signature_hashes` commits to every published authority signature
+in the finalized consensus envelope. A consumer requires the envelope's exact
+sorted signature-record hash set to match the archive.
+
+### 24.3 Merkle construction
+
+Each canonical `EpochArchive` byte string is one log leaf in increasing epoch
+order. There is exactly one leaf per scheduled epoch. Missing consensus is
+represented by the canonical failure archive; leaf indices never shift or get
+reused. If quorum loss temporarily prevents checkpointing a failure archive,
+the gap MUST be filled before a later checkpoint can advance past it.
+
+The Merkle tree, leaf hashing, node hashing, inclusion proofs, and consistency
+proofs follow the RFC 9162 append-only construction with FOG-specific domain
+separation and the hash suite pinned by the trust manifest.
+
+The version-1 hashes are:
+
+```text
+empty_hash = HASH(["FOG-PKI-LOG-EMPTY-1", log_id])
+
+leaf_hash = HASH([
+ "FOG-PKI-LOG-LEAF-1",
+ log_id,
+ epoch_archive_bytes
+])
+
+node_hash = HASH([
+ "FOG-PKI-LOG-NODE-1",
+ log_id,
+ left_child_hash,
+ right_child_hash
+])
+```
+
+Tree splitting, inclusion paths, and consistency paths follow RFC 9162. The
+FOG domains above replace the RFC leaf and node prefixes; they do not change
+tree ordering or proof traversal.
+
+The log MUST NOT use commutative child hashing. Left and right position are
+part of verification.
+
+### 24.4 Checkpoint
+
+A `LogCheckpoint` contains:
+
+```text
+[
+ network_id,
+ log_id,
+ authority_set_version,
+ tree_size,
+ root_hash,
+ first_epoch,
+ last_epoch,
+ checkpoint_time
+]
+```
+
+It requires M independent online authority signatures. For a successful
+consensus, its archive and checkpoint MUST be published before that
+consensus's `valid_after`. If quorum cannot checkpoint it by then, consumers do
+not use it for new work. Failure archives are checkpointed before the log can
+advance to any later epoch.
+
+`first_epoch`, `last_epoch`, and `tree_size` MUST describe one contiguous
+epoch sequence with exactly one leaf per scheduled epoch.
+
+### 24.5 Proofs
+
+Mirrors provide:
+
+- an inclusion proof that the target `EpochArchive` is in the new checkpoint;
+- a consistency proof that the new checkpoint extends the consumer's stored
+ checkpoint;
+- the target archive and consensus envelope;
+- any intervening authority-set transitions and online vote-key certificates;
+- authority wire-key certificates required by an online consumer's selected
+ FOG-WIRE contexts.
+
+Proofs are not trusted objects and need no signature. Their validity derives
+from the old stored root and new threshold-signed checkpoint.
+
+### 24.6 Checkpoint comparison
+
+The following are evidence of failure or equivocation:
+
+- two threshold-signed checkpoints with the same `tree_size` and different
+ roots;
+- a newer threshold-signed checkpoint for which no valid consistency proof
+ from an accepted older checkpoint exists;
+- one epoch archive committing to a consensus hash different from the accepted
+ threshold consensus;
+- a checkpoint omitting a promised finalized epoch beyond the publication
+ deadline.
+
+Consumers freeze ordinary PKI updates on verified checkpoint inconsistency.
+They do not reset their stored tree size to make a proof pass.
+
+## 25. Offline Composer Update Bundle
+
+The blind relay or controlled import medium supplies one bounded
+`PKIUpdateBundle` containing:
+
+- the target full consensus envelope;
+- authority online-key certificates needed to verify it;
+- current revocations and emergency revocations;
+- every sequential authority-set transition since the stored manifest;
+- the target epoch archive;
+- a threshold-signed current log checkpoint;
+- an inclusion proof for the target archive;
+- a consistency proof from the Composer's stored checkpoint;
+- independently fetched distinct checkpoints or witness statements where
+ available;
+- a coarse untrusted retrieval timestamp for diagnostics only.
+
+The bundle is a transfer container, not a signed PKI object. Every contained
+object is independently bounded and verified. Extra, duplicate, conflicting,
+or unrelated objects make the bundle invalid.
+
+The Composer MUST:
+
+1. verify transitions sequentially from its stored manifest;
+2. verify the new checkpoint quorum under the correct active authority set;
+3. verify checkpoint consistency from its stored tree root;
+4. verify inclusion of the target epoch archive;
+5. verify the archive's consensus hash;
+6. validate the consensus through Section 19;
+7. compare all supplied distinct checkpoints and evidence;
+8. atomically persist the entire new trusted state;
+9. retain sufficient prior checkpoint and manifest metadata for recovery and
+ equivocation evidence.
+
+If the relay withholds newer data, it can cause freeze or denial of service.
+It cannot make stale data satisfy hard expiry or monotonic checks.
+
+If the Composer lacks its previous checkpoint or manifest state, it MUST NOT
+silently bootstrap from the relay. It requires the explicit recovery process.
+
+## 26. Equivocation Evidence
+
+An `EquivocationEvidence` object contains two or more complete independently
+verifiable signed objects demonstrating one of:
+
+- one authority signs two different consensus hashes for one epoch;
+- two threshold-valid consensus bodies exist for one epoch;
+- one node signs different descriptors with the same sequence and predecessor;
+- one operator signs conflicting records with the same sequence;
+- an authority signs two different storage manifest hashes for one storage
+ epoch;
+- one authority signs incompatible commits, reveals, or proposals;
+- threshold-signed checkpoints conflict or fail append-only consistency;
+- an authority-set transition conflicts at one manifest version.
+
+Evidence objects MUST contain no secret randomness beyond a reveal already due
+for publication and no private governance evidence.
+
+Node or operator equivocation causes deterministic exclusion pending a
+threshold decision. Authority or checkpoint equivocation freezes affected
+consumers until a valid authority-set transition or explicit recovery
+manifest resolves the trust state.
+
+A consumer MUST NOT locally rewrite the authority set merely because it has
+evidence against one authority. That would create a client-specific trust
+view.
+
+## 27. Distribution and Mirrors
+
+Authorities and mirrors publish immutable objects addressed by object hash.
+The latest pointer is an untrusted convenience and MUST return the complete
+bytes needed for verification.
+
+Publishers SHOULD support retrieval by:
+
+- exact consensus epoch and hash;
+- object hash;
+- authority-set manifest version;
+- transparency checkpoint tree size;
+- inclusion and consistency proof parameters;
+- revocation sequence.
+
+HTTP, HTTPS, removable media, QR, FOG-SX-adjacent transfer tooling, or another
+transport MAY carry public PKI objects. Transport security can improve
+availability and privacy but does not create PKI authenticity.
+
+Relays SHOULD fetch from at least two independently operated authorities or
+mirrors and preserve distinct valid responses. They MUST NOT merge them. A
+Composer import bundle includes conflicts as evidence rather than hiding them.
+
+Mirrors MUST NOT receive authority private keys, admission credentials, user
+identities, message traffic, or special consensus signing privilege.
+
+## 28. Failure Behavior
+
+| Condition | Required behavior |
+| --- | --- |
+| Fewer than M valid consensus signatures | reject |
+| Signature from wrong authority set | reject |
+| Any included malformed or invalid signature | reject envelope |
+| Same authority listed twice | reject envelope |
+| Non-canonical encoding | reject before signature acceptance |
+| Unknown-critical value | reject |
+| Wrong network ID | reject |
+| Same epoch, different hash | freeze and retain evidence |
+| Lower epoch or manifest version | reject as rollback |
+| Broken descriptor chain | exclude descriptor; proposal must agree |
+| Missing required future key | exclude node |
+| Invalid topology or insufficient diversity | no consensus for that profile |
+| Commit/reveal quorum failure | no consensus |
+| Proposal body mismatch | do not sign |
+| Consensus past `fresh_until` | report stale; continue only to hard expiry |
+| Consensus past `valid_until` | stop new work |
+| Checkpoint consistency failure | freeze ordinary update |
+| Authority transition lacks dual quorum | reject transition |
+| Lost local monotonic state | require explicit recovery |
+| Clock uncertainty exceeds bound | stop time-sensitive acceptance |
+
+Remote protocol errors MUST be coarse and non-amplifying. Local diagnostics
+MAY identify deterministic validation stages but MUST NOT log private keys,
+private admission material, unpublished random reveals, or credentials.
+
+## 29. Key Lifecycle Table
+
+| Key or secret | Generator | Authorized use | Lifetime and overlap | Compromise response | Backup |
+| --- | --- | --- | --- | --- | --- |
+| Network ID | genesis ceremony | domain and network separation | permanent | new network genesis | public, widely copied |
+| Authority root private key | offline authority ceremony | online-key certificates and set transitions | long-term, one controlled transition overlap | root transition or explicit recovery | encrypted, separate recovery secret |
+| Authority online vote private key | authority root ceremony or controlled online generation | commits, reveals, proposals, consensus, checkpoints | at most 32 epochs, at most 2-epoch overlap | threshold revoke certificate and rotate | SHOULD NOT be restored into concurrent signer |
+| Authority wire private key | authority wire service OS CSPRNG or controlled ceremony | mutually authenticated `FOG-WIRE` authority and descriptor links | root-certified for at most 32 epochs, at most 2-epoch overlap | revoke certificate, stop new sessions, and rotate | SHOULD NOT be restored into concurrent service |
+| Authority randomness secret | online authority CSPRNG | one epoch commit/reveal | one protocol run; erase after reveal and audit window | exclude invalid run; investigate RNG | no backup |
+| Operator identity private key | operator ceremony | operator records and descriptor co-signing | long-term with admitted replacement | suspend operator, replace through admission | encrypted operator-controlled backup |
+| Node identity private key | node enrollment | descriptor continuity | long-term for one node role | self-revoke and new admission | encrypted role-local backup if policy permits |
+| Node epoch private key | owning node CSPRNG | one declared role purpose | current plus bounded grace; future key staged | revoke purpose or node; generate replacement | no routine backup |
+| Replica receipt private key | one storage replica CSPRNG | authenticate one manifest-bounded local durable-result receipt | storage-manifest current plus bounded verification drain | stop receipts, revoke node or purpose, rotate through new manifest | no routine backup |
+| Transparency checkpoint state | every authority | append-only root computation and sign-once tracking | permanent monotonic public history | freeze on inconsistency; recover from audited replicas | authenticated independent authority backups |
+| Consumer monotonic state | each consumer | rollback and consistency detection | lifetime of installation or identity | explicit authenticated recovery | authenticated backup bound to consumer profile |
+
+The networkless Composer refines the final row through the local commitment,
+external-anchor, import, recovery, and update-consumer rules in
+`FOG-COMPOSER.md`. A self-contained consumer backup does not provide complete
+rollback detection.
+
+No private key or randomness secret may appear in consensus, transparency
+logs, test vectors, examples, command lines, environment templates, container
+images, metrics, crash dumps, or support bundles. Tests generate ephemeral
+fixtures at runtime.
+
+## 30. Privacy and Operational Data
+
+Public PKI necessarily reveals:
+
+- node and authority public identities;
+- endpoints and supported transports;
+- effective roles and mix layers;
+- declared operator, family, provider, ASN, country, and infrastructure groups;
+- public key schedules, profiles, validity, admission, suspension, and
+ revocation state;
+- consensus timing and topology changes.
+
+This enables targeting and operational correlation. FOG accepts that exposure
+because clients need a common auditable view and route-diversity inputs.
+
+FOG-PKI MUST NOT publish:
+
+- user or contact identities;
+- mailbox capabilities or packet identifiers;
+- node traffic counts or fine-grained health events;
+- operator legal identity unless voluntarily required by a separate public
+ governance policy;
+- private email, phone, billing, account, or management data;
+- exact physical addresses;
+- unpublished vulnerability or forensic details;
+- authority or node private-key storage design beyond the public assurance
+ profile.
+
+Descriptor uploads, votes, and public objects SHOULD use fixed schedule
+windows and bounded request behavior. Operational metrics belong to the
+aggregate observer interface, not node descriptors.
+
+## 31. Denial-of-Service and Resource Controls
+
+Authorities MUST:
+
+- accept descriptor uploads only for admitted identities;
+- authenticate before expensive signature or policy work where possible;
+- accept at most one selected descriptor chain head per node and epoch;
+- bound connections, body size, signatures, records, keys, endpoints, and
+ pending votes;
+- rate-limit invalid uploads without creating different consensus views;
+- persist protocol phase and sign-once state atomically;
+- use bounded backoff for peer authority exchange;
+- avoid error responses larger than the triggering request;
+- keep publication serving separate from sensitive signing state;
+- remain able to publish existing immutable objects during voting overload.
+
+A malicious admitted node can consume review and descriptor resources. The
+permissioned registry, bounds, expiry, suspension, and operator-wide actions
+limit but do not eliminate this risk.
+
+Authority quorum and transparency do not provide availability against a
+sustained distributed attack or coordinated withholding.
+
+## 32. Conformance and Adversarial Tests
+
+Before the local PoC, FOG-PKI MUST have deterministic fixtures for:
+
+- every object type and exact canonical encoding;
+- re-encoding equality and rejection of alternative CBOR encodings;
+- every registered identifier and domain-separated hash;
+- valid M-of-N consensus for 2-of-3 and 3-of-5 sets;
+- duplicate, unknown, expired, revoked, and wrong-set signatures;
+- composite signature all-component validation;
+- authority online-key certification and overlap boundaries;
+- authority wire-key certification, overlap, profile binding, and rejection of vote-key reuse;
+- descriptor sequence, predecessor, node, and operator signatures;
+- role-specific key-purpose acceptance and cross-purpose rejection;
+- admission, denial, suspension, reinstatement, retirement, and self-revocation;
+- commit, reveal, missing reveal, invalid reveal, and insufficient quorum;
+- byte-identical topology generation from seed and inputs;
+- operator, family, provider, ASN, country, and infrastructure constraints;
+- same-epoch authority and node equivocation;
+- storage-manifest canonical encoding, sign-once persistence, quorum,
+ chaining, previous/current/next windows, receipt keys, and no cross-manifest
+ replica merging;
+- stale, expired, future, rolled-back, frozen, and split consensus;
+- authority sign-once persistence across crash, restore, and failover;
+- ordinary and emergency revocation;
+- dual-quorum authority-set transition;
+- loss of old-root quorum and explicit recovery refusal;
+- RFC 9162 inclusion and consistency proofs, including edge tree sizes;
+- conflicting checkpoints and missing archive leaves;
+- long-offline Composer update from old checkpoint;
+- interrupted atomic state update and recovery;
+- maximum document, array, string, key, signature, and proof limits;
+- parser mutation, fuzz, differential, and allocation tests;
+- clock skew and uncertainty at every boundary;
+- consensus publication and mirror corruption scenarios.
+
+Independent implementations MUST consume the same conformance corpus before
+interoperability is claimed.
+
+## 33. Claim Gates
+
+### 33.1 Functional PoC
+
+The PoC may use simulated authorities but MUST exercise:
+
+- independent signature records;
+- canonical consensus construction;
+- descriptor validation;
+- three-layer topology assignment;
+- current and next node keys;
+- rollback state;
+- revocation;
+- sign-once behavior;
+- transparency inclusion and consistency proofs;
+- expired-consensus fail-closed behavior.
+
+`FOG-LOCAL-POC.md` keeps the authority fixture networkless and explicitly
+non-claim-bearing. Its fault plan requires insufficient-quorum, same-epoch
+fork, stale-consensus, rollback-state, and clock-uncertainty cases before a
+runnable fixture can pass.
+
+### 33.2 Operator alpha
+
+Alpha requires:
+
+- three independently administered authority roots and online services;
+- a 2-of-3 quorum;
+- independent consensus mirrors;
+- at least two independent checkpoint monitors or witnesses;
+- rehearsed online-key compromise, node revocation, authority replacement,
+ quorum loss, clock failure, and restore exercises;
+- public admission, family, revocation, and residual-risk policy;
+- confirmation that no shared provider account or management credential
+ controls the authority quorum.
+
+### 33.3 Production PKI claims
+
+Production claims additionally require:
+
+- independent protocol and implementation review;
+- reviewed concrete classical and post-quantum policy;
+- independently reproduced consensus and transparency roots;
+- published conformance results and unresolved findings;
+- demonstrated long-offline update and recovery ceremonies;
+- ongoing operator-family and common-control auditing;
+- explicit documentation that a compromised authority threshold can still
+ authorize a malicious network view.
+
+## 34. Requirements Traceability
+
+| Requirement | FOG-PKI control |
+| --- | --- |
+| `TM-NET-06` | full canonical consensus, fixed profile IDs, no partial-view merge |
+| `TM-PKI-01` | permissioned admission, operator records, family and infrastructure constraints |
+| `TM-PKI-02` | monotonic epoch and hash state, hard expiry, Merkle inclusion and consistency |
+| `TM-PKI-03` | independent M-of-N authorities, offline roots, bounded online keys, deterministic quorum failure |
+| `TM-OPS-01` | minimal public fields, no user data or private governance evidence |
+| `TM-SUPPLY-01` | pinned genesis, certified online keys, canonical objects, authenticated transitions |
+| `TM-CRYPTO-01` | purpose-specific key hierarchy, bounded overlap, explicit compromise response |
+| `TM-CRYPTO-02` | already-trusted authentication suite, composite all-component validation, no downgrade |
+| `TM-AVAIL-01` | permissioned uploads, strict limits, non-amplification, explicit no-consensus state |
+| `ARC-005` | Composer-validated complete authenticated network view |
+| `ARC-007` | one owner and purpose for root, vote, operator, node, and epoch keys |
+| `ARC-008` | restricted CBOR, exact schema, absolute limits, unknown-critical rejection |
+| `ARC-009` | stale and hard-expiry states, no locally synthesized fallback consensus |
+| `IF-03` | authenticated bounded node descriptor upload |
+| `IF-04` | signed commit, reveal, proposal, signature, and checkpoint exchange |
+| `IF-05` | immutable hash-addressed full consensus and offline update bundle |
+
+## 35. Open Pre-Implementation Selections
+
+The protocol structure is fixed, but these selections block implementation:
+
+- exact encoding, vectors, implementation, artifact-separability analysis,
+ side-channel evidence, and activation record for the non-active SHA3-256
+ and ML-DSA-65 plus Ed25519 candidates;
+- exact epoch duration, schedule offsets, freshness, hard expiry, and clock
+ uncertainty;
+- exact deterministic topology shuffle and diversity constraint algorithm;
+- initial wire, KEMSphinx, entry, storage, cover, and application profile IDs;
+- authority wire-key certificate issuance, storage, revocation, and rollover
+ profile;
+- initial lower operational document and node-count limits;
+- hardware and ceremony profile for authority roots;
+- monitor and witness operators for alpha;
+- explicit `RecoveryManifest` ceremony and user interface;
+- public governance reason-code registry and private evidence retention policy.
+
+These values MUST be selected through reviewed profiles and conformance
+vectors. Implementations MUST NOT invent local defaults.
+
+## 36. References
+
+- FOG threat model: `FOG-THREAT-MODEL.md`
+- FOG architecture: `FOG-ARCHITECTURE.md`
+- FOG wire protocol: `FOG-WIRE.md`
+- FOG storage protocol: `FOG-STORAGE.md`
+- FOG Composer protocol: `FOG-COMPOSER.md`
+- FOG cryptographic suite evaluation: `FOG-CRYPTO-SUITES.md`
+- FOG cryptographic benchmark baseline: `FOG-CRYPTO-BENCHMARKS.md`
+- FOG local Podman PoC: `FOG-LOCAL-POC.md`
+- NIST FIPS 204, Module-Lattice-Based Digital Signature Standard:
+ <https://csrc.nist.gov/pubs/fips/204/final>
+- RFC 9955, Hybrid Signature Spectrums:
+ <https://www.rfc-editor.org/rfc/rfc9955.html>
+- RFC 9980, Post-Quantum Cryptography in OpenPGP:
+ <https://www.rfc-editor.org/rfc/rfc9980.html>
+- Katzenpost public key infrastructure specification:
+ <https://katzenpost.network/docs/specs/pki/>
+- Katzenpost mix network specification:
+ <https://katzenpost.network/docs/specs/mixnet/>
+- Tor directory authority and consensus specifications:
+ <https://spec.torproject.org/dir-spec/>
+- Tor shared-random protocol:
+ <https://spec.torproject.org/srv-spec/>
+- RFC 8949, Concise Binary Object Representation:
+ <https://www.rfc-editor.org/rfc/rfc8949.html>
+- RFC 9162, Certificate Transparency Version 2.0:
+ <https://www.rfc-editor.org/rfc/rfc9162.html>
+- The Update Framework specification:
+ <https://theupdateframework.github.io/specification/>
+
+These references inform quorum operation, offline and online key separation,
+deterministic encoding, append-only consistency proofs, root transitions,
+rollback handling, and freeze detection. They do not make FOG-PKI secure by
+inheritance. FOG requires its own concrete suites, test vectors,
+implementations, operations, and independent review.