A small proof-of-concept touching the primitives a Bitcoin coordination / recovery layer (post-Coldcard) would need to compose cleanly:
-
FROST threshold Schnorr signing (2-of-3). No single device or vendor ever holds a full private key. A 2-of-3 quorum can still produce a valid signature under the shared group key even when one participant (e.g. a lost phone) never shows up. This is the actual hard problem in post-Coldcard recovery: not "how do I back up a seed phrase" but "how do I reach quorum without a single point of failure or a single vendor dependency."
-
BIP-352 Silent Payments (sketch). The threshold group key from (1) is used as the receiver's spend key (
B_spend) for a silent payment address. Because spending authority is still gated by the 2-of-3 quorum, the recovery guarantee holds all the way through to the silent-payment output — not just at the wallet level.
This was built in a sandboxed environment with no network path to
install a newer Rust toolchain — only rustc 1.75 was available via
apt. The official frost-secp256k1 crate (and its frost-core
dependency) requires rustc 1.81+, so rather than fake the result,
src/main.rs implements the FROST signing math directly against
k256's curve arithmetic:
- Shamir secret sharing for the trusted-dealer keygen (
f(x) = s0 + a1*x) - Per-signer nonce commit/reveal (
d,eand their curve points) - Binding factors (
rho_i) and group commitmentR - BIP340-style Schnorr challenge
c = H(R || Y || m) - Lagrange-coefficient interpolation for signature-share aggregation
This is the same protocol frost-core implements internally — on a
normal toolchain, swapping this out for the real frost-secp256k1
crate would take about 20 lines and drop most of this file. Kept the
from-scratch version here deliberately, since it's a more honest signal
of understanding the protocol than a library call would be.
The signature is verified in-process (z*G == R + c*Y) and the code
has been run repeatedly, including with different 2-of-3 signer
subsets ({1,2} and {2,3}), to confirm it isn't a lucky pass.
cargo run
Expected output includes:
Group public key (anchors the silent payment spend key): 03...
2-of-3 signature produced with participants [1, 2] only (participant(s) [3] absent).
Signature verifies against group key: true
...
B_spend (cold, FROST 2-of-3 group key): 03...
- Real distributed key generation (Pedersen DKG) — this uses a trusted
dealer for simplicity. A real deployment would run FROST DKG so no
party ever sees
s0. - bech32m encoding of the actual
sp1...address — the fingerprint hash stands in for it. - The sender-side ECDH tweak computation from BIP-352 (per-input, per-transaction).
- Any persistence, networking, or coordination transport between signers — this is single-process for clarity.
- Swap in
frost-secp256k1+ real DKG once on a normal toolchain. - Implement the sender-side tweak and full bech32m address encoding per BIP-352.
- Design the actual quorum-recovery UX: how a 3rd signer gets replaced
(key rotation) without re-deriving
B_spend, and what happens if 2 of 3 quorum members are simultaneously unavailable.