# 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.
