Skip to content

Conversation

@vietddude
Copy link
Collaborator

@vietddude vietddude commented Oct 6, 2025

PR Summary

Implement all Taurus protocols (CMP, FROST, Taproot) and add Presign support for CMP (CGGMP21).

Presign for CMP (CGGMP21)

  • Added presign endpoint for preparing pre-signature data.
  • To optimize latency, call Presign before signing a transaction.
  • Presign entries are cached locally with TTL and cleaned up automatically.

@vietddude vietddude requested a review from anhthii October 6, 2025 10:31
@anhthii
Copy link
Contributor

anhthii commented Nov 1, 2025

image

I just checked documentation. Presign is a step to generate a preSig that doesn't depend on the message being signed

So I think we might need to change implementation of Presign api , in the presign examples, it's presigning with transaction data which make it difficult for application integration.

txMsg := &types.PresignTxMessage{
		KeyType:             types.KeyTypeCGGMP21,
		WalletID:            "196c6858-30de-4a49-9134-8bc825d40764", // Use the generated wallet ID
		NetworkInternalCode: "solana-devnet",
		TxID:                txID,
		Tx:                  dummyTx,
	}
	err = mpcClient.PresignTransaction(txMsg)
	if err != nil {
		logger.Fatal("PresignTransaction failed", err)

I think the correct flow is that it only expose PresignTransaction that accept KeyType only.

And we can specify the number of Presigs that we want to generate. For intance 30 , that will be generated sequentially through a worker. The presigs can be stored both in Ram using a pool implementation, and can be persisted in badger with used boolean to mark if the presig is already used or not

Pooling strategy

Keep RAM pool (e.g. up to 30 unused pre-signs per wallet) for sub-millisecond access.

Persist all in BadgerDB (or Postgres if cluster-wide).

Worker thread runs in background:

If pool size < threshold (e.g. 30), refill N new presigns.

Mark used=true atomically to prevent reuse.

Encryption: store pre-signs encrypted with workspace key (AES-GCM).

In the config, we can have a flag to automatically enable presig pool fill. This mean that when the mpcium node detects that it's idle doesn't process any transaciton, it will run fillPresignPool

WalletID string `json:"wallet_id"`
ECDSAPubKey []byte `json:"ecdsa_pub_key"`
EDDSAPubKey []byte `json:"eddsa_pub_key"`
CGGMP21PubKey []byte `json:"cggmp21_pub_key"`
Copy link
Contributor

Choose a reason for hiding this comment

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

is cggmp21_pub_key ecdsa or eddsa?

I think in keygen, sign event payload. We pass algorithm: Enum : gg18/20 | cggmp21 | ...

In the result event, we use ECDSAPubKey, EDDSAPubKey onl

Copy link
Contributor

Choose a reason for hiding this comment

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

type MPCAlgorithm string

const (
    // Threshold ECDSA family (GG18/GG20)
    MPCAlgorithmGG MPCAlgorithm = "gg18/20"

    // Advanced threshold ECDSA (modern successors)
    MPCAlgorithmCGGMP21 MPCAlgorithm = "cggmp21"

    // Threshold Schnorr family
    MPCAlgorithmFROST   MPCAlgorithm = "frost"
    MPCAlgorithmTaproot MPCAlgorithm = "taproot"
)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

currently all three cggmp21, frost, and taproot only support ECDSA

ec.handleKeygenSessionError(walletID, err, "Failed to create EdDSA key generation session", natMsg)
return
}
cggmp21Session, err := ec.node.CreateTaurusSession(walletID, ec.mpcThreshold, types.KeyTypeCGGMP21, taurus.ActKeygen)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we call it CreateCGGMP21Session to be more generic

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This one’s a factory that sets up sessions for all protocols (CGGMP21, FROST, Taproot). Keeping it generic makes sign/presign creation cleaner and the code easier to read.

Comment on lines +6 to +12
type TaurusMessage struct {
SID string
From string
To []string
IsBroadcast bool
Data []byte
Signature []byte
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if this Taurus Message is necessary, can we use existing events in initiator_msg.go

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah this one’s like a generic TssMessage wrapper for protocol transport, not the same as the initiator events

@anhthii
Copy link
Contributor

anhthii commented Nov 1, 2025

The pull request lacking pratical examples for cggmp21 + taproot + frost signing. May need to add more examples in examples folder

@socket-security
Copy link

socket-security bot commented Nov 6, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedgithub.com/​fxamacker/​cbor/​v2@​v2.4.098100100100100
Addedgithub.com/​taurusgroup/​multi-party-sig@​v0.7.0-alpha-2025-01-28100100100100100

View full report

@vietddude vietddude requested a review from anhthii November 7, 2025 04:41
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.

3 participants