Entropy, recipes, and derivation — the deterministic core.
Domino Compass is a deterministic secret-generation and key-runtime system. It is not a seed-phrase generator, a wallet, a password manager, or a key vault — it is the thing that produces those from physical reality.
An 8×7 domino card — two passes of all 28 tiles — is the source. It is read, canonicalized, and hashed. Nothing else is the root.
A recipe is an explicit deterministic program: which ceremony, which ordering, which normalization, which lane. It is not the secret.
From one root, domain-separated derivation produces an identity lane and a Bitcoin lane as siblings — never one as the child of the other.
Capabilities, descriptors, and encrypted operational state can be rotated, revoked, and persisted — without ever exposing the root.
The domino set is a finite, observable physical system. Its state — the ordered arrangement and orientation of 28 tiles across two passes — is the entropy source. The physical object is not magic; the deterministic encoding rules are what make it reproducible.
The compass is the navigation metaphor: from the root, a recipe steers through a derivation space to reach specific keys. Doubles carry a compass quadrant (p/b/d/q) — 2 bits of entropy each — because the quadrant is an independent, observable post-spin state.
The physical object is not magic. The deterministic encoding rules are what allow reproducibility.
There are two distinct things, and the site keeps them separate:
| Random physical entropy | Deterministically encoded physical state | |
|---|---|---|
| What it is | The unpredictable outcome of a physical process (a shuffle, a spin, a toss). | The recorded state of that outcome, written down under fixed rules so it can be reproduced exactly. |
| Role | Supplies the uncertainty. | Makes the uncertainty reproducible — the same state always yields the same bytes. |
| Example | Shuffling 28 dominoes into a random order. | Reading that order as 56 canonical tokens, in a fixed pass structure, with doubles carrying a compass quadrant. |
For the Domino Compass ceremony specifically:
One pass of 28 tiles contributes:
Two independent passes:
265.89 > 256 — two full sortitions exceed the 256-bit target. This is why the ceremony requires exactly two passes.
56 × log2(70) ≈ 343 bits. This is wrong: each pass uses every tile exactly once (a permutation, not independent draws), and the canonical byte encoding is a bijection onto the true sample space (28!·2²¹·4⁷)².| Material | Status | Why |
|---|---|---|
| The 8×7 domino card / transcript / canonical bytes | SECRET | It is the root. Anyone with it can regenerate every key. |
| The derivation path / transcript bytes | SECRET | With a public start seed, the path is the secrecy. |
| The recipe | GRADED | Not root-equivalent, but reveals purpose, scope, lane context, and the commitment. Protect it. |
| Public fingerprints | PUBLIC | Verification handles. They prove regeneration without revealing the secret. |
| Capability records | PUBLIC | Delegation statements. They can be shared with service peers. |
| Watch-only descriptors / xpub | PUBLIC | Track funds without signing authority. |
A recipe is an explicit deterministic program — a transformation description — not vague "instructions." It describes how physical material becomes deterministic entropy and which lanes to derive.
The recipe is a versioned structured object. Its canonical serialization hashes to its identifier:
The recipe must not contain S_root, the canonical transcript bytes, or any value from which S_root is recoverable. It may be backed up or stored without necessarily revealing the root secret.
| Field | Meaning |
|---|---|
recipe_version | e.g. dc-recipe-v1 |
ceremony_profile | which physical ceremony, e.g. dc-v1-8x7 |
domain_tag | high-level namespace, e.g. pluronymous |
entropy_card_commitment | non-revealing commitment to the physical card |
purpose | Nostr identity, Kapnet actor, service-peer access, trustee recovery, decoy… |
scope | read-only, sign events, publish to channel, spend up to limit… |
service_namespace | which service the key is for |
actor_namespace | which actor / identity |
identity_lane | Nostr, Kapnet, KNU, Pluronymous, delegation, recovery, revocation |
bitcoin_lane | key paths, descriptors, watch-only, payment, claim, recovery, decoy |
time_authorization | wall-clock and/or Bitcoin-native |
revocation_lane | which revocation path applies |
child_index | per-recipe child index |
network | mainnet / testnet / regtest / KNU |
output_type | nsec, private key, BIP-39, BIP-85 child, descriptor… |
checksum | integrity of the recipe itself |
signature | recipe signature by an authority |
The commitment is a one-way hash that is not equal to S_root and does not reveal it:
The domain tag "dc-commit-v1" makes the commitment input different from the KDF input (canonical_transcript_bytes alone), so the commitment is a distinct hash. An attacker who obtains the recipe gets a one-way hash of the transcript, not the root secret. The commitment is used for verification and binding, never as a derivation input.
The recipe must be signed by an authority, and the signature must be over the canonical recipe bytes. A recipe without a valid signature from a trusted authority must be rejected — otherwise an attacker could substitute a malicious recipe with bitcoin_lane: spend-capable for a watch-only recipe, and the user would derive spend keys they never intended.
Build a recipe and inspect its exact serialized form. The builder shows the canonical JSON and the resulting recipe_id.
entropy_card_commitment is filled from the current transcript in the simulator. Changing any field changes recipe_id — and therefore every derived key.From the root secret, a domain-separated runtime derives parallel, independent key lanes. The Bitcoin tree is a sibling of the identity key — never a child.
S_root = SHA-256(canonical_transcript_bytes) is the ceremony root and is unchanged. HKDF is a post-root lane expander, not the root derivation. It never replaces S_root; it domain-separates it into per-lane seeds.Two derivations are distinct if any bound field differs:
identity vs bitcoin lanes use different lane_tag values, so the same recipe yields distinct keys per lane.recipe_id salt) yield distinct keys even for the same lane.child_index values yield distinct keys.scope) changes the transcript bytes and therefore the derived secret.The info input to HKDF is a length-delimited binary transcript. Each field is serialized as 1-byte tag || 2-byte big-endian length || field bytes, in a fixed order. No field may be omitted, reordered, or padded.
Root Secret branches into sibling runtime lanes — parallel domain-separated derivations, not one lane as the child of the other.
Changing the derivation profile (e.g. BIP-86 vs BIP-84) visibly produces a different subtree.
Identity and Bitcoin keys originate from the same deterministic root while remaining cryptographically domain separated.
Explicitly:
This is a core Domino Compass property. The two lanes are derived from the same master (which comes from the lane seed), as siblings — never one as the child of the other.
If the Bitcoin tree were a child of the identity key, then identity compromise would equal funds compromise. Because the Bitcoin tree is a sibling of the identity key (both children of the same master), a leaked identity key does not reveal the Bitcoin lane.
The Bitcoin lane is not a single spend capability; it is a namespace whose spend posture is set by the profile:
| Posture | Meaning |
|---|---|
spend-capable | the lane derives spend keys |
watch-only | the lane derives descriptors / xpub only, no private spend keys |
claim-only | the lane derives claim keys for a specific claim |
service-payment-only | the lane derives payment keys for a specific service |
recovery-only | the lane derives recovery-branch keys |
decoy | the lane derives decoy keys |
A spend-capable lane is an explicit, deliberate choice, never the default.
Deterministic cryptographic systems require strict versioning. Changing any versioned component may deliberately produce a different derivation result.
Changing any versioned component may deliberately produce a different derivation result. The system must not silently reinterpret older recipes.