Introduction

Imagine a company vault that requires three of five executives to open it — no single person can act alone, and the vault does not even exist in the form where any two executives could be bribed into opening it.

Threshold signatures achieve exactly this for cryptographic keys. In a (t,n)(t, n) threshold scheme, nn participants each hold a share of a private key. Any tt of them can collaborate to produce a valid signature on a message. Fewer than tt learn nothing that helps them sign — the missing shares cannot be computed from the ones they have.

The state of the art for Schnorr-based threshold signing is FROSTFlexible Round-Optimized Schnorr Threshold — published by Chelsea Komlo and Ian Goldberg in 2020 and standardized as RFC 9591 in 2024. FROST achieves the threshold property in just two communication rounds while producing a signature indistinguishable from one made by a single signer.

Related primitives you might also know: secret sharing distributes a secret so that tt of nn shares reconstruct it, and public-key cryptography underpins the hardness assumption that makes all of this secure.

Try It

The demo below models a (t,n)(t, n) threshold scheme with small toy numbers. Each participant holds a key share — a piece of the private key. To sign a message, at least tt participants each produce a partial signature using their share. When tt partial signatures are combined they aggregate into one valid signature; with fewer than tt shares the combination fails.

<!-- {{c_html_intro}} -->
<p class="hint">{{hint_para}}</p>
<div class="controls">
  <label>
    <span class="lbl">t ({{lbl_threshold}})</span>
    <input type="range" id="tSlider" min="2" max="4" value="3" step="1">
    <span id="tVal" class="val">3</span>
  </label>
  <label>
    <span class="lbl">n ({{lbl_parties}})</span>
    <input type="range" id="nSlider" min="3" max="6" value="5" step="1">
    <span id="nVal" class="val">5</span>
  </label>
</div>
<div id="participants" class="participants"></div>
<div class="btns">
  <button id="signBtn" type="button">{{btn_sign}}</button>
  <button id="resetBtn" type="button" class="ghost">{{btn_reset}}</button>
