Skip to content

Commit

Permalink
update PrivateKeyFromBase58 with IsOnCurve
Browse files Browse the repository at this point in the history
  • Loading branch information
pikomonde committed Aug 1, 2024
1 parent 14a3ff9 commit 91e4280
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 2 deletions.
27 changes: 27 additions & 0 deletions keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,29 @@ func MustPrivateKeyFromBase58(in string) PrivateKey {
}

// PrivateKeyFromBase58 returns a PrivateKey from a base58-encoded string.
//
// PrivateKeyFromBase58 returns a PrivateKey from a base58-encoded string. The function
// first decodes the input string using base58, then checks if the resulting private key
// is valid by deriving the corresponding public key and checking if it is on the Ed25519
// curve. If the private key is invalid, an error is returned.
//
// Parameters:
//
// privkey - the base58-encoded private key string
//
// Returns:
//
// PrivateKey - the decoded private key
// error - an error if the input string is invalid or the derived public key is not on the curve
func PrivateKeyFromBase58(privkey string) (PrivateKey, error) {
res, err := base58.Decode(privkey)
if err != nil {
return nil, err
}
pub := PrivateKey(res).PublicKey().Bytes()
if !IsOnCurve(pub) {
return nil, errors.New("invalid private key")
}
return res, nil
}

Expand All @@ -74,6 +92,15 @@ func (k PrivateKey) String() string {
return base58.Encode(k)
}

// NewRandomPrivateKey generates a new random Ed25519 private key.
//
// NewRandomPrivateKey returns a new random Ed25519 private key. The private key is
// generated using a cryptographically secure random number generator.
//
// Returns:
//
// PrivateKey: a new random Ed25519 private key
// error: an error if the key generation fails
func NewRandomPrivateKey() (PrivateKey, error) {
pub, priv, err := ed25519.GenerateKey(crypto_rand.Reader)
if err != nil {
Expand Down
37 changes: 35 additions & 2 deletions keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
package solana

import (
"crypto/ed25519"
"crypto/rand"
"encoding/binary"
"encoding/hex"
"errors"
Expand Down Expand Up @@ -111,8 +113,8 @@ func TestPrivateKeyFromBase58(t *testing.T) {
}{
{
name: "normal case",
in: "3yZe7d",
want: "3yZe7d",
in: "6HsFaXKVD7mo43oTbdqyGgAnYFeNNhqY75B3JGJ6K8a227KjjG3uW3v",
want: "6HsFaXKVD7mo43oTbdqyGgAnYFeNNhqY75B3JGJ6K8a227KjjG3uW3v",
},
{
name: "edge case - empty string",
Expand Down Expand Up @@ -479,7 +481,38 @@ func TestGetAddedRemoved(t *testing.T) {
)
}
}
func TestIsOnCurve(t *testing.T) {
// Test a valid private key
privateKey, err := NewRandomPrivateKey()
if err != nil {
t.Errorf("Failed to generate private key: %v", err)
}

// Test a valid public key
publicKey := privateKey.PublicKey()
if !IsOnCurve(publicKey.Bytes()) {
t.Errorf("Valid public key is not on the curve")
}

// Test an invalid key (too short)
shortKey := []byte{1, 2, 3}
if IsOnCurve(shortKey) {
t.Errorf("Invalid key (too short) is on the curve")
}

// Test an invalid key (too long)
longKey := make([]byte, ed25519.PrivateKeySize+1)
if IsOnCurve(longKey) {
t.Errorf("Invalid key (too long) is on the curve")
}

// Test an invalid key (random bytes)
randKey := make([]byte, ed25519.PrivateKeySize)
_, _ = rand.Read(randKey)
if IsOnCurve(randKey) {
t.Errorf("Invalid key (random bytes) is on the curve")
}
}
func TestIsNativeProgramID(t *testing.T) {
require.True(t, isNativeProgramID(ConfigProgramID))
}
Expand Down

0 comments on commit 91e4280

Please sign in to comment.