fix(account): select t+1 parties for threshold signing

TSS threshold semantics: for threshold parameter t, the required number of signers is t+1.
For 2-of-3 with t=2, we need 2+1=3 signers (all parties must participate).

Previous error: 't+1=3 is not satisfied by the key count of 2'
Fix: Changed from selecting t parties to selecting t+1 parties.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
hailin 2025-12-06 07:46:32 -08:00
parent 0ea64e02ae
commit 7660868a38
1 changed files with 7 additions and 5 deletions

View File

@ -732,9 +732,10 @@ func (h *AccountHTTPHandler) CreateSigningSession(c *gin.Context) {
zap.String("username", req.Username),
zap.Strings("configured_parties", partyIDs))
} else {
// For threshold signing, select minimum required parties (threshold_t)
// For 2-of-3, we need exactly 2 parties to sign (not all 3)
requiredParties := accountOutput.Account.ThresholdT
// For threshold signing, select minimum required parties (threshold_t + 1)
// TSS threshold semantics: for threshold t, we need t+1 signers
// For 2-of-3: t=1, so we need t+1=2 parties to sign
requiredParties := accountOutput.Account.ThresholdT + 1
if len(allActivePartyIDs) < requiredParties {
c.JSON(http.StatusBadRequest, gin.H{
"error": "insufficient active parties for signing",
@ -744,12 +745,13 @@ func (h *AccountHTTPHandler) CreateSigningSession(c *gin.Context) {
return
}
// Select first 'threshold_t' parties
// Select first 'threshold_t + 1' parties
partyIDs = allActivePartyIDs[:requiredParties]
logger.Info("Using minimum required parties for threshold signing",
zap.String("username", req.Username),
zap.Int("threshold_t", requiredParties),
zap.Int("threshold_t", accountOutput.Account.ThresholdT),
zap.Int("required_signers", requiredParties),
zap.Int("total_active", len(allActivePartyIDs)),
zap.Strings("selected_parties", partyIDs))
}