1.064 Threshold Signature & Secret Sharing Libraries#
Explainer
Domain Explainer: Threshold Signatures & Secret Sharing#
Who is this for? A developer who knows what cryptography is but hasn’t worked with multi-party key management. You understand symmetric encryption, public/private key pairs, and digital signatures. Now you want to understand what happens when no single person should hold the key.
The Core Problem: Single Points of Trust#
Standard cryptography has a painful flaw for high-stakes systems: one entity holds the private key. If that entity is compromised — through breach, coercion, or insider threat — everything protected by that key is compromised.
Three scenarios where this matters:
1. The dead key problem: A company’s root CA signing key lives on one HSM. The senior engineer who knew the PIN left the company. The key is inaccessible. Business continuity requires that no single person be the key.
2. The colluding insider problem: An exchange’s hot wallet has one signing key. A sufficiently motivated attacker only needs to compromise one operator. If signing required 3 of 5 operators to agree, the attack surface is much harder.
3. The custodian problem: A law firm holds crypto assets for clients. Any single partner could theoretically misappropriate funds. A threshold system makes unilateral action impossible.
The domain of threshold cryptography and secret sharing is about solving these problems: distributing trust so that no single party can act alone, and no minority coalition can reconstruct a secret or forge a signature.
Two Different Problems, Often Confused#
Before going further, a distinction that resolves most architecture confusion:
Problem A: Secret Splitting (for storage/backup)#
“I want to split a secret so it can be reconstructed when needed.”
This is Shamir’s Secret Sharing (SSS). A dealer takes a secret (say, a root key), splits it into N shares, and distributes one share each to N trustees. Any K trustees can reconstruct the secret. Fewer than K shares reveals nothing about the secret — this is information-theoretically perfect.
Key property: The secret is assembled at reconstruction time. For that brief moment, it exists in memory on one machine.
Right for: Cold key backup, seed phrase splitting, disaster recovery, escrow.
Problem B: Threshold Signing (for operations)#
“I want to sign messages without the full key ever existing on any single machine.”
This is threshold signatures (FROST, TSS). Through multi-party computation (MPC), N parties each hold a share of a private key. To sign, K parties collaborate through an interactive protocol. The final signature is valid but no party held the complete key at any point.
Key property: The private key never exists in one place — not at setup, not at signing time.
Right for: Distributed custody, continuous signing operations, hot wallets, any case where key assembly is itself a security concern.
Shamir’s Secret Sharing — How It Works#
SSS is elegant mathematics. A secret is a point, and a polynomial is constructed through that point. Shares are other points on the polynomial. With K shares, you can uniquely reconstruct the polynomial and recover the secret. With K-1 shares, the polynomial is underdetermined — completely ambiguous.
Secret = polynomial(0)
Share₁ = polynomial(1)
Share₂ = polynomial(2)
...
ShareN = polynomial(N)
Any K shares → reconstruct polynomial → recover Secret
Any K-1 shares → infinite possible polynomials → zero information about SecretThis happens over a finite field (modular arithmetic), not ordinary numbers. PyCryptodome uses GF(2^128), which means shares are always exactly 16 bytes.
Practical limitation: Because the secret must be assembled for use, SSS is not appropriate for systems where signing must happen frequently or where the assembly point itself is a threat.
FROST — Threshold Schnorr Signatures#
FROST (Flexible Round-Optimized Schnorr Threshold signatures) is the modern standard for threshold signing when your signature scheme is Schnorr-based (Ed25519, P-256, Taproot, ristretto255).
Why Schnorr enables this: Schnorr signatures have a linear structure. The math works out such that partial signatures from K parties can be combined into one valid signature that is identical to a standard single-party Schnorr signature. An observer cannot tell whether a FROST signature came from one person or fifty.
FROST standardized: RFC 9591 (June 2024). This is now an IETF standard, meaning implementations can test for interoperability and enterprise buyers can point to a stable specification.
Two Ways to Set Up FROST Keys#
Trusted Dealer: One entity generates the keypair, splits the private key via SSS, distributes shares. Simpler. Requires trusting the dealer not to retain the key.
Distributed Key Generation (DKG): Participants run an interactive protocol. No single entity ever holds the full private key, even during setup. Uses Pedersen VSS — participants can verify their shares are consistent without revealing the secret. More complex, higher assurance.
FROST Signing Flow#
Setup (once):
All N parties run DKG → each holds a key share
Public key is known to everyone
Signing (when needed, with K of N):
Round 1: Each signer generates a nonce, broadcasts commitment
Round 2: Aggregator sends signing package; each signer computes partial signature
Aggregation: Aggregator combines K partial signatures → one valid Schnorr signatureThe resulting signature is verifiable with the group’s public key using standard Schnorr verification. The verifier doesn’t need to know this was a threshold operation.
Threshold ECDSA — Why It’s Harder#
ECDSA (Ethereum, Bitcoin legacy) is not linearly structured the way Schnorr is. The nonce inversion step (k⁻¹ mod n) means partial signatures can’t simply be added together.
Threshold ECDSA requires more heavyweight MPC techniques: Oblivious Transfer, Paillier homomorphic encryption, and zero-knowledge proofs. The protocols are significantly more complex:
GG18/GG20: First practical threshold ECDSA protocols (2018-2021). Complex setup, multiple rounds, many ZK proofs.
tss-lib(Go, BNB Chain) implements GG20.CGGMP21 (2021): UC-secure, identifiable aborts, non-interactive signing after precomputation, proactive key refresh.
dfns/cggmp21(Rust) is the audited implementation.
The practical takeaway: If you can choose your signature scheme, use Schnorr/Ed25519 and FROST. If you’re constrained to ECDSA (compatibility with Ethereum, Bitcoin), use CGGMP21.
Verifiable Secret Sharing — The Gap#
Basic SSS has a subtle vulnerability: shares aren’t authenticated. If a malicious trustee submits a corrupted share during reconstruction, the result is wrong output — not an error. You can’t tell which share was bad.
Feldman VSS adds polynomial commitments, published by the dealer. Each shareholder can verify their share is on the committed polynomial. Corrupted share → detected.
Pedersen VSS adds a blinding factor for privacy-preserving commitments (used by FROST’s DKG).
The gap: no clean Python library implements Feldman VSS. PyCryptodome’s SSS has no share verification. If trustees might be adversarial, you either need Rust/Go libraries or an out-of-band share verification ceremony.
The Python Ecosystem Gap#
This is the uncomfortable truth of this domain: Python has no production-grade threshold signing library.
| Use case | Python option | Caveats |
|---|---|---|
| Secret splitting (SSS) | PyCryptodome | Audited. No Feldman VSS. |
| Mnemonic shares (SLIP-39) | shamir-mnemonic | For humans, not servers. No side-channel hardening. |
| Threshold Schnorr (FROST) | PyFrost | Unaudited. Real production use by Zellular but small ecosystem. |
| Threshold ECDSA | None viable | Use managed service or Rust sidecar. |
Why this gap exists: Threshold cryptography requires high-performance, low-level implementations with side-channel hardening. The Rust ecosystem moved faster here. By the time there was enough developer demand for Python wrappers, the production Rust libraries (ZF FROST, dfns/cggmp21) were the obvious targets, and Python bindings remain experimental.
For Python applications that need threshold signing, in priority order:
- Reconsider the requirement — is standard multisig (K independent ECDSA/Ed25519 signatures) sufficient? Often yes.
- Use a managed service (Dfns, Fireblocks, Turnkey) — audited MPC, REST API.
- Build a Rust sidecar — ZF FROST or dfns/cggmp21 as a gRPC/REST service called from Python.
- Use PyFrost — if you accept the unaudited risk for non-adversarial environments.
Library Map#
For Secret Splitting#
| Library | Language | Standard | Audit |
|---|---|---|---|
| PyCryptodome | Python | GF(2^128) SSS | Part of PyCryptodome review |
| shamir-mnemonic | Python | SLIP-39 | Not audited for server use |
For Threshold Schnorr (FROST)#
| Library | Language | Curves | Audit |
|---|---|---|---|
| ZF FROST | Rust | Ed25519, P-256, ristretto255, Ed448 (audited); secp256k1-tr (not audited) | NCC Group, 2023 |
| givre (dfns) | Rust | Ed25519, secp256k1 | No public audit yet |
| PyFrost | Python | secp256k1 (BLS12-381) | No public audit |
For Threshold ECDSA#
| Library | Language | Protocol | Audit |
|---|---|---|---|
| dfns/cggmp21 | Rust | CGGMP21 | Kudelski Security |
| bnb-chain/tss-lib | Go | GG20 | No public audit; battle-tested |
When to Use Each Pattern#
What are you trying to do?
│
├── Protect a key at rest (backup, escrow, disaster recovery)
│ → Shamir Secret Sharing (PyCryptodome)
│ → Human-readable shares? → shamir-mnemonic (SLIP-39)
│
├── Sign messages with quorum consent, key never assembled
│ ├── Schnorr/Ed25519/Taproot signatures?
│ │ → ZF FROST (Rust) — RFC 9591 compliant, partially audited
│ │ → Python only? → PyFrost (unaudited) or managed service
│ │
│ └── ECDSA (Ethereum/Bitcoin)?
│ → dfns/cggmp21 (Rust, audited) — new systems
│ → bnb-chain/tss-lib (Go, battle-tested) — Go shops or GG20 compat
│ → Python? → Managed service only
│
└── Approve K-of-N actions at application layer?
→ Often: regular multisig is enough
(K independent signatures, verifier checks K valid sigs)
→ Threshold only if: compact 1 signature required, or signer privacy neededKey Concepts Glossary#
Threshold (K-of-N): K participants out of N are required to perform an operation. Any coalition of K-1 or fewer cannot.
Share: A piece of information distributed to a participant. Useless alone (below threshold), enabling when combined with enough others.
DKG (Distributed Key Generation): A protocol where N parties jointly generate a keypair without any single party learning the full private key.
Proactive Security: Periodic share refresh — shares are updated without changing the public key. If a node is compromised over time, old shares become invalid after a refresh cycle. CGGMP21 supports this; GG20 does not.
Identifiable Abort: If a signing session fails because a participant misbehaved, the protocol can identify which participant. Critical for accountability in custody systems. CGGMP21 has this; GG20 does not.
VSS (Verifiable Secret Sharing): SSS extended so share holders can verify their share is correct (Feldman VSS) or verify without revealing the secret (Pedersen VSS). Detects malicious dealers.
UC Security (Universally Composable): A strong security model that guarantees the protocol remains secure even when composed with arbitrary other protocols. CGGMP21 has a UC proof; GG20 does not.
ICE-FROST: “Identifiable Cheating Entity FROST” — an extension of FROST that can identify misbehaving participants during signing. Used by PyFrost.
Aggregator: In FROST, the party (or designated node) that collects partial signatures and combines them into the final Schnorr signature. Does not need to be trusted — cannot forge signatures.
Sources and Further Reading#
- RFC 9591 — FROST — The IETF standard
- NCC Group FROST Audit — What was audited, what wasn’t
- Cryptologie.net: SSS vs multisig vs BLS vs DKG vs threshold — Authoritative comparison
- dfns: CGGMP21 in Rust at Last — Background on the library
- PyCryptodome SecretSharing docs — Python SSS API
- SLIP-0039 spec — Mnemonic share standard
- Blockchain Commons FROST Developer Resources — Practical guides
S1: Rapid Discovery
S1 Approach: Rapid Discovery#
Objective: Map the threshold signature and secret sharing library landscape in Python, Rust, and Go. Identify the key categories, leading libraries, and fundamental distinctions between SSS (offline key splitting) and threshold signing (distributed key operations).
Method: Web search for “threshold signature library python rust”, “shamir secret sharing python library”, “FROST threshold signature”, “threshold ECDSA library”, and related queries. Review GitHub repositories for star counts, recent commits, and readme descriptions.
Time budget: ~15 minutes.
Key questions to answer:
- What are the library categories in this domain?
- Is there a viable Python option for production use?
- What is the audit status of the major libraries?
- Which protocols (GG20, CGGMP21, FROST) correspond to which libraries?
S1 Rapid Discovery: Threshold Signature / Secret Sharing Libraries#
Research ID: 1.064 Pass: S1 — Rapid Discovery Date: 2026-02-16 Scope: 5-10 min ecosystem survey
The Domain#
Two related but distinct problems:
Secret Sharing — Split a secret value into n shares such that any k shares can reconstruct it, but k-1 shares reveal nothing. Offline; no network required. Used for key backup, seed phrase splitting, credential escrow.
Threshold Signatures — A group of n parties can collectively produce a single valid cryptographic signature if at least k of them participate, but no party ever holds the full private key. Requires an interactive protocol. Used for distributed custody, multi-party approval, quorum signing.
These are often conflated. Shamir’s Secret Sharing solves the first; FROST and threshold ECDSA solve the second. A naive “SSS + recombine + sign” is NOT threshold signing — it requires reassembling the key, which defeats the security model.
Landscape by Category#
1. Shamir’s Secret Sharing (SSS) — Offline Key Splitting#
| Library | Language | Notes |
|---|---|---|
PyCryptodome (Crypto.Protocol.SecretSharing) | Python | Best production option: audited, maintained, GF(2^128) |
trezor/python-shamir-mnemonic | Python | Reference impl of SLIP-39; mnemonic encoding; not hardened against side-channels |
sssa-python (SSSaaS) | Python | Simple GF(prime) implementation; unmaintained |
secretshare (PyPI) | Python | Tiny; GF(prime); 8192-bit limit |
python-sslib | Python | Minimal; no audits |
vsss / Feldman VSS | varies | Adds polynomial commitment (verifiable shares) |
SLIP-39 (shamir-mnemonic on PyPI) is the standard for human-readable mnemonic shares used by hardware wallets (Trezor). Not for raw key material in code — for backup UX.
2. FROST — Threshold Schnorr Signatures#
The state of the art for threshold Schnorr. Standardized as RFC 9591 (2024).
| Library | Language | Curves | Status |
|---|---|---|---|
ZcashFoundation/frost (frost-core et al.) | Rust | ed25519, p256, secp256k1, ristretto255, secp256k1-tr | Production-ready; partial NCC audit (v0.6.0); actively maintained |
frost-secp256k1-tr | Rust | secp256k1 (taproot) | Stable, not yet in audit scope |
frost-python (devos50) | Python | Bindings to ZF FROST Rust | Experimental; not for production |
| Go FROST (Taurus group) | Go | ed25519 | Not production-ready; no external audit |
frost-dalek | Rust | Ristretto255 | Older, lower-level |
| Blockchain Commons FROST | various | multiple | Research/reference implementations |
Key insight: The only production-ready FROST implementation is ZcashFoundation’s Rust crates. Python access requires FFI bindings.
3. Threshold ECDSA — Distributed secp256k1/P-256 Signing#
More complex than FROST; used heavily in crypto custody.
| Library | Language | Protocol | Status |
|---|---|---|---|
bnb-chain/tss-lib | Go | GG20 | Production; used by Binance, many bridges |
dfns-tech/cggmp21 | Rust | CGGMP21 | Audited (Kudelski Security); first audited CGGMP21 impl |
ZenGo-X/multi-party-ecdsa | Rust | GG18/GG20 | Abandoned (2023); no security updates |
cggmp-threshold-ecdsa (tangle-network) | Rust | CGGMP21 | Active; Webb Protocol |
boltlabs/tss-ecdsa | Rust | Custom | Research-grade |
tss4j | Java | GG20 + FROST | Lightweight; newer |
Protocol lineage: GG18 → GG20 (adds one-round signing) → CGGMP21 (identifiable aborts, more efficient). CGGMP21 is the current recommended protocol.
4. MPC Frameworks (General)#
Not threshold-signature-specific but enable building them:
| Framework | Language | Notes |
|---|---|---|
| MP-SPDZ | C++ | Academic; many protocols (SPDZ, BMR, Yao) |
| MOTION | C++ | Research; garbled circuits + OT |
| ABY | C++ | Academic; Boolean + arithmetic |
tf-encrypted | Python/TF | ML-focused MPC |
General MPC frameworks are research-grade. For threshold signatures specifically, use purpose-built libraries above.
Key Distinctions#
| Concern | SSS | FROST | Threshold ECDSA |
|---|---|---|---|
| Requires network round-trips | No | 2 rounds | 2+ rounds |
| Full key ever assembled | At reconstruction | Never | Never |
| Curve | Any (arbitrary secret) | Schnorr curves | secp256k1, P-256 |
| Bitcoin/Ethereum compatible | — | BIP-340 Taproot (secp256k1-tr) | secp256k1 ✓ |
| Production library exists | PyCryptodome | ZF FROST (Rust) | bnb tss-lib (Go), dfns cggmp21 (Rust) |
Preliminary Verdicts (S1)#
For key backup / escrow (offline): PyCryptodome.SecretSharing — only audited Python option.
For threshold Schnorr / Taproot: ZF FROST (frost-secp256k1-tr) — only production-ready option, Rust only.
For threshold ECDSA (Ethereum/Bitcoin legacy): bnb-chain/tss-lib (Go, battle-tested) or dfns-tech/cggmp21 (Rust, audited, more modern protocol).
For Python applications needing threshold signing: No pure-Python production option exists. Must use FFI to Rust or subprocess to Go binary, or use a threshold signing service (Fireblocks, Dfns, Lit Protocol).
Open Questions for S2#
- How production-ready is ZF FROST’s DKG (distributed key generation) vs. trusted dealer setup?
- What exactly did the NCC audit of ZF FROST cover, and what wasn’t audited?
- Is there a Python wrapper for
bnb-chain/tss-libordfns-tech/cggmp21? - What does “identifiable aborts” in CGGMP21 mean in practice, and does it matter for a small quorum?
- Proactive secret sharing (share refresh without key reconstruction) — which libraries support it?
- Feldman VSS vs Pedersen VSS — which does ZF FROST use, and why does it matter?
Sources#
- ZcashFoundation/frost (GitHub)
- frost-core on crates.io
- ZF FROST Book
- dfns-tech CGGMP21 blog
- bnb-chain/tss-lib
- trezor/python-shamir-mnemonic
- PyCryptodome Secret Sharing docs
- RFC 9591 — FROST
S1 Recommendation: Rapid Discovery#
Core Finding#
The domain splits into two families with very different maturity profiles:
- SSS (Secret Splitting): Mature, simple, well-understood. PyCryptodome covers Python.
- Threshold Signatures: No production-ready Python library exists. Rust is the only audited option.
Preliminary Winners by Use Case#
| Use Case | Library | Language |
|---|---|---|
| Secret backup / key splitting | PyCryptodome | Python |
| SLIP-39 mnemonic shares | shamir-mnemonic | Python |
| Threshold Schnorr | ZF FROST | Rust |
| Threshold ECDSA | dfns/cggmp21 | Rust |
| Threshold ECDSA (Go) | bnb-chain/tss-lib | Go |
| Python threshold signing | Managed service or FFI | — |
Confidence Level#
High confidence on the Python gap (structural, confirmed by multiple searches). Medium confidence on library rankings (pending S2 audit and feature confirmation).
What S2 Must Validate#
- Exact audit scope and gaps for ZF FROST (NCC Group)
- DKG support (trusted dealer vs. distributed)
- Whether any Python binding is production-viable
- Proactive security / share refresh capabilities
S1 Synthesis: Threshold Signature / Secret Sharing#
The Core Finding#
This domain splits cleanly into two families with very different maturity profiles:
Secret sharing (SSS) — mature, simple, well-understood. PyCryptodome covers it in Python. The main trap is using SSS for signing (reconstruct key → sign), which defeats the whole threat model.
Threshold signatures — the hard problem. No production-ready Python library exists. The Rust ecosystem is the only place with audited code. Python developers must choose between FFI (hard), subprocess (fragile), or a managed threshold service.
The Python Gap#
The survey was prompted by the question: “which library for quorum signing?” The honest answer is: none, in pure Python. The options are:
- Call Rust via FFI (
frost-pythonbindings — experimental) - Ship a Go or Rust binary and call it as subprocess
- Use a managed threshold signing service (Fireblocks, Dfns, Lit Protocol, Turnkey)
- Use SSS + reconstruct key if the threat model allows it (simpler but weaker)
This is the “hardest unsolved library question” because it IS unsolved in the Python ecosystem.
Recommendation Direction (pending S2 confirmation)#
| Use Case | Library | Language | Risk |
|---|---|---|---|
| Secret backup, key splitting | PyCryptodome | Python | Low |
| SLIP-39 mnemonic shares | shamir-mnemonic | Python | Low (side-channel aware) |
| Threshold Schnorr (Taproot) | ZF FROST (frost-secp256k1-tr) | Rust | Medium (partial audit) |
| Threshold ECDSA | dfns-tech/cggmp21 | Rust | Medium (audited) |
| Threshold ECDSA (Go preferred) | bnb-chain/tss-lib | Go | Low (battle-tested) |
| Python w/ threshold signing | Managed service or FFI | — | Varies |
What S2 Must Resolve#
- Exact audit coverage and gaps for ZF FROST
- DKG ceremony requirements (trusted dealer vs. distributed)
- Whether any Python binding is viable for S2 → production path
- Proactive security / share refresh support
S2: Comprehensive
S2 Approach: Comprehensive Analysis#
Objective: Deep-dive each major library. Confirm audit scope, protocol details, API patterns, and Python access paths. Establish a decision framework.
Method:
- Read NCC Group FROST audit report and ZF FROST audit announcement
- Review RFC 9591 for protocol details
- Search dfns/cggmp21 blog posts and audit disclosure
- Search PyFrost (zellular-xyz) GitHub and documentation
- Research PyCryptodome’s GF(2^128) implementation details and VSS gap
- Compare GG20 vs CGGMP21 protocol properties
Libraries examined in depth:
- PyCryptodome (
Crypto.Protocol.SecretSharing) — Python SSS - shamir-mnemonic (Trezor, SLIP-39) — Python mnemonic shares
- ZF FROST — Rust threshold Schnorr (RFC 9591)
- givre (LFDT-Lockness/dfns) — Rust FROST alternative
- PyFrost (zellular-xyz) — Python threshold signing
- dfns/cggmp21 — Rust threshold ECDSA (CGGMP21 protocol)
- bnb-chain/tss-lib — Go threshold ECDSA (GG20 protocol)
Key questions:
- What exactly was audited in ZF FROST, and what wasn’t?
- Why is threshold ECDSA harder than threshold Schnorr?
- What is the honest Python path to production threshold signing?
S2 Comprehensive Analysis: Threshold Signature / Secret Sharing Libraries#
Research ID: 1.064 Pass: S2 — Comprehensive Analysis Date: 2026-02-16
1. Shamir’s Secret Sharing — Deep Dive#
PyCryptodome (Crypto.Protocol.SecretSharing)#
Implementation: GF(2^128) with irreducible polynomial x^128 + x^7 + x^2 + x + 1 (same as AES-GCM).
Design choice: GF(2^128) rather than GF(prime) means:
- All shares are exactly 16 bytes (fixed-size, no padding)
- XOR-based field arithmetic (fast, side-channel-resistant vs prime modular arithmetic)
- Naturally protects 128-bit secrets (AES-128 keys, GUIDs)
- For longer secrets: split into chunks (PyCryptodome handles this automatically)
Security properties:
- Information-theoretic security (not computational — even unlimited compute can’t break it)
- Perfect secrecy: any
k-1shares reveal literally zero information about the secret - Not audited as a standalone component, but part of PyCryptodome which has received extensive review
- Compatible with the
sssscommand-line tool (-s 128 -Dflags)
Limitations:
- No verifiable shares (Feldman/Pedersen VSS not included)
- Shares are not authenticated — a malicious share holder can submit a bad share and reconstruction silently produces garbage (vs. an error)
- No proactive refresh (cannot refresh shares without reassembling the secret)
- 16-byte output limit per chunk (but auto-chunks for larger secrets)
API:
from Crypto.Protocol.SecretSharing import Shamir
# Split: 2-of-5 scheme
shares = Shamir.split(2, 5, b'\xAA' * 16)
# Recombine:
secret = Shamir.combine(shares[:2])SLIP-39 / shamir-mnemonic (Trezor)#
Purpose: Human-readable Shamir shares for seed phrase backup. This is NOT a library for programmatic use in signing systems — it’s a UX layer for hardware wallet seed backup.
Standard: SLIP-0039 (Satoshi Labs)
How it differs from raw SSS:
- Secret is first encrypted by a passphrase → Encrypted Master Secret
- Shares are encoded as mnemonic words (like BIP-39 but for shares)
- Supports two-level sharing: groups of shares with a group threshold
Caveat (from Trezor themselves): “This implementation is not using any hardening techniques; secrets are passed in the open and calculations are vulnerable to side-channel attacks.” Intended as reference implementation, not production server code.
Wallet support: Trezor, Ledger (planned), Electrum, Sparrow.
Use case: Seed phrase backup split across trustees. Not for application-layer quorum signing.
Feldman VSS vs. Pedersen VSS#
Both add a polynomial commitment scheme to SSS so share holders can verify their share is consistent with the others (without learning the secret).
- Feldman VSS: Commitments are public; share holders can verify against published commitments. Commitment reveals nothing about the secret in the DL hardness assumption.
- Pedersen VSS: Adds a blinding factor; computationally hiding even if DL is broken. Used by ZF FROST’s DKG.
Why it matters: Without VSS, a malicious dealer can distribute invalid shares that reconstruct to a wrong secret. VSS detects this.
2. FROST — Comprehensive Analysis#
RFC 9591 (FROST Standard)#
FROST was standardized as RFC 9591 in June 2024. This is significant: it’s now an IETF standard, not just a research paper. Implementations can be compared against a fixed specification.
Protocol overview:
- Key Generation (one-time): Either trusted dealer (dealer generates key, distributes shares) or DKG (no trusted party, participants collaborate to generate key no one knows)
- Signing Round 1: Each signer generates a nonce commitment, broadcasts to aggregator
- Signing Round 2: Aggregator constructs signing package, each signer computes a partial signature
- Aggregation: Aggregator combines partial signatures into final Schnorr signature
Security: The resulting signature is indistinguishable from a single-party Schnorr signature. An observer cannot tell how many parties signed.
ZcashFoundation/frost (Rust) — The Reference#
Audit: NCC Group, Summer 2023, 25 person-days, v0.6.0.
- In scope: key generation (trusted dealer + DKG), FROST signing, frost-core, frost-ed25519, frost-p256, frost-ristretto255, frost-ed448
- Not in scope: frost-secp256k1-tr (Taproot), rerandomized FROST
- Result: All findings fixed and re-verified by NCC.
Crate structure:
frost-core # base traits, curve-agnostic
frost-ed25519 # Ed25519 (audited)
frost-p256 # P-256/NIST (audited)
frost-ristretto255 # Ristretto255 (audited)
frost-ed448 # Ed448 (audited)
frost-secp256k1 # secp256k1 (NOT in audit)
frost-secp256k1-tr # secp256k1 Taproot BIP-340 (NOT in audit)DKG: Implements Pedersen DKG (no trusted dealer required). Each participant runs the DKG ceremony; the final key pair is distributed with no single party ever holding the full private key.
Trusted Dealer: Simpler setup — one party generates the key, splits it via Shamir, distributes shares. Party must be trusted not to retain the key.
Usage pattern (simplified):
// Trusted dealer setup
let (shares, pubkey_package) = frost::keys::generate_with_dealer(
5, // max_signers
3, // min_signers
IdentifierList::Default,
&mut rng,
)?;
// Round 1: each signer generates commitments
let (nonces, commitments) = frost::round1::commit(key_package.signing_share(), &mut rng);
// Round 2: each signer signs
let signature_share = frost::round2::sign(&signing_package, &nonces, &key_package)?;
// Aggregator combines
let signature = frost::aggregate(&signing_package, &signature_shares, &pubkeys)?;Dfns/Givre (Rust) — The Alternative FROST#
Dfns released givre (under LFDT-Lockness organization) as a FROST implementation with a focus on performance.
Claims: Fastest Threshold EdDSA in Rust, outperforming ZF FROST.
Key differentiator: Uses round_based framework for interactive protocol execution — handles the network layer explicitly, whereas ZF FROST leaves networking to the application.
Curves: secp256k1, Ed25519 at minimum.
Audit status: Not yet publicly reported (unlike cggmp21 which was Kudelski-audited).
Production status: Used by Dfns internally.
PyFrost (zellular-xyz) — The Python Option#
What it is: Pure Python implementation of FROST for Schnorr threshold signatures.
Includes: libp2p-based networking for nodes, signature aggregator, DKG.
ICE-FROST: Incorporates “Identifiable Cheating Entity FROST” — an extension that can identify which participant misbehaved during signing.
Audit status: No public audit found.
Production status: Used by Zellular (a decentralized sequencer project). Not independently audited.
Risk: Pure Python crypto is generally slower and more side-channel-prone than Rust. No external security review. The Zellular use case provides some real-world validation but it’s a small ecosystem.
3. Threshold ECDSA — Comprehensive Analysis#
Why Threshold ECDSA is Harder Than FROST#
Schnorr signatures have a linear structure that makes threshold construction relatively natural. ECDSA has a non-linear inversion step (k^{-1} mod n) that requires MPC protocols involving Oblivious Transfer, Paillier encryption, or zero-knowledge proofs — making threshold ECDSA significantly more complex.
Protocol evolution:
- GG18 (2018): First practical threshold ECDSA. Complex setup, many ZK proofs.
- GG20 (2021): Added one-round online signing, improved efficiency.
- CGGMP21 (2021): UC-secure, identifiable aborts, non-interactive signing with precomputation, proactive security.
bnb-chain/tss-lib (Go) — The Battle-Tested Option#
Background: Originally developed by Binance as part of their cross-chain bridge infrastructure. Now maintained by BNB Chain. Used in production by multiple cross-chain protocols.
Protocol: GG20 (not CGGMP21).
Supported signatures: ECDSA (secp256k1) and EdDSA.
Architecture: Each party runs a state machine. Communication is handled externally — the library produces and consumes messages but doesn’t handle networking itself.
Audit: Not a public audit report found, but battle-tested across multiple production deployments (Thorchain, dYdX, various cross-chain bridges).
Python access: None native. Would require Go binary subprocess or cgo FFI.
dfns-tech/cggmp21 (Rust) — The Modern Audited Option#
Protocol: CGGMP21 — current state-of-the-art for threshold ECDSA.
Key features:
- UC Security: Universally Composable security proof
- Non-interactive signing: 1-round after precomputation (Auxiliary Info phase)
- Proactive security: Periodic key share refresh without changing the public key
- Identifiable aborts: Can identify which party misbehaved if signing fails
Audit: Kudelski Security. Report available publicly. Vulnerabilities found in earlier versions were patched and disclosed.
License: MIT + Apache 2.0 (dual).
Production: Dfns uses this for their own ECDSA signing keys. Open-sourced after internal production use.
Python access: None native. Rust FFI via PyO3 possible but not provided.
Repository: github.com/dfns/cggmp21 (now under LFDT-Lockness).
Comparison: GG20 vs CGGMP21#
| Property | GG20 (tss-lib) | CGGMP21 (dfns) |
|---|---|---|
| UC Security proof | No | Yes |
| Online signing rounds | 1 (with presigning) | 1 (with presigning) |
| Identifiable abort | No | Yes |
| Proactive refresh | No (in tss-lib) | Yes |
| Language | Go | Rust |
| Public audit | Not found | Kudelski Security ✓ |
| Battle-tested in prod | Yes (bridges, custodians) | Yes (Dfns) |
| Python support | None | None |
4. Python Access Paths — The Honest Assessment#
Option A: frost-python FFI (devos50)#
- Python bindings to ZF FROST Rust
- Experimental, not production-ready
- API coverage: partial
Option B: PyFrost (zellular-xyz)#
- Pure Python, no FFI required
- No public audit
- ICE-FROST variant (not RFC 9591 vanilla FROST)
- Includes networking layer
- Viable for: research, internal tooling, non-adversarial environments
Option C: Subprocess to binary#
- Compile ZF FROST demo or tss-lib to a binary
- Python calls it via subprocess with JSON I/O
- Fragile, deployment complexity, latency overhead
- Production-unsuitable for high-frequency signing
Option D: Managed threshold service#
| Service | Protocol | Language | Notes |
|---|---|---|---|
| Fireblocks | GG20/CGGMP | Proprietary SDK | Custodial, enterprise pricing |
| Dfns | CGGMP21 | REST API | Audited protocol |
| Lit Protocol | FROST | JavaScript | Open source; permissioned network |
| Turnkey | MPC-TSS | REST API | Key management as a service |
| Web3Auth (Torus) | MPC | JavaScript | OAuth-linked key sharding |
5. Decision Framework (Preliminary)#
Do you need threshold SIGNING (no key assembly) or key BACKUP (split + reassemble ok)?
│
├── Key backup only → PyCryptodome (Python, audited, GF(2^128))
│ ├── Need human-readable mnemonic shares → shamir-mnemonic (SLIP-39)
│ └── Need verifiable shares → Add Feldman VSS on top (no good Python lib; see gaps)
│
└── Threshold signing (key never assembled)
│
├── Schnorr / Ed25519 / Taproot?
│ ├── Rust ok → ZF FROST (audited for most curves) or givre (faster, less audited)
│ ├── Python acceptable → PyFrost (no audit; ok for non-adversarial)
│ └── Full service → Lit Protocol or Fireblocks
│
└── ECDSA (Ethereum/Bitcoin legacy)?
├── Rust ok → dfns/cggmp21 (audited, CGGMP21)
├── Go ok → bnb-chain/tss-lib (battle-tested, GG20)
├── Python required → No good option; use managed service
└── Full service → Fireblocks, Dfns, TurnkeyKey Findings from S2#
ZF FROST audit is comprehensive but has gaps: secp256k1-tr (Taproot) and rerandomized FROST were not audited. For Bitcoin Taproot specifically, this is the relevant crate.
CGGMP21 > GG20: If choosing between protocols, CGGMP21 has UC security, identifiable aborts, and proactive refresh. The dfns implementation is audited. Prefer it over tss-lib for new systems.
PyFrost is the best Python option for FROST but carries risk: No public audit, but real production use by Zellular. Usable for internal tooling. Not appropriate for adversarial, high-value custody.
PyCryptodome SSS has a critical limitation: No verifiable shares. A malicious/corrupted share silently produces wrong output. For trust-minimized setups, need VSS.
Proactive security matters for long-lived keys: CGGMP21 supports share refresh without key rotation. GG20/tss-lib does not (in the standard library). Over time, if a node is compromised, old shares become invalid after refresh.
The Python gap is real and structural: Threshold ECDSA and audited FROST are Rust/Go only. The Python ecosystem has no production-grade threshold signing library.
Sources#
- NCC Group FROST audit report
- ZF FROST announcement
- RFC 9591 — FROST
- dfns cggmp21 article
- dfns givre article
- dfns/cggmp21 GitHub
- LFDT-Lockness/givre GitHub
- bnb-chain/tss-lib GitHub
- zellular-xyz/pyfrost GitHub
- devos50/frost-python GitHub
- PyCryptodome SecretSharing docs
- SLIP-0039 spec
S2 Recommendation: Comprehensive Analysis#
What S2 Confirmed#
- Python gap is structural: No audited Python threshold signing library. Not a gap that will close soon.
- ZF FROST audit scope: NCC Group, v0.6.0. Ed25519, P-256, ristretto255, Ed448 audited. secp256k1-tr (Taproot) NOT audited.
- CGGMP21 > GG20: UC security, proactive refresh, identifiable aborts. dfns/cggmp21 (Kudelski-audited).
- PyCryptodome VSS gap: No share verification — corrupted share yields silent wrong output.
- PyFrost is real: Production use by Zellular, but no public audit.
Recommended Slots by Language#
| Language | SSS | Threshold Schnorr | Threshold ECDSA |
|---|---|---|---|
| Python | PyCryptodome | PyFrost (unaudited) | None — use service |
| Rust | — | ZF FROST or givre | dfns/cggmp21 |
| Go | — | — | bnb-chain/tss-lib |
Key Architecture Guidance#
For Python applications needing threshold signing:
- Reconsider: Is standard multisig (K independent signatures) sufficient? Often yes.
- Managed service: Dfns, Fireblocks, Turnkey for production.
- Rust sidecar: ZF FROST or cggmp21 as a gRPC service called from Python.
- PyFrost: Internal/research use only (no audit).
S2 Synthesis: Threshold Signature / Secret Sharing#
What S2 Confirmed from S1#
- Python has no production-grade threshold signing library (confirmed, structural, not a gap that will close soon)
- ZF FROST is the right Rust option for Schnorr, but the Taproot crate is outside the audit scope
- PyCryptodome is the right Python option for SSS/key-splitting only
- dfns/cggmp21 is the best audited option for threshold ECDSA
What S2 Added#
VSS gap in PyCryptodome: Unverifiable shares. A corrupted share yields silent wrong output, not an error. For adversarial setups, need Feldman VSS added on top (no clean Python library for this).
Proactive security is a differentiator: CGGMP21 supports periodic key share refresh without key rotation. GG20 does not. Long-lived threshold keys (custody over years) need this.
RFC 9591: FROST is now a standard. ZF FROST tracks this. This is the stable interoperability baseline.
PyFrost (Zellular) is real but unaudited: Has real production use. Includes networking. Best Python option for FROST, but carries unknown security risk.
Two FROST Rust implementations: ZF FROST (partial NCC audit) vs givre/dfns (faster, no public audit yet). Neither is universally dominant.
Recommended Slots by Language#
| Language | SSS | Threshold Schnorr | Threshold ECDSA |
|---|---|---|---|
| Python | PyCryptodome | PyFrost (unaudited) | None — use service |
| Rust | (use PyCryptodome from Python) | ZF FROST or givre | dfns/cggmp21 |
| Go | (use subprocess) | — | bnb-chain/tss-lib |
| “I need Python + threshold signing” | — | PyFrost + accept risk, OR managed service | Managed service only |
S3 Focus Areas#
- Real-world architectures: how do systems that use threshold signing in Python actually do it?
- When is SSS “good enough” vs threshold signing required?
- Managed service TCO vs self-hosted
- DKG ceremony UX in practice
S3: Need-Driven
S3 Approach: Need-Driven Discovery#
Objective: Map concrete use cases to specific libraries. Determine when SSS is “good enough” vs. when threshold signing is required. Assess managed service options for the Python gap.
Method: Identify real-world scenarios from web research, blog posts, and product documentation. Compare SSS vs. threshold signing for each use case. Price managed services.
Use cases examined:
- Distributed key backup (cold storage / escrow)
- Hardware wallet seed backup (SLIP-39, human-readable)
- Quorum-gated signing (distributed custody, hot wallets)
- Approval quorum for high-stakes actions (deployment, transfers)
- Distributed MPC for agent/service signing keys
Key question: When can you use SSS instead of threshold signing, and when does the distinction matter?
Managed Threshold Services#
For Python applications that need production threshold signing, the practical answer is a managed service.
Service Comparison#
| Service | Protocol | Pricing | Audit | Notes |
|---|---|---|---|---|
| Fireblocks | GG20 / CGGMP21 | Enterprise (custom) | SOC 2, multiple audits | Industry leader; custodial; deep wallet integrations |
| Dfns | CGGMP21 | Per-operation + monthly | Kudelski Security | Developer-friendly API; open-source protocol layer |
| Turnkey | MPC-TSS | Per-key + per-operation | SOC 2 | Key management as a service; good API |
| Lit Protocol | FROST | Network fee | — | Decentralized threshold network; open source; JavaScript-native |
| Web3Auth (Torus) | MPC | Free tier available | — | OAuth-linked key sharding; user-facing |
Decision Guide#
I need institutional-grade custody (real assets, compliance): → Fireblocks or Dfns. Both SOC 2 certified; Dfns specifically audited on CGGMP21.
I’m a developer building an app (reasonable budget): → Dfns or Turnkey. Good APIs, clear pricing, no enterprise procurement required.
I want decentralized / no-single-vendor-dependency: → Lit Protocol. Open source, permissioned nodes, verifiable threshold computation. JavaScript SDK.
I’m building for consumer users (social login): → Web3Auth. Ties threshold key shares to OAuth credentials; user-friendly recovery.
Self-Hosted Alternative#
For teams comfortable with Rust:
- Deploy ZF FROST (Schnorr) or dfns/cggmp21 (ECDSA) as an internal service
- Expose via gRPC or REST
- Python application calls the sidecar
- Operational cost: running N threshold signing nodes
This avoids vendor lock-in but requires cryptographic ops expertise.
S3 Recommendation: Need-Driven Discovery#
Clear Winner by Use Case#
- Key backup / escrow → PyCryptodome (Python, audited, simple)
- Human-readable seed backup → shamir-mnemonic (SLIP-39, Trezor)
- Threshold Schnorr (Rust) → ZF FROST (RFC 9591, partial audit)
- Threshold ECDSA (Rust) → dfns/cggmp21 (audited, CGGMP21)
- Python-native threshold signing → PyFrost (unaudited; accept risk) or managed service
- Application quorum approval → Standard multisig first; threshold only for signature compactness or signer privacy
The Uncomfortable Truth#
There is no clean Python path to production-grade threshold signing without either:
- Accepting unaudited code (PyFrost)
- Using a managed service (Dfns, Fireblocks, Turnkey)
This is the state of the ecosystem as of 2026.
SSS vs. Threshold Signing Rule of Thumb#
Use SSS if:
- Signing frequency is low (< once/day)
- Assembly can happen in a controlled, air-gapped environment
- The assembly point is not itself a security concern
Use threshold signing if:
- Signing is frequent (hot wallet, continuous operations)
- The assembly point is on an internet-connected machine
- You need to eliminate the key reconstruction attack surface entirely
S3 Need-Driven Discovery: Threshold Signature / Secret Sharing#
Research ID: 1.064 Pass: S3 — Need-Driven Discovery Date: 2026-02-16
The Central Question from Architecture#
“Shamir is for secrets at rest; threshold crypto is for secrets in use.”
This single distinction resolves most architecture questions. The choice is about operational vs. cold access:
| Scenario | Right tool |
|---|---|
| Backup a root key across 5 trustees; recover on device loss | SSS (PyCryptodome) |
| Approve transactions without any party holding the full key | Threshold signing (FROST/TSS) |
| Store a shared secret with quorum reconstruction | SSS |
| Continuous quorum approval of messages/actions | Threshold signing |
Use Case 1: Distributed Key Backup (Cold Storage)#
Pattern: A sensitive key (master seed, root CA key, signing key) is split via Shamir into N shares distributed to N trustees. Recovery requires K trustees to present shares.
Library: PyCryptodome (Crypto.Protocol.SecretSharing)
Key considerations:
- Key is assembled at reconstruction time — temporarily exists in memory on one machine
- Appropriate for cold storage where assembly is a rare, high-ceremony event
- Vulnerable to compromise at assembly point — this is the inherent limitation
- Add Feldman VSS if shares might be corrupted (no clean Python lib — verify shares externally)
Code pattern:
from Crypto.Protocol.SecretSharing import Shamir
from Crypto.Random import get_random_bytes
# Key generation (at setup ceremony)
key = get_random_bytes(16) # 128-bit key
shares = Shamir.split(3, 5, key) # 3-of-5 threshold
# Distribute shares[0..4] to 5 trustees
# Recovery (when needed, with 3+ trustees present)
reconstructed = Shamir.combine([shares[0], shares[2], shares[4]])
assert reconstructed == keyProduction checklist:
- Run split ceremony on air-gapped machine
- Zero memory after distribution
- Audit log of who holds which share number (share number is not secret)
- Consider SLIP-39 if trustees need human-readable paper backups
Use Case 2: Hardware Wallet Seed Backup (SLIP-39)#
Pattern: A user’s BIP-32 seed is split into mnemonic shares (like BIP-39 words, but multiple cards). Any K-of-N cards can recover the wallet.
Library: shamir-mnemonic (PyPI) — Trezor’s SLIP-39 reference
Key considerations:
- Human-oriented: shares are word lists, not bytes
- Supports group thresholds (e.g., 2-of-3 groups, each needing 2-of-5 shares)
- NOT for server-side use — no side-channel hardening
- For server-side, use PyCryptodome and encode yourself
When to use: User-facing key backup for hardware wallets or high-security personal key management.
Use Case 3: Quorum-Gated Signing (Distributed Custody)#
Pattern: A service holds a signing key distributed across N nodes. Any transaction requires K nodes to co-sign. No node ever holds the complete key. Key never leaves hardware.
Library: FROST (ZF FROST via Rust, PyFrost for Python research)
This is the main gap: No audited Python library. Real production systems use:
- Managed services (Fireblocks, Dfns, Turnkey)
- Rust/Go services with Python calling them via gRPC or REST
Architecture patterns for Python applications:
Option A: Sidecar service
┌─────────────────┐ gRPC/REST ┌──────────────────────┐
│ Python app │ ─────────────→ │ Rust signing service │
│ (business logic│ ←───────────── │ (ZF FROST / cggmp21) │
└─────────────────┘ sig bytes └──────────────────────┘
Option B: Subprocess
┌─────────────────┐ stdin/stdout ┌──────────────────────┐
│ Python app │ ─────────────→ │ frost-cli binary │
└─────────────────┘ signature └──────────────────────┘
Option C: PyFrost (pure Python, unaudited)
┌─────────────────────────────────────────┐
│ Python app + PyFrost signing nodes │
│ (internal trust model, no external audit)│
└─────────────────────────────────────────┘Recommendation: For non-adversarial internal tooling (team approval workflows, dev ops signing), PyFrost is viable. For custody of real value, use a managed service or build a Rust sidecar.
Use Case 4: Approval Quorum for High-Stakes Actions#
Pattern: Before an action executes (deploy to production, wire transfer, key rotation), K-of-N approvers must sign the action descriptor. The signature proves quorum consent.
Two sub-patterns:
Sub-pattern A: Regular multisig (not threshold) Each approver signs independently with their own key. Verifier checks K signatures.
- Simpler: just use standard ECDSA/Ed25519 signing per approver
- Reveals which specific approvers signed
- Signature bundle grows with K
Sub-pattern B: Threshold signature Approvers collectively produce one signature that looks identical to a single-signer signature.
- Compact: always one signature, independent of K and N
- Privacy-preserving: verifier cannot tell which specific K approved
- Requires threshold key setup upfront
- More complex
For most application-layer quorum use cases: Sub-pattern A (multisig) is simpler and sufficient. FROST/TSS adds value when: (a) signature size matters, (b) you want signer privacy, or (c) you need hardware-custody of a single signing key without key custodians.
Use Case 5: Distributed MPC for Application Signing (General Agent Keys)#
Pattern: An AI agent has a signing key. The key is distributed across K nodes so no single node can sign unilaterally. Signing requires threshold participation.
Example: A relay network validates by each relay node contributing a partial signature. Quorum of relay nodes validates the request path.
Library landscape for this:
- If signatures are Ed25519: PyFrost (Python, unaudited) or ZF FROST via sidecar
- If signatures are ECDSA/secp256k1: dfns/cggmp21 or tss-lib via sidecar
- If “signatures” are just HMAC/hash validation (weaker model): vanilla Python
Key design question: Does the quorum need to produce a standard signature (ECDSA/Schnorr), or can it use a bespoke multi-party validation protocol? If bespoke, you don’t need a threshold signature library at all — you can use standard signatures + a coordinator checking K valid independent signatures.
The “Good Enough” Question: SSS vs Threshold Signing#
| Criterion | SSS | Threshold Signing |
|---|---|---|
| Key ever assembled | Yes (at reconstruction) | Never |
| Operational signing | Reconstruct each time (impractical for frequent ops) | Any time K nodes available |
| Side-channel attack surface | One machine at reconstruction | Distributed, smaller surface |
| Protocol complexity | Simple polynomial math | Multi-round interactive MPC |
| Library maturity (Python) | PyCryptodome (audited) | PyFrost (unaudited) or managed service |
| Right for cold storage | Yes | Overkill |
| Right for hot signing | No | Yes |
Rule of thumb: If signing frequency is low (< 1/day) and the assembly can happen in a controlled environment (air-gapped, HSM), SSS is “good enough.” If signing is frequent or if the assembly point is itself a security concern, use threshold signing.
Managed Service Cost Comparison#
| Service | Pricing model | Audit | Notes |
|---|---|---|---|
| Fireblocks | Enterprise/custom | SOC 2, multiple audits | Industry leader, crypto-custody focused |
| Dfns | Per-operation + monthly | Kudelski (CGGMP21) | Developer-friendly API |
| Turnkey | Per-key + ops | SOC 2 | MPC key management service |
| Lit Protocol | Network fee | — | Decentralized; open source nodes |
For small-scale / research: Self-hosted PyFrost or subprocess to ZF FROST binary. For production with real value: Managed service + audit trail.
Synthesis for S3#
Clear winner by use case:
- Key backup → PyCryptodome (Python, audited, simple)
- Human-readable backup → shamir-mnemonic (SLIP-39, Trezor)
- Threshold Schnorr in Rust → ZF FROST (audited for ed25519/p256/ristretto255)
- Threshold ECDSA in Rust → dfns/cggmp21 (audited, CGGMP21 protocol)
- Python-native threshold signing → PyFrost (unaudited; accept risk) or managed service
- Quorum approval for app actions → Consider standard multisig first; threshold only if signature compactness or signer privacy is required
The uncomfortable truth: There is no clean Python path to production-grade threshold signing without either accepting unaudited code (PyFrost) or using a managed service. This is the state of the ecosystem as of 2026.
Sources#
S4: Strategic
S4 Approach: Strategic Analysis#
Objective: Assess 5-year viability of each recommended library. Identify ecosystem trajectories (RFC 9591 standardization, CGGMP21 displacing GG20, Python gap scenarios). Produce final decision tree.
Method: Analyze maintenance signals (sponsor incentives, audit continuity, governance), protocol aging, and ecosystem momentum. Extrapolate Python gap scenarios based on project funding and library maturity trajectories.
Libraries assessed for viability:
- PyCryptodome (5-year horizon)
- ZF FROST (5-year horizon)
- dfns/cggmp21 (3-5 year horizon)
- bnb-chain/tss-lib (3-5 year horizon)
- PyFrost (1-3 year horizon)
- shamir-mnemonic (5-year horizon)
Key questions:
- Will the Python gap close, or will managed services absorb it?
- Is GG20 (tss-lib) on a deprecation path?
- What does RFC 9591 standardization mean for FROST library stability?
S4 Final Recommendations#
Winners by Category#
Secret Splitting / Key Backup#
Winner: PyCryptodome (Crypto.Protocol.SecretSharing)
- Audited, maintained, production-grade
- GF(2^128) — fixed-size 16-byte shares
- Simple API; 50M+ monthly PyPI downloads
Human-Readable Seed Backup#
Winner: shamir-mnemonic (Trezor, SLIP-39)
- Standard; supported by hardware wallets
- Caveat: Not for server-side use (no side-channel hardening)
Threshold Schnorr Signing (Rust)#
Winner: ZF FROST
- RFC 9591 compliant
- Partial NCC audit (Ed25519, P-256, ristretto255, Ed448 in scope)
- Caveat: secp256k1-tr (Taproot) NOT in audit scope
Alternative: givre (dfns) — faster, no public audit yet
Threshold ECDSA Signing (Rust)#
Winner: dfns/cggmp21
- CGGMP21 protocol (state-of-art; UC-secure)
- Kudelski-audited
- Proactive security (share refresh) + identifiable aborts
- MIT + Apache 2.0
Alternative: bnb-chain/tss-lib — Go, GG20, battle-tested in bridges
Python Applications Needing Threshold Signing#
First choice: Reconsider the requirement
- Is standard multisig sufficient? Often yes.
If truly needed:
- Research/internal: PyFrost (no audit; accept risk)
- Production: Managed service (Dfns, Turnkey, Fireblocks)
- Advanced: Rust sidecar with ZF FROST / cggmp21 via gRPC
Viability Summary#
| Library | Viability | Horizon |
|---|---|---|
| PyCryptodome | High | 5 year |
| shamir-mnemonic | High | 5 year |
| ZF FROST | High | 5 year |
| dfns/cggmp21 | High | 3-5 year |
| bnb-chain/tss-lib | Moderate | 3-5 year |
| PyFrost | Low-Medium | 1-3 year |
S4 Strategic Analysis: Threshold Signature / Secret Sharing Libraries#
Research ID: 1.064 Pass: S4 — Strategic Analysis Date: 2026-02-16
Ecosystem Trajectory#
The Standardization Tailwind#
RFC 9591 (FROST, June 2024) is the most significant recent event. A threshold signature scheme now has IETF standardization, which means:
- Implementations can be tested for interoperability
- The protocol is stable — no more breaking changes from academic revisions
- Enterprise buyers can justify adoption (“IETF standard, not crypto-startup novel scheme”)
- Tooling (wallets, HSMs) will gradually add native support
Prediction: Within 2-3 years, major languages will have production-ready FROST libraries, similar to how Ed25519 moved from “exotic” to “default” in 2015-2020.
Python Library Gap — Will It Close?#
The Python ecosystem is 2-3 years behind Rust/Go for threshold cryptography. Likely trajectories:
Scenario A (most likely): PyFrost matures with an audit as Zellular and the decentralized signing space grows. Python FROST becomes viable for production by 2027.
Scenario B: The Python gap remains, and managed services (Dfns, Fireblocks, Turnkey) absorb the use case. Python apps call REST APIs rather than using native libraries.
Scenario C: PyO3-based bindings to ZF FROST become official/maintained. Python gets audited FROST via Rust FFI.
For planning today: assume Scenario B for production (managed service), Scenario A for research/internal tooling.
CGGMP21 Displacing GG20#
GG20 will continue working (tss-lib is stable), but CGGMP21 is the correct choice for new systems:
- Audited implementation available (dfns/cggmp21)
- Proactive security (share refresh) is increasingly required by institutional custody compliance
- Identifiable aborts add accountability: if signing fails, you know who misbehaved
- UC security proof is a stronger guarantee
tss-lib (GG20) status: Battle-tested, stable, not being deprecated, but new development will gravitate toward CGGMP21 implementations.
Library Viability Assessment#
PyCryptodome — High Viability (5-year)#
- Maintained by a solo developer (Legrandin) but widely deployed (50M+ monthly PyPI downloads)
- Part of PyCryptodome project with active security CVE responses
- SSS module is simple enough that the maintenance burden is low
- Risk: Solo maintainer; if unmaintained, fork PyCryptodomex is available
ZF FROST (Rust) — High Viability (5-year)#
- Zcash Foundation has multi-year FROST commitment
- RFC 9591 alignment = standard is stable
- HRF grant funding for continued development
- Partial audit (ed25519, p256, ristretto255) with more audit work expected
- Risk: secp256k1-tr remains outside audit scope; Taproot use case is therefore higher risk
dfns/cggmp21 (Rust) — High Viability (3-5 year)#
- Dfns uses in production for their commercial product
- Open source (MIT + Apache 2.0) — anyone can fork if Dfns pivots
- Audited by Kudelski; vulnerabilities disclosed and patched promptly
- Active development under LFDT-Lockness governance
- Risk: Dependent on Dfns’ continued commitment; governance model is still young
bnb-chain/tss-lib (Go) — Moderate Viability (3-5 year)#
- BNB Chain maintains for their cross-chain infrastructure
- GG20 protocol is aging but stable
- Used by Thorchain, multiple bridges — battle-tested
- Risk: Protocol aging; if Binance priorities shift, maintenance could slow; GG20 lacks proactive security
PyFrost (zellular-xyz) — Low-Medium Viability (1-3 year)#
- Backed by Zellular project funding
- No public audit — biggest risk factor
- If Zellular gets an audit, viability increases substantially
- Risk: Small team, no audit, dependent on one project’s continued funding
shamir-mnemonic (Trezor) — High Viability (5-year)#
- Official SLIP-39 reference implementation
- Trezor has strong incentive to maintain (core wallet functionality)
- Narrow scope = low maintenance burden
- Risk: Explicitly not for server-side use (side-channel caveat)
The Architecture Decision Tree (Final)#
What are you trying to protect?
│
├── A key/secret at rest (split for backup/escrow)
│ ├── Python ok → PyCryptodome.SecretSharing (audited)
│ ├── Human-readable mnemonic shares → shamir-mnemonic (SLIP-39)
│ └── Need verifiable shares (catch corruption) → No clean Python lib
│ → Option: Use PyCryptodome + out-of-band share verification ceremony
│
└── Signing capability (no key assembly ever)
│
├── Schnorr / Ed25519 / Taproot signing?
│ ├── Rust → ZF FROST (audited for ed25519/p256/ristretto255)
│ │ Or givre/dfns (faster, no public audit yet)
│ ├── Python (research/internal) → PyFrost (unaudited, has networking)
│ ├── Python (production) → REST API to Lit Protocol or managed service
│ └── secp256k1 Taproot specifically → frost-secp256k1-tr (not in audit)
│
└── ECDSA signing? (Ethereum, Bitcoin legacy)
├── Rust (modern) → dfns/cggmp21 (audited, CGGMP21, proactive)
├── Go (battle-tested) → bnb-chain/tss-lib (GG20, no fresh audit)
├── Python → No viable option → use managed service
│ (Fireblocks, Dfns REST API, Turnkey)
└── Don't actually need threshold → Consider multisig instead
(K independent signatures checked by verifier; simpler, well-supported)When NOT to Use Threshold Signatures#
Threshold signatures are often overkill. Use simpler alternatives when:
K-of-N independent approval is sufficient: Have each approver sign with their own key. Verifier checks K valid signatures. This is standard multisig and works fine for most approval flows. SSS for custody.
Only one party needs the signing capability: Threshold signing requires N parties to set up a distributed key. If there’s really one party, just use a standard key + HSM.
Low-frequency, high-ceremony signing: SSS + air-gapped reconstruction. Cold storage.
You’re using ECDSA and Python: The library ecosystem isn’t there. Either use standard multisig (multiple ECDSA signatures), Ed25519 + PyFrost, or a managed service.
Final Recommendations#
For Secret Splitting / Key Backup#
Winner: PyCryptodome (Crypto.Protocol.SecretSharing)
- Audited, maintained, production-grade
- GF(2^128) — fixed-size 16-byte shares, side-channel-resistant field arithmetic
- Simple API
For Human-Readable Seed Backup#
Winner: shamir-mnemonic (trezor, SLIP-39)
- Standard; supported by hardware wallets
- Not for server-side use
For Threshold Schnorr Signing (Rust)#
Winner: ZF FROST
- RFC 9591 compliant
- Partial NCC audit (ed25519, p256, ristretto255)
- Both trusted dealer and DKG supported
- Caveat: secp256k1-tr (Taproot) not in audit scope
Alternative: givre (dfns)
- Faster than ZF FROST
- No public audit yet (watch for 2025-2026 audit)
For Threshold ECDSA Signing (Rust)#
Winner: dfns/cggmp21
- CGGMP21 protocol (state-of-art)
- Kudelski-audited
- Proactive security (share refresh)
- Identifiable aborts
- MIT + Apache 2.0
Alternative: bnb-chain/tss-lib
- Go, not Rust
- GG20 (older protocol)
- Battle-tested in bridges/custody
- Use when Go is preferred or GG20 compatibility required
For Python Applications Needing Threshold Signing#
First choice: Reconsider the requirement
- Is standard multisig (K independent ECDSA/Ed25519 sigs) sufficient? Often yes.
If threshold signing truly needed:
- Research/internal: PyFrost (no audit; accept risk)
- Production: Managed service (Dfns API, Turnkey, Fireblocks)
- Advanced: Build Rust sidecar with ZF FROST or cggmp21, call from Python via gRPC
Sources#
- ZF FROST audit announcement
- NCC Group FROST audit
- RFC 9591
- dfns CGGMP21 blog
- dfns vulnerabilities patched
- dfns givre blog
- Blockchain Commons FROST developers
Library Viability Matrix#
Assessment Criteria#
- Maintenance sponsor: Who pays for ongoing development?
- Protocol stability: Is the underlying protocol stable (standardized, not evolving)?
- Audit coverage: Has the library been reviewed by an external security firm?
- Governance: What happens if the primary sponsor pivots?
Detailed Assessments#
PyCryptodome — High Viability (5 years)#
| Criterion | Assessment |
|---|---|
| Sponsor | Solo developer (Legrandin) |
| Protocol | Well-established SSS math |
| Audit | Part of broader PyCryptodome reviews; CVE response track record |
| Governance | Fork PyCryptodomex available; widely deployed (50M+/month PyPI) |
| Risk | Solo maintainer dependency |
ZF FROST — High Viability (5 years)#
| Criterion | Assessment |
|---|---|
| Sponsor | Zcash Foundation (multi-year commitment) |
| Protocol | RFC 9591 (IETF standard, frozen) |
| Audit | NCC Group 2023 (ed25519, p256, ristretto255, ed448) |
| Governance | HRF grant funding; stable institutional backing |
| Risk | secp256k1-tr outside audit scope |
dfns/cggmp21 — High Viability (3-5 years)#
| Criterion | Assessment |
|---|---|
| Sponsor | Dfns (production use) → LFDT-Lockness governance |
| Protocol | CGGMP21 (2021, UC-secure, academic consensus) |
| Audit | Kudelski Security; vulnerabilities disclosed and patched |
| Governance | MIT + Apache 2.0; anyone can fork |
| Risk | Dependent on Dfns’ continued investment; governance still maturing |
bnb-chain/tss-lib — Moderate Viability (3-5 years)#
| Criterion | Assessment |
|---|---|
| Sponsor | BNB Chain (Binance) |
| Protocol | GG20 (2021; aging but stable; no proactive security) |
| Audit | No public audit; battle-tested in Thorchain, bridges |
| Governance | Single corporate sponsor |
| Risk | Protocol aging; if Binance priorities shift, maintenance slows |
PyFrost (zellular-xyz) — Low-Medium Viability (1-3 years)#
| Criterion | Assessment |
|---|---|
| Sponsor | Zellular project |
| Protocol | ICE-FROST variant (not vanilla RFC 9591) |
| Audit | None |
| Governance | Small team, single-project dependency |
| Risk | No audit is the fundamental blocker; small ecosystem |
Upgrade path: If Zellular or another party funds a public audit of PyFrost, viability jumps to 3-5 years.
shamir-mnemonic — High Viability (5 years)#
| Criterion | Assessment |
|---|---|
| Sponsor | Trezor (core wallet product) |
| Protocol | SLIP-39 (narrow, stable) |
| Audit | Part of Trezor’s security review program |
| Governance | Narrow scope = low maintenance burden |
| Risk | Explicitly not for server-side use |