-
Notifications
You must be signed in to change notification settings - Fork 0
/
kmac512.go
84 lines (65 loc) · 1.44 KB
/
kmac512.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
73
74
75
76
77
78
79
80
81
82
83
84
package kupyna
import (
"hash"
)
// kmac512 represents the partial evaluation of a checksum.
type kmac512 struct {
h hash.Hash
ik [64]byte
len uint64
}
// NewKmac512 returns a new hash.Hash computing the Kmac512 checksum
func NewKmac512(key []byte) (hash.Hash, error) {
l := len(key)
if l != 64 {
return nil, KeySizeError(l)
}
d := new(kmac512)
d.h = New512()
d.init(key)
return d, nil
}
func (d *kmac512) init(key []byte) {
d.h.Write(key)
d.h.Write(kpad64[:])
d.len = 0
for i := 0; i < 64; i++ {
d.ik[i] = ^key[i]
}
}
func (d *kmac512) Reset() {
d.h.Reset()
}
func (d *kmac512) Size() int {
return d.h.Size()
}
func (d *kmac512) BlockSize() int {
return d.h.BlockSize()
}
func (d *kmac512) Write(p []byte) (nn int, err error) {
d.len += uint64(len(p))
return d.h.Write(p)
}
func (d *kmac512) Sum(in []byte) []byte {
// Make a copy of d so that caller can keep writing and summing.
d0 := *d
hash := d0.checkSum()
return append(in, hash...)
}
func (d *kmac512) checkSum() []byte {
var n uint64 = d.len
var pad_size uint64
if n < 116 {
pad_size = 115 - n
} else {
pad_size = 127 - ((n - 116) % 128)
}
n = n * 8
d.h.Write(dpad[:pad_size + 1])
nbytes := uint64sToBytes([]uint64{n})
d.h.Write(nbytes)
d.h.Write(dpad[16:20])
d.h.Write(d.ik[:])
hash := d.h.Sum(nil)
return hash
}