2 # PyGOST -- Pure Python GOST cryptographic functions library
3 # Copyright (C) 2015-2016 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/>.
17 """ GOST R 34.11-2012 (Streebog) hash function common files
19 This is implementation of :rfc:`6986`. Most function and variable names are
20 taken according to specification's terminology.
24 from struct import pack
25 from struct import unpack
27 from pygost.iface import PEP247
28 from pygost.utils import hexdec
29 from pygost.utils import strxor
30 from pygost.utils import xrange # pylint: disable=redefined-builtin
34 # pylint: disable=bad-whitespace,bad-continuation
36 252, 238, 221, 17, 207, 110, 49, 22, 251, 196, 250,
37 218, 35, 197, 4, 77, 233, 119, 240, 219, 147, 46,
38 153, 186, 23, 54, 241, 187, 20, 205, 95, 193, 249,
39 24, 101, 90, 226, 92, 239, 33, 129, 28, 60, 66,
40 139, 1, 142, 79, 5, 132, 2, 174, 227, 106, 143,
41 160, 6, 11, 237, 152, 127, 212, 211, 31, 235, 52,
42 44, 81, 234, 200, 72, 171, 242, 42, 104, 162, 253,
43 58, 206, 204, 181, 112, 14, 86, 8, 12, 118, 18,
44 191, 114, 19, 71, 156, 183, 93, 135, 21, 161, 150,
45 41, 16, 123, 154, 199, 243, 145, 120, 111, 157, 158,
46 178, 177, 50, 117, 25, 61, 255, 53, 138, 126, 109,
47 84, 198, 128, 195, 189, 13, 87, 223, 245, 36, 169,
48 62, 168, 67, 201, 215, 121, 214, 246, 124, 34, 185,
49 3, 224, 15, 236, 222, 122, 148, 176, 188, 220, 232,
50 40, 80, 78, 51, 10, 74, 167, 151, 96, 115, 30,
51 0, 98, 68, 26, 184, 56, 130, 100, 159, 38, 65,
52 173, 69, 70, 146, 39, 94, 85, 47, 140, 163, 165,
53 125, 105, 213, 149, 59, 7, 88, 179, 64, 134, 172,
54 29, 247, 48, 55, 107, 228, 136, 217, 231, 137, 225,
55 27, 131, 73, 76, 63, 248, 254, 141, 83, 170, 144,
56 202, 216, 133, 97, 32, 113, 103, 164, 45, 43, 9,
57 91, 203, 155, 37, 208, 190, 229, 108, 82, 89, 166,
58 116, 210, 230, 244, 180, 192, 209, 102, 175, 194, 57,
62 A = [unpack(">Q", hexdec(s))[0] for s in (
63 "8e20faa72ba0b470", "47107ddd9b505a38", "ad08b0e0c3282d1c", "d8045870ef14980e",
64 "6c022c38f90a4c07", "3601161cf205268d", "1b8e0b0e798c13c8", "83478b07b2468764",
65 "a011d380818e8f40", "5086e740ce47c920", "2843fd2067adea10", "14aff010bdd87508",
66 "0ad97808d06cb404", "05e23c0468365a02", "8c711e02341b2d01", "46b60f011a83988e",
67 "90dab52a387ae76f", "486dd4151c3dfdb9", "24b86a840e90f0d2", "125c354207487869",
68 "092e94218d243cba", "8a174a9ec8121e5d", "4585254f64090fa0", "accc9ca9328a8950",
69 "9d4df05d5f661451", "c0a878a0a1330aa6", "60543c50de970553", "302a1e286fc58ca7",
70 "18150f14b9ec46dd", "0c84890ad27623e0", "0642ca05693b9f70", "0321658cba93c138",
71 "86275df09ce8aaa8", "439da0784e745554", "afc0503c273aa42a", "d960281e9d1d5215",
72 "e230140fc0802984", "71180a8960409a42", "b60c05ca30204d21", "5b068c651810a89e",
73 "456c34887a3805b9", "ac361a443d1c8cd2", "561b0d22900e4669", "2b838811480723ba",
74 "9bcf4486248d9f5d", "c3e9224312c8c1a0", "effa11af0964ee50", "f97d86d98a327728",
75 "e4fa2054a80b329c", "727d102a548b194e", "39b008152acb8227", "9258048415eb419d",
76 "492c024284fbaec0", "aa16012142f35760", "550b8e9e21f7a530", "a48b474f9ef5dc18",
77 "70a6a56e2440598e", "3853dc371220a247", "1ca76e95091051ad", "0edd37c48a08a6d8",
78 "07e095624504536c", "8d70c431ac02a736", "c83862965601dd1b", "641c314b2b8ee083",
82 0, 8, 16, 24, 32, 40, 48, 56,
83 1, 9, 17, 25, 33, 41, 49, 57,
84 2, 10, 18, 26, 34, 42, 50, 58,
85 3, 11, 19, 27, 35, 43, 51, 59,
86 4, 12, 20, 28, 36, 44, 52, 60,
87 5, 13, 21, 29, 37, 45, 53, 61,
88 6, 14, 22, 30, 38, 46, 54, 62,
89 7, 15, 23, 31, 39, 47, 55, 63,
91 # pylint: disable=bad-whitespace,bad-continuation
93 C = [hexdec("".join(s))[::-1] for s in (
95 "b1085bda1ecadae9ebcb2f81c0657c1f",
96 "2f6a76432e45d016714eb88d7585c4fc",
97 "4b7ce09192676901a2422a08a460d315",
98 "05767436cc744d23dd806559f2a64507",
101 "6fa3b58aa99d2f1a4fe39d460f70b5d7",
102 "f3feea720a232b9861d55e0f16b50131",
103 "9ab5176b12d699585cb561c2db0aa7ca",
104 "55dda21bd7cbcd56e679047021b19bb7",
107 "f574dcac2bce2fc70a39fc286a3d8435",
108 "06f15e5f529c1f8bf2ea7514b1297b7b",
109 "d3e20fe490359eb1c1c93a376062db09",
110 "c2b6f443867adb31991e96f50aba0ab2",
113 "ef1fdfb3e81566d2f948e1a05d71e4dd",
114 "488e857e335c3c7d9d721cad685e353f",
115 "a9d72c82ed03d675d8b71333935203be",
116 "3453eaa193e837f1220cbebc84e3d12e",
119 "4bea6bacad4747999a3f410c6ca92363",
120 "7f151c1f1686104a359e35d7800fffbd",
121 "bfcd1747253af5a3dfff00b723271a16",
122 "7a56a27ea9ea63f5601758fd7c6cfe57",
125 "ae4faeae1d3ad3d96fa4c33b7a3039c0",
126 "2d66c4f95142a46c187f9ab49af08ec6",
127 "cffaa6b71c9ab7b40af21f66c2bec6b6",
128 "bf71c57236904f35fa68407a46647d6e",
131 "f4c70e16eeaac5ec51ac86febf240954",
132 "399ec6c7e6bf87c9d3473e33197a93c9",
133 "0992abc52d822c3706476983284a0504",
134 "3517454ca23c4af38886564d3a14d493",
137 "9b1f5b424d93c9a703e7aa020c6e4141",
138 "4eb7f8719c36de1e89b4443b4ddbc49a",
139 "f4892bcb929b069069d18d2bd1a5c42f",
140 "36acc2355951a8d9a47f0dd4bf02e71e",
143 "378f5a541631229b944c9ad8ec165fde",
144 "3a7d3a1b258942243cd955b7e00d0984",
145 "800a440bdbb2ceb17b2b8a9aa6079c54",
146 "0e38dc92cb1f2a607261445183235adb",
149 "abbedea680056f52382ae548b2e4f3f3",
150 "8941e71cff8a78db1fffe18a1b336103",
151 "9fe76702af69334b7a1e6c303b7652f4",
152 "3698fad1153bb6c374b4c7fb98459ced",
155 "7bcd9ed0efc889fb3002c6cd635afe94",
156 "d8fa6bbbebab07612001802114846679",
157 "8a1d71efea48b9caefbacd1d7d476e98",
158 "dea2594ac06fd85d6bcaa4cd81f32d1b",
161 "378ee767f11631bad21380b00449b17a",
162 "cda43c32bcdf1d77f82012d430219f9b",
163 "5d80ef9d1891cc86e71da4aa88e12852",
164 "faf417d5d9b21b9948bc924af11bd720",
170 """ Add two 512 integers
177 cb = a[i] + b[i] + (cb >> 8)
183 res = E(LPS(strxor(hsh[:8], pack("<Q", n)) + hsh[8:]), msg)
184 return strxor(strxor(res, hsh), msg)
189 msg = LPS(strxor(k, msg))
190 k = LPS(strxor(k, C[i]))
191 return strxor(k, msg)
195 return L(PS(bytearray(data)))
199 res = bytearray(BLOCKSIZE)
200 for i in range(BLOCKSIZE):
201 res[Tau[i]] = Pi[data[i]]
208 val = unpack("<Q", data[i * 8:i * 8 + 8])[0]
210 for j in range(BLOCKSIZE):
211 if val & 0x8000000000000000:
214 res.append(pack("<Q", res64))
218 class GOST34112012(PEP247):
219 """ GOST 34.11-2012 big-endian hash
221 >>> m = GOST34112012(digest_size=32)
225 'e3c9fd89226d93b489a9fe27d686806e24a514e3787bca053c698ec4616ceb78'
227 block_size = BLOCKSIZE
229 def __init__(self, data=b"", digest_size=64):
231 :param digest_size: hash digest size to compute
232 :type digest_size: 32 or 64 bytes
235 self._digest_size = digest_size
238 return GOST34112012(copy(self.data), self.digest_size)
241 def digest_size(self):
242 return self._digest_size
244 def update(self, data):
245 """ Append data that has to be hashed
250 """ Get hash of the provided data
252 hsh = BLOCKSIZE * (b"\x01" if self.digest_size == 32 else b"\x00")
253 chk = bytearray(BLOCKSIZE * b"\x00")
256 for i in xrange(0, len(data) // BLOCKSIZE * BLOCKSIZE, BLOCKSIZE):
257 block = data[i:i + BLOCKSIZE]
258 hsh = g(n, hsh, block)
259 chk = add512bit(chk, block)
263 padblock_size = len(data) * 8 - n
265 padlen = BLOCKSIZE - len(data) % BLOCKSIZE
266 if padlen != BLOCKSIZE:
267 data += b"\x00" * padlen
269 hsh = g(n, hsh, data[-BLOCKSIZE:])
271 chk = add512bit(chk, data[-BLOCKSIZE:])
272 hsh = g(0, hsh, pack("<Q", n) + 56 * b"\x00")
274 return hsh[-self._digest_size:]