2 # PyGOST -- Pure Python GOST cryptographic functions library
3 # Copyright (C) 2015-2022 Sergey Matveev <stargrave@stargrave.org>
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, version 3 of the License.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 from pygost.gost28147 import block2ns
22 from pygost.gost28147 import BLOCKSIZE
23 from pygost.gost28147 import DEFAULT_SBOX
24 from pygost.gost28147 import ns2block
25 from pygost.gost28147 import validate_iv
26 from pygost.gost28147 import validate_key
27 from pygost.gost28147 import validate_sbox
28 from pygost.gost28147 import xcrypt
29 from pygost.gost3413 import pad1
30 from pygost.iface import PEP247
31 from pygost.utils import strxor
32 from pygost.utils import xrange
36 0, 1, 2, 3, 4, 5, 6, 7,
37 0, 1, 2, 3, 4, 5, 6, 7,
42 """GOST 28147-89 MAC mode of operation
45 >>> m.update("some data")
46 >>> m.update("another data")
50 digest_size = digest_size
52 def __init__(self, key, data=b"", iv=8 * b"\x00", sbox=DEFAULT_SBOX):
54 :param key: authentication key
55 :type key: bytes, 32 bytes
56 :param iv: initialization vector
57 :type iv: bytes, BLOCKSIZE length
58 :param sbox: S-box parameters to use
59 :type sbox: str, SBOXES'es key
70 return MAC(self.key, copy(self.data), self.iv, self.sbox)
72 def update(self, data):
73 """Append data that has to be authenticated
78 """Get MAC tag of supplied data
80 You have to provide at least single byte of data.
81 If you want to produce tag length of 3 bytes, then
85 raise ValueError("No data processed")
86 data = pad1(self.data, BLOCKSIZE)
87 prev = block2ns(self.iv)[::-1]
88 for i in xrange(0, len(data), BLOCKSIZE):
90 SEQ_MAC, self.sbox, self.key, block2ns(strxor(
91 data[i:i + BLOCKSIZE],
98 def new(key, data=b"", iv=8 * b"\x00", sbox=DEFAULT_SBOX):
99 return MAC(key, data, iv, sbox)