The costheta Federation Protocol

An open proposal · v0.3 (draft) · August 2026

Author: Andrei Nemirschi · the costheta project · Constanța, Romania · federation@costheta.dev

Status of this document. This is a draft proposal, published for discussion. It describes a protocol that today runs on one detector, under one operator. Nothing in this document should be read as a description of a deployed multi-node network. Open questions are marked as such. Comments and prospective node operators: federation@costheta.dev


1. Abstract

costheta turns cosmic-ray muon arrival times into commit-and-reveal decisions with cryptographically signed certificates. This proposal specifies how multiple independently operated detector nodes attest each decision, so that the validity of a certificate derives from protocol structure rather than from trust in any single operator, including the protocol's author.

2. Motivation and trust model

A certificate produced by one operator establishes provenance and integrity, but its binding to a real physical event rests on that operator's honesty. The purpose of federation is to replace this residual trust with structure: a fully attested certificate requires agreement between nodes that are operationally, geographically, and personally independent.

The design follows a long lineage: Turing's oracle machines (1939), computation coupled to a non-computable source; Rabin's randomness beacons (1983); and federation-ready public infrastructure such as drand.

What the protocol guarantees:

What it does not guarantee:

3. Terminology

4. Certificate format

A certificate is a JSON object, canonically serialized, carrying an array of per-node attestations:

{
  "version": "0.3",
  "commitment": "sha256:…",
  "commit_time": "…Z",
  "registry_hash": "sha256:…",
  "selection": { "pulse_index": 4416, "counter": 0 },
  "pulse": {
    "index": 4417,
    "t_dev_ms": 336021,
    "adc": 365,
    "pressure_hpa": 1014.2,
    "prev_hash": "sha256:…"
  },
  "outcome": 1,
  "attestations": [
    {
      "node_id": "constanta-1",
      "window": ["…Z", "…Z"],
      "sig_ed25519": "…",
      "sig_mldsa": "…"
    }
  ]
}

Each attestation is dual-signed (Ed25519 per RFC 8032; ML-DSA per FIPS 204). The pulse chain (prev_hash) is append-only and published; retroactive modification of any pulse invalidates all subsequent ones.

registry_hash is the hash of the published node-registry snapshot in effect at commit time. selection identifies the selection pulse and retry counter of §7, so that quorum selection is recomputable from the certificate alone. With N = 1 both fields are present and carry the degenerate values: the single-node registry, selection counter 0.

4.1 Commitment construction

A commitment MUST be constructed as:

commitment = SHA-256( salt ‖ options_canonical )

where salt is at least 16 bytes drawn from a cryptographically secure local generator, and options_canonical is the caller's option list in a canonical serialization of the caller's choosing. The salt and the option list remain with the caller; the service receives only the digest and the option count.

The salt is REQUIRED. Without it, a commitment over a small option set can be reversed by enumeration: an observer who can guess the candidate options can hash each candidate and identify the committed set. Callers who later need to prove what was committed (dispute resolution, audit) disclose the salt and option list; verification is then a single hash.

The salt protects confidentiality only. It does not, and is not intended to, constrain how many commitments a caller creates; the protocol's resistance to commitment grinding comes from quorum selection (§7), not from the commitment format.

4.2 Certificate levels

Two certificate levels are defined. The format is identical; the level is determined by the attestation array.

A single-node certificate carries one attestation. It allows anyone to verify the signature, the integrity of the record, the binding of the commitment and the derivation of the outcome. Trust in the operator's physical record remains: the certificate does not independently establish that the attested event occurred as recorded.

A fully attested certificate carries attestations from a quorum of M nodes (§7) in distinct trust domains, selected under §7 and each contributing its own detection to the combined derivation. No single node, including the coordinating one, can produce a fully attested certificate alone.

Certificates state their own level implicitly through the attestation count; verifiers MUST determine the level from the array, not from any label, and MUST check that attesting nodes belong to distinct trust domains as published in the node registry.

