-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
btcec/v2/schnorr: add initial BIP-340 schnorr sig implementation
In this commit, we add an initial implementation of BIP-340. Mirroring the recently added `ecsda` package, we create a new `schnorr` package with a unique `Signature` type and `ParsePubkey` function. The new `Signature` type implements the fixed-sized 64-byte signatures, and the `ParsePubkey` method only accepts pubkeys that are 32-bytes in length, with an implicit sign byte. The signing implementation by default, deviates from BIP-340 as it opts to use rfc6979 deterministic signatures by default, which means callers don't need to always pass in their own `auxNonce` randomness. A set of functional arguments allows callers to pass in their own value, which is the way all the included test vectors function. The other optional functional argument added is the `FastSign` option that allows callers to skip the final step of verifying each signature they generate.
- Loading branch information
Showing
6 changed files
with
871 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Copyright (c) 2013-2017 The btcsuite developers | ||
// Copyright (c) 2015-2021 The Decred developers | ||
// Use of this source code is governed by an ISC | ||
// license that can be found in the LICENSE file. | ||
|
||
package schnorr | ||
|
||
import ( | ||
ecdsa_schnorr "github.com/decred/dcrd/dcrec/secp256k1/v4/schnorr" | ||
) | ||
|
||
// ErrorKind identifies a kind of error. It has full support for errors.Is | ||
// and errors.As, so the caller can directly check against an error kind | ||
// when determining the reason for an error. | ||
type ErrorKind = ecdsa_schnorr.ErrorKind | ||
|
||
// Error identifies an error related to a schnorr signature. It has full | ||
// support for errors.Is and errors.As, so the caller can ascertain the | ||
// specific reason for the error by checking the underlying error. | ||
type Error = ecdsa_schnorr.Error | ||
|
||
// signatureError creates an Error given a set of arguments. | ||
func signatureError(kind ErrorKind, desc string) Error { | ||
return Error{Err: kind, Description: desc} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright (c) 2013-2017 The btcsuite developers | ||
// Copyright (c) 2015-2021 The Decred developers | ||
// Use of this source code is governed by an ISC | ||
// license that can be found in the LICENSE file. | ||
|
||
package schnorr | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/btcsuite/btcd/btcec/v2" | ||
) | ||
|
||
// These constants define the lengths of serialized public keys. | ||
const ( | ||
PubKeyBytesLen = 32 | ||
|
||
pubkeyCompressed byte = 0x2 // y_bit + x coord | ||
) | ||
|
||
// ParsePubKey parses a public key for a koblitz curve from a bytestring into a | ||
// ecdsa.Publickey, verifying that it is valid. It only supports public keys in | ||
// the BIP-340 32-byte format. | ||
func ParsePubKey(pubKeyStr []byte) (*btcec.PublicKey, error) { | ||
if pubKeyStr == nil { | ||
err := fmt.Errorf("nil pubkey byte string") | ||
return nil, err | ||
} | ||
if len(pubKeyStr) != PubKeyBytesLen { | ||
err := fmt.Errorf("bad pubkey byte string size (want %v, have %v)", | ||
PubKeyBytesLen, len(pubKeyStr)) | ||
return nil, err | ||
} | ||
|
||
// We'll manually prepend the compressed byte so we can re-use the | ||
// existing pubkey parsing routine of the main btcec package. | ||
var keyCompressed [btcec.PubKeyBytesLenCompressed]byte | ||
keyCompressed[0] = btcec.PubKeyFormatCompressedEven | ||
copy(keyCompressed[1:], pubKeyStr) | ||
|
||
return btcec.ParsePubKey(keyCompressed[:]) | ||
} | ||
|
||
// TODO(roasbeef): new type aliases on main pubkey struct for diff serialization? |
Oops, something went wrong.