Skip to content

Commit

Permalink
chaincfg: add BIP-340 tagged hash implementation
Browse files Browse the repository at this point in the history
In this commit, we add an implementation of the BIP-340 tagged hash
scheme. This initial version can be optimized quite a bit, for example,
we can hard code the output of frequently used `sha256(tag)` values and
save two `sha256` invocations.
  • Loading branch information
Roasbeef committed Dec 5, 2021
1 parent ce675ff commit d62bde6
Showing 1 changed file with 27 additions and 0 deletions.
27 changes: 27 additions & 0 deletions chaincfg/chainhash/hash.go
Expand Up @@ -6,6 +6,7 @@
package chainhash

import (
"crypto/sha256"
"encoding/hex"
"fmt"
)
Expand Down Expand Up @@ -80,6 +81,32 @@ func NewHash(newHash []byte) (*Hash, error) {
return &sh, err
}

// TaggedHash implements the tagged hash scheme described in BIP-340. We use
// sha-256 to bind a message hash to a speicifc context using a tag:
// sha256(sha256(tag) || sha257(tag) || msg).
//
// TODO(roasbeef): add fast paths for common known tags
func TaggedHash(tag []byte, msgs ...[]byte) *Hash {
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)

// The function can't error out since the above hash is guaranteed to
// be 32 bytes.
hash, _ := NewHash(taggedHash)

return hash
}

// NewHashFromStr creates a Hash from a hash string. The string should be
// the hexadecimal string of a byte-reversed hash, but any missing characters
// result in zero padding at the end of the Hash.
Expand Down

0 comments on commit d62bde6

Please sign in to comment.