Skip to content

Port BNB cryptographic hardening follow-ups#6

Open
mswilkison wants to merge 5 commits into
codex/remove-unused-protocolsfrom
codex/review-residual-cleanup
Open

Port BNB cryptographic hardening follow-ups#6
mswilkison wants to merge 5 commits into
codex/remove-unused-protocolsfrom
codex/review-residual-cleanup

Conversation

@mswilkison
Copy link
Copy Markdown

@mswilkison mswilkison commented May 21, 2026

Summary

Stacked on #5. Ports the remaining BNB cryptographic hardening follow-ups into Threshold's secp256k1-only TSS stack.

  • Adds tagged Fiat-Shamir domains across proof systems and stronger proof input validation.
  • Adds shared validators for unknown-order moduli, canonical generators, and Paillier ciphertexts.
  • Rejects malformed VSS reconstruction inputs, invalid parameter bounds, duplicate party keys, and mod-q PartyID collisions.
  • Makes keygen/signing message redelivery idempotent while rejecting content-different peer replays.
  • Addresses review follow-ups for unregistered generic curves, GetRandomInt's zero-inclusive range, deterministic message wire bytes, and large-modulus sampleYModN block indexing.

Compatibility

BREAKING: tagged Fiat-Shamir challenge inputs change proof transcripts. All operational nodes must upgrade in lockstep; mixed old/new proof verification is expected to fail.

Additional API/behavior changes:

  • ecdsa/signing.PrepareForSigning now returns an error as its third return value.
  • tss.NewParameters rejects party counts below 2, thresholds outside [1, partyCount), zero PartyID residues, and mod-q PartyID collisions.
  • tss.SortPartyIDs panics on duplicate raw party keys instead of silently sorting invalid input.

Downstream Check

  • GitHub code search found no current threshold-network/keep-core uses of PrepareForSigning.
  • threshold-network/keep-core NewParameters call sites use group-derived party sets; the visible test call site uses five parties.

Validation

  • go test ./...
  • go test ./common ./crypto/schnorr ./crypto/vss ./crypto/paillier ./ecdsa/keygen ./ecdsa/signing -run 'Test(GetRandomIntPreservesZeroInclusiveRange|Schnorr.*UnregisteredCurve|VerifyAllowsUnregisteredCurve|SampleYModNDeterministicAndSupportsManyBlocks|StoreMessage)'
  • git diff --check

@mswilkison mswilkison force-pushed the codex/remove-unused-protocols branch from b366e27 to 3284c6b Compare May 21, 2026 17:10
Doc + small defensive-code follow-ups to the PR #2/#4/#5 review thread.
None of these are security-blocking; they close out the cosmetic and
pre-existing items that did not warrant their own PR earlier.

- common/hash_utils.go: strengthen RejectionSample doc so the name does
  not mislead future readers — the function is modular reduction, not
  true rejection sampling, and the bias bound depends on q vs the hash
  width.
- crypto/paillier/factor_proof.go: document that the tagged and legacy
  FactorChallenge paths emit different challenge distributions
  (positive-only vs signed), and note that FactorVerify's CmpAbs bounds
  exist to accommodate the legacy signed encoding.
- tss/params.go: expand SetSessionNonceBytes docstring with the
  collision/uniqueness/entropy guidance reviewers asked for.
- ecdsa/{keygen,signing}/rounds.go: document the round-1-capture
  invariant for getSSID so future refactors do not silently drift the
  hashed round.number domain separator.
- crypto/ecpoint.go: flag SetCurve's in-place mutation in the doc
  comment; the chained-call style is a footgun on shared points.
- crypto/vss/feldman_vss.go: reject nil shares, nil/zero share IDs, and
  duplicate IDs in ReConstruct before the Lagrange loop, so malformed
  inputs return an error instead of panicking through ModInverse(0).
  Add focused test coverage for each rejection path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mswilkison mswilkison force-pushed the codex/review-residual-cleanup branch from fb8602e to c9e9c09 Compare May 21, 2026 17:12
The previous text stated the bias bound as `q / 2^eHash.BitLen()`, which
evaluates to ≈ 1 for secp256k1 and cannot support the docstring's own
≈ 2^-128 conclusion. The "q significantly smaller than 2^eHash.BitLen()
(e.g., q = 2^256)" example was also internally inconsistent (q = 2^256
is not smaller than 2^256).

Rewrite the paragraph to:
  - State the safe regime as a property of q ("close to 2^k from below")
    rather than via a loose formula or call-site enumeration.
  - Drop the unused curve25519 reference whose conclusion is correct but
    not derivable from the simple `r/M` bound.
  - Cross-reference HashToN / HashToNTagged for the large-modulus regime
    that they were introduced to address.

Documentation-only change. RejectionSample's behavior is unchanged
(LiterallyJustMod under the hood), so no computed challenge value moves.
@mswilkison mswilkison changed the title Address residual review items from BNB hardening stack Port BNB cryptographic hardening follow-ups May 28, 2026
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