5. Derivation and bias

A completed decision combines the caller's commitment with the selected physical contribution or contributions and maps the resulting digest into the caller-requested option count by rejection sampling, not by modulo reduction.

The derivation input is canonically serialized and domain-separated. For a single-node certificate the input includes the commitment, the selected pulse hash, n_options, registry_hash and selection. For a fully attested certificate the input includes the same request fields plus the ordered set of revealed node contributions.

To avoid modulo bias, the verifier interprets the digest stream as unsigned integers of fixed width and accepts the first value below the largest multiple of n_options in that width. If the value falls in the rejected tail, the counter is incremented and a new digest block is derived. The accepted value is reduced by n_options to produce the outcome. The counter used for unbiased mapping is distinct from the quorum-selection retry counter carried in selection.

All inputs needed to recompute the outcome are public in the certificate and published pulse/registry records, except the caller's salt and option list, which are only needed to prove the preimage of the commitment.

6. Node lifecycle

Enrollment. A node generates its keypairs on-device, at first boot, in the operator's custody. Private keys never leave the node; the hub receives public keys only. The hub publishes the node registry: id, trust domain, public keys, status and join date.

Operation. Nodes initiate all connections (outbound HTTPS only); the hub never connects inward. A node streams its pulses and signs attestations for decision requests routed to it.

Departure. An operator may leave at any time. Departed nodes remain in chain history; their past attestations remain verifiable. Registry snapshots are append-only records: a node removed from active service is not removed from history.

7. Attestation and agreement

A decision certificate is fully attested when at least M of the N active nodes have signed attestations whose time windows mutually overlap.

The protocol default is M = min(2, N). With N = 1, certificates carry a single attestation and are labeled by their attestation count. From N ≥ 2, every default certificate carries two attestations, the pair selected by the quorum-selection rule below. Higher M may be available per request and priced accordingly; the attestation count is always visible in the certificate.

7.1 Timing and agreement rules

Agreement window. Node clocks drift (consumer RTCs); the window must tolerate honest drift while bounding the interval in which a dishonest hub could substitute pulses. Candidate: windows anchored to hub receipt time with per-node drift bounds learned from health beacons. This remains open until two independent nodes produce calibration data.

Quorum selection. When M < N, the choice of which nodes attest must not belong to the hub, or the hub regains exactly the discretion federation removes. It must also not be derivable by the requester at commit time: the seed in earlier drafts, H(prev_pulse_hash ‖ commitment), was computable by the requester before committing, since the previous pulse is already public. A requester could therefore grind commitments until the selection landed on a convenient quorum.

v0.3 derives the selection from an event that does not exist when the commitment is sealed:

seed = H( "costheta-quorum-v1" ‖ registry_hash ‖ commitment ‖ pulse_s )

where pulse_s is the first pulse appended to the public chain with a hub receipt time strictly after the commitment was recorded (the selection pulse), and registry_hash is the hash of the published node-registry snapshot in effect at commit time. The quorum is the first M distinct nodes produced by expanding H(seed ‖ i) for i = 0, 1, 2, … over that snapshot. Both inputs are published; anyone can recompute the selection from the certificate.

This closes the requester's grinding: the deciding input to the seed does not exist at commit time. It closes the hub's discretion over membership: the eligible set is pinned by a hash fixed before the selection pulse arrives, so nodes cannot be added, removed or reordered after the commitment. The chain's append-only ordering, which is public, determines which pulse is the selection pulse.

What remains is narrower: the operator of the node that happens to produce the selection pulse cannot choose its content (the pulse is a physical detection, chained to its predecessor), but could delay or suppress it, shifting selection to the next pulse. Suppression is visible as a rate anomaly under §8 and is attributable, because the chain shows whose pulse was due. This residual is declared in §9.

