pubkey.go raw

   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