Files
mpc/cmd
zeekayandHanzo Dev 6cf38d2e48 fix(mpcd): wire --threshold into CGGMP21 keygen degree (was silently 1-of-n)
SECURITY: every wallet keyed by these rings was a 1-of-n key — any single
node's share could produce a valid signature, with no threshold protection
against single-node compromise. This affects real value: the bridge-mpc
`bridge-oracle` (LUX↔ZOO corridor signer), zoo-treasury-v1, and the
hanzo-dao wallet were all keyed at CGGMP21 polynomial degree 0.

Root cause: two disconnected "threshold" values. The --threshold flag
(c.Int("threshold")) drove only the HasSigningQuorum health gate and status
display. The keygen DEGREE was read separately from viper key
"mpc_threshold" (pkg/eventconsumer → CreateKeyGenSession → cmp.Keygen), which
nothing ever set — and mpcd never calls config.InitViperConfig, so
viper.AutomaticEnv was off and even an MPC_THRESHOLD env would not have been
read. viper.GetInt("mpc_threshold") was therefore always 0 → degree 0 →
1-of-n.

Fix: bridge the flag to the keygen degree at consensus start via
viper.Set("mpc_threshold", keygenDegreeForThreshold(threshold)). --threshold
is the number of signers required (matches HasSigningQuorum); cmp.Keygen
needs degree+1 signers, so degree = threshold-1. --threshold=3 → degree 2 →
3-of-5; --threshold=2 → degree 1 → 2-of-3. keygenDegreeForThreshold is a
named, unit-tested function so the security-critical off-by-one is explicit.

Takes effect for NEW keygens only; existing 1-of-n wallets must be re-keyed
to gain threshold security (the live bridge-oracle needs a coordinated
migration — do not re-key in place).

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-14 15:15:28 -07:00
..