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"`
|
PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func PrivateKeyToDER(privateKey *btcec.PrivateKey) ([]byte, error) {
|
func PrivateKeyToDER(key *btcec.PrivateKey) ([]byte, error) {
|
||||||
priv := privateKey.ToECDSA()
|
privateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8)
|
||||||
privateKeyBytes := elliptic.Marshal(priv.Curve, priv.X, priv.Y)
|
oid := asn1.ObjectIdentifier{1, 3, 132, 0, 10}
|
||||||
pub := privateKey.PubKey().ToECDSA()
|
|
||||||
publicKeyBytes := elliptic.Marshal(pub.Curve, pub.X, pub.Y)
|
|
||||||
return asn1.Marshal(ecPrivateKey{
|
return asn1.Marshal(ecPrivateKey{
|
||||||
Version: 1,
|
Version: 1,
|
||||||
PrivateKey: priv.D.FillBytes(privateKeyBytes),
|
PrivateKey: key.D.FillBytes(privateKey),
|
||||||
//asn1 encoding oid for secp256k1 https://github.com/bitpay/bitpay-go/blob/v2.2.2/key_utils/key_utils.go#L30
|
NamedCurveOID: oid,
|
||||||
NamedCurveOID: asn1.ObjectIdentifier{1, 3, 132, 0, 10},
|
PublicKey: asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)},
|
||||||
PublicKey: asn1.BitString{
|
|
||||||
Bytes: publicKeyBytes,
|
|
||||||
BitLength: 8 * len(publicKeyBytes),
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPublicKeyFromBytes(pubKeyBytes []byte) (*btcec.PublicKey, error) {
|
func GetPublicKeyFromBytes(pubKeyBytes []byte) (*btcec.PublicKey, error) {
|
||||||
PKInfo := publicKeyInfo{}
|
PKInfo := publicKeyInfo{}
|
||||||
asn1.Unmarshal(pubKeyBytes, &PKInfo)
|
_, err := asn1.Unmarshal(pubKeyBytes, &PKInfo)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Err(err)
|
||||||
|
}
|
||||||
pubkeyBytes1 := []byte(PKInfo.PublicKey.Bytes)
|
pubkeyBytes1 := []byte(PKInfo.PublicKey.Bytes)
|
||||||
return btcec.ParsePubKey(pubkeyBytes1, btcec.S256())
|
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.
|
//Returns a btec.Private key object if provided a correct secp256k1 encoded pem.
|
||||||
func ExtractKeyFromPem(pm string) (*btcec.PrivateKey, *btcec.PublicKey) {
|
func ExtractKeyFromPem(pm string) (*btcec.PrivateKey, *btcec.PublicKey) {
|
||||||
byta := []byte(pm)
|
byta := []byte(pm)
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
package keys
|
package keys
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"encoding/pem"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"gotest.tools/assert"
|
"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!")
|
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