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 "smesh.lol/pkg/nostr/ec"
12 "smesh.lol/pkg/nostr/ec/secp256k1"
13 )
14 15 // These constants define the lengths of serialized public keys.
16 17 const (
18 PubKeyBytesLen = 32
19 )
20 21 // ParsePubKey parses a public key for a koblitz curve from a bytestring into a
22 // btcec.Publickey, verifying that it is valid. It only supports public keys in
23 // the BIP-340 32-byte format.
24 func ParsePubKey(pubKeyStr []byte) (*btcec.PublicKey, error) {
25 if pubKeyStr == nil {
26 err := fmt.Errorf("nil pubkey byte string")
27 return nil, err
28 }
29 if len(pubKeyStr) != PubKeyBytesLen {
30 err := fmt.Errorf(
31 "bad pubkey byte string size (want %v, have %v)",
32 PubKeyBytesLen, len(pubKeyStr),
33 )
34 return nil, err
35 }
36 // We'll manually prepend the compressed byte so we can re-use the existing
37 // pubkey parsing routine of the main btcec package.
38 var keyCompressed [btcec.PubKeyBytesLenCompressed]byte
39 keyCompressed[0] = secp256k1.PubKeyFormatCompressedEven
40 copy(keyCompressed[1:], pubKeyStr)
41 return btcec.ParsePubKey(keyCompressed[:])
42 }
43 44 // SerializePubKey serializes a public key as specified by BIP 340. Public keys
45 // in this format are 32 bytes in length and are assumed to have an even y
46 // coordinate.
47 func SerializePubKey(pub *btcec.PublicKey) []byte {
48 pBytes := pub.SerializeCompressed()
49 return pBytes[1:]
50 }
51