Skip to content

DKG & TSS — distributed keys and threshold signatures

These are the two ideas at the bottom of everything in Trustless Core:

  • DKG — Distributed Key Generation: how a key is born in pieces.
  • TSS — Threshold Signature Scheme: how those pieces sign without being combined into a whole key.

Start with a magic trick from high-school algebra. A straight line is fixed by two points; a parabola by three. In general, a curve of degree t−1 is uniquely pinned down by exactly t points — and t−1 points tell you nothing about where it crosses the y-axis.

So: hide your secret as the y-intercept of a degree-t−1 curve. Hand each participant one point on the curve. Any t of them can reconstruct the curve and read off the secret; any t−1 of them learn nothing at all. That’s Shamir Secret Sharing, and it’s the seed of everything below.

%%{init: {'flowchart':{'htmlLabels':true,'curve':'basis'}}}%%
flowchart BT
    R1["1 · Shamir Secret Sharing<br/><i>split a secret into N shares; any t reconstruct</i>"]
    R2["2 · Feldman VSS<br/><i>shares + public commitments → verifiable, no trusted dealer</i>"]
    R3["3 · DKG<br/><i>every participant is a dealer; joint key, no whole secret</i>"]
    R4["4 · FROST threshold signing<br/><i>sign with shares, never reconstruct the key</i>"]
    R5["5 · Per-entity ceremonies<br/><i>fresh DKGs for every entity</i>"]
    R1 --> R2 --> R3 --> R4 --> R5

Split a secret s into N shares such that any t reconstruct it and fewer than t learn nothing.

Pick a random polynomial of degree t−1 whose constant term is the secret:

f(x) = s + a₁·x + a₂·x² + … + a_{t-1}·x^{t-1}

Give participant i the point (i, f(i)). To recover, any t participants combine their points with Lagrange interpolation at x = 0, which yields f(0) = s. All arithmetic is modulo a prime (for the on-chain ed25519 keys, the ed25519 scalar-field prime ℓ ≈ 2²⁵²) for bounded values and perfect secrecy below the threshold.


Rung 2 — Feldman Verifiable Secret Sharing (VSS)

Section titled “Rung 2 — Feldman Verifiable Secret Sharing (VSS)”

Plain Shamir trusts the dealer not to hand out inconsistent shares. Feldman VSS removes that trust by publishing public commitments to the polynomial’s coefficients — Cⱼ = g^{aⱼ} on an elliptic-curve group. The commitments reveal nothing about the secret (computing aⱼ from g^{aⱼ} is the discrete-log problem), but every participant can verify their own share is consistent:

g^{f(i)} ?= ∏ⱼ Cⱼ^{i^j}

If the check fails, the dealer cheated and everyone notices.


Rung 3 — Distributed Key Generation (DKG)

Section titled “Rung 3 — Distributed Key Generation (DKG)”

A DKG is a peer-to-peer Shamir where every participant acts as a dealer simultaneously. No one is the trusted dealer; the trust dissolves into the group.

%%{init: {'sequence':{'showSequenceNumbers':false}}}%%
sequenceDiagram
    autonumber
    participant V1 as Validator 1
    participant V2 as Validator 2
    participant V3 as Validator 3
    Note over V1,V3: Each validator i picks a random polynomial fᵢ of degree t−1

    V1->>V2: share f₁(2) + publish commitments C₁,ₖ
    V1->>V3: share f₁(3)
    V2->>V1: share f₂(1) + commitments C₂,ₖ
    V2->>V3: share f₂(3)
    V3->>V1: share f₃(1) + commitments C₃,ₖ
    V3->>V2: share f₃(2)

    Note over V1,V3: Each verifies every received share against the sender's commitments (Feldman VSS)
    V1->>V1: my share s₁ = Σᵢ fᵢ(1)
    V2->>V2: my share s₂ = Σᵢ fᵢ(2)
    V3->>V3: my share s₃ = Σᵢ fᵢ(3)
    Note over V1,V3: Joint public key P = ∏ᵢ g^{aᵢ,₀} — derived without ever assembling the joint secret

The crucial property: the joint secret s = Σᵢ aᵢ,₀ is never materialized anywhere. Each validator only ever holds its own share sᵢ, and only shares are stored. The joint public key is computed from the public commitments alone.

How the ceremony behaves in Smart Engines:

  • Every share is sealed to its recipient. A share sent to a peer is encrypted to that peer’s post-quantum ML-KEM-1024 key; a share that cannot be sealed is withheld, never sent in plaintext.
  • Every committee member must take part. The ceremony completes only when every participant’s commitments and shares have arrived and checked out. A bad share aborts the creation; nothing half-made is kept.
  • Each validator checks the request before it contributes. It refuses a ceremony whose participants are not exactly its own committee, or whose threshold is below a strict majority of the committee or above its size.

Smart Engines runs two independent DKGs per entity:

System Curve Purpose On chain?
A BLS12-381 Cluster-internal attestations, quorum certificates, claim verification. BLS signatures aggregate (many → one). No — never appears on chain.
B ed25519 On-chain keys. Run N times per entity (one DKG per slot in the chain-native multisig). Yes — slot public keys can appear in the entity’s on-chain KeyList / SignerList.

Both run as real distributed ceremonies: no node ever holds another participant’s polynomial or share, or the group secret.


Now sign with the distributed key — without the fatal “collect the shares, rebuild the key, sign, delete” shortcut.

FROST (Flexible Round-Optimized Schnorr Threshold signatures, RFC 9591) produces a normal Schnorr signature in two rounds. Each signer’s share stays on its own machine; the coordinator only ever sees nonce commitments and signature shares:

%%{init: {'sequence':{'showSequenceNumbers':false}}}%%
sequenceDiagram
    autonumber
    participant Co as Coordinator
    participant S1 as Signer 1
    participant S2 as Signer 2
    participant St as Signer t
    Note over Co,St: Round 1 — nonce commitments
    S1-->>Co: commit to random nonce
    S2-->>Co: commit to random nonce
    St-->>Co: commit to random nonce
    Co->>S1: commitment list
    Co->>S2: commitment list
    Co->>St: commitment list
    Note over Co,St: Round 2 — partial signatures
    S1-->>Co: signature share (from key share + nonce)
    S2-->>Co: signature share
    St-->>Co: signature share
    Co->>Co: aggregate → one Schnorr signature
    Note over Co: Verifies under the joint public key.<br/>Indistinguishable from a single-signer signature.

A verifier (or the blockchain) cannot tell a FROST signature from a “normal” ed25519 one — that’s the entire point. Smart Engines signs with its DKG-created ed25519 slot keys this way: signing combines partial signatures, never key shares, so the whole key is never assembled — not at rest and not while signing. Before it sends anything in round 1, each signer checks the transaction against the entity’s rules and derives the message it will sign from the transaction itself, not from what the coordinator tells it.

The System-A BLS keys sign the same way in spirit: each holder produces a partial signature and the partials are combined, without any party holding the group secret.

The principle (sign with shares, never with a whole key) is universal; the algorithm varies. The platform’s design rule is to prefer the chain’s native multisig when it has one. Hedera and XRPL, the chains that are live today, both verify ed25519 signatures and both have native multisig, so the chain itself checks the quorum. Some XRPL entities go one step further and list each validator’s own XRPL key in their signer list, so each validator signs separately and the ledger counts the signatures. For the chains coming next (Stellar, Polkadot, Solana and Bitcoin), the same rule applies. See Zero Single-Signature.


Rung 5 — Per-entity ceremonies tie it together

Section titled “Rung 5 — Per-entity ceremonies tie it together”

When an entity is created, the validators: (1) run the System-A BLS DKG once, (2) run N parallel System-B ed25519 DKGs (one per multisig slot), (3) build the chain’s native multisig description for the entity, and (4) record a binding that links the entity to its validators, its slots and its rules published on HCS.

Membership changes reshare — pubkeys stay identical

Section titled “Membership changes reshare — pubkeys stay identical”

When the validator set changes (a node joins or leaves), the Shamir shares are reshared for every entity the cluster owns — but the slot public keys are unchanged, so a multisig built from them stays bit-identical across rotations. Each reshare needs a membership decision signed by a quorum of validators, and every new holder checks every contribution against its dealer’s signature before it keeps anything.


Why secrets are never derived from public data

Section titled “Why secrets are never derived from public data”

Deriving a group secret as a deterministic hash of a public payload (e.g. action + timestamp + validatorsHash + chain) is catastrophically insecure: combined with published public keys, such a secret can be recovered by brute-forcing the timestamp in seconds. Deriving per-slot ed25519 keys from a hash of a public key fails the same way. Smart Engines therefore generates every secret from a cryptographically secure random source (crypto.getRandomValues()) and shares it through real DKG — no key material is ever a function of public data.


  • Shamir splits a secret so any t-of-N reconstruct, fewer learn nothing.
  • Feldman VSS adds public commitments so shares are verifiable without a trusted dealer.
  • DKG is peer-to-peer Shamir — every validator is a dealer; the joint secret is never assembled, and only shares are stored.
  • Two DKGs per entity: BLS (internal) + N × ed25519 (on-chain slots).
  • FROST signs with shares in two rounds; the slot key is never reconstructed.
  • Resharing rotates custody; slot public keys never change.