1 // Copyright (c) 2013-2017 The btcsuite developers
2 // Copyright (c) 2015-2021 The Decred developers
3 // Use of this source code is governed by an ISC
4 // license that can be found in the LICENSE file.
5 6 package schnorr
7 8 import (
9 "fmt"
10 11 "github.com/btcsuite/btcd/btcec/v2"
12 secp "github.com/decred/dcrd/dcrec/secp256k1/v4"
13 )
14 15 // These constants define the lengths of serialized public keys.
16 const (
17 PubKeyBytesLen = 32
18 )
19 20 // ParsePubKey parses a public key for a koblitz curve from a bytestring into a
21 // btcec.Publickey, verifying that it is valid. It only supports public keys in
22 // the BIP-340 32-byte format.
23 func ParsePubKey(pubKeyStr []byte) (*btcec.PublicKey, error) {
24 if pubKeyStr == nil {
25 err := fmt.Errorf("nil pubkey byte string")
26 return nil, err
27 }
28 if len(pubKeyStr) != PubKeyBytesLen {
29 err := fmt.Errorf("bad pubkey byte string size (want %v, have %v)",
30 PubKeyBytesLen, len(pubKeyStr))
31 return nil, err
32 }
33 34 // We'll manually prepend the compressed byte so we can re-use the
35 // existing pubkey parsing routine of the main btcec package.
36 var keyCompressed [btcec.PubKeyBytesLenCompressed]byte
37 keyCompressed[0] = secp.PubKeyFormatCompressedEven
38 copy(keyCompressed[1:], pubKeyStr)
39 40 return btcec.ParsePubKey(keyCompressed[:])
41 }
42 43 // SerializePubKey serializes a public key as specified by BIP 340. Public keys
44 // in this format are 32 bytes in length, and are assumed to have an even y
45 // coordinate.
46 func SerializePubKey(pub *btcec.PublicKey) []byte {
47 pBytes := pub.SerializeCompressed()
48 return pBytes[1:]
49 }
50