@@ -2,6 +2,7 @@ package client
22
33import (
44 "context"
5+ "crypto/ecdsa"
56 "crypto/ed25519"
67 "encoding/hex"
78 "encoding/json"
@@ -12,6 +13,7 @@ import (
1213 "strings"
1314
1415 "filippo.io/age"
16+ "github.com/fystack/mpcium/pkg/encryption"
1517 "github.com/fystack/mpcium/pkg/event"
1618 "github.com/fystack/mpcium/pkg/eventconsumer"
1719 "github.com/fystack/mpcium/pkg/logger"
@@ -36,14 +38,23 @@ type MPCClient interface {
3638 OnResharingResult (callback func (event event.ResharingResultEvent )) error
3739}
3840
41+ type InitiatorPrivKey struct {
42+ Algorithm types.KeyType
43+ Ed25519 ed25519.PrivateKey
44+ P256 ecdsa.PrivateKey
45+ }
46+
3947type mpcClient struct {
4048 signingBroker messaging.MessageBroker
4149 keygenBroker messaging.MessageBroker
4250 pubsub messaging.PubSub
4351 genKeySuccessQueue messaging.MessageQueue
4452 signResultQueue messaging.MessageQueue
4553 reshareSuccessQueue messaging.MessageQueue
46- privKey ed25519.PrivateKey
54+ // privKey ed25519.PrivateKey
55+ // privKeyECDSA *ecdsa.PrivateKey
56+ initiatorPrivKey * InitiatorPrivKey
57+ algorithm string
4758}
4859
4960// Options defines configuration options for creating a new MPCClient
@@ -57,10 +68,13 @@ type Options struct {
5768 // Encryption options
5869 Encrypted bool // Whether the key is encrypted
5970 Password string // Password for encrypted key
71+
72+ // Algorithm for key type
73+ Algorithm string // Either "ed25519" or "p256" (default: "ed25519")
6074}
6175
6276// NewMPCClient creates a new MPC client using the provided options.
63- // It reads the Ed25519 private key from disk and sets up messaging connections.
77+ // It reads the Ed25519 or P256 private key from disk and sets up messaging connections.
6478// If the key is encrypted (.age file), decryption options must be provided in the config.
6579func NewMPCClient (opts Options ) MPCClient {
6680 // Set default paths if not provided
@@ -105,16 +119,28 @@ func NewMPCClient(opts Options) MPCClient {
105119 logger .Fatal ("No private key file found" , nil )
106120 }
107121
108- privHex := string (privHexBytes )
109- // Decode private key from hex
110- privSeed , err := hex .DecodeString (privHex )
111- if err != nil {
112- fmt .Println ("Failed to decode private key hex:" , err )
113- os .Exit (1 )
114- }
122+ var priv ed25519.PrivateKey
123+ var privECDSA * ecdsa.PrivateKey
124+
125+ if opts .Algorithm == "p256" {
126+ // Parse P256 key
127+ privECDSA , err = encryption .ParseP256PrivateKey (privHexBytes )
128+ if err != nil {
129+ logger .Fatal ("Failed to parse P256 private key" , err )
130+ }
131+ } else {
132+ // Parse Ed25519 key (default behavior)
133+ privHex := string (privHexBytes )
134+ // Decode private key from hex
135+ privSeed , err := hex .DecodeString (privHex )
136+ if err != nil {
137+ fmt .Println ("Failed to decode private key hex:" , err )
138+ os .Exit (1 )
139+ }
115140
116- // Reconstruct full Ed25519 private key from seed
117- priv := ed25519 .NewKeyFromSeed (privSeed )
141+ // Reconstruct full Ed25519 private key from seed
142+ priv = ed25519 .NewKeyFromSeed (privSeed )
143+ }
118144
119145 // 2) Create the PubSub for both publish & subscribe
120146 signingBroker , err := messaging .NewJetStreamBroker (
@@ -159,7 +185,14 @@ func NewMPCClient(opts Options) MPCClient {
159185 genKeySuccessQueue : genKeySuccessQueue ,
160186 signResultQueue : signResultQueue ,
161187 reshareSuccessQueue : reshareSuccessQueue ,
162- privKey : priv ,
188+ // privKey: priv,
189+ // privKeyECDSA: privECDSA,
190+ initiatorPrivKey : & InitiatorPrivKey {
191+ Algorithm : types .KeyType (opts .Algorithm ),
192+ Ed25519 : priv ,
193+ P256 : * privECDSA ,
194+ },
195+ algorithm : opts .Algorithm ,
163196 }
164197}
165198
@@ -197,8 +230,24 @@ func (c *mpcClient) CreateWallet(walletID string) error {
197230 if err != nil {
198231 return fmt .Errorf ("CreateWallet: raw payload error: %w" , err )
199232 }
200- // sign
201- msg .Signature = ed25519 .Sign (c .privKey , raw )
233+ logger .Info ("Raw payload for signing" , "raw" , string (raw ), "raw_bytes" , raw )
234+ // sign based on algorithm
235+ var signature []byte
236+ if c .algorithm == "p256" {
237+ if c .initiatorPrivKey .P256 .Curve == nil {
238+ return fmt .Errorf ("CreateWallet: P256 private key not initialized" )
239+ }
240+ signature , err = encryption .SignWithP256 (& c .initiatorPrivKey .P256 , raw )
241+ if err != nil {
242+ return fmt .Errorf ("CreateWallet: failed to create P256 signature: %w" , err )
243+ }
244+ if signature == nil {
245+ return fmt .Errorf ("CreateWallet: failed to create P256 signature" )
246+ }
247+ } else {
248+ signature = ed25519 .Sign (c .initiatorPrivKey .Ed25519 , raw )
249+ }
250+ msg .Signature = signature
202251
203252 bytes , err := json .Marshal (msg )
204253 if err != nil {
@@ -237,8 +286,23 @@ func (c *mpcClient) SignTransaction(msg *types.SignTxMessage) error {
237286 if err != nil {
238287 return fmt .Errorf ("SignTransaction: raw payload error: %w" , err )
239288 }
240- // sign
241- msg .Signature = ed25519 .Sign (c .privKey , raw )
289+ // sign based on algorithm
290+ var signature []byte
291+ if c .algorithm == "p256" {
292+ if c .initiatorPrivKey .P256 .Curve == nil {
293+ return fmt .Errorf ("SignTransaction: P256 private key not initialized" )
294+ }
295+ signature , err = encryption .SignWithP256 (& c .initiatorPrivKey .P256 , raw )
296+ if err != nil {
297+ return fmt .Errorf ("SignTransaction: failed to create P256 signature: %w" , err )
298+ }
299+ if signature == nil {
300+ return fmt .Errorf ("SignTransaction: failed to create P256 signature" )
301+ }
302+ } else {
303+ signature = ed25519 .Sign (c .initiatorPrivKey .Ed25519 , raw )
304+ }
305+ msg .Signature = signature
242306
243307 bytes , err := json .Marshal (msg )
244308 if err != nil {
@@ -275,8 +339,23 @@ func (c *mpcClient) Resharing(msg *types.ResharingMessage) error {
275339 if err != nil {
276340 return fmt .Errorf ("Resharing: raw payload error: %w" , err )
277341 }
278- // sign
279- msg .Signature = ed25519 .Sign (c .privKey , raw )
342+ // sign based on algorithm
343+ var signature []byte
344+ if c .algorithm == "p256" {
345+ if c .initiatorPrivKey .P256 .Curve == nil {
346+ return fmt .Errorf ("Resharing: P256 private key not initialized" )
347+ }
348+ signature , err = encryption .SignWithP256 (& c .initiatorPrivKey .P256 , raw )
349+ if err != nil {
350+ return fmt .Errorf ("Resharing: failed to create P256 signature: %w" , err )
351+ }
352+ if signature == nil {
353+ return fmt .Errorf ("Resharing: failed to create P256 signature" )
354+ }
355+ } else {
356+ signature = ed25519 .Sign (c .initiatorPrivKey .Ed25519 , raw )
357+ }
358+ msg .Signature = signature
280359
281360 bytes , err := json .Marshal (msg )
282361 if err != nil {
0 commit comments