# 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: - RFC 9955, Hybrid Signature Spectrums: - RFC 9980, Post-Quantum Cryptography in OpenPGP: - Katzenpost public key infrastructure specification: - Katzenpost mix network specification: - Tor directory authority and consensus specifications: - Tor shared-random protocol: - RFC 8949, Concise Binary Object Representation: - RFC 9162, Certificate Transparency Version 2.0: - The Update Framework 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.