]> Cypherpunks.ru repositories - gogost.git/blob - gost28147/ctr.go
Raise copyright years
[gogost.git] / gost28147 / ctr.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 gost28147
17
18 type CTR struct {
19         c  *Cipher
20         n1 nv
21         n2 nv
22 }
23
24 func (c *Cipher) NewCTR(iv []byte) *CTR {
25         if len(iv) != BlockSize {
26                 panic("iv length is not equal to blocksize")
27         }
28         n1, n2 := block2nvs(iv)
29         n2, n1 = c.xcrypt(SeqEncrypt, n1, n2)
30         return &CTR{c, n1, n2}
31 }
32
33 func (c *CTR) XORKeyStream(dst, src []byte) {
34         var n1t nv
35         var n2t nv
36         block := make([]byte, BlockSize)
37         i := 0
38         var n int
39 MainLoop:
40         for {
41                 c.n1 += 0x01010101 // C2
42                 c.n2 += 0x01010104 // C1
43                 if c.n2 >= 1<<32-1 {
44                         c.n2 -= 1<<32 - 1
45                 }
46                 n1t, n2t = c.c.xcrypt(SeqEncrypt, c.n1, c.n2)
47                 nvs2block(n1t, n2t, block)
48                 for n = 0; n < BlockSize; n++ {
49                         if i*BlockSize+n == len(src) {
50                                 break MainLoop
51                         }
52                         dst[i*BlockSize+n] = src[i*BlockSize+n] ^ block[n]
53                 }
54                 i++
55         }
56         return
57 }