Skip to content

Commit 707833c

Browse files
committed
Worked. Update generate examples to test with p256
1 parent 4e358c5 commit 707833c

7 files changed

Lines changed: 281 additions & 128 deletions

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ node0
2121
node1
2222
node2
2323
config.yaml
24-
peers.json
24+
.vscode

cmd/mpcium-cli/generate-initiator.go

Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@ package main
22

33
import (
44
"context"
5-
"crypto/ecdsa"
65
"crypto/ed25519"
7-
"crypto/elliptic"
86
"crypto/rand"
9-
"crypto/x509"
107
"encoding/hex"
118
"encoding/json"
129
"fmt"
@@ -18,6 +15,7 @@ import (
1815

1916
"filippo.io/age"
2017
"github.com/fystack/mpcium/pkg/common/pathutil"
18+
"github.com/fystack/mpcium/pkg/encryption"
2119
"github.com/urfave/cli/v3"
2220
)
2321

@@ -32,12 +30,6 @@ type InitiatorIdentity struct {
3230
MachineName string `json:"machine_name"`
3331
}
3432

35-
// KeyData holds the generated key information
36-
type KeyData struct {
37-
PublicKeyHex string
38-
PrivateKeyHex string
39-
}
40-
4133
func generateInitiatorIdentity(ctx context.Context, c *cli.Command) error {
4234
nodeName := c.String("node-name")
4335
outputDir := c.String("output-dir")
@@ -86,13 +78,13 @@ func generateInitiatorIdentity(ctx context.Context, c *cli.Command) error {
8678
}
8779

8880
// Generate keys based on algorithm
89-
var keyData KeyData
81+
var keyData encryption.KeyData
9082
var err error
9183

9284
if algorithm == "ed25519" {
9385
keyData, err = generateEd25519Keys()
9486
} else {
95-
keyData, err = generateP256Keys()
87+
keyData, err = encryption.GenerateP256Keys()
9688
}
9789

9890
if err != nil {
@@ -194,40 +186,15 @@ func generateInitiatorIdentity(ctx context.Context, c *cli.Command) error {
194186
}
195187

196188
// generateEd25519Keys generates Ed25519 keypair
197-
func generateEd25519Keys() (KeyData, error) {
189+
func generateEd25519Keys() (encryption.KeyData, error) {
198190
pubKey, privKeyFull, err := ed25519.GenerateKey(rand.Reader)
199191
if err != nil {
200-
return KeyData{}, err
192+
return encryption.KeyData{}, err
201193
}
202194

203195
privKeySeed := privKeyFull.Seed()
204-
return KeyData{
196+
return encryption.KeyData{
205197
PublicKeyHex: hex.EncodeToString(pubKey),
206198
PrivateKeyHex: hex.EncodeToString(privKeySeed),
207199
}, nil
208200
}
209-
210-
// generateP256Keys generates P-256 keypair
211-
func generateP256Keys() (KeyData, error) {
212-
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
213-
if err != nil {
214-
return KeyData{}, err
215-
}
216-
217-
// Convert private key to PEM format
218-
privateKeyBytes, err := x509.MarshalECPrivateKey(privateKey)
219-
if err != nil {
220-
return KeyData{}, err
221-
}
222-
223-
// Convert public key to DER format
224-
publicKeyBytes, err := x509.MarshalPKIXPublicKey(&privateKey.PublicKey)
225-
if err != nil {
226-
return KeyData{}, err
227-
}
228-
229-
return KeyData{
230-
PublicKeyHex: hex.EncodeToString(publicKeyBytes),
231-
PrivateKeyHex: hex.EncodeToString(privateKeyBytes),
232-
}, nil
233-
}

examples/generate/main.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,25 @@ import (
2323
func main() {
2424
const environment = "development"
2525
numWallets := flag.Int("n", 1, "Number of wallets to generate")
26+
2627
flag.Parse()
2728

2829
config.InitViperConfig()
2930
logger.Init(environment, false)
3031

32+
algorithm := viper.GetString("event_initiator_algorithm")
33+
if algorithm == "" {
34+
algorithm = "ed25519"
35+
}
36+
37+
// Validate algorithm
38+
if algorithm != "ed25519" && algorithm != "p256" {
39+
logger.Fatal(
40+
"Invalid event_initiator_algorithm in config. Must be 'ed25519' or 'p256'",
41+
nil,
42+
)
43+
}
44+
3145
natsURL := viper.GetString("nats.url")
3246
natsConn, err := nats.Connect(natsURL)
3347
if err != nil {
@@ -37,8 +51,9 @@ func main() {
3751
defer natsConn.Close()
3852

3953
mpcClient := client.NewMPCClient(client.Options{
40-
NatsConn: natsConn,
41-
KeyPath: "./event_initiator.key",
54+
Algorithm: algorithm,
55+
NatsConn: natsConn,
56+
KeyPath: "./event_initiator.key",
4257
})
4358

4459
var walletStartTimes sync.Map
@@ -89,13 +104,13 @@ func main() {
89104

90105
// STEP 3: Create wallets
91106
for _, walletID := range walletIDs {
92-
wg.Add(1)
93107
if err := mpcClient.CreateWallet(walletID); err != nil {
94108
logger.Error("CreateWallet failed", err)
95109
walletStartTimes.Delete(walletID)
96110
wg.Done()
97111
continue
98112
}
113+
wg.Add(1)
99114
logger.Info("CreateWallet sent, awaiting result...", "walletID", walletID)
100115
}
101116

pkg/client/client.go

Lines changed: 97 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package client
22

33
import (
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+
3947
type 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.
6579
func 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

Comments
 (0)