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