mirror of
https://github.com/btcsuite/btcd.git
synced 2024-11-19 01:40:07 +01:00
btcec+chaincfg: use pre-computed tag hash values
In this commit, we optimize our signature implementation slightly, by defining pre-computed sha256(tag) variables for the commonly used values. If a tag matches this, then we'll use that hash value to avoid an extra round of hashing.
This commit is contained in:
parent
973fb37600
commit
b7a4622a6b
@ -22,14 +22,6 @@ const (
|
||||
scalarSize = 32
|
||||
)
|
||||
|
||||
var (
|
||||
tagHashAux = []byte("BIP0340/aux")
|
||||
|
||||
tagHashNonce = []byte("BIP0340/nonce")
|
||||
|
||||
tagHashChallenge = []byte("BIP0340/challenge")
|
||||
)
|
||||
|
||||
var (
|
||||
// rfc6979ExtraDataV0 is the extra data to feed to RFC6979 when
|
||||
// generating the deterministic nonce for the BIP-340 scheme. This
|
||||
@ -183,7 +175,7 @@ func schnorrVerify(sig *Signature, hash []byte, pubKeyBytes []byte) error {
|
||||
pBytes := SerializePubKey(pubKey)
|
||||
|
||||
commitment := chainhash.TaggedHash(
|
||||
tagHashChallenge, rBytes[:], pBytes, hash,
|
||||
chainhash.TagBIP0340Challenge, rBytes[:], pBytes, hash,
|
||||
)
|
||||
|
||||
var e btcec.ModNScalar
|
||||
@ -325,7 +317,7 @@ func schnorrSign(privKey, nonce *btcec.ModNScalar, pubKey *btcec.PublicKey, hash
|
||||
pBytes := SerializePubKey(pubKey)
|
||||
|
||||
commitment := chainhash.TaggedHash(
|
||||
tagHashChallenge, rBytes[:], pBytes, hash,
|
||||
chainhash.TagBIP0340Challenge, rBytes[:], pBytes, hash,
|
||||
)
|
||||
|
||||
var e btcec.ModNScalar
|
||||
@ -492,7 +484,9 @@ func Sign(privKey *btcec.PrivateKey, hash []byte,
|
||||
//
|
||||
// t = bytes(d) xor tagged_hash("BIP0340/aux", a)
|
||||
privBytes := privKeyScalar.Bytes()
|
||||
t := chainhash.TaggedHash(tagHashAux, (*opts.authNonce)[:])
|
||||
t := chainhash.TaggedHash(
|
||||
chainhash.TagBIP0340Aux, (*opts.authNonce)[:],
|
||||
)
|
||||
for i := 0; i < len(t); i++ {
|
||||
t[i] ^= privBytes[i]
|
||||
}
|
||||
@ -504,7 +498,7 @@ 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(
|
||||
tagHashNonce, t[:], pubKeyBytes[1:], hash,
|
||||
chainhash.TagBIP0340Nonce, t[:], pubKeyBytes[1:], hash,
|
||||
)
|
||||
|
||||
// Step 8.
|
||||
|
@ -17,6 +17,25 @@ const HashSize = 32
|
||||
// MaxHashStringSize is the maximum length of a Hash hash string.
|
||||
const MaxHashStringSize = HashSize * 2
|
||||
|
||||
var (
|
||||
// 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")
|
||||
|
||||
// precomputedTags is a map containing the SHA-256 hash of the BIP-0340
|
||||
// tags.
|
||||
precomputedTags = map[string]Hash{
|
||||
string(TagBIP0340Challenge): sha256.Sum256(TagBIP0340Challenge),
|
||||
string(TagBIP0340Aux): sha256.Sum256(TagBIP0340Aux),
|
||||
string(TagBIP0340Nonce): sha256.Sum256(TagBIP0340Nonce),
|
||||
}
|
||||
)
|
||||
|
||||
// ErrHashStrSize describes an error that indicates the caller specified a hash
|
||||
// string that has too many characters.
|
||||
var ErrHashStrSize = fmt.Errorf("max hash string length is %v bytes", MaxHashStringSize)
|
||||
@ -84,10 +103,13 @@ func NewHash(newHash []byte) (*Hash, error) {
|
||||
// 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).
|
||||
//
|
||||
// TODO(roasbeef): add fast paths for common known tags
|
||||
func TaggedHash(tag []byte, msgs ...[]byte) *Hash {
|
||||
shaTag := sha256.Sum256(tag)
|
||||
// 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()
|
||||
|
Loading…
Reference in New Issue
Block a user