Two-phase commitment between nodes. Combined derivation would otherwise let a node that reveals last compute the outcome before publishing, and substitute a different contribution if the result is unfavourable. Commit-and-reveal removes substitution: once a node has committed to H(pulse), the only pulse it can validly reveal is that one. It does not remove refusal. A node can always decline to reveal; no protocol can force a message. What the protocol does is make refusal unable to change any outcome, and make it visible and attributable when it happens.

1. The hub records the caller commitment and registry snapshot. 2. Selected nodes commit to their contributions before seeing each other's reveals. 3. After all commits arrive, nodes reveal the committed contributions and the hub assembles the certificate.

Timeouts and failure handling. Commit phase: 30 seconds from request. This is bounded by physics rather than by network latency: at a single-detector rate near 0.21 events per second, inter-arrival times are exponential and roughly 0.2 percent of intervals exceed 30 seconds, so a shorter window would exclude honest nodes routinely. Reveal phase: 5 seconds from the hub's request, since no detection is being waited on.

The two phases fail differently, and the difference is load-bearing.

A commit-phase expiry carries no information about any outcome: no node has yet bound itself to a pulse, and no pulse has been revealed. The quorum is therefore reselected once, deterministically, by incrementing the counter in the selection seed. If the second attempt also expires, the request fails and is not charged.

A reveal-phase failure is different: by the time reveals begin, pulses become public as they are published, and a node that has seen the others' contributions can compute what the outcome would be. If failure at this stage triggered reselection, a node could abort selectively, discarding outcomes it disliked and re-rolling the decision. Earlier drafts reselected on any expiry; v0.3 does not. A reveal-phase failure terminates the request: it fails, it is not charged, it is never re-rolled. The failure is recorded against the withholding node and published. A withholding node can therefore deny a specific answer, at public cost to itself, but can never obtain a different one.

The protocol deliberately does not degrade to a smaller quorum on any timeout: doing so would let an adversarial node force single-attestation mode by remaining silent.

Every timeout is recorded against the node that caused it and published. Occasional misses indicate network trouble; a high rate, and especially a rate that correlates with request activity, is an anomaly under §8.

8. Anomaly handling

Nodes are semi-trusted. The hub, and any observer from published data, monitors each node's pulse stream for rate excursions incompatible with cosmic-ray flux and its barometric modulation; ADC distributions departing from the expected energy-deposit spectrum; clock behavior inconsistent with declared drift; and timeout or withholding patterns inconsistent with honest operation. Flagged nodes are excluded from attestation quorums pending review; exclusions are public.

9. Limits and non-goals

Throughput is bounded by physics: about one usable event per several seconds per detector. The protocol serves decisions, not bulk randomness. Public randomness is by definition unsuitable for secret key material. The protocol does not attempt Byzantine agreement over pulse content across nodes observing different particles; attestation binds requests to a physical event under agreed windows, not to a global shared event.

Withholding. A selected node can refuse to reveal its contribution. The protocol cannot prevent this; it ensures instead that refusal is outcome-neutral (a reveal-phase failure terminates the request rather than re-rolling it, §7.1), publicly attributed, and cumulatively disqualifying under §8. Availability of any single decision is therefore not guaranteed; integrity of every completed decision is.

10. Status and versioning

v0.3, draft. One detector, one operator, one attestation per certificate. Changes from v0.2: quorum selection is reseeded from the first pulse following the commitment over a pinned registry snapshot, closing commitment grinding (§7); reveal-phase failures terminate the request instead of reselecting, closing selective abort, and withholding is declared as a visible, outcome-neutral limit (§7.1, §9); commitment construction is normative and salted (§4.1); certificate levels are named and defined (§4.2); certificate format 0.3 adds registry_hash and selection fields; timing and agreement rules are collected under §7.1.

All versions: https://doi.org/10.5281/zenodo.21901353 This version: https://doi.org/10.5281/zenodo.21965029 Repository: https://github.com/costhetadev/federation-proposal

Implementations should treat all fields not defined here as reserved.


This proposal is licensed under the Creative Commons Attribution 4.0 International License (CC BY 4.0). Contact: federation@costheta.dev