github.com/piotrnar/gocoin@v0.0.0-20240512203912-faa0448c5e96/lib/btc/hash.go (about) 1 package btc 2 3 import ( 4 "bytes" 5 "crypto/sha256" 6 "encoding" 7 "github.com/piotrnar/gocoin/lib/others/ripemd160" 8 "hash" 9 ) 10 11 const ( 12 HASHER_TAPSIGHASH = 0 13 HASHER_TAPLEAF = 1 14 HASHER_TAPBRANCH = 2 15 HASHER_TAPTWEAK = 3 16 ) 17 18 var ( 19 hash_tags = []string{"TapSighash", "TapLeaf", "TapBranch", "TapTweak"} 20 hashers [HASHER_TAPTWEAK + 1][]byte 21 ) 22 23 func _TaggedHash(tag string) hash.Hash { 24 sha := sha256.New() 25 sha.Write([]byte(tag)) 26 taghash := sha.Sum(nil) 27 sha.Reset() 28 sha.Write(taghash) 29 sha.Write(taghash) 30 return sha 31 } 32 33 func Hasher(idx int) hash.Hash { 34 s := sha256.New() 35 unmarshaler, _ := s.(encoding.BinaryUnmarshaler) 36 unmarshaler.UnmarshalBinary(hashers[idx]) 37 return s 38 } 39 40 func init() { 41 for i, t := range hash_tags { 42 sha := _TaggedHash(t) 43 marshaler, _ := sha.(encoding.BinaryMarshaler) 44 hashers[i], _ = marshaler.MarshalBinary() 45 } 46 } 47 48 func ShaHash(b []byte, out []byte) { 49 s := sha256.New() 50 s.Write(b[:]) 51 tmp := s.Sum(nil) 52 s.Reset() 53 s.Write(tmp) 54 copy(out[:], s.Sum(nil)) 55 } 56 57 // Sha2Sum returns hash: SHA256( SHA256( data ) ). 58 // Where possible, using ShaHash() should be a bit faster. 59 func Sha2Sum(b []byte) (out [32]byte) { 60 ShaHash(b, out[:]) 61 return 62 } 63 64 func RimpHash(in []byte, out []byte) { 65 sha := sha256.New() 66 sha.Write(in) 67 rim := ripemd160.New() 68 rim.Write(sha.Sum(nil)[:]) 69 copy(out, rim.Sum(nil)) 70 } 71 72 // Rimp160AfterSha256 returns hash: RIMP160( SHA256( data ) ). 73 // Where possible, using RimpHash() should be a bit faster. 74 func Rimp160AfterSha256(b []byte) (out [20]byte) { 75 RimpHash(b, out[:]) 76 return 77 } 78 79 // HashFromMessage is used to sign and verify messages using the Bitcoin standard. 80 // The second parameter must point to a 32-bytes buffer, where the hash will be stored. 81 func HashFromMessage(msg []byte, out []byte) { 82 b := new(bytes.Buffer) 83 WriteVlen(b, uint64(len(MessageMagic))) 84 b.Write([]byte(MessageMagic)) 85 WriteVlen(b, uint64(len(msg))) 86 b.Write(msg) 87 ShaHash(b.Bytes(), out) 88 }