Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

hmac.gno

1.02 Kb · 38 lines
 1package wesh
 2
 3import "crypto/sha256"
 4
 5// blockSize is SHA-256's internal block size, the padding width HMAC uses.
 6const blockSize = 64
 7
 8// HMACSHA256 computes HMAC-SHA256 as specified in RFC 2104.
 9//
10// gno's standard library exposes sha256.Sum256 but no streaming hash.Hash and
11// no crypto/hmac, so the construction is spelled out here:
12//
13//	HMAC(K, m) = H((K' ⊕ opad) ‖ H((K' ⊕ ipad) ‖ m))
14//
15// with K' the key hashed down when longer than the block size, then
16// zero-padded up to it. This is the primitive weshnet's rendezvous point
17// derivation is built on, so it has to agree byte-for-byte; see
18// [RendezvousPoint].
19func HMACSHA256(key, msg []byte) []byte {
20	k := key
21	if len(k) > blockSize {
22		sum := sha256.Sum256(k)
23		k = sum[:]
24	}
25
26	ipad := make([]byte, blockSize)
27	opad := make([]byte, blockSize)
28	copy(ipad, k)
29	copy(opad, k)
30	for i := 0; i < blockSize; i++ {
31		ipad[i] ^= 0x36
32		opad[i] ^= 0x5c
33	}
34
35	inner := sha256.Sum256(append(ipad, msg...))
36	outer := sha256.Sum256(append(opad, inner[:]...))
37	return outer[:]
38}