Files
mpc/cmd
zeekayandHanzo Dev b19863787b fix(mpcd): canonical EVM-ready threshold-ECDSA signatures (low-S + recovery id)
The signing sessions emitted a raw, possibly high-S S with a recovery byte that
was then dropped at every serialization boundary. luxfi/evm ecrecover rejects a
high-S signature (EIP-2 "invalid sender"), and without a propagated recovery id
a caller must guess v (wrong guess => wrong sender). This is what broke the KMS
/sign output.

- signing_session.go + signing_session_lss.go: produce the signature through
  the shared threshold helper s.signature.SigEthereum() (EIP-2 low-S + recovery
  id in ONE place), then self-verify the recovery id against the wallet's own
  public key via CalculateRecoveryByte and FAIL CLOSED on mismatch — never emit
  a signature that binds to the wrong address.
- pkg/api SignResult: carry V (recovery id "0"/"1").
- cmd/mpcd TriggerSign: propagate V from the signing session's signature_recovery
  and assemble the canonical 65-byte r‖s‖v so KMS /sign never returns an empty
  signature.
- handlers_kms REST: include v in the response.

Requires the non-mutating, tested SigEthereum in threshold v1.12.4; bumps
luxfi/threshold v1.12.0 -> v1.12.4 (MVS pulls its transitive updates). Builds
GOWORK=off; pkg/api + pkg/mpc tests green.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-21 08:32:35 -07:00
..