</div>
<div id="status" class="status"></div>
<div id="sigDisplay" class="sig-display"></div>
/* {{c_css_intro}} */
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; color: #222; margin: 0; font-size: 14px; }
.hint { font-size: .88rem; color: #444; margin: 0 0 .8rem; line-height: 1.5; }
.controls { display: flex; gap: 1.4rem; flex-wrap: wrap; margin-bottom: .8rem; }
.controls label { display: flex; align-items: center; gap: .5rem; }
.lbl { font-weight: 600; color: #1d3557; min-width: 7rem; }
.val { font: 700 1rem ui-monospace, monospace; color: #1d3557; min-width: 1.4rem; }
input[type=range] { accent-color: #1d3557; width: 110px; }
.participants { display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: .8rem; }
.party { display: flex; flex-direction: column; align-items: center; gap: .3rem;
         background: #e8eef3; border: 2px solid #cdd9e3; border-radius: 10px;
         padding: .5rem .7rem; cursor: pointer; user-select: none; transition: all .15s; min-width: 60px; }
.party.active { background: #1d3557; border-color: #1d3557; color: #fff; }
.party .pid { font: 700 1rem ui-monospace, monospace; }
.party .share-lbl { font-size: .72rem; opacity: .75; }
.party .partial { font-size: .72rem; font-weight: 600; min-height: 1em; }
.party.active .partial { color: #a8d8b0; }
.btns { display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: .6rem; }
button { font: 600 14px system-ui; padding: .45rem 1rem; border: 1px solid #1d3557;
         background: #1d3557; color: #fff; border-radius: 8px; cursor: pointer; }
button.ghost { background: #fff; color: #1d3557; }
.status { font-size: 1rem; font-weight: 600; min-height: 1.4em; margin-bottom: .4rem; }
.status.ok { color: #0a7d33; }
.status.bad { color: #c92f3c; }
.sig-display { font: .8rem ui-monospace, monospace; color: #555; word-break: break-all;
               background: #f4f7fa; border-radius: 6px; padding: .5rem .7rem; min-height: 2rem; }
// Code not found

Adjust tt and nn with the sliders, toggle individual participants on or off, then click Sign. Notice that exactly tt active participants succeed; t1t - 1 always fails. The signature produced is identical in structure no matter which tt participants contribute.

The Real Complexity

FROST combines two classical ideas:

Shamir secret sharing. The private key ss is split into nn shares using a random polynomial f(x)f(x) of degree t1t - 1 with f(0)=sf(0) = s. Each participant ii receives f(i)f(i). Any tt shares reconstruct ff by Lagrange interpolation — and therefore recover ss. Fewer than tt shares define a family of polynomials all consistent with those shares, so they reveal nothing about ss.

Schnorr signatures. A standard Schnorr signature on message mm by a key ss with nonce kk is the pair (R,z)(R, z) where R=kGR = k \cdot G and z=k+sH(R,m)z = k + s \cdot H(R, m). The verification equation zG=R+H(R,m)Sz \cdot G = R + H(R, m) \cdot S (with public key S=sGS = s \cdot G) holds if and only if the signer knew ss.

FROST's trick. Each of the tt participants contributes their Lagrange-weighted key share λif(i)\lambda_i \cdot f(i) as a partial response zi=ki+λif(i)H(R,m)z_i = k_i + \lambda_i \cdot f(i) \cdot H(R, m). Because the Lagrange weights sum the shares back to ss, the aggregate z=ziz = \sum z_i satisfies the single-signer verification equation exactly — without ever assembling ss in one place.

The security of the scheme rests on the discrete logarithm problem: given S=sGS = s \cdot G on an elliptic curve, computing ss is believed to be infeasible. An attacker who intercepts all tt partial signatures still cannot recover the key faster than brute-forcing the discrete log.

FROST was proven secure under the one-more discrete logarithm assumption in 2020, and the two-round variant (the basis of RFC 9591) later received a full security proof in the random oracle model.

Where It Matters

Anytime a single private key is a single point of failure, threshold signatures help:

  • Cryptocurrency custody: exchanges and self-custody wallets use (t,n)(t, n) signing so no single employee or device can drain funds. FROST is already deployed in several Bitcoin and Zcash wallets.
  • Certificate authorities: a root CA key that never exists in one place cannot be stolen in one breach. Threshold schemes protect the keys that anchor TLS for millions of websites.
  • Hardware security modules (HSMs): instead of one HSM holding the master key, a cluster of HSMs each hold a share. Quorum approval is enforced cryptographically, not just by policy.
  • Decentralized oracles and bridges: blockchain bridges that move assets across chains use threshold signatures so no single operator can forge a cross-chain transfer.
  • Government and enterprise signing: treaty documents, code-signing certificates, and audit logs benefit from requiring multiple authorized parties to co-sign.

The beauty of FROST specifically is that its output signature is indistinguishable from a regular Schnorr signature — verifiers need no special code, and the scheme integrates transparently into existing infrastructure built on discrete logarithm cryptography.

Conclusion

Threshold signatures solve a fundamental tension in cryptography: a key powerful enough to be useful is dangerous enough to be stolen. FROST's answer is elegant — never let the whole key exist in one place. Instead, distribute shares so that tt participants can act together but t1t - 1 cannot act at all.

The mathematics is a clean marriage of Shamir's secret sharing and Schnorr's signature scheme, and the result looks, to any verifier, exactly like a normal single-party signature. The vault metaphor at the start is not just an analogy — it is the precise mathematical guarantee: fewer than tt keyholders hold a system of equations with infinitely many solutions for the secret, so the secret remains hidden no matter how hard they try.

Next time you trust an exchange with your cryptocurrency, or rely on a TLS certificate to secure your connection, there is a good chance a threshold scheme is quietly enforcing the rule that no single person can betray you alone.

Share this article

Pick a channel — or use your device's native share sheet.

Comments

Loading comments...

https://www.kipuhub.com/en/article/threshold-signatures-frost/Content licensed under CC BY-NC 4.0.