2 # PyGOST -- Pure Python GOST cryptographic functions library
3 # Copyright (C) 2015-2017 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, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 from pygost.gost28147 import block2ns
23 from pygost.gost28147 import BLOCKSIZE
24 from pygost.gost28147 import DEFAULT_SBOX
25 from pygost.gost28147 import ns2block
26 from pygost.gost28147 import validate_iv
27 from pygost.gost28147 import validate_key
28 from pygost.gost28147 import validate_sbox
29 from pygost.gost28147 import xcrypt
30 from pygost.gost3413 import pad1
31 from pygost.iface import PEP247
32 from pygost.utils import strxor
33 from pygost.utils import xrange # pylint: disable=redefined-builtin
37 0, 1, 2, 3, 4, 5, 6, 7,
38 0, 1, 2, 3, 4, 5, 6, 7,
43 """ GOST 28147-89 MAC mode of operation
46 >>> m.update("some data")
47 >>> m.update("another data")
51 digest_size = digest_size
53 def __init__(self, key, data=b"", iv=8 * b"\x00", sbox=DEFAULT_SBOX):
55 :param key: authentication key
56 :type key: bytes, 32 bytes
57 :param iv: initialization vector
58 :type iv: bytes, BLOCKSIZE length
59 :param sbox: S-box parameters to use
60 :type sbox: str, SBOXES'es key
71 return MAC(self.key, copy(self.data), self.iv, self.sbox)
73 def update(self, data):
74 """ Append data that has to be authenticated
79 """ Get MAC tag of supplied data
81 You have to provide at least single byte of data.
82 If you want to produce tag length of 3 bytes, then
86 raise ValueError("No data processed")
87 data = pad1(self.data, BLOCKSIZE)
88 prev = block2ns(self.iv)[::-1]
89 for i in xrange(0, len(data), BLOCKSIZE):
91 SEQ_MAC, self.sbox, self.key, block2ns(strxor(
92 data[i:i + BLOCKSIZE],
99 def new(key, data=b"", iv=8 * b"\x00", sbox=DEFAULT_SBOX):
100 return MAC(key, data, iv, sbox)