2-of-3 Feldman VSS + Schnorr-like Signing on secp256k1 — Visual Guide
Each party independently generates a random polynomial f(x) = a0 + a1·x.
Degree = threshold−1 = 1. The constant term a0 is their secret contribution to the group key.
Nothing is shared yet. Each polynomial lives only on one machine. Files: alice/secrets.json, bob/secrets.json, carol/secrets.json
Each party multiplies their secret coefficients by the generator point G to create commitments. These go on the public board — everyone sees them, but can't reverse-engineer the secrets (discrete log problem).
Key idea: C0 = a0·G locks in the secret without revealing it. Later, anyone can verify shares against these commitments.
Each party evaluates their polynomial at the other parties' indices and sends the result as a secret share via encrypted private mail. Only the recipient can read it.
Each share is a single scalar (big number). The polynomial evaluation at index i gives that party their piece of the puzzle. Nobody sees anyone else's mail.
Each party: (1) verifies received shares using Feldman VSS, (2) combines all shares into their final key share, (3) everyone computes the same group public key.
Feldman verification: share·G should equal C0 + index·C1. This catches cheaters without revealing the secret polynomial. If anyone lies about their shares, the check fails and we abort.
Only 2-of-3 needed! Alice and Bob cooperate while Carol is offline. Each picks a random nonce (one-time secret) and publishes the corresponding curve point.
Not needed for 2-of-3
Each signer uses their private nonce, private key share, and the public challenge to compute a partial signature. The math is Schnorr-style.
Lagrange coefficients adjust each party's key share for the specific subset signing. For parties {1,2}: λ1 = 2/(2-1) = 2 and λ2 = 1/(1-2) = -1. These ensure λA·xA + λB·xB = x (the full private key), even though nobody computes x directly.
Anyone (even Carol, even a stranger!) can combine the partial signatures. No secrets needed — just addition on the public board.
The combined signature is indistinguishable from a single-signer Schnorr signature. The MPC protocol is completely invisible in the output.
Standard Schnorr verification. No MPC knowledge required. The verifier just checks one equation.
The blockchain sees a normal signature from one Ethereum address.
No idea that 2 people made it together, or that a 3rd person exists.
| Variable | What it is | Step |
|---|---|---|
| C0i, C1i | Commitment points (a0·G, a1·G) | 2 |
| PK | Group public key = ∑C0i | 4 |
| ETH addr | keccak256(PK)[12:] | 4 |
| RA, RB | Nonce points (ki·G) | 5 |
| R | Combined nonce RA+RB | 6 |
| e | Challenge hash(R || msg) | 6 |
| λA, λB | Lagrange coefficients | 6 |
| sA, sB | Partial signatures | 6 |
| s | Combined signature | 7 |
| Variable | Who | What it is |
|---|---|---|
| a0A, a1A | Alice | Polynomial coefficients |
| a0B, a1B | Bob | Polynomial coefficients |
| a0C, a1C | Carol | Polynomial coefficients |
| fi(j) | Receiver j | Share from party i |
| xA | Alice | Final key share |
| xB | Bob | Final key share |
| xC | Carol | Final key share |
| kA | Alice | Signing nonce |
| kB | Bob | Signing nonce |
| x | NOBODY | Full private key |
MPC Playground Visual Guide — Open in browser or print to PDF (Cmd+P / Ctrl+P)