]> Cypherpunks.ru repositories - pygost.git/blob - pygost/test_gost3410.py
2.3 release is ready
[pygost.git] / pygost / test_gost3410.py
1 # coding: utf-8
2 # PyGOST -- Pure Python GOST cryptographic functions library
3 # Copyright (C) 2015-2016 Sergey Matveev <stargrave@stargrave.org>
4 #
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.
9 #
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.
14 #
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
18 from os import urandom
19 from unittest import TestCase
20
21 from pygost.gost3410 import CURVE_PARAMS
22 from pygost.gost3410 import GOST3410Curve
23 from pygost.gost3410 import kek
24 from pygost.gost3410 import public_key
25 from pygost.gost3410 import sign
26 from pygost.gost3410 import SIZE_3410_2001
27 from pygost.gost3410 import SIZE_3410_2012
28 from pygost.gost3410 import verify
29 from pygost.utils import bytes2long
30 from pygost.utils import long2bytes
31
32
33 class Test341001(TestCase):
34     def test_rfc(self):
35         """ Test vector from :rfc:`5832`
36         """
37         private_key = bytes(bytearray((
38             0x7A, 0x92, 0x9A, 0xDE, 0x78, 0x9B, 0xB9, 0xBE,
39             0x10, 0xED, 0x35, 0x9D, 0xD3, 0x9A, 0x72, 0xC1,
40             0x1B, 0x60, 0x96, 0x1F, 0x49, 0x39, 0x7E, 0xEE,
41             0x1D, 0x19, 0xCE, 0x98, 0x91, 0xEC, 0x3B, 0x28
42         )))
43         public_key_x = bytes(bytearray((
44             0x7F, 0x2B, 0x49, 0xE2, 0x70, 0xDB, 0x6D, 0x90,
45             0xD8, 0x59, 0x5B, 0xEC, 0x45, 0x8B, 0x50, 0xC5,
46             0x85, 0x85, 0xBA, 0x1D, 0x4E, 0x9B, 0x78, 0x8F,
47             0x66, 0x89, 0xDB, 0xD8, 0xE5, 0x6F, 0xD8, 0x0B
48         )))
49         public_key_y = bytes(bytearray((
50             0x26, 0xF1, 0xB4, 0x89, 0xD6, 0x70, 0x1D, 0xD1,
51             0x85, 0xC8, 0x41, 0x3A, 0x97, 0x7B, 0x3C, 0xBB,
52             0xAF, 0x64, 0xD1, 0xC5, 0x93, 0xD2, 0x66, 0x27,
53             0xDF, 0xFB, 0x10, 0x1A, 0x87, 0xFF, 0x77, 0xDA
54         )))
55         digest = bytes(bytearray((
56             0x2D, 0xFB, 0xC1, 0xB3, 0x72, 0xD8, 0x9A, 0x11,
57             0x88, 0xC0, 0x9C, 0x52, 0xE0, 0xEE, 0xC6, 0x1F,
58             0xCE, 0x52, 0x03, 0x2A, 0xB1, 0x02, 0x2E, 0x8E,
59             0x67, 0xEC, 0xE6, 0x67, 0x2B, 0x04, 0x3E, 0xE5
60         )))
61         signature = bytes(bytearray((
62             0x41, 0xAA, 0x28, 0xD2, 0xF1, 0xAB, 0x14, 0x82,
63             0x80, 0xCD, 0x9E, 0xD5, 0x6F, 0xED, 0xA4, 0x19,
64             0x74, 0x05, 0x35, 0x54, 0xA4, 0x27, 0x67, 0xB8,
65             0x3A, 0xD0, 0x43, 0xFD, 0x39, 0xDC, 0x04, 0x93,
66             0x01, 0x45, 0x6C, 0x64, 0xBA, 0x46, 0x42, 0xA1,
67             0x65, 0x3C, 0x23, 0x5A, 0x98, 0xA6, 0x02, 0x49,
68             0xBC, 0xD6, 0xD3, 0xF7, 0x46, 0xB6, 0x31, 0xDF,
69             0x92, 0x80, 0x14, 0xF6, 0xC5, 0xBF, 0x9C, 0x40
70         )))
71         private_key = bytes2long(private_key)
72         signature = signature[32:] + signature[:32]
73
74         c = GOST3410Curve(*CURVE_PARAMS["GostR3410_2001_TestParamSet"])
75         pubX, pubY = public_key(c, private_key)
76         self.assertEqual(long2bytes(pubX), public_key_x)
77         self.assertEqual(long2bytes(pubY), public_key_y)
78         s = sign(c, private_key, digest)
79         self.assertTrue(verify(c, pubX, pubY, digest, s))
80         self.assertTrue(verify(c, pubX, pubY, digest, signature))
81
82     def test_sequence(self):
83         c = GOST3410Curve(*CURVE_PARAMS['GostR3410_2001_TestParamSet'])
84         private_key = bytes2long(urandom(32))
85         pubX, pubY = public_key(c, private_key)
86         for _ in range(20):
87             digest = urandom(32)
88             s = sign(c, private_key, digest, size=SIZE_3410_2001)
89             self.assertTrue(verify(c, pubX, pubY, digest, s, size=SIZE_3410_2001))
90
91
92 class Test34102012(TestCase):
93     def test_gcl3(self):
94         """ Test vector from libgcl3
95         """
96         p = bytes(bytearray((
97             0x45, 0x31, 0xAC, 0xD1, 0xFE, 0x00, 0x23, 0xC7,
98             0x55, 0x0D, 0x26, 0x7B, 0x6B, 0x2F, 0xEE, 0x80,
99             0x92, 0x2B, 0x14, 0xB2, 0xFF, 0xB9, 0x0F, 0x04,
100             0xD4, 0xEB, 0x7C, 0x09, 0xB5, 0xD2, 0xD1, 0x5D,
101             0xF1, 0xD8, 0x52, 0x74, 0x1A, 0xF4, 0x70, 0x4A,
102             0x04, 0x58, 0x04, 0x7E, 0x80, 0xE4, 0x54, 0x6D,
103             0x35, 0xB8, 0x33, 0x6F, 0xAC, 0x22, 0x4D, 0xD8,
104             0x16, 0x64, 0xBB, 0xF5, 0x28, 0xBE, 0x63, 0x73
105         )))
106         q = bytes(bytearray((
107             0x45, 0x31, 0xAC, 0xD1, 0xFE, 0x00, 0x23, 0xC7,
108             0x55, 0x0D, 0x26, 0x7B, 0x6B, 0x2F, 0xEE, 0x80,
109             0x92, 0x2B, 0x14, 0xB2, 0xFF, 0xB9, 0x0F, 0x04,
110             0xD4, 0xEB, 0x7C, 0x09, 0xB5, 0xD2, 0xD1, 0x5D,
111             0xA8, 0x2F, 0x2D, 0x7E, 0xCB, 0x1D, 0xBA, 0xC7,
112             0x19, 0x90, 0x5C, 0x5E, 0xEC, 0xC4, 0x23, 0xF1,
113             0xD8, 0x6E, 0x25, 0xED, 0xBE, 0x23, 0xC5, 0x95,
114             0xD6, 0x44, 0xAA, 0xF1, 0x87, 0xE6, 0xE6, 0xDF
115         )))
116         a = bytes(bytearray((
117             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07
125         )))
126         b = bytes(bytearray((
127             0x1C, 0xFF, 0x08, 0x06, 0xA3, 0x11, 0x16, 0xDA,
128             0x29, 0xD8, 0xCF, 0xA5, 0x4E, 0x57, 0xEB, 0x74,
129             0x8B, 0xC5, 0xF3, 0x77, 0xE4, 0x94, 0x00, 0xFD,
130             0xD7, 0x88, 0xB6, 0x49, 0xEC, 0xA1, 0xAC, 0x43,
131             0x61, 0x83, 0x40, 0x13, 0xB2, 0xAD, 0x73, 0x22,
132             0x48, 0x0A, 0x89, 0xCA, 0x58, 0xE0, 0xCF, 0x74,
133             0xBC, 0x9E, 0x54, 0x0C, 0x2A, 0xDD, 0x68, 0x97,
134             0xFA, 0xD0, 0xA3, 0x08, 0x4F, 0x30, 0x2A, 0xDC
135         )))
136         x = bytes(bytearray((
137             0x24, 0xD1, 0x9C, 0xC6, 0x45, 0x72, 0xEE, 0x30,
138             0xF3, 0x96, 0xBF, 0x6E, 0xBB, 0xFD, 0x7A, 0x6C,
139             0x52, 0x13, 0xB3, 0xB3, 0xD7, 0x05, 0x7C, 0xC8,
140             0x25, 0xF9, 0x10, 0x93, 0xA6, 0x8C, 0xD7, 0x62,
141             0xFD, 0x60, 0x61, 0x12, 0x62, 0xCD, 0x83, 0x8D,
142             0xC6, 0xB6, 0x0A, 0xA7, 0xEE, 0xE8, 0x04, 0xE2,
143             0x8B, 0xC8, 0x49, 0x97, 0x7F, 0xAC, 0x33, 0xB4,
144             0xB5, 0x30, 0xF1, 0xB1, 0x20, 0x24, 0x8A, 0x9A
145         )))
146         y = bytes(bytearray((
147             0x2B, 0xB3, 0x12, 0xA4, 0x3B, 0xD2, 0xCE, 0x6E,
148             0x0D, 0x02, 0x06, 0x13, 0xC8, 0x57, 0xAC, 0xDD,
149             0xCF, 0xBF, 0x06, 0x1E, 0x91, 0xE5, 0xF2, 0xC3,
150             0xF3, 0x24, 0x47, 0xC2, 0x59, 0xF3, 0x9B, 0x2C,
151             0x83, 0xAB, 0x15, 0x6D, 0x77, 0xF1, 0x49, 0x6B,
152             0xF7, 0xEB, 0x33, 0x51, 0xE1, 0xEE, 0x4E, 0x43,
153             0xDC, 0x1A, 0x18, 0xB9, 0x1B, 0x24, 0x64, 0x0B,
154             0x6D, 0xBB, 0x92, 0xCB, 0x1A, 0xDD, 0x37, 0x1E
155         )))
156         private_key = bytes(bytearray((
157             0x0B, 0xA6, 0x04, 0x8A, 0xAD, 0xAE, 0x24, 0x1B,
158             0xA4, 0x09, 0x36, 0xD4, 0x77, 0x56, 0xD7, 0xC9,
159             0x30, 0x91, 0xA0, 0xE8, 0x51, 0x46, 0x69, 0x70,
160             0x0E, 0xE7, 0x50, 0x8E, 0x50, 0x8B, 0x10, 0x20,
161             0x72, 0xE8, 0x12, 0x3B, 0x22, 0x00, 0xA0, 0x56,
162             0x33, 0x22, 0xDA, 0xD2, 0x82, 0x7E, 0x27, 0x14,
163             0xA2, 0x63, 0x6B, 0x7B, 0xFD, 0x18, 0xAA, 0xDF,
164             0xC6, 0x29, 0x67, 0x82, 0x1F, 0xA1, 0x8D, 0xD4
165         )))
166         public_key_x = bytes(bytearray((
167             0x11, 0x5D, 0xC5, 0xBC, 0x96, 0x76, 0x0C, 0x7B,
168             0x48, 0x59, 0x8D, 0x8A, 0xB9, 0xE7, 0x40, 0xD4,
169             0xC4, 0xA8, 0x5A, 0x65, 0xBE, 0x33, 0xC1, 0x81,
170             0x5B, 0x5C, 0x32, 0x0C, 0x85, 0x46, 0x21, 0xDD,
171             0x5A, 0x51, 0x58, 0x56, 0xD1, 0x33, 0x14, 0xAF,
172             0x69, 0xBC, 0x5B, 0x92, 0x4C, 0x8B, 0x4D, 0xDF,
173             0xF7, 0x5C, 0x45, 0x41, 0x5C, 0x1D, 0x9D, 0xD9,
174             0xDD, 0x33, 0x61, 0x2C, 0xD5, 0x30, 0xEF, 0xE1
175         )))
176         public_key_y = bytes(bytearray((
177             0x37, 0xC7, 0xC9, 0x0C, 0xD4, 0x0B, 0x0F, 0x56,
178             0x21, 0xDC, 0x3A, 0xC1, 0xB7, 0x51, 0xCF, 0xA0,
179             0xE2, 0x63, 0x4F, 0xA0, 0x50, 0x3B, 0x3D, 0x52,
180             0x63, 0x9F, 0x5D, 0x7F, 0xB7, 0x2A, 0xFD, 0x61,
181             0xEA, 0x19, 0x94, 0x41, 0xD9, 0x43, 0xFF, 0xE7,
182             0xF0, 0xC7, 0x0A, 0x27, 0x59, 0xA3, 0xCD, 0xB8,
183             0x4C, 0x11, 0x4E, 0x1F, 0x93, 0x39, 0xFD, 0xF2,
184             0x7F, 0x35, 0xEC, 0xA9, 0x36, 0x77, 0xBE, 0xEC
185         )))
186         digest = bytes(bytearray((
187             0x37, 0x54, 0xF3, 0xCF, 0xAC, 0xC9, 0xE0, 0x61,
188             0x5C, 0x4F, 0x4A, 0x7C, 0x4D, 0x8D, 0xAB, 0x53,
189             0x1B, 0x09, 0xB6, 0xF9, 0xC1, 0x70, 0xC5, 0x33,
190             0xA7, 0x1D, 0x14, 0x70, 0x35, 0xB0, 0xC5, 0x91,
191             0x71, 0x84, 0xEE, 0x53, 0x65, 0x93, 0xF4, 0x41,
192             0x43, 0x39, 0x97, 0x6C, 0x64, 0x7C, 0x5D, 0x5A,
193             0x40, 0x7A, 0xDE, 0xDB, 0x1D, 0x56, 0x0C, 0x4F,
194             0xC6, 0x77, 0x7D, 0x29, 0x72, 0x07, 0x5B, 0x8C
195         )))
196         signature = bytes(bytearray((
197             0x2F, 0x86, 0xFA, 0x60, 0xA0, 0x81, 0x09, 0x1A,
198             0x23, 0xDD, 0x79, 0x5E, 0x1E, 0x3C, 0x68, 0x9E,
199             0xE5, 0x12, 0xA3, 0xC8, 0x2E, 0xE0, 0xDC, 0xC2,
200             0x64, 0x3C, 0x78, 0xEE, 0xA8, 0xFC, 0xAC, 0xD3,
201             0x54, 0x92, 0x55, 0x84, 0x86, 0xB2, 0x0F, 0x1C,
202             0x9E, 0xC1, 0x97, 0xC9, 0x06, 0x99, 0x85, 0x02,
203             0x60, 0xC9, 0x3B, 0xCB, 0xCD, 0x9C, 0x5C, 0x33,
204             0x17, 0xE1, 0x93, 0x44, 0xE1, 0x73, 0xAE, 0x36,
205             0x10, 0x81, 0xB3, 0x94, 0x69, 0x6F, 0xFE, 0x8E,
206             0x65, 0x85, 0xE7, 0xA9, 0x36, 0x2D, 0x26, 0xB6,
207             0x32, 0x5F, 0x56, 0x77, 0x8A, 0xAD, 0xBC, 0x08,
208             0x1C, 0x0B, 0xFB, 0xE9, 0x33, 0xD5, 0x2F, 0xF5,
209             0x82, 0x3C, 0xE2, 0x88, 0xE8, 0xC4, 0xF3, 0x62,
210             0x52, 0x60, 0x80, 0xDF, 0x7F, 0x70, 0xCE, 0x40,
211             0x6A, 0x6E, 0xEB, 0x1F, 0x56, 0x91, 0x9C, 0xB9,
212             0x2A, 0x98, 0x53, 0xBD, 0xE7, 0x3E, 0x5B, 0x4A
213         )))
214         private_key = bytes2long(private_key)
215         signature = signature[64:] + signature[:64]
216
217         c = GOST3410Curve(p, q, a, b, x, y)
218         pubX, pubY = public_key(c, private_key)
219         self.assertEqual(long2bytes(pubX), public_key_x)
220         self.assertEqual(long2bytes(pubY), public_key_y)
221         s = sign(c, private_key, digest, size=SIZE_3410_2012)
222         self.assertTrue(verify(c, pubX, pubY, digest, s, size=SIZE_3410_2012))
223         self.assertTrue(verify(c, pubX, pubY, digest, signature, size=SIZE_3410_2012))
224
225     def test_sequence(self):
226         c = GOST3410Curve(*CURVE_PARAMS['GostR3410_2012_TC26_ParamSetA'])
227         private_key = bytes2long(urandom(64))
228         pubX, pubY = public_key(c, private_key)
229         for _ in range(20):
230             digest = urandom(64)
231             s = sign(c, private_key, digest, size=SIZE_3410_2012)
232             self.assertTrue(verify(c, pubX, pubY, digest, s, size=SIZE_3410_2012))
233             self.assertNotIn(b'\x00' * 8, s)
234
235
236 class TestVKO(TestCase):
237     def test_sequence(self):
238         curve = GOST3410Curve(*CURVE_PARAMS['GostR3410_2001_TestParamSet'])
239         for _ in range(20):
240             ukm = urandom(8)
241             prv1 = bytes2long(urandom(32))
242             prv2 = bytes2long(urandom(32))
243             pub1 = public_key(curve, prv1)
244             pub2 = public_key(curve, prv2)
245             kek1 = kek(curve, prv1, ukm, pub2)
246             kek2 = kek(curve, prv2, ukm, pub1)
247             self.assertEqual(kek1, kek2)
248             kek1 = kek(curve, prv1, ukm, pub1)
249             kek2 = kek(curve, prv2, ukm, pub2)
250             self.assertNotEqual(kek1, kek2)