-
Notifications
You must be signed in to change notification settings - Fork 3
/
hash.go
72 lines (60 loc) · 1.92 KB
/
hash.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package xmss
import "crypto/sha256"
// PRF: SHA2-256(toByte(3, 32) || KEY || M)
// Message must be exactly 32 bytes
func hashPRF(params *Params, out, key, m []byte) {
h := sha256.New()
h.Write(toByte(3, params.n))
h.Write(key)
h.Write(m)
copy(out, h.Sum(nil))
}
// H_msg: SHA2-256(toByte(2, 32) || KEY || M)
// Computes the message hash using R, the public root, the index of the leaf
// node, and the message.
func hashMsg(params *Params, out, R, root, mPlus []byte, idx uint64) {
h := sha256.New()
copy(mPlus[:params.n], toByte(2, params.n))
copy(mPlus[params.n:2*params.n], R)
copy(mPlus[2*params.n:3*params.n], root)
copy(mPlus[3*params.n:4*params.n], toByte(int(idx), params.n))
h.Write(mPlus)
copy(out, h.Sum(nil))
}
// H: SHA2-256(toByte(1, 32) || KEY || M)
// A cryptographic hash function H. H accepts n-byte keys and byte
// strings of length 2n and returns an n-byte string.
// Includes: Algorithm 7: RAND_HASH
func hashH(params *Params, out, seed, m []byte, a *address) {
h := sha256.New()
h.Write(toByte(1, params.n))
// Generate the n-byte key
a.setKeyAndMask(0)
buf := make([]byte, 3*params.n)
hashPRF(params, buf[:params.n], seed, a.toByte())
// Generate the 2n-byte mask
a.setKeyAndMask(1)
bitmask := make([]byte, 2*params.n)
hashPRF(params, bitmask[:params.n], seed, a.toByte())
a.setKeyAndMask(2)
hashPRF(params, bitmask[params.n:], seed, a.toByte())
xor(buf[params.n:], m, bitmask)
h.Write(buf)
copy(out, h.Sum(nil))
}
// F: SHA2-256(toByte(0, 32) || KEY || M)
func hashF(params *Params, out, seed, m []byte, a *address) {
h := sha256.New()
h.Write(make([]byte, params.n))
// Generate the n-byte key
a.setKeyAndMask(0)
buf := make([]byte, 2*params.n)
hashPRF(params, buf[:params.n], seed, a.toByte())
// Generate the n-byte mask
a.setKeyAndMask(1)
bitmask := make([]byte, params.n)
hashPRF(params, bitmask, seed, a.toByte())
xor(buf[params.n:], m, bitmask)
h.Write(buf)
copy(out, h.Sum(nil))
}