]> Cypherpunks.ru repositories - gogost.git/blob - gost34112012256/esptree.go
Raise copyright years
[gogost.git] / gost34112012256 / esptree.go
1 // GoGOST -- Pure Go GOST cryptographic functions library
2 // Copyright (C) 2015-2020 Sergey Matveev <stargrave@stargrave.org>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, version 3 of the License.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 package gost34112012256
17
18 import (
19         "crypto/subtle"
20 )
21
22 type ESPTree struct {
23         keyRoot []byte
24         isPrev  [5]byte
25         key     []byte
26 }
27
28 func NewESPTree(keyRoot []byte) *ESPTree {
29         key := make([]byte, len(keyRoot))
30         copy(key, keyRoot)
31         t := &ESPTree{
32                 keyRoot: key,
33                 key:     make([]byte, Size),
34         }
35         t.isPrev[0] += 1 // invalidate cache
36         t.DeriveCached([]byte{0x00, 0x00, 0x00, 0x00, 0x00})
37         return t
38 }
39
40 func (t *ESPTree) DeriveCached(is []byte) ([]byte, bool) {
41         if len(is) != 1+2+2 {
42                 panic("invalid i1+i2+i3 input")
43         }
44         if subtle.ConstantTimeCompare(t.isPrev[:], is) == 1 {
45                 return t.key, true
46         }
47         kdf1 := NewKDF(t.keyRoot)
48         kdf2 := NewKDF(kdf1.Derive(t.key[:0], []byte("level1"), append([]byte{0}, is[0])))
49         kdf3 := NewKDF(kdf2.Derive(t.key[:0], []byte("level2"), is[1:3]))
50         kdf3.Derive(t.key[:0], []byte("level3"), is[3:5])
51         copy(t.isPrev[:], is)
52         return t.key, false
53 }
54
55 func (t *ESPTree) Derive(is []byte) []byte {
56         keyDerived := make([]byte, Size)
57         key, _ := t.DeriveCached(is)
58         copy(keyDerived, key)
59         return keyDerived
60 }