Fix up PrivateKeyToDER function and add tests
This commit is contained in:
parent
bd452c421f
commit
a365d63d16
2 changed files with 78 additions and 14 deletions
|
@ -50,30 +50,37 @@ type ecPrivateKey struct {
|
|||
PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"`
|
||||
}
|
||||
|
||||
func PrivateKeyToDER(privateKey *btcec.PrivateKey) ([]byte, error) {
|
||||
priv := privateKey.ToECDSA()
|
||||
privateKeyBytes := elliptic.Marshal(priv.Curve, priv.X, priv.Y)
|
||||
pub := privateKey.PubKey().ToECDSA()
|
||||
publicKeyBytes := elliptic.Marshal(pub.Curve, pub.X, pub.Y)
|
||||
func PrivateKeyToDER(key *btcec.PrivateKey) ([]byte, error) {
|
||||
privateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8)
|
||||
oid := asn1.ObjectIdentifier{1, 3, 132, 0, 10}
|
||||
return asn1.Marshal(ecPrivateKey{
|
||||
Version: 1,
|
||||
PrivateKey: priv.D.FillBytes(privateKeyBytes),
|
||||
//asn1 encoding oid for secp256k1 https://github.com/bitpay/bitpay-go/blob/v2.2.2/key_utils/key_utils.go#L30
|
||||
NamedCurveOID: asn1.ObjectIdentifier{1, 3, 132, 0, 10},
|
||||
PublicKey: asn1.BitString{
|
||||
Bytes: publicKeyBytes,
|
||||
BitLength: 8 * len(publicKeyBytes),
|
||||
},
|
||||
Version: 1,
|
||||
PrivateKey: key.D.FillBytes(privateKey),
|
||||
NamedCurveOID: oid,
|
||||
PublicKey: asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)},
|
||||
})
|
||||
}
|
||||
|
||||
func GetPublicKeyFromBytes(pubKeyBytes []byte) (*btcec.PublicKey, error) {
|
||||
PKInfo := publicKeyInfo{}
|
||||
asn1.Unmarshal(pubKeyBytes, &PKInfo)
|
||||
_, err := asn1.Unmarshal(pubKeyBytes, &PKInfo)
|
||||
if err != nil {
|
||||
return nil, errors.Err(err)
|
||||
}
|
||||
pubkeyBytes1 := []byte(PKInfo.PublicKey.Bytes)
|
||||
return btcec.ParsePubKey(pubkeyBytes1, btcec.S256())
|
||||
}
|
||||
|
||||
func GetPrivateKeyFromBytes(privKeyBytes []byte) (*btcec.PrivateKey, *btcec.PublicKey, error) {
|
||||
ecPK := ecPrivateKey{}
|
||||
_, err := asn1.Unmarshal(privKeyBytes, &ecPK)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Err(err)
|
||||
}
|
||||
priv, publ := btcec.PrivKeyFromBytes(btcec.S256(), ecPK.PrivateKey)
|
||||
return priv, publ, nil
|
||||
}
|
||||
|
||||
//Returns a btec.Private key object if provided a correct secp256k1 encoded pem.
|
||||
func ExtractKeyFromPem(pm string) (*btcec.PrivateKey, *btcec.PublicKey) {
|
||||
byta := []byte(pm)
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package keys
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"gotest.tools/assert"
|
||||
)
|
||||
|
||||
|
@ -36,3 +39,57 @@ func TestPublicKeyToDER(t *testing.T) {
|
|||
}
|
||||
assert.Assert(t, p1.IsEqual(p2), "The keys produced must be the same key!")
|
||||
}
|
||||
|
||||
func TestPrivateKeyToDER(t *testing.T) {
|
||||
private1, err := btcec.NewPrivateKey(btcec.S256())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
bytes, err := PrivateKeyToDER(private1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
private2, _, err := GetPrivateKeyFromBytes(bytes)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !private1.ToECDSA().Equal(private2.ToECDSA()) {
|
||||
t.Error("private keys dont match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPrivateKeyFromBytes(t *testing.T) {
|
||||
private, err := btcec.NewPrivateKey(btcec.S256())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
bytes, err := PrivateKeyToDER(private)
|
||||
private2, _, err := GetPrivateKeyFromBytes(bytes)
|
||||
if !private.ToECDSA().Equal(private2.ToECDSA()) {
|
||||
t.Error("private keys dont match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodePEMAndBack(t *testing.T) {
|
||||
private1, err := btcec.NewPrivateKey(btcec.S256())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b := bytes.NewBuffer(nil)
|
||||
derBytes, err := PrivateKeyToDER(private1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = pem.Encode(b, &pem.Block{Type: "PRIVATE KEY", Bytes: derBytes})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
println(string(b.Bytes()))
|
||||
private2, _ := ExtractKeyFromPem(string(b.Bytes()))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !private1.ToECDSA().Equal(private2.ToECDSA()) {
|
||||
t.Error("private keys dont match")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue