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 hexenc
30 from pygost.utils import strxor
31 from pygost.utils import xrange
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,
92 C = [hexdec("".join(s))[::-1] for s in (
94 "b1085bda1ecadae9ebcb2f81c0657c1f",
95 "2f6a76432e45d016714eb88d7585c4fc",
96 "4b7ce09192676901a2422a08a460d315",
97 "05767436cc744d23dd806559f2a64507",
100 "6fa3b58aa99d2f1a4fe39d460f70b5d7",
101 "f3feea720a232b9861d55e0f16b50131",
102 "9ab5176b12d699585cb561c2db0aa7ca",
103 "55dda21bd7cbcd56e679047021b19bb7",
106 "f574dcac2bce2fc70a39fc286a3d8435",
107 "06f15e5f529c1f8bf2ea7514b1297b7b",
108 "d3e20fe490359eb1c1c93a376062db09",
109 "c2b6f443867adb31991e96f50aba0ab2",
112 "ef1fdfb3e81566d2f948e1a05d71e4dd",
113 "488e857e335c3c7d9d721cad685e353f",
114 "a9d72c82ed03d675d8b71333935203be",
115 "3453eaa193e837f1220cbebc84e3d12e",
118 "4bea6bacad4747999a3f410c6ca92363",
119 "7f151c1f1686104a359e35d7800fffbd",
120 "bfcd1747253af5a3dfff00b723271a16",
121 "7a56a27ea9ea63f5601758fd7c6cfe57",
124 "ae4faeae1d3ad3d96fa4c33b7a3039c0",
125 "2d66c4f95142a46c187f9ab49af08ec6",
126 "cffaa6b71c9ab7b40af21f66c2bec6b6",
127 "bf71c57236904f35fa68407a46647d6e",
130 "f4c70e16eeaac5ec51ac86febf240954",
131 "399ec6c7e6bf87c9d3473e33197a93c9",
132 "0992abc52d822c3706476983284a0504",
133 "3517454ca23c4af38886564d3a14d493",
136 "9b1f5b424d93c9a703e7aa020c6e4141",
137 "4eb7f8719c36de1e89b4443b4ddbc49a",
138 "f4892bcb929b069069d18d2bd1a5c42f",
139 "36acc2355951a8d9a47f0dd4bf02e71e",
142 "378f5a541631229b944c9ad8ec165fde",
143 "3a7d3a1b258942243cd955b7e00d0984",
144 "800a440bdbb2ceb17b2b8a9aa6079c54",
145 "0e38dc92cb1f2a607261445183235adb",
148 "abbedea680056f52382ae548b2e4f3f3",
149 "8941e71cff8a78db1fffe18a1b336103",
150 "9fe76702af69334b7a1e6c303b7652f4",
151 "3698fad1153bb6c374b4c7fb98459ced",
154 "7bcd9ed0efc889fb3002c6cd635afe94",
155 "d8fa6bbbebab07612001802114846679",
156 "8a1d71efea48b9caefbacd1d7d476e98",
157 "dea2594ac06fd85d6bcaa4cd81f32d1b",
160 "378ee767f11631bad21380b00449b17a",
161 "cda43c32bcdf1d77f82012d430219f9b",
162 "5d80ef9d1891cc86e71da4aa88e12852",
163 "faf417d5d9b21b9948bc924af11bd720",
169 """ Add two 512 integers
176 cb = a[i] + b[i] + (cb >> 8)
182 res = E(LPS(strxor(hsh[:8], pack("<Q", n)) + hsh[8:]), msg)
183 return strxor(strxor(res, hsh), msg)
188 msg = LPS(strxor(k, msg))
189 k = LPS(strxor(k, C[i]))
190 return strxor(k, msg)
194 return L(PS(bytearray(data)))
198 res = bytearray(BLOCKSIZE)
199 for i in range(BLOCKSIZE):
200 res[Tau[i]] = Pi[data[i]]
207 val = unpack("<Q", data[i * 8:i * 8 + 8])[0]
209 for j in range(BLOCKSIZE):
210 if val & 0x8000000000000000:
213 res.append(pack("<Q", res64))
217 class GOST34112012(PEP247):
218 """ GOST 34.11-2012 big-endian hash
220 >>> m = GOST34112012(digest_size=32)
224 'e3c9fd89226d93b489a9fe27d686806e24a514e3787bca053c698ec4616ceb78'
226 block_size = BLOCKSIZE
228 def __init__(self, data=b"", digest_size=64):
230 :param digest_size: hash digest size to compute
231 :type digest_size: 32 or 64 bytes
234 self._digest_size = digest_size
237 return GOST34112012(copy(self.data), self.digest_size)
240 def digest_size(self):
241 return self._digest_size
243 def update(self, data):
244 """ Append data that has to be hashed
249 """ Get hash of the provided data
251 hsh = BLOCKSIZE * (b"\x01" if self.digest_size == 32 else b"\x00")
252 chk = bytearray(BLOCKSIZE * b"\x00")
255 for i in xrange(0, len(data) // BLOCKSIZE * BLOCKSIZE, BLOCKSIZE):
256 block = data[i:i + BLOCKSIZE]
257 hsh = g(n, hsh, block)
258 chk = add512bit(chk, block)
262 padblock_size = len(data) * 8 - n
264 padlen = BLOCKSIZE - len(data) % BLOCKSIZE
265 if padlen != BLOCKSIZE:
266 data += b"\x00" * padlen
268 hsh = g(n, hsh, data[-BLOCKSIZE:])
270 chk = add512bit(chk, data[-BLOCKSIZE:])
271 hsh = g(0, hsh, pack("<Q", n) + 56 * b"\x00")
273 return hsh[-self._digest_size:]
276 return hexenc(self.digest())