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/>.
18 from unittest import skip
19 from unittest import TestCase
22 from pygost import gost3411_94
23 from pygost.gost3411_94 import GOST341194
24 from pygost.utils import bytes2long
25 from pygost.utils import hexenc
26 from pygost.utils import long2bytes
27 from pygost.utils import strxor
28 from pygost.utils import xrange
31 class TestCopy(TestCase):
38 self.assertEqual(m.digest(), c.digest())
41 class TestHMACPEP247(TestCase):
43 h = hmac.new(b"foo", digestmod=gost3411_94)
48 class TestVectors(TestCase):
51 GOST341194(b"", "GostR3411_94_TestParamSet").hexdigest(),
52 "ce85b99cc46752fffee35cab9a7b0278abb4c2d2055cff685af4912c49490f8d",
57 GOST341194(b"a", "GostR3411_94_TestParamSet").hexdigest(),
58 "d42c539e367c66e9c88a801f6649349c21871b4344c6a573f849fdce62f314dd",
63 GOST341194(b"abc", "GostR3411_94_TestParamSet").hexdigest(),
64 "f3134348c44fb1b2a277729e2285ebb5cb5e0f29c975bc753b70497c06a4d51d",
67 def test_message_digest(self):
69 GOST341194(b"message digest", "GostR3411_94_TestParamSet").hexdigest(),
70 "ad4434ecb18f2c99b60cbe59ec3d2469582b65273f48de72db2fde16a4889a4d",
75 GOST341194(128 * b"U", "GostR3411_94_TestParamSet").hexdigest(),
76 "53a3a3ed25180cef0c1d85a074273e551c25660a87062a52d926a9e8fe5733a4",
81 GOST341194(b"The quick brown fox jumps over the lazy dog", "GostR3411_94_TestParamSet",).hexdigest(),
82 "77b7fa410c9ac58a25f49bca7d0468c9296529315eaca76bd1a10f376d1f4294",
87 GOST341194(b"The quick brown fox jumps over the lazy cog", "GostR3411_94_TestParamSet",).hexdigest(),
88 "a3ebc4daaab78b0be131dab5737a7f67e602670d543521319150d2e14eeec445",
93 GOST341194(b"This is message, length=32 bytes", "GostR3411_94_TestParamSet",).hexdigest(),
94 "b1c466d37519b82e8319819ff32595e047a28cb6f83eff1c6916a815a637fffa",
99 GOST341194(b"Suppose the original message has length = 50 bytes", "GostR3411_94_TestParamSet",).hexdigest(),
100 "471aba57a60a770d3a76130635c1fbea4ef14de51f78b4ae57dd893b62f55208",
104 class TestVectorsCryptoPro(TestCase):
105 """ CryptoPro S-box test vectors
107 def test_empty(self):
109 GOST341194(b"", "GostR3411_94_CryptoProParamSet").hexdigest(),
110 "981e5f3ca30c841487830f84fb433e13ac1101569b9c13584ac483234cd656c0",
115 GOST341194(b"a", "GostR3411_94_CryptoProParamSet").hexdigest(),
116 "e74c52dd282183bf37af0079c9f78055715a103f17e3133ceff1aacf2f403011",
121 GOST341194(b"abc", "GostR3411_94_CryptoProParamSet").hexdigest(),
122 "b285056dbf18d7392d7677369524dd14747459ed8143997e163b2986f92fd42c",
125 def test_message_digest(self):
127 GOST341194(b"message digest", "GostR3411_94_CryptoProParamSet",).hexdigest(),
128 "bc6041dd2aa401ebfa6e9886734174febdb4729aa972d60f549ac39b29721ba0",
133 GOST341194(b"The quick brown fox jumps over the lazy dog", "GostR3411_94_CryptoProParamSet",).hexdigest(),
134 "9004294a361a508c586fe53d1f1b02746765e71b765472786e4770d565830a76",
139 GOST341194(b"This is message, length=32 bytes", "GostR3411_94_CryptoProParamSet",).hexdigest(),
140 "2cefc2f7b7bdc514e18ea57fa74ff357e7fa17d652c75f69cb1be7893ede48eb",
145 GOST341194(b"Suppose the original message has length = 50 bytes", "GostR3411_94_CryptoProParamSet",).hexdigest(),
146 "c3730c5cbccacf915ac292676f21e8bd4ef75331d9405e5f1a61dc3130a65011",
151 GOST341194(128 * b"U", "GostR3411_94_CryptoProParamSet").hexdigest(),
152 "1c4ac7614691bbf427fa2316216be8f10d92edfd37cd1027514c1008f649c4e8",
156 # This implementation is based on Python 3.5.2 source code.
157 # PyGOST does not register itself in hashlib anyway, so use
158 # pbkdf2_hmac directly.
159 def pbkdf2_hmac(password, salt, iterations, dklen):
160 inner = GOST341194(sbox="GostR3411_94_CryptoProParamSet")
161 outer = GOST341194(sbox="GostR3411_94_CryptoProParamSet")
162 password = password + b'\x00' * (inner.block_size - len(password))
163 inner.update(strxor(password, len(password) * b"\x36"))
164 outer.update(strxor(password, len(password) * b"\x5C"))
170 ocpy.update(icpy.digest())
175 while len(dkey) < dklen:
176 prev = prf(salt + long2bytes(loop, 4))
177 rkey = bytes2long(prev)
178 for _ in xrange(iterations - 1):
180 rkey ^= bytes2long(prev)
182 dkey += long2bytes(rkey, inner.digest_size)
186 class TestPBKDF2(TestCase):
187 """http://tc26.ru/methods/containers_v1/Addition_to_PKCS5_v1_0.pdf test vectors
191 hexenc(pbkdf2_hmac(b"password", b"salt", 1, 32)),
192 "7314e7c04fb2e662c543674253f68bd0b73445d07f241bed872882da21662d58",
197 hexenc(pbkdf2_hmac(b"password", b"salt", 2, 32)),
198 "990dfa2bd965639ba48b07b792775df79f2db34fef25f274378872fed7ed1bb3",
203 hexenc(pbkdf2_hmac(b"password", b"salt", 4096, 32)),
204 "1f1829a94bdff5be10d0aeb36af498e7a97467f3b31116a5a7c1afff9deadafe",
207 @skip("it takes too long")
210 hexenc(pbkdf2_hmac(b"password", b"salt", 16777216, 32)),
211 "a57ae5a6088396d120850c5c09de0a525100938a59b1b5c3f7810910d05fcd97",
217 b"passwordPASSWORDpassword",
218 b"saltSALTsaltSALTsaltSALTsaltSALTsalt",
222 "788358c69cb2dbe251a7bb17d5f4241f265a792a35becde8d56f326b49c85047b7638acb4764b1fd",
233 "43e06c5590b08c0225242373127edf9c8e9c3291",