btcd/btcec/pubkey.go
ffranr 665eeb52b1
btcec: add new type SerializedKey
This commit adds a new type called `SerializedKey`.

A serialized type is useful when using public keys as map keys. This is
because functionally identical public keys can have different internal
representations. These differences would cause the map to treat them as
different keys.
2024-04-02 21:19:03 +01:00

89 lines
2.9 KiB
Go

// Copyright (c) 2013-2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcec
import (
secp "github.com/decred/dcrd/dcrec/secp256k1/v4"
)
// These constants define the lengths of serialized public keys.
const (
// PubKeyBytesLenCompressed is the bytes length of a serialized compressed
// public key.
PubKeyBytesLenCompressed = 33
)
const (
pubkeyCompressed byte = 0x2 // y_bit + x coord
pubkeyUncompressed byte = 0x4 // x coord + y coord
pubkeyHybrid byte = 0x6 // y_bit + x coord + y coord
)
// IsCompressedPubKey returns true the passed serialized public key has
// been encoded in compressed format, and false otherwise.
func IsCompressedPubKey(pubKey []byte) bool {
// The public key is only compressed if it is the correct length and
// the format (first byte) is one of the compressed pubkey values.
return len(pubKey) == PubKeyBytesLenCompressed &&
(pubKey[0]&^byte(0x1) == pubkeyCompressed)
}
// ParsePubKey parses a public key for a koblitz curve from a bytestring into a
// ecdsa.Publickey, verifying that it is valid. It supports compressed,
// uncompressed and hybrid signature formats.
func ParsePubKey(pubKeyStr []byte) (*PublicKey, error) {
return secp.ParsePubKey(pubKeyStr)
}
// PublicKey is an ecdsa.PublicKey with additional functions to
// serialize in uncompressed, compressed, and hybrid formats.
type PublicKey = secp.PublicKey
// NewPublicKey instantiates a new public key with the given x and y
// coordinates.
//
// It should be noted that, unlike ParsePubKey, since this accepts arbitrary x
// and y coordinates, it allows creation of public keys that are not valid
// points on the secp256k1 curve. The IsOnCurve method of the returned instance
// can be used to determine validity.
func NewPublicKey(x, y *FieldVal) *PublicKey {
return secp.NewPublicKey(x, y)
}
// SerializedKey is a type for representing a public key in its compressed
// serialized form.
//
// NOTE: This type is useful when using public keys as keys in maps.
type SerializedKey [PubKeyBytesLenCompressed]byte
// ToPubKey returns the public key parsed from the serialized key.
func (s SerializedKey) ToPubKey() (*PublicKey, error) {
return ParsePubKey(s[:])
}
// SchnorrSerialized returns the Schnorr serialized, x-only 32-byte
// representation of the serialized key.
func (s SerializedKey) SchnorrSerialized() [32]byte {
var serializedSchnorr [32]byte
copy(serializedSchnorr[:], s[1:])
return serializedSchnorr
}
// CopyBytes returns a copy of the underlying array as a byte slice.
func (s SerializedKey) CopyBytes() []byte {
c := make([]byte, PubKeyBytesLenCompressed)
copy(c, s[:])
return c
}
// ToSerialized serializes a public key into its compressed form.
func ToSerialized(pubKey *PublicKey) SerializedKey {
var serialized SerializedKey
copy(serialized[:], pubKey.SerializeCompressed())
return serialized
}