lbry.go/schema/keys/keys.go
2020-11-18 01:30:50 -05:00

67 lines
2 KiB
Go

package keys
import (
"crypto/elliptic"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"github.com/lbryio/lbry.go/v2/extras/errors"
"github.com/btcsuite/btcd/btcec"
)
type publicKeyInfo struct {
Raw asn1.RawContent
Algorithm pkix.AlgorithmIdentifier
PublicKey asn1.BitString
}
//This type provides compatibility with the btcec package
type ecPrivateKey struct {
Version int
PrivateKey []byte
NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"`
PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"`
}
func PublicKeyToDER(publicKey *btcec.PublicKey) ([]byte, error) {
var publicKeyBytes []byte
var publicKeyAlgorithm pkix.AlgorithmIdentifier
var err error
pub := publicKey.ToECDSA()
publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y)
//ans1 encoding oid for ecdsa public key https://github.com/golang/go/blob/release-branch.go1.12/src/crypto/x509/x509.go#L457
publicKeyAlgorithm.Algorithm = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
//asn1 encoding oid for secp256k1 https://github.com/bitpay/bitpay-go/blob/v2.2.2/key_utils/key_utils.go#L30
paramBytes, err := asn1.Marshal(asn1.ObjectIdentifier{1, 3, 132, 0, 10})
if err != nil {
return nil, errors.Err(err)
}
publicKeyAlgorithm.Parameters.FullBytes = paramBytes
return asn1.Marshal(publicKeyInfo{
Algorithm: publicKeyAlgorithm,
PublicKey: asn1.BitString{
Bytes: publicKeyBytes,
BitLength: 8 * len(publicKeyBytes),
},
})
}
func GetPublicKeyFromBytes(pubKeyBytes []byte) (*btcec.PublicKey, error) {
PKInfo := publicKeyInfo{}
asn1.Unmarshal(pubKeyBytes, &PKInfo)
pubkeyBytes1 := []byte(PKInfo.PublicKey.Bytes)
return btcec.ParsePubKey(pubkeyBytes1, btcec.S256())
}
//Returns a btec.Private key object if provided a correct secp256k1 encoded pem.
func ExtractKeyFromPem(pm string) (*btcec.PrivateKey, *btcec.PublicKey) {
byta := []byte(pm)
blck, _ := pem.Decode(byta)
var ecp ecPrivateKey
asn1.Unmarshal(blck.Bytes, &ecp)
return btcec.PrivKeyFromBytes(btcec.S256(), ecp.PrivateKey)
}