Skip to content

tss/rsa: validate sign share protocol parameters - #674

Merged
bwesterb merged 1 commit into
mainfrom
bas/gw37
Aug 3, 2026
Merged

bwesterb merged 1 commit into
mainfrom
bas/gw37

Conversation

@bwesterb

@bwesterb bwesterb commented Jul 31, 2026 •

Copy link
Copy Markdown
Member

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

View 1 additional finding in Devin Review.

Open in Devin Review

Comment thread tss/rsa/rsa_threshold.go
Comment on lines +201 to +207
// CombineSignShares combines SignShares to produce a valid signature. Players
// and threshold must be trusted protocol parameters; the function checks them
// against every share before combining.
func CombineSignShares(pub *rsa.PublicKey, players, threshold uint, shares []SignShare, msg []byte) (Signature, error) {
if err := validateParams(players, threshold); err != nil {
return nil, err
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Signature-combining function changes its public call signature without a compatible alternative or deprecation path

The publicly exported signature-combining entry point gains two required arguments (CombineSignShares at tss/rsa/rsa_threshold.go:204) with no additive alternative kept around, so every existing user of this library stops working until they rewrite their calls.
Impact: Downstream projects that call the threshold RSA combine step break on upgrade with no deprecation warning or migration shim.

Repository rules on breaking public API changes

REVIEW.md (API and compatibility) requires: "Additive changes are preferred. Breaking changes are called out in the PR description and paired with // Deprecated: where feasible". AGENTS.md also says to stop and escalate before changing a public API signature. Here CombineSignShares(pub, shares, msg) becomes CombineSignShares(pub, players, threshold, shares, msg) at tss/rsa/rsa_threshold.go:204, with no // Deprecated: wrapper and no additively named alternative (e.g. a separate function accepting trusted parameters). The docs in tss/rsa/README.md also still describe the old flow.

Prompt for agents
CombineSignShares is an exported API whose signature changed in a breaking way (two new required parameters players/threshold). Repository policy (REVIEW.md "API and compatibility", AGENTS.md) prefers additive changes and requires breaking changes to be documented and paired with a `// Deprecated:` marker on the old API where feasible. Consider keeping the old three-argument entry point (marked `// Deprecated:`, delegating to the new logic using the share-derived parameters) and exposing the parameter-validating variant under a new name, or explicitly document the break in the PR description and package docs (tss/rsa/README.md still describes the old flow).
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread tss/rsa/rsa_threshold.go
Comment on lines 210 to 220
}

players := shares[0].Players
threshold := shares[0].Threshold

for i := range shares {
if shares[i].Players != players {
return nil, errors.New("rsa_threshold: shares didn't have consistent players")
return nil, errors.New("rsa_threshold: share players did not match protocol players")
}
if shares[i].Threshold != threshold {
return nil, errors.New("rsa_threshold: shares didn't have consistent threshold")
return nil, errors.New("rsa_threshold: share threshold did not match protocol threshold")
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟨 Share index from untrusted shares is still not validated against the trusted player count

The PR makes players/threshold trusted inputs and checks each share's Players/Threshold against them (tss/rsa/rsa_threshold.go:210-219), but each share's Index remains fully attacker-controlled and is never checked to be within 1..players or to be distinct across shares. computeLambda (tss/rsa/rsa_threshold.go:312) only requires that the index appears in the provided set, so out-of-range or duplicated indices flow into the Lagrange computation; the combine only fails later via the generic rsa: internal error self-check (tss/rsa/rsa_threshold.go:280-282) or ErrInvalidCalc.

(Refers to lines 210-221)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread tss/rsa/rsa_threshold.go
@bwesterb
bwesterb merged commit 2ce0fd7 into main Aug 3, 2026
14 checks passed
@bwesterb
bwesterb deleted the bas/gw37 branch August 3, 2026 22:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants