]> Cypherpunks.ru repositories - gogost.git/blob - gost28147/cfb.go
dfcd8f7b7f9812ea3f23c52a34580cf3f6a8d8f8
[gogost.git] / gost28147 / cfb.go
1 // GoGOST -- Pure Go GOST cryptographic functions library
2 // Copyright (C) 2015-2019 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 CFBEncrypter struct {
19         c  *Cipher
20         iv []byte
21 }
22
23 func (c *Cipher) NewCFBEncrypter(iv []byte) *CFBEncrypter {
24         if len(iv) != BlockSize {
25                 panic("iv length is not equal to blocksize")
26         }
27         encrypter := CFBEncrypter{c: c, iv: make([]byte, BlockSize)}
28         copy(encrypter.iv, iv)
29         return &encrypter
30 }
31
32 func (c *CFBEncrypter) XORKeyStream(dst, src []byte) {
33         var n int
34         i := 0
35 MainLoop:
36         for {
37                 c.c.Encrypt(c.iv, c.iv)
38                 for n = 0; n < BlockSize; n++ {
39                         if i*BlockSize+n == len(src) {
40                                 break MainLoop
41                         }
42                         c.iv[n] ^= src[i*BlockSize+n]
43                         dst[i*BlockSize+n] = c.iv[n]
44                 }
45                 i++
46         }
47         return
48 }
49
50 type CFBDecrypter struct {
51         c  *Cipher
52         iv []byte
53 }
54
55 func (c *Cipher) NewCFBDecrypter(iv []byte) *CFBDecrypter {
56         if len(iv) != BlockSize {
57                 panic("iv length is not equal to blocksize")
58         }
59         decrypter := CFBDecrypter{c: c, iv: make([]byte, BlockSize)}
60         copy(decrypter.iv, iv)
61         return &decrypter
62 }
63
64 func (c *CFBDecrypter) XORKeyStream(dst, src []byte) {
65         var n int
66         i := 0
67 MainLoop:
68         for {
69                 c.c.Encrypt(c.iv, c.iv)
70                 for n = 0; n < BlockSize; n++ {
71                         if i*BlockSize+n == len(src) {
72                                 break MainLoop
73                         }
74                         dst[i*BlockSize+n] = c.iv[n] ^ src[i*BlockSize+n]
75                         c.iv[n] = src[i*BlockSize+n]
76                 }
77                 i++
78         }
79         return
80 }