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