Files
kms/pkg
zeekayandHanzo Dev 56debeba46 keys: verify the threshold a generated key actually has, and fail closed
GenerateValidatorKeys validated req.Threshold (>=2, parties >= threshold) and
then never sent it — mpc.KeygenRequest has no threshold field, because the MPC
ring's own --threshold decides the CGGMP21 polynomial degree. The request was
advisory; the result was trusted blind.

That was not a theoretical gap. mpcd's KeygenResult carried neither threshold
nor participants, so `Threshold: blsResult.Threshold` and
`Parties: len(blsResult.Participants)` both evaluated to zero. Every validator
key set on record reads 0-of-0 while its caller requested 3-of-5 and passed
validation. The unit tests missed it because the mock server returned
threshold:3 and five participants — it told the truth the real ring never did.

Add verifyThreshold: one function, called for both the BLS and Corona keys.
It refuses a mismatch in either direction, and refuses just as firmly when the
ring declines to state what it did — silently trusting an unstated threshold is
the exact failure being guarded. Nothing is written to the store on refusal, so
a rejected key leaves behind no record asserting a property never established.

DEPLOY ORDER: requires mpcd >= v1.17.15 (luxfi/mpc 81be6b9), which is what
began reporting these fields. Against an older ring every keygen now fails
closed with an explicit "upgrade the MPC ring" error instead of silently
recording 0-of-0. Roll the MPC quorums first.

Tests: 5 refusal cases (unreported, weaker, degree-0, fewer parties, stronger)
each asserting nothing is stored, plus a positive control proving a matching
3-of-5 is accepted and recorded as 3-of-5.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-25 16:42:10 -07:00
..