-
Notifications
You must be signed in to change notification settings - Fork 0
/
esptree.go
55 lines (40 loc) · 1.05 KB
/
esptree.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
package gost34112012256
import (
"crypto/subtle"
)
type ESPTree struct {
keyRoot []byte
isPrev [5]byte
key []byte
}
func NewESPTree(keyRoot []byte) *ESPTree {
key := make([]byte, len(keyRoot))
copy(key, keyRoot)
t := &ESPTree{
keyRoot: key,
key: make([]byte, Size),
}
t.isPrev[0]++
t.DeriveCached([]byte{0x00, 0x00, 0x00, 0x00, 0x00})
return t
}
func (t *ESPTree) DeriveCached(is []byte) ([]byte, bool) {
if len(is) != 1+2+2 {
panic("invalid i1+i2+i3 input")
}
if subtle.ConstantTimeCompare(t.isPrev[:], is) == 1 {
return t.key, true
}
pass1 := KDF(New, t.keyRoot, []byte("level1"), append([]byte{0}, is[0]))
pass2 := KDF(New, pass1, []byte("level2"), is[1:3])
pass3 := KDF(New, pass2, []byte("level3"), is[3:5])
copy(t.isPrev[:], is)
t.key = pass3
return t.key, false
}
func (t *ESPTree) Derive(is []byte) []byte {
key, _ := t.DeriveCached(is)
keyDerived := make([]byte, Size)
copy(keyDerived, key)
return keyDerived
}