DRAFT: Feat schnorr

Summary

Adds a BTC-only FROST signing engine for Taproot/BIP340, gated by EnableFrostBTC.

The implementation uses Zcash Foundation FROST, specifically frost-secp256k1-tr, via an in-repo Rust FFI wrapper and Go bindings. Existing GG20 BTC vaults remain signable; only new BTC vaults created after EnableFrostBTC=1 use FROST.

Implementation

  • Added native FROST wrapper under schnorr/rust/libgoschnorr.
  • Added Go wrapper under schnorr/go-wrappers/go-schnorr.
  • Added signing_engine=frost local keygen state.
  • Added BTC-only routing for FROST keygen/keysign.
  • Added FROST P2P message flow matching the existing TSS session model.
  • Added BIP340 verification before accepting FROST signatures.
  • Added P2TR address/signing support for BTC FROST vaults.
  • Added THORChain vault engine metadata so BTC vault address derivation can distinguish legacy GG20 P2WPKH from FROST P2TR.

Upstream Sources

Upgrade Behavior

  • EnableFrostBTC=0 or absent: new BTC vaults continue using GG20.
  • EnableFrostBTC=1: new BTC vaults use FROST and publish P2TR addresses.
  • Existing GG20 vaults remain P2WPKH and continue signing with GG20.
  • Vaults do not switch address type in place.
  • Churn migrates funds from retiring GG20 P2WPKH vaults into new FROST P2TR vaults.

Compatibility

FROST is mostly plug-and-play with the existing TSS flow:

  • same keygen/keysign request shape
  • same party coordination
  • same P2P message loop
  • same timeout handling
  • same result broadcast path
  • same keygen/keysign failure posting paths

The BTC chainclient is the only chainclient that uses FROST. DOGE/LTC/BCH/ZEC/EVM/Ed25519 paths are unchanged.

Validation

  • Rust wrapper keygen/keysign tests.
  • Go wrapper session tests.
  • Docker make test-go-tss.
  • Docker make test-coverage-sum.
  • BTC regtest FROST keygen/keysign.
  • Blame validation for keygen and keysign paths:
    • default timeout
    • malformed message
    • auth failure
    • bad result broadcaster
    • native identifiable party error

Sample 7-node timing:

Metric Result
GG20 keysign ~1.03s
GG20 keyshare size ~30.8 KB
FROST keygen ~0.51s
FROST keysign ~0.51s
FROST keyshare size ~2.5 KB

Production Note

The FROST blame/fault injection hooks are test-only and should be removed or hard-disabled before production release.

Merge request reports

Loading