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

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

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}