Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

btcec: remove import of chainhash #1848

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions btcec/ecdsa/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@
package ecdsa_test

import (
"crypto/sha256"
"encoding/hex"
"fmt"

"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)

func doubleHash(b []byte) []byte {
first := sha256.Sum256(b)
second := sha256.Sum256(first[:])
return second[:]
}

// This example demonstrates signing a message with a secp256k1 private key that
// is first parsed form raw bytes and serializing the generated signature.
func Example_signMessage() {
Expand All @@ -27,7 +33,7 @@ func Example_signMessage() {

// Sign a message using the private key.
message := "test message"
messageHash := chainhash.DoubleHashB([]byte(message))
messageHash := doubleHash([]byte(message))
signature := ecdsa.Sign(privKey, messageHash)

// Serialize and display the signature.
Expand Down Expand Up @@ -76,7 +82,7 @@ func Example_verifySignature() {

// Verify the signature for the message using the public key.
message := "test message"
messageHash := chainhash.DoubleHashB([]byte(message))
messageHash := doubleHash([]byte(message))
verified := signature.Verify(messageHash, pubKey)
fmt.Println("Signature Verified?", verified)

Expand Down
3 changes: 1 addition & 2 deletions btcec/field_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
package btcec

import (
"math/rand"

"encoding/hex"
"math/rand"
"testing"
)

Expand Down
1 change: 0 additions & 1 deletion btcec/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module github.com/btcsuite/btcd/btcec/v2
go 1.17

require (
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0
github.com/davecgh/go-spew v1.1.1
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1
)
Expand Down
2 changes: 0 additions & 2 deletions btcec/go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0 h1:MSskdM4/xJYcFzy0altH/C/xHopifpWzHUi1JeVI34Q=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
Expand Down
105 changes: 85 additions & 20 deletions btcec/schnorr/signature.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
package schnorr

import (
"crypto/sha256"
"fmt"

"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/chaincfg/chainhash"
secp "github.com/decred/dcrd/dcrec/secp256k1/v4"
ecdsa_schnorr "github.com/decred/dcrd/dcrec/secp256k1/v4/schnorr"
)
Expand All @@ -35,8 +35,73 @@ var (
0x68, 0x6d, 0x71, 0xe8, 0x7f, 0x39, 0x4f, 0x79,
0x9c, 0x00, 0xa5, 0x21, 0x03, 0xcb, 0x4e, 0x17,
}

// tagBIP0340Challenge is the BIP-0340 tag for challenges.
tagBIP0340Challenge = []byte("BIP0340/challenge")

// tagBIP0340Aux is the BIP-0340 tag for aux data.
tagBIP0340Aux = []byte("BIP0340/aux")

// tagBIP0340Nonce is the BIP-0340 tag for nonces.
tagBIP0340Nonce = []byte("BIP0340/nonce")

// tagTapSighash is the tag used by BIP 341 to generate the sighash
// flags.
tagTapSighash = []byte("TapSighash")

// tagTagTapLeaf is the message tag prefix used to compute the hash
// digest of a tapscript leaf.
tagTapLeaf = []byte("TapLeaf")

// tagTapBranch is the message tag prefix used to compute the
// hash digest of two tap leaves into a taproot branch node.
tagTapBranch = []byte("TapBranch")

// tagTapTweak is the message tag prefix used to compute the hash tweak
// used to enable a public key to commit to the taproot branch root
// for the witness program.
tagTapTweak = []byte("TapTweak")

// precomputedTags is a map containing the SHA-256 hash of the BIP-0340
// tags.
precomputedTags = map[string][32]byte{
string(tagBIP0340Challenge): sha256.Sum256(tagBIP0340Challenge),
string(tagBIP0340Aux): sha256.Sum256(tagBIP0340Aux),
string(tagBIP0340Nonce): sha256.Sum256(tagBIP0340Nonce),
string(tagTapSighash): sha256.Sum256(tagTapSighash),
string(tagTapLeaf): sha256.Sum256(tagTapLeaf),
string(tagTapBranch): sha256.Sum256(tagTapBranch),
string(tagTapTweak): sha256.Sum256(tagTapTweak),
}
)

// taggedHash implements the tagged hash scheme described in BIP-340. We use
// sha-256 to bind a message hash to a specific context using a tag:
// sha256(sha256(tag) || sha256(tag) || msg).
func taggedHash(tag []byte, msgs ...[]byte) [32]byte {
// Check to see if we've already pre-computed the hash of the tag. If
// so then this'll save us an extra sha256 hash.
shaTag, ok := precomputedTags[string(tag)]
if !ok {
shaTag = sha256.Sum256(tag)
}

// h = sha256(sha256(tag) || sha256(tag) || msg)
h := sha256.New()
h.Write(shaTag[:])
h.Write(shaTag[:])

for _, msg := range msgs {
h.Write(msg)
}

taggedHash := h.Sum(nil)
var hash [32]byte
copy(hash[:], taggedHash)

return hash
}

// Signature is a type representing a Schnorr signature.
type Signature struct {
r btcec.FieldVal
Expand Down Expand Up @@ -129,7 +194,7 @@ func schnorrVerify(sig *Signature, hash []byte, pubKeyBytes []byte) error {
// 7. Fail if is_infinite(R)
// 8. Fail if not hash_even_y(R)
// 9. Fail is x(R) != r.
// 10. Return success iff not failure occured before reachign this
// 10. Return success iff not failure occurred before reaching this
// point.

// Step 1.
Expand Down Expand Up @@ -174,12 +239,12 @@ func schnorrVerify(sig *Signature, hash []byte, pubKeyBytes []byte) error {
sig.r.PutBytesUnchecked(rBytes[:])
pBytes := SerializePubKey(pubKey)

commitment := chainhash.TaggedHash(
chainhash.TagBIP0340Challenge, rBytes[:], pBytes, hash,
commitment := taggedHash(
tagBIP0340Challenge, rBytes[:], pBytes, hash,
)

var e btcec.ModNScalar
if overflow := e.SetBytes((*[32]byte)(commitment)); overflow != 0 {
if overflow := e.SetBytes(&commitment); overflow != 0 {
str := "hash of (r || P || m) too big"
return signatureError(ecdsa_schnorr.ErrSchnorrHashValue, str)
}
Expand Down Expand Up @@ -228,7 +293,7 @@ func schnorrVerify(sig *Signature, hash []byte, pubKeyBytes []byte) error {

// Step 10.
//
// Return success iff not failure occured before reachign this
// Return success iff not failure occurred before reaching this
return nil
}

Expand Down Expand Up @@ -264,7 +329,7 @@ func schnorrSign(privKey, nonce *btcec.ModNScalar, pubKey *btcec.PublicKey, hash
// n = curve order
// d = private key
// m = message
// a = input randmoness
// a = input randomness
// r, s = signature
//
// 1. d' = int(d)
Expand Down Expand Up @@ -316,12 +381,12 @@ func schnorrSign(privKey, nonce *btcec.ModNScalar, pubKey *btcec.PublicKey, hash
r.PutBytesUnchecked(rBytes[:])
pBytes := SerializePubKey(pubKey)

commitment := chainhash.TaggedHash(
chainhash.TagBIP0340Challenge, rBytes[:], pBytes, hash,
commitment := taggedHash(
tagBIP0340Challenge, rBytes[:], pBytes, hash,
)

var e btcec.ModNScalar
if overflow := e.SetBytes((*[32]byte)(commitment)); overflow != 0 {
if overflow := e.SetBytes(&commitment); overflow != 0 {
k.Zero()
str := "hash of (r || P || m) too big"
return nil, signatureError(ecdsa_schnorr.ErrSchnorrHashValue, str)
Expand Down Expand Up @@ -350,8 +415,8 @@ func schnorrSign(privKey, nonce *btcec.ModNScalar, pubKey *btcec.PublicKey, hash
return sig, nil
}

// SignOption is a functional option arguemnt that allows callers to modify the
// way we generate BIP-340 schnorr signatues.
// SignOption is a functional option argument that allows callers to modify the
// way we generate BIP-340 schnorr signatures.
type SignOption func(*signOptions)

// signOptions houses the set of functional options that can be used to modify
Expand All @@ -372,7 +437,7 @@ func defaultSignOptions() *signOptions {
}

// FastSign forces signing to skip the extra verification step at the end.
// Peformance sensitive applications may opt to use this option to speed up the
// Performance sensitive applications may opt to use this option to speed up the
// signing operation.
func FastSign() SignOption {
return func(o *signOptions) {
Expand Down Expand Up @@ -417,7 +482,7 @@ func Sign(privKey *btcec.PrivateKey, hash []byte,
// n = curve order
// d = private key
// m = message
// a = input randmoness
// a = input randomness
// r, s = signature
//
// 1. d' = int(d)
Expand Down Expand Up @@ -478,14 +543,14 @@ func Sign(privKey *btcec.PrivateKey, hash []byte,

// At this point, we check to see if a CustomNonce has been passed in,
// and if so, then we'll deviate from the main routine here by
// generating the nonce value as specifid by BIP-0340.
// generating the nonce value as specified by BIP-0340.
if opts.authNonce != nil {
// Step 6.
//
// t = bytes(d) xor tagged_hash("BIP0340/aux", a)
privBytes := privKeyScalar.Bytes()
t := chainhash.TaggedHash(
chainhash.TagBIP0340Aux, (*opts.authNonce)[:],
t := taggedHash(
tagBIP0340Aux, (*opts.authNonce)[:],
)
for i := 0; i < len(t); i++ {
t[i] ^= privBytes[i]
Expand All @@ -497,15 +562,15 @@ func Sign(privKey *btcec.PrivateKey, hash []byte,
//
// We snip off the first byte of the serialized pubkey, as we
// only need the x coordinate and not the market byte.
rand := chainhash.TaggedHash(
chainhash.TagBIP0340Nonce, t[:], pubKeyBytes[1:], hash,
rand := taggedHash(
tagBIP0340Nonce, t[:], pubKeyBytes[1:], hash,
)

// Step 8.
//
// k'= int(rand) mod n
var kPrime btcec.ModNScalar
kPrime.SetBytes((*[32]byte)(rand))
kPrime.SetBytes(&rand)

// Step 9.
//
Expand Down