]> Cypherpunks.ru repositories - gogost.git/blob - src/cypherpunks.ru/gogost/gost3410/2012_test.go
Some RFC 8133 SESPAKE test vectors
[gogost.git] / src / cypherpunks.ru / gogost / gost3410 / 2012_test.go
1 // GoGOST -- Pure Go GOST cryptographic functions library
2 // Copyright (C) 2015-2019 Sergey Matveev <stargrave@stargrave.org>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 package gost3410
18
19 import (
20         "bytes"
21         "crypto/rand"
22         "encoding/hex"
23         "testing"
24         "testing/quick"
25 )
26
27 func TestGCL3Vectors(t *testing.T) {
28         p := []byte{
29                 0x45, 0x31, 0xAC, 0xD1, 0xFE, 0x00, 0x23, 0xC7,
30                 0x55, 0x0D, 0x26, 0x7B, 0x6B, 0x2F, 0xEE, 0x80,
31                 0x92, 0x2B, 0x14, 0xB2, 0xFF, 0xB9, 0x0F, 0x04,
32                 0xD4, 0xEB, 0x7C, 0x09, 0xB5, 0xD2, 0xD1, 0x5D,
33                 0xF1, 0xD8, 0x52, 0x74, 0x1A, 0xF4, 0x70, 0x4A,
34                 0x04, 0x58, 0x04, 0x7E, 0x80, 0xE4, 0x54, 0x6D,
35                 0x35, 0xB8, 0x33, 0x6F, 0xAC, 0x22, 0x4D, 0xD8,
36                 0x16, 0x64, 0xBB, 0xF5, 0x28, 0xBE, 0x63, 0x73,
37         }
38         q := []byte{
39                 0x45, 0x31, 0xAC, 0xD1, 0xFE, 0x00, 0x23, 0xC7,
40                 0x55, 0x0D, 0x26, 0x7B, 0x6B, 0x2F, 0xEE, 0x80,
41                 0x92, 0x2B, 0x14, 0xB2, 0xFF, 0xB9, 0x0F, 0x04,
42                 0xD4, 0xEB, 0x7C, 0x09, 0xB5, 0xD2, 0xD1, 0x5D,
43                 0xA8, 0x2F, 0x2D, 0x7E, 0xCB, 0x1D, 0xBA, 0xC7,
44                 0x19, 0x90, 0x5C, 0x5E, 0xEC, 0xC4, 0x23, 0xF1,
45                 0xD8, 0x6E, 0x25, 0xED, 0xBE, 0x23, 0xC5, 0x95,
46                 0xD6, 0x44, 0xAA, 0xF1, 0x87, 0xE6, 0xE6, 0xDF,
47         }
48         a := []byte{
49                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
57         }
58         b := []byte{
59                 0x1C, 0xFF, 0x08, 0x06, 0xA3, 0x11, 0x16, 0xDA,
60                 0x29, 0xD8, 0xCF, 0xA5, 0x4E, 0x57, 0xEB, 0x74,
61                 0x8B, 0xC5, 0xF3, 0x77, 0xE4, 0x94, 0x00, 0xFD,
62                 0xD7, 0x88, 0xB6, 0x49, 0xEC, 0xA1, 0xAC, 0x43,
63                 0x61, 0x83, 0x40, 0x13, 0xB2, 0xAD, 0x73, 0x22,
64                 0x48, 0x0A, 0x89, 0xCA, 0x58, 0xE0, 0xCF, 0x74,
65                 0xBC, 0x9E, 0x54, 0x0C, 0x2A, 0xDD, 0x68, 0x97,
66                 0xFA, 0xD0, 0xA3, 0x08, 0x4F, 0x30, 0x2A, 0xDC,
67         }
68         x := []byte{
69                 0x24, 0xD1, 0x9C, 0xC6, 0x45, 0x72, 0xEE, 0x30,
70                 0xF3, 0x96, 0xBF, 0x6E, 0xBB, 0xFD, 0x7A, 0x6C,
71                 0x52, 0x13, 0xB3, 0xB3, 0xD7, 0x05, 0x7C, 0xC8,
72                 0x25, 0xF9, 0x10, 0x93, 0xA6, 0x8C, 0xD7, 0x62,
73                 0xFD, 0x60, 0x61, 0x12, 0x62, 0xCD, 0x83, 0x8D,
74                 0xC6, 0xB6, 0x0A, 0xA7, 0xEE, 0xE8, 0x04, 0xE2,
75                 0x8B, 0xC8, 0x49, 0x97, 0x7F, 0xAC, 0x33, 0xB4,
76                 0xB5, 0x30, 0xF1, 0xB1, 0x20, 0x24, 0x8A, 0x9A,
77         }
78         y := []byte{
79                 0x2B, 0xB3, 0x12, 0xA4, 0x3B, 0xD2, 0xCE, 0x6E,
80                 0x0D, 0x02, 0x06, 0x13, 0xC8, 0x57, 0xAC, 0xDD,
81                 0xCF, 0xBF, 0x06, 0x1E, 0x91, 0xE5, 0xF2, 0xC3,
82                 0xF3, 0x24, 0x47, 0xC2, 0x59, 0xF3, 0x9B, 0x2C,
83                 0x83, 0xAB, 0x15, 0x6D, 0x77, 0xF1, 0x49, 0x6B,
84                 0xF7, 0xEB, 0x33, 0x51, 0xE1, 0xEE, 0x4E, 0x43,
85                 0xDC, 0x1A, 0x18, 0xB9, 0x1B, 0x24, 0x64, 0x0B,
86                 0x6D, 0xBB, 0x92, 0xCB, 0x1A, 0xDD, 0x37, 0x1E,
87         }
88         priv := []byte{
89                 0xD4, 0x8D, 0xA1, 0x1F, 0x82, 0x67, 0x29, 0xC6,
90                 0xDF, 0xAA, 0x18, 0xFD, 0x7B, 0x6B, 0x63, 0xA2,
91                 0x14, 0x27, 0x7E, 0x82, 0xD2, 0xDA, 0x22, 0x33,
92                 0x56, 0xA0, 0x00, 0x22, 0x3B, 0x12, 0xE8, 0x72,
93                 0x20, 0x10, 0x8B, 0x50, 0x8E, 0x50, 0xE7, 0x0E,
94                 0x70, 0x69, 0x46, 0x51, 0xE8, 0xA0, 0x91, 0x30,
95                 0xC9, 0xD7, 0x56, 0x77, 0xD4, 0x36, 0x09, 0xA4,
96                 0x1B, 0x24, 0xAE, 0xAD, 0x8A, 0x04, 0xA6, 0x0B,
97         }
98         pubX := []byte{
99                 0xE1, 0xEF, 0x30, 0xD5, 0x2C, 0x61, 0x33, 0xDD,
100                 0xD9, 0x9D, 0x1D, 0x5C, 0x41, 0x45, 0x5C, 0xF7,
101                 0xDF, 0x4D, 0x8B, 0x4C, 0x92, 0x5B, 0xBC, 0x69,
102                 0xAF, 0x14, 0x33, 0xD1, 0x56, 0x58, 0x51, 0x5A,
103                 0xDD, 0x21, 0x46, 0x85, 0x0C, 0x32, 0x5C, 0x5B,
104                 0x81, 0xC1, 0x33, 0xBE, 0x65, 0x5A, 0xA8, 0xC4,
105                 0xD4, 0x40, 0xE7, 0xB9, 0x8A, 0x8D, 0x59, 0x48,
106                 0x7B, 0x0C, 0x76, 0x96, 0xBC, 0xC5, 0x5D, 0x11,
107         }
108         pubY := []byte{
109                 0xEC, 0xBE, 0x77, 0x36, 0xA9, 0xEC, 0x35, 0x7F,
110                 0xF2, 0xFD, 0x39, 0x93, 0x1F, 0x4E, 0x11, 0x4C,
111                 0xB8, 0xCD, 0xA3, 0x59, 0x27, 0x0A, 0xC7, 0xF0,
112                 0xE7, 0xFF, 0x43, 0xD9, 0x41, 0x94, 0x19, 0xEA,
113                 0x61, 0xFD, 0x2A, 0xB7, 0x7F, 0x5D, 0x9F, 0x63,
114                 0x52, 0x3D, 0x3B, 0x50, 0xA0, 0x4F, 0x63, 0xE2,
115                 0xA0, 0xCF, 0x51, 0xB7, 0xC1, 0x3A, 0xDC, 0x21,
116                 0x56, 0x0F, 0x0B, 0xD4, 0x0C, 0xC9, 0xC7, 0x37,
117         }
118         digest := []byte{
119                 0x37, 0x54, 0xF3, 0xCF, 0xAC, 0xC9, 0xE0, 0x61,
120                 0x5C, 0x4F, 0x4A, 0x7C, 0x4D, 0x8D, 0xAB, 0x53,
121                 0x1B, 0x09, 0xB6, 0xF9, 0xC1, 0x70, 0xC5, 0x33,
122                 0xA7, 0x1D, 0x14, 0x70, 0x35, 0xB0, 0xC5, 0x91,
123                 0x71, 0x84, 0xEE, 0x53, 0x65, 0x93, 0xF4, 0x41,
124                 0x43, 0x39, 0x97, 0x6C, 0x64, 0x7C, 0x5D, 0x5A,
125                 0x40, 0x7A, 0xDE, 0xDB, 0x1D, 0x56, 0x0C, 0x4F,
126                 0xC6, 0x77, 0x7D, 0x29, 0x72, 0x07, 0x5B, 0x8C,
127         }
128         signature := []byte{
129                 0x10, 0x81, 0xB3, 0x94, 0x69, 0x6F, 0xFE, 0x8E,
130                 0x65, 0x85, 0xE7, 0xA9, 0x36, 0x2D, 0x26, 0xB6,
131                 0x32, 0x5F, 0x56, 0x77, 0x8A, 0xAD, 0xBC, 0x08,
132                 0x1C, 0x0B, 0xFB, 0xE9, 0x33, 0xD5, 0x2F, 0xF5,
133                 0x82, 0x3C, 0xE2, 0x88, 0xE8, 0xC4, 0xF3, 0x62,
134                 0x52, 0x60, 0x80, 0xDF, 0x7F, 0x70, 0xCE, 0x40,
135                 0x6A, 0x6E, 0xEB, 0x1F, 0x56, 0x91, 0x9C, 0xB9,
136                 0x2A, 0x98, 0x53, 0xBD, 0xE7, 0x3E, 0x5B, 0x4A,
137                 0x2F, 0x86, 0xFA, 0x60, 0xA0, 0x81, 0x09, 0x1A,
138                 0x23, 0xDD, 0x79, 0x5E, 0x1E, 0x3C, 0x68, 0x9E,
139                 0xE5, 0x12, 0xA3, 0xC8, 0x2E, 0xE0, 0xDC, 0xC2,
140                 0x64, 0x3C, 0x78, 0xEE, 0xA8, 0xFC, 0xAC, 0xD3,
141                 0x54, 0x92, 0x55, 0x84, 0x86, 0xB2, 0x0F, 0x1C,
142                 0x9E, 0xC1, 0x97, 0xC9, 0x06, 0x99, 0x85, 0x02,
143                 0x60, 0xC9, 0x3B, 0xCB, 0xCD, 0x9C, 0x5C, 0x33,
144                 0x17, 0xE1, 0x93, 0x44, 0xE1, 0x73, 0xAE, 0x36,
145         }
146         c, err := NewCurve(
147                 bytes2big(p),
148                 bytes2big(q),
149                 bytes2big(a),
150                 bytes2big(b),
151                 bytes2big(x),
152                 bytes2big(y),
153         )
154         if err != nil {
155                 t.FailNow()
156         }
157         prv, err := NewPrivateKey(c, Mode2012, priv)
158         if err != nil {
159                 t.FailNow()
160         }
161         pub, err := prv.PublicKey()
162         if err != nil {
163                 t.FailNow()
164         }
165         if bytes.Compare(pub.Raw()[:64], pubX) != 0 {
166                 t.FailNow()
167         }
168         if bytes.Compare(pub.Raw()[64:], pubY) != 0 {
169                 t.FailNow()
170         }
171         ourSign, err := prv.SignDigest(digest, rand.Reader)
172         if err != nil {
173                 t.FailNow()
174         }
175         valid, err := pub.VerifyDigest(digest, ourSign)
176         if err != nil || !valid {
177                 t.FailNow()
178         }
179         valid, err = pub.VerifyDigest(digest, signature)
180         if err != nil || !valid {
181                 t.FailNow()
182         }
183 }
184
185 func TestRandom2012(t *testing.T) {
186         c := CurveIdtc26gost341012512paramSetA()
187         f := func(prvRaw [64 - 1]byte, digest [64]byte) bool {
188                 prv, err := NewPrivateKey(
189                         c,
190                         Mode2012,
191                         append([]byte{0xde}, prvRaw[:]...),
192                 )
193                 if err != nil {
194                         return false
195                 }
196                 pub, err := prv.PublicKey()
197                 if err != nil {
198                         return false
199                 }
200                 pubRaw := pub.Raw()
201                 pub, err = NewPublicKey(c, Mode2012, pubRaw)
202                 if err != nil {
203                         return false
204                 }
205                 sign, err := prv.SignDigest(digest[:], rand.Reader)
206                 if err != nil {
207                         return false
208                 }
209                 valid, err := pub.VerifyDigest(digest[:], sign)
210                 if err != nil {
211                         return false
212                 }
213                 return valid
214         }
215         if err := quick.Check(f, nil); err != nil {
216                 t.Error(err)
217         }
218 }
219
220 // Test vectors from RFC 8133
221 func TestSESPAKE(t *testing.T) {
222         type vector struct {
223                 curve          *Curve
224                 qIndX          string
225                 qIndY          string
226                 fPW            string
227                 xExpected      string
228                 yExpected      string
229                 alpha          string
230                 xAlphaExpected string
231                 yAlphaExpected string
232                 beta           string
233                 xBetaExpected  string
234                 yBetaExpected  string
235         }
236         vectors := []vector{
237                 vector{
238                         curve:          CurveIdGostR34102001CryptoProAParamSet(),
239                         qIndX:          "A69D51CAF1A309FA9E9B66187759B0174C274E080356F23CFCBFE84D396AD7BB",
240                         qIndY:          "5D26F29ECC2E9AC0404DCF7986FA55FE94986362170F54B9616426A659786DAC",
241                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067",
242                         xExpected:      "59495655D1E7C7424C622485F575CCF121F3122D274101E8AB734CC9C9A9B45E",
243                         yExpected:      "48D1C311D33C9B701F3B03618562A4A07A044E3AF31E3999E67B487778B53C62",
244                         alpha:          "1F2538097D5A031FA68BBB43C84D12B3DE47B7061C0D5E24993E0C873CDBA6B3",
245                         xAlphaExpected: "BBC77CF42DC1E62D06227935379B4AA4D14FEA4F565DDF4CB4FA4D31579F9676",
246                         yAlphaExpected: "8E16604A4AFDF28246684D4996274781F6CB80ABBBA1414C1513EC988509DABF",
247                         beta:           "DC497D9EF6324912FD367840EE509A2032AEDB1C0A890D133B45F596FCCBD45D",
248                         xBetaExpected:  "6097341C1BE388E83E7CA2DF47FAB86E2271FD942E5B7B2EB2409E49F742BC29",
249                         yBetaExpected:  "C81AA48BDB4CA6FA0EF18B9788AE25FE30857AA681B3942217F9FED151BAB7D0",
250                 },
251                 vector{
252                         curve:          CurveIdGostR34102001CryptoProBParamSet(),
253                         qIndX:          "3D715A874A4B17CB3B517893A9794A2B36C89D2FFC693F01EE4CC27E7F49E399",
254                         qIndY:          "1C5A641FCF7CE7E87CDF8CEA38F3DB3096EACE2FAD158384B53953365F4FE7FE",
255                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067",
256                         xExpected:      "6DC2AE26BC691FCA5A73D9C452790D15E34BA5404D92955B914C8D2662ABB985",
257                         yExpected:      "3B02AAA9DD65AE30C335CED12F3154BBAC059F66B088306747453EDF6E5DB077",
258                         alpha:          "499D72B90299CAB0DA1F8BE19D9122F622A13B32B730C46BD0664044F2144FAD",
259                         xAlphaExpected: "61D6F916DB717222D74877F179F7EBEF7CD4D24D8C1F523C048E34A1DF30F8DD",
260                         yAlphaExpected: "3EC48863049CFCFE662904082E78503F4973A4E105E2F1B18C69A5E7FB209000",
261                         beta:           "0F69FF614957EF83668EDC2D7ED614BE76F7B253DB23C5CC9C52BF7DF8F4669D",
262                         xBetaExpected:  "33BC6F7E9C0BA10CFB2B72546C327171295508EA97F8C8BA9F890F2478AB4D6C",
263                         yBetaExpected:  "75D57B396C396F492F057E9222CCC686437A2AAD464E452EF426FC8EEED1A4A6",
264                 },
265                 vector{
266                         curve:          CurveIdGostR34102001CryptoProCParamSet(),
267                         qIndX:          "1E36383E43BB6CFA2917167D71B7B5DD3D6D462B43D7C64282AE67DFBEC2559D",
268                         qIndY:          "137478A9F721C73932EA06B45CF72E37EB78A63F29A542E563C614650C8B6399",
269                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067",
270                         xExpected:      "945821DAF91E158B839939630655A3B21FF3E146D27041E86C05650EB3B46B59",
271                         yExpected:      "3A0C2816AC97421FA0E879605F17F0C9C3EB734CFF196937F6284438D70BDC48",
272                         alpha:          "3A54AC3F19AD9D0B1EAC8ACDCEA70E581F1DAC33D13FEAFD81E762378639C1A8",
273                         xAlphaExpected: "96B7F09C94D297C257A7DA48364C0076E59E48D221CBA604AE111CA3933B446A",
274                         yAlphaExpected: "54E4953D86B77ECCEB578500931E822300F7E091F79592CA202A020D762C34A6",
275                         beta:           "448781782BF7C0E52A1DD9E6758FD3482D90D3CFCCF42232CF357E59A4D49FD4",
276                         xBetaExpected:  "4B9C0AB55A938121F282F48A2CC4396EB16E7E0068B495B0C1DD4667786A3EB7",
277                         yBetaExpected:  "223460AA8E09383E9DF9844C5A0F2766484738E5B30128A171B69A77D9509B96",
278                 },
279                 vector{
280                         curve:          CurveIdtc26gost341012512paramSetA(),
281                         qIndX:          "2A17F8833A32795327478871B5C5E88AEFB91126C64B4B8327289BEA62559425D18198F133F400874328B220C74497CD240586CB249E158532CB8090776CD61C",
282                         qIndY:          "728F0C4A73B48DA41CE928358FAD26B47A6E094E9362BAE82559F83CDDC4EC3A4676BD3707EDEAF4CD85E99695C64C241EDC622BE87DC0CF87F51F4367F723C5",
283                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F181270671C6213E3930EFDDA26451792C6208122EE60D200520D695DFD9F5F0FD5ABA702",
284                         xExpected:      "0C0AB53D0E0A9C607CAD758F558915A0A7DC5DC87B45E9A58FDDF30EC3385960283E030CD322D9E46B070637785FD49D2CD711F46807A24C40AF9A42C8E2D740",
285                         yExpected:      "DF93A8012B86D3A3D4F8A4D487DA15FC739EB31B20B3B0E8C8C032AAF8072C6337CF7D5B404719E5B4407C41D9A3216A08CA69C271484E9ED72B8AAA52E28B8B",
286                         alpha:          "3CE54325DB52FE798824AEAD11BB16FA766857D04A4AF7D468672F16D90E7396046A46F815693E85B1CE5464DA9270181F82333B0715057BBE8D61D400505F0E",
287                         xAlphaExpected: "B93093EB0FCC463239B7DF276E09E592FCFC9B635504EA4531655D76A0A3078E2B4E51CFE2FA400CC5DE9FBE369DB204B3E8ED7EDD85EE5CCA654C1AED70E396",
288                         yAlphaExpected: "809770B8D910EA30BD2FA89736E91DC31815D2D9B31128077EEDC371E9F69466F497DC64DD5B1FADC587F860EE256109138C4A9CD96B628E65A8F590520FC882",
289                         beta:           "B5C286A79AA8E97EC0E19BC1959A1D15F12F8C97870BA9D68CC12811A56A3BB11440610825796A49D468CDC9C2D02D76598A27973D5960C5F50BCE28D8D345F4",
290                         xBetaExpected:  "238B38644E440452A99FA6B93D9FD7DA0CB83C32D3C1E3CFE5DF5C3EB0F9DB91E588DAEDC849EA2FB867AE855A21B4077353C0794716A6480995113D8C20C7AF",
291                         yBetaExpected:  "B2273D5734C1897F8D15A7008B862938C8C74CA7E877423D95243EB7EBD02FD2C456CF9FC956F078A59AA86F19DD1075E5167E4ED35208718EA93161C530ED14",
292                 },
293                 vector{
294                         curve:          CurveIdtc26gost341012512paramSetB(),
295                         qIndX:          "7E1FAE8285E035BEC244BEF2D0E5EBF436633CF50E55231DEA9C9CF21D4C8C33DF85D4305DE92971F0A4B4C07E00D87BDBC720EB66E49079285AAF12E0171149",
296                         qIndY:          "2CC89998B875D4463805BA0D858A196592DB20AB161558FF2F4EF7A85725D20953967AE621AFDEAE89BB77C83A2528EF6FCE02F68BDA4679D7F2704947DBC408",
297                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F181270671C6213E3930EFDDA26451792C6208122EE60D200520D695DFD9F5F0FD5ABA702",
298                         xExpected:      "7D03E65B8050D1E12CBB601A17B9273B0E728F5021CD47C8A4DD822E4627BA5F9C696286A2CDDA9A065509866B4DEDEDC4A118409604AD549F87A60AFA621161",
299                         yExpected:      "16037DAD45421EC50B00D50BDC6AC3B85348BC1D3A2F85DB27C3373580FEF87C2C743B7ED30F22BE22958044E716F93A61CA3213A361A2797A16A3AE62957377",
300                         alpha:          "715E893FA639BF341296E0623E6D29DADF26B163C278767A7982A989462A3863FE12AEF8BD403D59C4DC4720570D4163DB0805C7C10C4E818F9CB785B04B9997",
301                         xAlphaExpected: "10C479EA1C04D3C2C02B0576A9C42D96226FF033C1191436777F66916030D87D02FB93738ED7669D07619FFCE7C1F3C4DB5E5DF49E2186D6FA1E2EB5767602B9",
302                         yAlphaExpected: "039F6044191404E707F26D59D979136A831CCE43E1C5F0600D1DDF8F39D0CA3D52FBD943BF04DDCED1AA2CE8F5EBD7487ACDEF239C07D015084D796784F35436",
303                         beta:           "30FA8C2B4146C2DBBE82BED04D7378877E8C06753BD0A0FF71EBF2BEFE8DA8F3DC0836468E2CE7C5C961281B6505140F8407413F03C2CB1D201EA1286CE30E6D",
304                         xBetaExpected:  "34C0149E7BB91AE377B02573FCC48AF7BFB7B16DEB8F9CE870F384688E3241A3A868588CC0EF4364CCA67D17E3260CD82485C202ADC76F895D5DF673B1788E67",
305                         yBetaExpected:  "608E944929BD643569ED5189DB871453F13333A1EAF82B2FE1BE8100E775F13DD9925BD317B63BFAF05024D4A738852332B64501195C1B2EF789E34F23DDAFC5",
306                 },
307                 vector{
308                         curve:          CurveIdtc26gost34102012256paramSetA(),
309                         qIndX:          "B51ADF93A40AB15792164FAD3352F95B66369EB2A4EF5EFAE32829320363350E",
310                         qIndY:          "74A358CC08593612F5955D249C96AFB7E8B0BB6D8BD2BBE491046650D822BE18",
311                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067",
312                         xExpected:      "DBF99827078956812FA48C6E695DF589DEF1D18A2D4D35A96D75BF6854237629",
313                         yExpected:      "9FDDD48BFBC57BEE1DA0CFF282884F284D471B388893C48F5ECB02FC18D67589",
314                         alpha:          "147B72F6684FB8FD1B418A899F7DBECAF5FCE60B13685BAA95328654A7F0707F",
315                         xAlphaExpected: "33FBAC14EAE538275A769417829C431BD9FA622B6F02427EF55BD60EE6BC2888",
316                         yAlphaExpected: "22F2EBCF960A82E6CDB4042D3DDDA511B2FBA925383C2273D952EA2D406EAE46",
317                         beta:           "30D5CFADAA0E31B405E6734C03EC4C5DF0F02F4BA25C9A3B320EE6453567B4CB",
318                         xBetaExpected:  "2B2D89FAB735433970564F2F28CFA1B57D640CB902BC6334A538F44155022CB2",
319                         yBetaExpected:  "10EF6A82EEF1E70F942AA81D6B4CE5DEC0DDB9447512962874870E6F2849A96F",
320                 },
321                 vector{
322                         curve:          CurveIdtc26gost34102012512paramSetC(),
323                         qIndX:          "489C91784E02E98F19A803ABCA319917F37689E5A18965251CE2FF4E8D8B298F5BA7470F9E0E713487F96F4A8397B3D09A270C9D367EB5E0E6561ADEEB51581D",
324                         qIndY:          "684EA885ACA64EAF1B3FEE36C0852A3BE3BD8011B0EF18E203FF87028D6EB5DB2C144A0DCC71276542BFD72CA2A43FA4F4939DA66D9A60793C704A8C94E16F18",
325                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F181270671C6213E3930EFDDA26451792C6208122EE60D200520D695DFD9F5F0FD5ABA702",
326                         xExpected:      "0185AE6271A81BB7F236A955F7CAA26FB63849813C0287D96C83A15AE6B6A86467AB13B6D88CE8CD7DC2E5B97FF5F28FAC2C108F2A3CF3DB5515C9E6D7D210E8",
327                         yExpected:      "ED0220F92EF771A71C64ECC77986DB7C03D37B3E2AB3E83F32CE5E074A762EC08253C9E2102B87532661275C4B1D16D2789CDABC58ACFDF7318DE70AB64F09B8",
328                         alpha:          "332F930421D14CFE260042159F18E49FD5A54167E94108AD80B1DE60B13DE7999A34D611E63F3F870E5110247DF8EC7466E648ACF385E52CCB889ABF491EDFF0",
329                         xAlphaExpected: "561655966D52952E805574F4281F1ED3A2D498932B00CBA9DECB42837F09835BFFBFE2D84D6B6B242FE7B57F92E1A6F2413E12DDD6383E4437E13D72693469AD",
330                         yAlphaExpected: "F6B18328B2715BD7F4178615273A36135BC0BF62F7D8BB9F080164AD36470AD03660F51806C64C6691BADEF30F793720F8E3FEAED631D6A54A4C372DCBF80E82",
331                         beta:           "38481771E7D054F96212686B613881880BD8A6C89DDBC656178F014D2C093432A033EE10415F13A160D44C2AD61E6E2E05A7F7EC286BCEA3EA4D4D53F8634FA2",
332                         xBetaExpected:  "B7C5818687083433BC1AFF61CB5CA79E38232025E0C1F123B8651E62173CE6873F3E6FFE7281C2E45F4F524F66B0C263616ED08FD210AC4355CA3292B51D71C3",
333                         yBetaExpected:  "497F14205DBDC89BDDAF50520ED3B1429AD30777310186BE5E68070F016A44E0C766DB08E8AC23FBDFDE6D675AA4DF591EB18BA0D348DF7AA40973A2F1DCFA55",
334                 },
335         }
336         for _, vector := range vectors {
337                 raw, _ := hex.DecodeString(vector.qIndX)
338                 qIndX := bytes2big(raw)
339                 raw, _ = hex.DecodeString(vector.qIndY)
340                 qIndY := bytes2big(raw)
341                 raw, _ = hex.DecodeString(vector.fPW)
342                 reverse(raw)
343                 f := bytes2big(raw)
344                 x, y, err := vector.curve.Exp(f, qIndX, qIndY)
345                 if err != nil {
346                         t.FailNow()
347                 }
348                 raw, _ = hex.DecodeString(vector.xExpected)
349                 if bytes.Compare(x.Bytes(), raw) != 0 {
350                         t.FailNow()
351                 }
352                 raw, _ = hex.DecodeString(vector.yExpected)
353                 if bytes.Compare(y.Bytes(), raw) != 0 {
354                         t.FailNow()
355                 }
356
357                 raw, _ = hex.DecodeString(vector.alpha)
358                 alpha := bytes2big(raw)
359                 x, y, err = vector.curve.Exp(alpha, vector.curve.X, vector.curve.Y)
360                 raw, _ = hex.DecodeString(vector.xAlphaExpected)
361                 if bytes.Compare(x.Bytes(), raw) != 0 {
362                         t.FailNow()
363                 }
364                 raw, _ = hex.DecodeString(vector.yAlphaExpected)
365                 if bytes.Compare(y.Bytes(), raw) != 0 {
366                         t.FailNow()
367                 }
368
369                 raw, _ = hex.DecodeString(vector.beta)
370                 beta := bytes2big(raw)
371                 x, y, err = vector.curve.Exp(beta, vector.curve.X, vector.curve.Y)
372                 raw, _ = hex.DecodeString(vector.xBetaExpected)
373                 if bytes.Compare(x.Bytes(), raw) != 0 {
374                         t.FailNow()
375                 }
376                 raw, _ = hex.DecodeString(vector.yBetaExpected)
377                 if bytes.Compare(y.Bytes(), raw) != 0 {
378                         t.FailNow()
379                 }
380         }
381 }
382 }
383
384 func BenchmarkSign2012(b *testing.B) {
385         c := CurveIdtc26gost341012512paramSetA()
386         prv, err := GenPrivateKey(c, Mode2012, rand.Reader)
387         if err != nil {
388                 b.FailNow()
389         }
390         digest := make([]byte, 64)
391         rand.Read(digest)
392         b.ResetTimer()
393         for i := 0; i < b.N; i++ {
394                 prv.SignDigest(digest, rand.Reader)
395         }
396 }
397
398 func BenchmarkVerify2012(b *testing.B) {
399         c := CurveIdtc26gost341012512paramSetA()
400         prv, err := GenPrivateKey(c, Mode2012, rand.Reader)
401         if err != nil {
402                 b.FailNow()
403         }
404         digest := make([]byte, 64)
405         rand.Read(digest)
406         sign, err := prv.SignDigest(digest, rand.Reader)
407         if err != nil {
408                 b.FailNow()
409         }
410         pub, err := prv.PublicKey()
411         if err != nil {
412                 b.FailNow()
413         }
414         b.ResetTimer()
415         for i := 0; i < b.N; i++ {
416                 pub.VerifyDigest(digest, sign)
417         }
418 }