]> Cypherpunks.ru repositories - gogost.git/blob - src/cypherpunks.ru/gogost/gost3410/2012_test.go
0a786dfadcea532f32f9f0099718fb87c3f27bd0
[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                 "some-name",
148                 bytes2big(p),
149                 bytes2big(q),
150                 bytes2big(a),
151                 bytes2big(b),
152                 bytes2big(x),
153                 bytes2big(y),
154                 nil,
155                 nil,
156         )
157         if err != nil {
158                 t.FailNow()
159         }
160         prv, err := NewPrivateKey(c, Mode2012, priv)
161         if err != nil {
162                 t.FailNow()
163         }
164         pub, err := prv.PublicKey()
165         if err != nil {
166                 t.FailNow()
167         }
168         if bytes.Compare(pub.Raw()[:64], pubX) != 0 {
169                 t.FailNow()
170         }
171         if bytes.Compare(pub.Raw()[64:], pubY) != 0 {
172                 t.FailNow()
173         }
174         ourSign, err := prv.SignDigest(digest, rand.Reader)
175         if err != nil {
176                 t.FailNow()
177         }
178         valid, err := pub.VerifyDigest(digest, ourSign)
179         if err != nil || !valid {
180                 t.FailNow()
181         }
182         valid, err = pub.VerifyDigest(digest, signature)
183         if err != nil || !valid {
184                 t.FailNow()
185         }
186 }
187
188 func TestRandom2012(t *testing.T) {
189         c := CurveIdtc26gost341012512paramSetA()
190         f := func(prvRaw [64 - 1]byte, digest [64]byte) bool {
191                 prv, err := NewPrivateKey(
192                         c,
193                         Mode2012,
194                         append([]byte{0xde}, prvRaw[:]...),
195                 )
196                 if err != nil {
197                         return false
198                 }
199                 pub, err := prv.PublicKey()
200                 if err != nil {
201                         return false
202                 }
203                 pubRaw := pub.Raw()
204                 pub, err = NewPublicKey(c, Mode2012, pubRaw)
205                 if err != nil {
206                         return false
207                 }
208                 sign, err := prv.SignDigest(digest[:], rand.Reader)
209                 if err != nil {
210                         return false
211                 }
212                 valid, err := pub.VerifyDigest(digest[:], sign)
213                 if err != nil {
214                         return false
215                 }
216                 return valid
217         }
218         if err := quick.Check(f, nil); err != nil {
219                 t.Error(err)
220         }
221 }
222
223 // Test vectors from RFC 8133
224 func TestSESPAKE(t *testing.T) {
225         type vector struct {
226                 curve          *Curve
227                 qIndX          string
228                 qIndY          string
229                 fPW            string
230                 xExpected      string
231                 yExpected      string
232                 alpha          string
233                 xAlphaExpected string
234                 yAlphaExpected string
235                 beta           string
236                 xBetaExpected  string
237                 yBetaExpected  string
238         }
239         vectors := []vector{
240                 vector{
241                         curve:          CurveIdGostR34102001CryptoProAParamSet(),
242                         qIndX:          "A69D51CAF1A309FA9E9B66187759B0174C274E080356F23CFCBFE84D396AD7BB",
243                         qIndY:          "5D26F29ECC2E9AC0404DCF7986FA55FE94986362170F54B9616426A659786DAC",
244                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067",
245                         xExpected:      "59495655D1E7C7424C622485F575CCF121F3122D274101E8AB734CC9C9A9B45E",
246                         yExpected:      "48D1C311D33C9B701F3B03618562A4A07A044E3AF31E3999E67B487778B53C62",
247                         alpha:          "1F2538097D5A031FA68BBB43C84D12B3DE47B7061C0D5E24993E0C873CDBA6B3",
248                         xAlphaExpected: "BBC77CF42DC1E62D06227935379B4AA4D14FEA4F565DDF4CB4FA4D31579F9676",
249                         yAlphaExpected: "8E16604A4AFDF28246684D4996274781F6CB80ABBBA1414C1513EC988509DABF",
250                         beta:           "DC497D9EF6324912FD367840EE509A2032AEDB1C0A890D133B45F596FCCBD45D",
251                         xBetaExpected:  "6097341C1BE388E83E7CA2DF47FAB86E2271FD942E5B7B2EB2409E49F742BC29",
252                         yBetaExpected:  "C81AA48BDB4CA6FA0EF18B9788AE25FE30857AA681B3942217F9FED151BAB7D0",
253                 },
254                 vector{
255                         curve:          CurveIdGostR34102001CryptoProBParamSet(),
256                         qIndX:          "3D715A874A4B17CB3B517893A9794A2B36C89D2FFC693F01EE4CC27E7F49E399",
257                         qIndY:          "1C5A641FCF7CE7E87CDF8CEA38F3DB3096EACE2FAD158384B53953365F4FE7FE",
258                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067",
259                         xExpected:      "6DC2AE26BC691FCA5A73D9C452790D15E34BA5404D92955B914C8D2662ABB985",
260                         yExpected:      "3B02AAA9DD65AE30C335CED12F3154BBAC059F66B088306747453EDF6E5DB077",
261                         alpha:          "499D72B90299CAB0DA1F8BE19D9122F622A13B32B730C46BD0664044F2144FAD",
262                         xAlphaExpected: "61D6F916DB717222D74877F179F7EBEF7CD4D24D8C1F523C048E34A1DF30F8DD",
263                         yAlphaExpected: "3EC48863049CFCFE662904082E78503F4973A4E105E2F1B18C69A5E7FB209000",
264                         beta:           "0F69FF614957EF83668EDC2D7ED614BE76F7B253DB23C5CC9C52BF7DF8F4669D",
265                         xBetaExpected:  "33BC6F7E9C0BA10CFB2B72546C327171295508EA97F8C8BA9F890F2478AB4D6C",
266                         yBetaExpected:  "75D57B396C396F492F057E9222CCC686437A2AAD464E452EF426FC8EEED1A4A6",
267                 },
268                 vector{
269                         curve:          CurveIdGostR34102001CryptoProCParamSet(),
270                         qIndX:          "1E36383E43BB6CFA2917167D71B7B5DD3D6D462B43D7C64282AE67DFBEC2559D",
271                         qIndY:          "137478A9F721C73932EA06B45CF72E37EB78A63F29A542E563C614650C8B6399",
272                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067",
273                         xExpected:      "945821DAF91E158B839939630655A3B21FF3E146D27041E86C05650EB3B46B59",
274                         yExpected:      "3A0C2816AC97421FA0E879605F17F0C9C3EB734CFF196937F6284438D70BDC48",
275                         alpha:          "3A54AC3F19AD9D0B1EAC8ACDCEA70E581F1DAC33D13FEAFD81E762378639C1A8",
276                         xAlphaExpected: "96B7F09C94D297C257A7DA48364C0076E59E48D221CBA604AE111CA3933B446A",
277                         yAlphaExpected: "54E4953D86B77ECCEB578500931E822300F7E091F79592CA202A020D762C34A6",
278                         beta:           "448781782BF7C0E52A1DD9E6758FD3482D90D3CFCCF42232CF357E59A4D49FD4",
279                         xBetaExpected:  "4B9C0AB55A938121F282F48A2CC4396EB16E7E0068B495B0C1DD4667786A3EB7",
280                         yBetaExpected:  "223460AA8E09383E9DF9844C5A0F2766484738E5B30128A171B69A77D9509B96",
281                 },
282                 vector{
283                         curve:          CurveIdtc26gost341012512paramSetA(),
284                         qIndX:          "2A17F8833A32795327478871B5C5E88AEFB91126C64B4B8327289BEA62559425D18198F133F400874328B220C74497CD240586CB249E158532CB8090776CD61C",
285                         qIndY:          "728F0C4A73B48DA41CE928358FAD26B47A6E094E9362BAE82559F83CDDC4EC3A4676BD3707EDEAF4CD85E99695C64C241EDC622BE87DC0CF87F51F4367F723C5",
286                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F181270671C6213E3930EFDDA26451792C6208122EE60D200520D695DFD9F5F0FD5ABA702",
287                         xExpected:      "0C0AB53D0E0A9C607CAD758F558915A0A7DC5DC87B45E9A58FDDF30EC3385960283E030CD322D9E46B070637785FD49D2CD711F46807A24C40AF9A42C8E2D740",
288                         yExpected:      "DF93A8012B86D3A3D4F8A4D487DA15FC739EB31B20B3B0E8C8C032AAF8072C6337CF7D5B404719E5B4407C41D9A3216A08CA69C271484E9ED72B8AAA52E28B8B",
289                         alpha:          "3CE54325DB52FE798824AEAD11BB16FA766857D04A4AF7D468672F16D90E7396046A46F815693E85B1CE5464DA9270181F82333B0715057BBE8D61D400505F0E",
290                         xAlphaExpected: "B93093EB0FCC463239B7DF276E09E592FCFC9B635504EA4531655D76A0A3078E2B4E51CFE2FA400CC5DE9FBE369DB204B3E8ED7EDD85EE5CCA654C1AED70E396",
291                         yAlphaExpected: "809770B8D910EA30BD2FA89736E91DC31815D2D9B31128077EEDC371E9F69466F497DC64DD5B1FADC587F860EE256109138C4A9CD96B628E65A8F590520FC882",
292                         beta:           "B5C286A79AA8E97EC0E19BC1959A1D15F12F8C97870BA9D68CC12811A56A3BB11440610825796A49D468CDC9C2D02D76598A27973D5960C5F50BCE28D8D345F4",
293                         xBetaExpected:  "238B38644E440452A99FA6B93D9FD7DA0CB83C32D3C1E3CFE5DF5C3EB0F9DB91E588DAEDC849EA2FB867AE855A21B4077353C0794716A6480995113D8C20C7AF",
294                         yBetaExpected:  "B2273D5734C1897F8D15A7008B862938C8C74CA7E877423D95243EB7EBD02FD2C456CF9FC956F078A59AA86F19DD1075E5167E4ED35208718EA93161C530ED14",
295                 },
296                 vector{
297                         curve:          CurveIdtc26gost341012512paramSetB(),
298                         qIndX:          "7E1FAE8285E035BEC244BEF2D0E5EBF436633CF50E55231DEA9C9CF21D4C8C33DF85D4305DE92971F0A4B4C07E00D87BDBC720EB66E49079285AAF12E0171149",
299                         qIndY:          "2CC89998B875D4463805BA0D858A196592DB20AB161558FF2F4EF7A85725D20953967AE621AFDEAE89BB77C83A2528EF6FCE02F68BDA4679D7F2704947DBC408",
300                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F181270671C6213E3930EFDDA26451792C6208122EE60D200520D695DFD9F5F0FD5ABA702",
301                         xExpected:      "7D03E65B8050D1E12CBB601A17B9273B0E728F5021CD47C8A4DD822E4627BA5F9C696286A2CDDA9A065509866B4DEDEDC4A118409604AD549F87A60AFA621161",
302                         yExpected:      "16037DAD45421EC50B00D50BDC6AC3B85348BC1D3A2F85DB27C3373580FEF87C2C743B7ED30F22BE22958044E716F93A61CA3213A361A2797A16A3AE62957377",
303                         alpha:          "715E893FA639BF341296E0623E6D29DADF26B163C278767A7982A989462A3863FE12AEF8BD403D59C4DC4720570D4163DB0805C7C10C4E818F9CB785B04B9997",
304                         xAlphaExpected: "10C479EA1C04D3C2C02B0576A9C42D96226FF033C1191436777F66916030D87D02FB93738ED7669D07619FFCE7C1F3C4DB5E5DF49E2186D6FA1E2EB5767602B9",
305                         yAlphaExpected: "039F6044191404E707F26D59D979136A831CCE43E1C5F0600D1DDF8F39D0CA3D52FBD943BF04DDCED1AA2CE8F5EBD7487ACDEF239C07D015084D796784F35436",
306                         beta:           "30FA8C2B4146C2DBBE82BED04D7378877E8C06753BD0A0FF71EBF2BEFE8DA8F3DC0836468E2CE7C5C961281B6505140F8407413F03C2CB1D201EA1286CE30E6D",
307                         xBetaExpected:  "34C0149E7BB91AE377B02573FCC48AF7BFB7B16DEB8F9CE870F384688E3241A3A868588CC0EF4364CCA67D17E3260CD82485C202ADC76F895D5DF673B1788E67",
308                         yBetaExpected:  "608E944929BD643569ED5189DB871453F13333A1EAF82B2FE1BE8100E775F13DD9925BD317B63BFAF05024D4A738852332B64501195C1B2EF789E34F23DDAFC5",
309                 },
310                 vector{
311                         curve:          CurveIdtc26gost34102012256paramSetA(),
312                         qIndX:          "B51ADF93A40AB15792164FAD3352F95B66369EB2A4EF5EFAE32829320363350E",
313                         qIndY:          "74A358CC08593612F5955D249C96AFB7E8B0BB6D8BD2BBE491046650D822BE18",
314                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067",
315                         xExpected:      "DBF99827078956812FA48C6E695DF589DEF1D18A2D4D35A96D75BF6854237629",
316                         yExpected:      "9FDDD48BFBC57BEE1DA0CFF282884F284D471B388893C48F5ECB02FC18D67589",
317                         alpha:          "147B72F6684FB8FD1B418A899F7DBECAF5FCE60B13685BAA95328654A7F0707F",
318                         xAlphaExpected: "33FBAC14EAE538275A769417829C431BD9FA622B6F02427EF55BD60EE6BC2888",
319                         yAlphaExpected: "22F2EBCF960A82E6CDB4042D3DDDA511B2FBA925383C2273D952EA2D406EAE46",
320                         beta:           "30D5CFADAA0E31B405E6734C03EC4C5DF0F02F4BA25C9A3B320EE6453567B4CB",
321                         xBetaExpected:  "2B2D89FAB735433970564F2F28CFA1B57D640CB902BC6334A538F44155022CB2",
322                         yBetaExpected:  "10EF6A82EEF1E70F942AA81D6B4CE5DEC0DDB9447512962874870E6F2849A96F",
323                 },
324                 vector{
325                         curve:          CurveIdtc26gost34102012512paramSetC(),
326                         qIndX:          "489C91784E02E98F19A803ABCA319917F37689E5A18965251CE2FF4E8D8B298F5BA7470F9E0E713487F96F4A8397B3D09A270C9D367EB5E0E6561ADEEB51581D",
327                         qIndY:          "684EA885ACA64EAF1B3FEE36C0852A3BE3BD8011B0EF18E203FF87028D6EB5DB2C144A0DCC71276542BFD72CA2A43FA4F4939DA66D9A60793C704A8C94E16F18",
328                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F181270671C6213E3930EFDDA26451792C6208122EE60D200520D695DFD9F5F0FD5ABA702",
329                         xExpected:      "0185AE6271A81BB7F236A955F7CAA26FB63849813C0287D96C83A15AE6B6A86467AB13B6D88CE8CD7DC2E5B97FF5F28FAC2C108F2A3CF3DB5515C9E6D7D210E8",
330                         yExpected:      "ED0220F92EF771A71C64ECC77986DB7C03D37B3E2AB3E83F32CE5E074A762EC08253C9E2102B87532661275C4B1D16D2789CDABC58ACFDF7318DE70AB64F09B8",
331                         alpha:          "332F930421D14CFE260042159F18E49FD5A54167E94108AD80B1DE60B13DE7999A34D611E63F3F870E5110247DF8EC7466E648ACF385E52CCB889ABF491EDFF0",
332                         xAlphaExpected: "561655966D52952E805574F4281F1ED3A2D498932B00CBA9DECB42837F09835BFFBFE2D84D6B6B242FE7B57F92E1A6F2413E12DDD6383E4437E13D72693469AD",
333                         yAlphaExpected: "F6B18328B2715BD7F4178615273A36135BC0BF62F7D8BB9F080164AD36470AD03660F51806C64C6691BADEF30F793720F8E3FEAED631D6A54A4C372DCBF80E82",
334                         beta:           "38481771E7D054F96212686B613881880BD8A6C89DDBC656178F014D2C093432A033EE10415F13A160D44C2AD61E6E2E05A7F7EC286BCEA3EA4D4D53F8634FA2",
335                         xBetaExpected:  "B7C5818687083433BC1AFF61CB5CA79E38232025E0C1F123B8651E62173CE6873F3E6FFE7281C2E45F4F524F66B0C263616ED08FD210AC4355CA3292B51D71C3",
336                         yBetaExpected:  "497F14205DBDC89BDDAF50520ED3B1429AD30777310186BE5E68070F016A44E0C766DB08E8AC23FBDFDE6D675AA4DF591EB18BA0D348DF7AA40973A2F1DCFA55",
337                 },
338         }
339         for _, vector := range vectors {
340                 raw, _ := hex.DecodeString(vector.qIndX)
341                 qIndX := bytes2big(raw)
342                 raw, _ = hex.DecodeString(vector.qIndY)
343                 qIndY := bytes2big(raw)
344                 raw, _ = hex.DecodeString(vector.fPW)
345                 reverse(raw)
346                 f := bytes2big(raw)
347                 x, y, err := vector.curve.Exp(f, qIndX, qIndY)
348                 if err != nil {
349                         t.FailNow()
350                 }
351                 raw, _ = hex.DecodeString(vector.xExpected)
352                 if bytes.Compare(x.Bytes(), raw) != 0 {
353                         t.FailNow()
354                 }
355                 raw, _ = hex.DecodeString(vector.yExpected)
356                 if bytes.Compare(y.Bytes(), raw) != 0 {
357                         t.FailNow()
358                 }
359
360                 raw, _ = hex.DecodeString(vector.alpha)
361                 alpha := bytes2big(raw)
362                 x, y, err = vector.curve.Exp(alpha, vector.curve.X, vector.curve.Y)
363                 raw, _ = hex.DecodeString(vector.xAlphaExpected)
364                 if bytes.Compare(x.Bytes(), raw) != 0 {
365                         t.FailNow()
366                 }
367                 raw, _ = hex.DecodeString(vector.yAlphaExpected)
368                 if bytes.Compare(y.Bytes(), raw) != 0 {
369                         t.FailNow()
370                 }
371
372                 raw, _ = hex.DecodeString(vector.beta)
373                 beta := bytes2big(raw)
374                 x, y, err = vector.curve.Exp(beta, vector.curve.X, vector.curve.Y)
375                 raw, _ = hex.DecodeString(vector.xBetaExpected)
376                 if bytes.Compare(x.Bytes(), raw) != 0 {
377                         t.FailNow()
378                 }
379                 raw, _ = hex.DecodeString(vector.yBetaExpected)
380                 if bytes.Compare(y.Bytes(), raw) != 0 {
381                         t.FailNow()
382                 }
383         }
384 }
385
386 // Twisted Edwards to Weierstrass coordinates conversion and vice versa
387 func TestUVXYConversion(t *testing.T) {
388         f := func(c *Curve, uRaw, vRaw []byte) {
389                 u := bytes2big(uRaw)
390                 v := bytes2big(vRaw)
391                 x, y := UV2XY(c, u, v)
392                 if x.Cmp(c.X) != 0 {
393                         t.FailNow()
394                 }
395                 if y.Cmp(c.Y) != 0 {
396                         t.FailNow()
397                 }
398                 uGot, vGot := XY2UV(c, c.X, c.Y)
399                 if u.Cmp(uGot) != 0 {
400                         t.FailNow()
401                 }
402                 if v.Cmp(vGot) != 0 {
403                         t.FailNow()
404                 }
405         }
406         raw, _ := hex.DecodeString("60CA1E32AA475B348488C38FAB07649CE7EF8DBE87F22E81F92B2592DBA300E7")
407         f(CurveIdtc26gost34102012256paramSetA(), []byte{0x0D}, raw)
408         raw, _ = hex.DecodeString("469AF79D1FB1F5E16B99592B77A01E2A0FDFB0D01794368D9A56117F7B38669522DD4B650CF789EEBF068C5D139732F0905622C04B2BAAE7600303EE73001A3D")
409         f(CurveIdtc26gost34102012512paramSetC(), []byte{0x12}, raw)
410 }
411
412 func BenchmarkSign2012(b *testing.B) {
413         c := CurveIdtc26gost341012512paramSetA()
414         prv, err := GenPrivateKey(c, Mode2012, rand.Reader)
415         if err != nil {
416                 b.FailNow()
417         }
418         digest := make([]byte, 64)
419         rand.Read(digest)
420         b.ResetTimer()
421         for i := 0; i < b.N; i++ {
422                 prv.SignDigest(digest, rand.Reader)
423         }
424 }
425
426 func BenchmarkVerify2012(b *testing.B) {
427         c := CurveIdtc26gost341012512paramSetA()
428         prv, err := GenPrivateKey(c, Mode2012, rand.Reader)
429         if err != nil {
430                 b.FailNow()
431         }
432         digest := make([]byte, 64)
433         rand.Read(digest)
434         sign, err := prv.SignDigest(digest, rand.Reader)
435         if err != nil {
436                 b.FailNow()
437         }
438         pub, err := prv.PublicKey()
439         if err != nil {
440                 b.FailNow()
441         }
442         b.ResetTimer()
443         for i := 0; i < b.N; i++ {
444                 pub.VerifyDigest(digest, sign)
445         }
446 }