1 // Copyright (c) 2013-2014 The btcsuite developers
2 // Use of this source code is governed by an ISC
3 // license that can be found in the LICENSE file.
4 5 package btcec
6 7 import (
8 secp "github.com/decred/dcrd/dcrec/secp256k1/v4"
9 )
10 11 // These constants define the lengths of serialized public keys.
12 const (
13 // PubKeyBytesLenCompressed is the bytes length of a serialized compressed
14 // public key.
15 PubKeyBytesLenCompressed = 33
16 )
17 18 const (
19 pubkeyCompressed byte = 0x2 // y_bit + x coord
20 pubkeyUncompressed byte = 0x4 // x coord + y coord
21 pubkeyHybrid byte = 0x6 // y_bit + x coord + y coord
22 )
23 24 // IsCompressedPubKey returns true the passed serialized public key has
25 // been encoded in compressed format, and false otherwise.
26 func IsCompressedPubKey(pubKey []byte) bool {
27 // The public key is only compressed if it is the correct length and
28 // the format (first byte) is one of the compressed pubkey values.
29 return len(pubKey) == PubKeyBytesLenCompressed &&
30 (pubKey[0]&^byte(0x1) == pubkeyCompressed)
31 }
32 33 // ParsePubKey parses a public key for a koblitz curve from a bytestring into a
34 // ecdsa.Publickey, verifying that it is valid. It supports compressed,
35 // uncompressed and hybrid signature formats.
36 func ParsePubKey(pubKeyStr []byte) (*PublicKey, error) {
37 return secp.ParsePubKey(pubKeyStr)
38 }
39 40 // PublicKey is an ecdsa.PublicKey with additional functions to
41 // serialize in uncompressed, compressed, and hybrid formats.
42 type PublicKey = secp.PublicKey
43 44 // NewPublicKey instantiates a new public key with the given x and y
45 // coordinates.
46 //
47 // It should be noted that, unlike ParsePubKey, since this accepts arbitrary x
48 // and y coordinates, it allows creation of public keys that are not valid
49 // points on the secp256k1 curve. The IsOnCurve method of the returned instance
50 // can be used to determine validity.
51 func NewPublicKey(x, y *FieldVal) *PublicKey {
52 return secp.NewPublicKey(x, y)
53 }
54 55 // SerializedKey is a type for representing a public key in its compressed
56 // serialized form.
57 //
58 // NOTE: This type is useful when using public keys as keys in maps.
59 type SerializedKey [PubKeyBytesLenCompressed]byte
60 61 // ToPubKey returns the public key parsed from the serialized key.
62 func (s SerializedKey) ToPubKey() (*PublicKey, error) {
63 return ParsePubKey(s[:])
64 }
65 66 // SchnorrSerialized returns the Schnorr serialized, x-only 32-byte
67 // representation of the serialized key.
68 func (s SerializedKey) SchnorrSerialized() [32]byte {
69 var serializedSchnorr [32]byte
70 copy(serializedSchnorr[:], s[1:])
71 return serializedSchnorr
72 }
73 74 // CopyBytes returns a copy of the underlying array as a byte slice.
75 func (s SerializedKey) CopyBytes() []byte {
76 c := make([]byte, PubKeyBytesLenCompressed)
77 copy(c, s[:])
78 79 return c
80 }
81 82 // ToSerialized serializes a public key into its compressed form.
83 func ToSerialized(pubKey *PublicKey) SerializedKey {
84 var serialized SerializedKey
85 copy(serialized[:], pubKey.SerializeCompressed())
86 87 return serialized
88 }
89