Skip to content

Commit

Permalink
Basic private key generation helper methods
Browse files Browse the repository at this point in the history
  • Loading branch information
mrz1836 committed Sep 30, 2020
1 parent 4fbb8e3 commit 17615fe
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 4 deletions.
2 changes: 1 addition & 1 deletion address.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (a *A25) ComputeChecksum() (c [4]byte) {

// AddressFromPrivateKey takes a private key string and returns a Bitcoin address
func AddressFromPrivateKey(privateKey string) (string, error) {
pubKey, err := PrivateKey(privateKey)
pubKey, err := PrivateKeyFromString(privateKey)
if err != nil {
return "", err
}
Expand Down
19 changes: 17 additions & 2 deletions private_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"github.com/bitcoinsv/bsvd/bsvec"
)

// PrivateKey turns a private key string into an bsvec.PrivateKey
func PrivateKey(privateKey string) (*bsvec.PrivateKey, error) {
// PrivateKeyFromString turns a private key (hex encoded string) into an bsvec.PrivateKey
func PrivateKeyFromString(privateKey string) (*bsvec.PrivateKey, error) {
privateKeyBytes, err := hex.DecodeString(privateKey)
if err != nil {
return nil, err
Expand All @@ -22,3 +22,18 @@ func PrivateKey(privateKey string) (*bsvec.PrivateKey, error) {
}
return &bsvec.PrivateKey{PublicKey: ecdsaPubKey, D: new(big.Int).SetBytes(privateKeyBytes)}, nil
}

// CreatePrivateKey will create a new private key
func CreatePrivateKey() (*bsvec.PrivateKey, error) {
return bsvec.NewPrivateKey(bsvec.S256())
}

// CreatePrivateKeyString will create a new private key (hex encoded)
func CreatePrivateKeyString() (string, error) {
privateKey, err := bsvec.NewPrivateKey(bsvec.S256())
if err != nil {
return "", err
}

return hex.EncodeToString(privateKey.Serialize()), nil
}
127 changes: 127 additions & 0 deletions private_key_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package bitcoin

import (
"encoding/hex"
"fmt"
"testing"
)

// TestCreatePrivateKey will test the method CreatePrivateKey()
func TestCreatePrivateKey(t *testing.T) {
rawKey, err := CreatePrivateKey()
if err != nil {
t.Fatalf("error occurred: %s", err.Error())
}
if rawKey == nil {
t.Fatalf("private key was nil")
}
if len(rawKey.Serialize()) == 0 {
t.Fatalf("key length was invalid")
}
}

// ExampleCreatePrivateKey example using CreatePrivateKey()
func ExampleCreatePrivateKey() {
rawKey, err := CreatePrivateKey()
if err != nil {
fmt.Printf("error occurred: %s", err.Error())
return
} else if len(rawKey.Serialize()) > 0 {
fmt.Printf("key created successfully!")
}
// Output:key created successfully!
}

// BenchmarkCreatePrivateKey benchmarks the method CreatePrivateKey()
func BenchmarkCreatePrivateKey(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _ = CreatePrivateKey()
}
}

// TestCreatePrivateKeyString will test the method CreatePrivateKeyString()
func TestCreatePrivateKeyString(t *testing.T) {
key, err := CreatePrivateKeyString()
if err != nil {
t.Fatalf("error occurred: %s", err.Error())
}
if len(key) == 0 {
t.Fatalf("private key is empty")
}
if len(key) != 64 {
t.Fatalf("key length is not 64")
}
}

// ExampleCreatePrivateKeyString example using CreatePrivateKeyString()
func ExampleCreatePrivateKeyString() {
key, err := CreatePrivateKeyString()
if err != nil {
fmt.Printf("error occurred: %s", err.Error())
return
} else if len(key) > 0 {
fmt.Printf("key created successfully!")
}
// Output:key created successfully!
}

// BenchmarkCreatePrivateKeyString benchmarks the method CreatePrivateKeyString()
func BenchmarkCreatePrivateKeyString(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _ = CreatePrivateKeyString()
}
}

// TestPrivateKeyFromString will test the method PrivateKeyFromString()
func TestPrivateKeyFromString(t *testing.T) {
t.Parallel()

// Create the list of tests
var tests = []struct {
input string
expectedKey string
expectedNil bool
expectedError bool
}{
{"54035dd4c7dda99ac473905a3d82f7864322b49bab1ff441cc457183b9bd8abd", "54035dd4c7dda99ac473905a3d82f7864322b49bab1ff441cc457183b9bd8abd", false, false},
{"E83385AF76B2B1997326B567461FB73DD9C27EAB9E1E86D26779F4650C5F2B75", "e83385af76b2b1997326b567461fb73dd9c27eab9e1e86d26779f4650c5f2b75", false, false},
{"E83385AF76B2B1997326B567461FB73DD9C27EAB9E1E86D26779F4650C5F", "0000e83385af76b2b1997326b567461fb73dd9c27eab9e1e86d26779f4650c5f", false, false},
{"E83385AF76B2B1997326B567461FB73DD9C27EAB9E1E86D26779F", "", true, true},
{"1234567", "", true, true},
{"0", "", true, true},
}

// Run tests
for _, test := range tests {
if rawKey, err := PrivateKeyFromString(test.input); err != nil && !test.expectedError {
t.Errorf("%s Failed: [%s] inputted and error not expected but got: %s", t.Name(), test.input, err.Error())
} else if err == nil && test.expectedError {
t.Errorf("%s Failed: [%s] inputted and error was expected", t.Name(), test.input)
} else if rawKey == nil && !test.expectedNil {
t.Errorf("%s Failed: [%s] inputted and was nil but not expected", t.Name(), test.input)
} else if rawKey != nil && test.expectedNil {
t.Errorf("%s Failed: [%s] inputted and was NOT nil but expected to be nil", t.Name(), test.input)
} else if rawKey != nil && hex.EncodeToString(rawKey.Serialize()) != test.expectedKey {
t.Errorf("%s Failed: [%s] inputted [%s] expected but failed comparison of keys, got: %s", t.Name(), test.input, test.expectedKey, hex.EncodeToString(rawKey.Serialize()))
}
}
}

// ExamplePrivateKeyFromString example using PrivateKeyFromString()
func ExamplePrivateKeyFromString() {
key, err := PrivateKeyFromString("54035dd4c7dda99ac473905a3d82f7864322b49bab1ff441cc457183b9bd8abd")
if err != nil {
fmt.Printf("error occurred: %s", err.Error())
return
}
fmt.Printf("key converted: %s", hex.EncodeToString(key.Serialize()))
// Output:key converted: 54035dd4c7dda99ac473905a3d82f7864322b49bab1ff441cc457183b9bd8abd
}

// BenchmarkPrivateKeyFromString benchmarks the method PrivateKeyFromString()
func BenchmarkPrivateKeyFromString(b *testing.B) {
key, _ := CreatePrivateKeyString()
for i := 0; i < b.N; i++ {
_, _ = PrivateKeyFromString(key)
}
}
2 changes: 1 addition & 1 deletion sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func SignMessage(privateKey string, message string) (string, error) {
bytes = append(bytes, prefixBytes...)
bytes = append(bytes, byte(len(messageBytes)))
bytes = append(bytes, messageBytes...)
ecdsaPrivateKey, err := PrivateKey(privateKey)
ecdsaPrivateKey, err := PrivateKeyFromString(privateKey)
if err != nil {
return "", err
}
Expand Down

0 comments on commit 17615fe

Please sign in to comment.