]> Cypherpunks.ru repositories - gogost.git/blob - gost3410/2012_test.go
Raise copyright years
[gogost.git] / gost3410 / 2012_test.go
1 // GoGOST -- Pure Go GOST cryptographic functions library
2 // Copyright (C) 2015-2021 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, version 3 of the License.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 package gost3410
17
18 import (
19         "bytes"
20         "crypto/rand"
21         "encoding/hex"
22         "math/big"
23         "testing"
24         "testing/quick"
25 )
26
27 // Test vector from GOST R 34.10-2012 appendix
28 func TestStdVector1(t *testing.T) {
29         prvRaw := []byte{
30                 0x7A, 0x92, 0x9A, 0xDE, 0x78, 0x9B, 0xB9, 0xBE,
31                 0x10, 0xED, 0x35, 0x9D, 0xD3, 0x9A, 0x72, 0xC1,
32                 0x1B, 0x60, 0x96, 0x1F, 0x49, 0x39, 0x7E, 0xEE,
33                 0x1D, 0x19, 0xCE, 0x98, 0x91, 0xEC, 0x3B, 0x28,
34         }
35         dgst := []byte{
36                 0x2D, 0xFB, 0xC1, 0xB3, 0x72, 0xD8, 0x9A, 0x11,
37                 0x88, 0xC0, 0x9C, 0x52, 0xE0, 0xEE, 0xC6, 0x1F,
38                 0xCE, 0x52, 0x03, 0x2A, 0xB1, 0x02, 0x2E, 0x8E,
39                 0x67, 0xEC, 0xE6, 0x67, 0x2B, 0x04, 0x3E, 0xE5,
40         }
41         rnd := []byte{
42                 0x77, 0x10, 0x5C, 0x9B, 0x20, 0xBC, 0xD3, 0x12,
43                 0x28, 0x23, 0xC8, 0xCF, 0x6F, 0xCC, 0x7B, 0x95,
44                 0x6D, 0xE3, 0x38, 0x14, 0xE9, 0x5B, 0x7F, 0xE6,
45                 0x4F, 0xED, 0x92, 0x45, 0x94, 0xDC, 0xEA, 0xB3,
46         }
47         r := []byte{
48                 0x41, 0xAA, 0x28, 0xD2, 0xF1, 0xAB, 0x14, 0x82,
49                 0x80, 0xCD, 0x9E, 0xD5, 0x6F, 0xED, 0xA4, 0x19,
50                 0x74, 0x05, 0x35, 0x54, 0xA4, 0x27, 0x67, 0xB8,
51                 0x3A, 0xD0, 0x43, 0xFD, 0x39, 0xDC, 0x04, 0x93,
52         }
53         s := []byte{
54                 0x01, 0x45, 0x6C, 0x64, 0xBA, 0x46, 0x42, 0xA1,
55                 0x65, 0x3C, 0x23, 0x5A, 0x98, 0xA6, 0x02, 0x49,
56                 0xBC, 0xD6, 0xD3, 0xF7, 0x46, 0xB6, 0x31, 0xDF,
57                 0x92, 0x80, 0x14, 0xF6, 0xC5, 0xBF, 0x9C, 0x40,
58         }
59         reverse(prvRaw)
60         prv, err := NewPrivateKey(CurveIdGostR34102001TestParamSet(), prvRaw)
61         if err != nil {
62                 t.FailNow()
63         }
64         sign, err := prv.SignDigest(dgst, bytes.NewBuffer(rnd))
65         if err != nil {
66                 t.FailNow()
67         }
68         if bytes.Compare(sign, append(s, r...)) != 0 {
69                 t.FailNow()
70         }
71 }
72
73 // Test vector from GOST R 34.10-2012 appendix
74 func TestStdVector2(t *testing.T) {
75         c, err := NewCurve(
76                 bytes2big([]byte{
77                         0x45, 0x31, 0xAC, 0xD1, 0xFE, 0x00, 0x23, 0xC7,
78                         0x55, 0x0D, 0x26, 0x7B, 0x6B, 0x2F, 0xEE, 0x80,
79                         0x92, 0x2B, 0x14, 0xB2, 0xFF, 0xB9, 0x0F, 0x04,
80                         0xD4, 0xEB, 0x7C, 0x09, 0xB5, 0xD2, 0xD1, 0x5D,
81                         0xF1, 0xD8, 0x52, 0x74, 0x1A, 0xF4, 0x70, 0x4A,
82                         0x04, 0x58, 0x04, 0x7E, 0x80, 0xE4, 0x54, 0x6D,
83                         0x35, 0xB8, 0x33, 0x6F, 0xAC, 0x22, 0x4D, 0xD8,
84                         0x16, 0x64, 0xBB, 0xF5, 0x28, 0xBE, 0x63, 0x73,
85                 }),
86                 bytes2big([]byte{
87                         0x45, 0x31, 0xAC, 0xD1, 0xFE, 0x00, 0x23, 0xC7,
88                         0x55, 0x0D, 0x26, 0x7B, 0x6B, 0x2F, 0xEE, 0x80,
89                         0x92, 0x2B, 0x14, 0xB2, 0xFF, 0xB9, 0x0F, 0x04,
90                         0xD4, 0xEB, 0x7C, 0x09, 0xB5, 0xD2, 0xD1, 0x5D,
91                         0xA8, 0x2F, 0x2D, 0x7E, 0xCB, 0x1D, 0xBA, 0xC7,
92                         0x19, 0x90, 0x5C, 0x5E, 0xEC, 0xC4, 0x23, 0xF1,
93                         0xD8, 0x6E, 0x25, 0xED, 0xBE, 0x23, 0xC5, 0x95,
94                         0xD6, 0x44, 0xAA, 0xF1, 0x87, 0xE6, 0xE6, 0xDF,
95                 }),
96                 big.NewInt(7),
97                 bytes2big([]byte{
98                         0x1C, 0xFF, 0x08, 0x06, 0xA3, 0x11, 0x16, 0xDA,
99                         0x29, 0xD8, 0xCF, 0xA5, 0x4E, 0x57, 0xEB, 0x74,
100                         0x8B, 0xC5, 0xF3, 0x77, 0xE4, 0x94, 0x00, 0xFD,
101                         0xD7, 0x88, 0xB6, 0x49, 0xEC, 0xA1, 0xAC, 0x43,
102                         0x61, 0x83, 0x40, 0x13, 0xB2, 0xAD, 0x73, 0x22,
103                         0x48, 0x0A, 0x89, 0xCA, 0x58, 0xE0, 0xCF, 0x74,
104                         0xBC, 0x9E, 0x54, 0x0C, 0x2A, 0xDD, 0x68, 0x97,
105                         0xFA, 0xD0, 0xA3, 0x08, 0x4F, 0x30, 0x2A, 0xDC,
106                 }),
107                 bytes2big([]byte{
108                         0x24, 0xD1, 0x9C, 0xC6, 0x45, 0x72, 0xEE, 0x30,
109                         0xF3, 0x96, 0xBF, 0x6E, 0xBB, 0xFD, 0x7A, 0x6C,
110                         0x52, 0x13, 0xB3, 0xB3, 0xD7, 0x05, 0x7C, 0xC8,
111                         0x25, 0xF9, 0x10, 0x93, 0xA6, 0x8C, 0xD7, 0x62,
112                         0xFD, 0x60, 0x61, 0x12, 0x62, 0xCD, 0x83, 0x8D,
113                         0xC6, 0xB6, 0x0A, 0xA7, 0xEE, 0xE8, 0x04, 0xE2,
114                         0x8B, 0xC8, 0x49, 0x97, 0x7F, 0xAC, 0x33, 0xB4,
115                         0xB5, 0x30, 0xF1, 0xB1, 0x20, 0x24, 0x8A, 0x9A,
116                 }),
117                 bytes2big([]byte{
118                         0x2B, 0xB3, 0x12, 0xA4, 0x3B, 0xD2, 0xCE, 0x6E,
119                         0x0D, 0x02, 0x06, 0x13, 0xC8, 0x57, 0xAC, 0xDD,
120                         0xCF, 0xBF, 0x06, 0x1E, 0x91, 0xE5, 0xF2, 0xC3,
121                         0xF3, 0x24, 0x47, 0xC2, 0x59, 0xF3, 0x9B, 0x2C,
122                         0x83, 0xAB, 0x15, 0x6D, 0x77, 0xF1, 0x49, 0x6B,
123                         0xF7, 0xEB, 0x33, 0x51, 0xE1, 0xEE, 0x4E, 0x43,
124                         0xDC, 0x1A, 0x18, 0xB9, 0x1B, 0x24, 0x64, 0x0B,
125                         0x6D, 0xBB, 0x92, 0xCB, 0x1A, 0xDD, 0x37, 0x1E,
126                 }),
127                 nil,
128                 nil,
129                 nil,
130         )
131         if err != nil {
132                 t.FailNow()
133         }
134         prvRaw := []byte{
135                 0x0B, 0xA6, 0x04, 0x8A, 0xAD, 0xAE, 0x24, 0x1B,
136                 0xA4, 0x09, 0x36, 0xD4, 0x77, 0x56, 0xD7, 0xC9,
137                 0x30, 0x91, 0xA0, 0xE8, 0x51, 0x46, 0x69, 0x70,
138                 0x0E, 0xE7, 0x50, 0x8E, 0x50, 0x8B, 0x10, 0x20,
139                 0x72, 0xE8, 0x12, 0x3B, 0x22, 0x00, 0xA0, 0x56,
140                 0x33, 0x22, 0xDA, 0xD2, 0x82, 0x7E, 0x27, 0x14,
141                 0xA2, 0x63, 0x6B, 0x7B, 0xFD, 0x18, 0xAA, 0xDF,
142                 0xC6, 0x29, 0x67, 0x82, 0x1F, 0xA1, 0x8D, 0xD4,
143         }
144         dgst := []byte{
145                 0x37, 0x54, 0xF3, 0xCF, 0xAC, 0xC9, 0xE0, 0x61,
146                 0x5C, 0x4F, 0x4A, 0x7C, 0x4D, 0x8D, 0xAB, 0x53,
147                 0x1B, 0x09, 0xB6, 0xF9, 0xC1, 0x70, 0xC5, 0x33,
148                 0xA7, 0x1D, 0x14, 0x70, 0x35, 0xB0, 0xC5, 0x91,
149                 0x71, 0x84, 0xEE, 0x53, 0x65, 0x93, 0xF4, 0x41,
150                 0x43, 0x39, 0x97, 0x6C, 0x64, 0x7C, 0x5D, 0x5A,
151                 0x40, 0x7A, 0xDE, 0xDB, 0x1D, 0x56, 0x0C, 0x4F,
152                 0xC6, 0x77, 0x7D, 0x29, 0x72, 0x07, 0x5B, 0x8C,
153         }
154         rnd := []byte{
155                 0x03, 0x59, 0xE7, 0xF4, 0xB1, 0x41, 0x0F, 0xEA,
156                 0xCC, 0x57, 0x04, 0x56, 0xC6, 0x80, 0x14, 0x96,
157                 0x94, 0x63, 0x12, 0x12, 0x0B, 0x39, 0xD0, 0x19,
158                 0xD4, 0x55, 0x98, 0x6E, 0x36, 0x4F, 0x36, 0x58,
159                 0x86, 0x74, 0x8E, 0xD7, 0xA4, 0x4B, 0x3E, 0x79,
160                 0x44, 0x34, 0x00, 0x60, 0x11, 0x84, 0x22, 0x86,
161                 0x21, 0x22, 0x73, 0xA6, 0xD1, 0x4C, 0xF7, 0x0E,
162                 0xA3, 0xAF, 0x71, 0xBB, 0x1A, 0xE6, 0x79, 0xF1,
163         }
164         r := []byte{
165                 0x2F, 0x86, 0xFA, 0x60, 0xA0, 0x81, 0x09, 0x1A,
166                 0x23, 0xDD, 0x79, 0x5E, 0x1E, 0x3C, 0x68, 0x9E,
167                 0xE5, 0x12, 0xA3, 0xC8, 0x2E, 0xE0, 0xDC, 0xC2,
168                 0x64, 0x3C, 0x78, 0xEE, 0xA8, 0xFC, 0xAC, 0xD3,
169                 0x54, 0x92, 0x55, 0x84, 0x86, 0xB2, 0x0F, 0x1C,
170                 0x9E, 0xC1, 0x97, 0xC9, 0x06, 0x99, 0x85, 0x02,
171                 0x60, 0xC9, 0x3B, 0xCB, 0xCD, 0x9C, 0x5C, 0x33,
172                 0x17, 0xE1, 0x93, 0x44, 0xE1, 0x73, 0xAE, 0x36,
173         }
174         s := []byte{
175                 0x10, 0x81, 0xB3, 0x94, 0x69, 0x6F, 0xFE, 0x8E,
176                 0x65, 0x85, 0xE7, 0xA9, 0x36, 0x2D, 0x26, 0xB6,
177                 0x32, 0x5F, 0x56, 0x77, 0x8A, 0xAD, 0xBC, 0x08,
178                 0x1C, 0x0B, 0xFB, 0xE9, 0x33, 0xD5, 0x2F, 0xF5,
179                 0x82, 0x3C, 0xE2, 0x88, 0xE8, 0xC4, 0xF3, 0x62,
180                 0x52, 0x60, 0x80, 0xDF, 0x7F, 0x70, 0xCE, 0x40,
181                 0x6A, 0x6E, 0xEB, 0x1F, 0x56, 0x91, 0x9C, 0xB9,
182                 0x2A, 0x98, 0x53, 0xBD, 0xE7, 0x3E, 0x5B, 0x4A,
183         }
184         reverse(prvRaw)
185         prv, err := NewPrivateKey(c, prvRaw)
186         if err != nil {
187                 t.FailNow()
188         }
189         sign, err := prv.SignDigest(dgst, bytes.NewBuffer(rnd))
190         if err != nil {
191                 t.FailNow()
192         }
193         if bytes.Compare(sign, append(s, r...)) != 0 {
194                 t.FailNow()
195         }
196 }
197
198 func TestGCL3Vectors(t *testing.T) {
199         p := []byte{
200                 0x45, 0x31, 0xAC, 0xD1, 0xFE, 0x00, 0x23, 0xC7,
201                 0x55, 0x0D, 0x26, 0x7B, 0x6B, 0x2F, 0xEE, 0x80,
202                 0x92, 0x2B, 0x14, 0xB2, 0xFF, 0xB9, 0x0F, 0x04,
203                 0xD4, 0xEB, 0x7C, 0x09, 0xB5, 0xD2, 0xD1, 0x5D,
204                 0xF1, 0xD8, 0x52, 0x74, 0x1A, 0xF4, 0x70, 0x4A,
205                 0x04, 0x58, 0x04, 0x7E, 0x80, 0xE4, 0x54, 0x6D,
206                 0x35, 0xB8, 0x33, 0x6F, 0xAC, 0x22, 0x4D, 0xD8,
207                 0x16, 0x64, 0xBB, 0xF5, 0x28, 0xBE, 0x63, 0x73,
208         }
209         q := []byte{
210                 0x45, 0x31, 0xAC, 0xD1, 0xFE, 0x00, 0x23, 0xC7,
211                 0x55, 0x0D, 0x26, 0x7B, 0x6B, 0x2F, 0xEE, 0x80,
212                 0x92, 0x2B, 0x14, 0xB2, 0xFF, 0xB9, 0x0F, 0x04,
213                 0xD4, 0xEB, 0x7C, 0x09, 0xB5, 0xD2, 0xD1, 0x5D,
214                 0xA8, 0x2F, 0x2D, 0x7E, 0xCB, 0x1D, 0xBA, 0xC7,
215                 0x19, 0x90, 0x5C, 0x5E, 0xEC, 0xC4, 0x23, 0xF1,
216                 0xD8, 0x6E, 0x25, 0xED, 0xBE, 0x23, 0xC5, 0x95,
217                 0xD6, 0x44, 0xAA, 0xF1, 0x87, 0xE6, 0xE6, 0xDF,
218         }
219         a := []byte{
220                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
222                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
223                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
224                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
226                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
228         }
229         b := []byte{
230                 0x1C, 0xFF, 0x08, 0x06, 0xA3, 0x11, 0x16, 0xDA,
231                 0x29, 0xD8, 0xCF, 0xA5, 0x4E, 0x57, 0xEB, 0x74,
232                 0x8B, 0xC5, 0xF3, 0x77, 0xE4, 0x94, 0x00, 0xFD,
233                 0xD7, 0x88, 0xB6, 0x49, 0xEC, 0xA1, 0xAC, 0x43,
234                 0x61, 0x83, 0x40, 0x13, 0xB2, 0xAD, 0x73, 0x22,
235                 0x48, 0x0A, 0x89, 0xCA, 0x58, 0xE0, 0xCF, 0x74,
236                 0xBC, 0x9E, 0x54, 0x0C, 0x2A, 0xDD, 0x68, 0x97,
237                 0xFA, 0xD0, 0xA3, 0x08, 0x4F, 0x30, 0x2A, 0xDC,
238         }
239         x := []byte{
240                 0x24, 0xD1, 0x9C, 0xC6, 0x45, 0x72, 0xEE, 0x30,
241                 0xF3, 0x96, 0xBF, 0x6E, 0xBB, 0xFD, 0x7A, 0x6C,
242                 0x52, 0x13, 0xB3, 0xB3, 0xD7, 0x05, 0x7C, 0xC8,
243                 0x25, 0xF9, 0x10, 0x93, 0xA6, 0x8C, 0xD7, 0x62,
244                 0xFD, 0x60, 0x61, 0x12, 0x62, 0xCD, 0x83, 0x8D,
245                 0xC6, 0xB6, 0x0A, 0xA7, 0xEE, 0xE8, 0x04, 0xE2,
246                 0x8B, 0xC8, 0x49, 0x97, 0x7F, 0xAC, 0x33, 0xB4,
247                 0xB5, 0x30, 0xF1, 0xB1, 0x20, 0x24, 0x8A, 0x9A,
248         }
249         y := []byte{
250                 0x2B, 0xB3, 0x12, 0xA4, 0x3B, 0xD2, 0xCE, 0x6E,
251                 0x0D, 0x02, 0x06, 0x13, 0xC8, 0x57, 0xAC, 0xDD,
252                 0xCF, 0xBF, 0x06, 0x1E, 0x91, 0xE5, 0xF2, 0xC3,
253                 0xF3, 0x24, 0x47, 0xC2, 0x59, 0xF3, 0x9B, 0x2C,
254                 0x83, 0xAB, 0x15, 0x6D, 0x77, 0xF1, 0x49, 0x6B,
255                 0xF7, 0xEB, 0x33, 0x51, 0xE1, 0xEE, 0x4E, 0x43,
256                 0xDC, 0x1A, 0x18, 0xB9, 0x1B, 0x24, 0x64, 0x0B,
257                 0x6D, 0xBB, 0x92, 0xCB, 0x1A, 0xDD, 0x37, 0x1E,
258         }
259         priv := []byte{
260                 0xD4, 0x8D, 0xA1, 0x1F, 0x82, 0x67, 0x29, 0xC6,
261                 0xDF, 0xAA, 0x18, 0xFD, 0x7B, 0x6B, 0x63, 0xA2,
262                 0x14, 0x27, 0x7E, 0x82, 0xD2, 0xDA, 0x22, 0x33,
263                 0x56, 0xA0, 0x00, 0x22, 0x3B, 0x12, 0xE8, 0x72,
264                 0x20, 0x10, 0x8B, 0x50, 0x8E, 0x50, 0xE7, 0x0E,
265                 0x70, 0x69, 0x46, 0x51, 0xE8, 0xA0, 0x91, 0x30,
266                 0xC9, 0xD7, 0x56, 0x77, 0xD4, 0x36, 0x09, 0xA4,
267                 0x1B, 0x24, 0xAE, 0xAD, 0x8A, 0x04, 0xA6, 0x0B,
268         }
269         pubX := []byte{
270                 0xE1, 0xEF, 0x30, 0xD5, 0x2C, 0x61, 0x33, 0xDD,
271                 0xD9, 0x9D, 0x1D, 0x5C, 0x41, 0x45, 0x5C, 0xF7,
272                 0xDF, 0x4D, 0x8B, 0x4C, 0x92, 0x5B, 0xBC, 0x69,
273                 0xAF, 0x14, 0x33, 0xD1, 0x56, 0x58, 0x51, 0x5A,
274                 0xDD, 0x21, 0x46, 0x85, 0x0C, 0x32, 0x5C, 0x5B,
275                 0x81, 0xC1, 0x33, 0xBE, 0x65, 0x5A, 0xA8, 0xC4,
276                 0xD4, 0x40, 0xE7, 0xB9, 0x8A, 0x8D, 0x59, 0x48,
277                 0x7B, 0x0C, 0x76, 0x96, 0xBC, 0xC5, 0x5D, 0x11,
278         }
279         pubY := []byte{
280                 0xEC, 0xBE, 0x77, 0x36, 0xA9, 0xEC, 0x35, 0x7F,
281                 0xF2, 0xFD, 0x39, 0x93, 0x1F, 0x4E, 0x11, 0x4C,
282                 0xB8, 0xCD, 0xA3, 0x59, 0x27, 0x0A, 0xC7, 0xF0,
283                 0xE7, 0xFF, 0x43, 0xD9, 0x41, 0x94, 0x19, 0xEA,
284                 0x61, 0xFD, 0x2A, 0xB7, 0x7F, 0x5D, 0x9F, 0x63,
285                 0x52, 0x3D, 0x3B, 0x50, 0xA0, 0x4F, 0x63, 0xE2,
286                 0xA0, 0xCF, 0x51, 0xB7, 0xC1, 0x3A, 0xDC, 0x21,
287                 0x56, 0x0F, 0x0B, 0xD4, 0x0C, 0xC9, 0xC7, 0x37,
288         }
289         digest := []byte{
290                 0x37, 0x54, 0xF3, 0xCF, 0xAC, 0xC9, 0xE0, 0x61,
291                 0x5C, 0x4F, 0x4A, 0x7C, 0x4D, 0x8D, 0xAB, 0x53,
292                 0x1B, 0x09, 0xB6, 0xF9, 0xC1, 0x70, 0xC5, 0x33,
293                 0xA7, 0x1D, 0x14, 0x70, 0x35, 0xB0, 0xC5, 0x91,
294                 0x71, 0x84, 0xEE, 0x53, 0x65, 0x93, 0xF4, 0x41,
295                 0x43, 0x39, 0x97, 0x6C, 0x64, 0x7C, 0x5D, 0x5A,
296                 0x40, 0x7A, 0xDE, 0xDB, 0x1D, 0x56, 0x0C, 0x4F,
297                 0xC6, 0x77, 0x7D, 0x29, 0x72, 0x07, 0x5B, 0x8C,
298         }
299         signature := []byte{
300                 0x10, 0x81, 0xB3, 0x94, 0x69, 0x6F, 0xFE, 0x8E,
301                 0x65, 0x85, 0xE7, 0xA9, 0x36, 0x2D, 0x26, 0xB6,
302                 0x32, 0x5F, 0x56, 0x77, 0x8A, 0xAD, 0xBC, 0x08,
303                 0x1C, 0x0B, 0xFB, 0xE9, 0x33, 0xD5, 0x2F, 0xF5,
304                 0x82, 0x3C, 0xE2, 0x88, 0xE8, 0xC4, 0xF3, 0x62,
305                 0x52, 0x60, 0x80, 0xDF, 0x7F, 0x70, 0xCE, 0x40,
306                 0x6A, 0x6E, 0xEB, 0x1F, 0x56, 0x91, 0x9C, 0xB9,
307                 0x2A, 0x98, 0x53, 0xBD, 0xE7, 0x3E, 0x5B, 0x4A,
308                 0x2F, 0x86, 0xFA, 0x60, 0xA0, 0x81, 0x09, 0x1A,
309                 0x23, 0xDD, 0x79, 0x5E, 0x1E, 0x3C, 0x68, 0x9E,
310                 0xE5, 0x12, 0xA3, 0xC8, 0x2E, 0xE0, 0xDC, 0xC2,
311                 0x64, 0x3C, 0x78, 0xEE, 0xA8, 0xFC, 0xAC, 0xD3,
312                 0x54, 0x92, 0x55, 0x84, 0x86, 0xB2, 0x0F, 0x1C,
313                 0x9E, 0xC1, 0x97, 0xC9, 0x06, 0x99, 0x85, 0x02,
314                 0x60, 0xC9, 0x3B, 0xCB, 0xCD, 0x9C, 0x5C, 0x33,
315                 0x17, 0xE1, 0x93, 0x44, 0xE1, 0x73, 0xAE, 0x36,
316         }
317         c, err := NewCurve(
318                 bytes2big(p),
319                 bytes2big(q),
320                 bytes2big(a),
321                 bytes2big(b),
322                 bytes2big(x),
323                 bytes2big(y),
324                 nil,
325                 nil,
326                 nil,
327         )
328         if err != nil {
329                 t.FailNow()
330         }
331         prv, err := NewPrivateKey(c, priv)
332         if err != nil {
333                 t.FailNow()
334         }
335         pub, err := prv.PublicKey()
336         if err != nil {
337                 t.FailNow()
338         }
339         if bytes.Compare(pub.Raw()[:64], pubX) != 0 {
340                 t.FailNow()
341         }
342         if bytes.Compare(pub.Raw()[64:], pubY) != 0 {
343                 t.FailNow()
344         }
345         ourSign, err := prv.SignDigest(digest, rand.Reader)
346         if err != nil {
347                 t.FailNow()
348         }
349         valid, err := pub.VerifyDigest(digest, ourSign)
350         if err != nil || !valid {
351                 t.FailNow()
352         }
353         valid, err = pub.VerifyDigest(digest, signature)
354         if err != nil || !valid {
355                 t.FailNow()
356         }
357 }
358
359 func TestRandom2012(t *testing.T) {
360         c := CurveIdtc26gost341012512paramSetA()
361         f := func(prvRaw [64 - 1]byte, digest [64]byte) bool {
362                 prv, err := NewPrivateKey(c, append([]byte{0xde}, prvRaw[:]...))
363                 if err != nil {
364                         return false
365                 }
366                 pub, err := prv.PublicKey()
367                 if err != nil {
368                         return false
369                 }
370                 pubRaw := pub.Raw()
371                 pub, err = NewPublicKey(c, pubRaw)
372                 if err != nil {
373                         return false
374                 }
375                 sign, err := prv.SignDigest(digest[:], rand.Reader)
376                 if err != nil {
377                         return false
378                 }
379                 valid, err := pub.VerifyDigest(digest[:], sign)
380                 if err != nil {
381                         return false
382                 }
383                 return valid
384         }
385         if err := quick.Check(f, nil); err != nil {
386                 t.Error(err)
387         }
388 }
389
390 // Test vectors from RFC 8133
391 func TestSESPAKE(t *testing.T) {
392         type vector struct {
393                 curve          *Curve
394                 qIndX          string
395                 qIndY          string
396                 fPW            string
397                 xExpected      string
398                 yExpected      string
399                 alpha          string
400                 xAlphaExpected string
401                 yAlphaExpected string
402                 beta           string
403                 xBetaExpected  string
404                 yBetaExpected  string
405         }
406         vectors := []vector{
407                 vector{
408                         curve:          CurveIdGostR34102001CryptoProAParamSet(),
409                         qIndX:          "A69D51CAF1A309FA9E9B66187759B0174C274E080356F23CFCBFE84D396AD7BB",
410                         qIndY:          "5D26F29ECC2E9AC0404DCF7986FA55FE94986362170F54B9616426A659786DAC",
411                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067",
412                         xExpected:      "59495655D1E7C7424C622485F575CCF121F3122D274101E8AB734CC9C9A9B45E",
413                         yExpected:      "48D1C311D33C9B701F3B03618562A4A07A044E3AF31E3999E67B487778B53C62",
414                         alpha:          "1F2538097D5A031FA68BBB43C84D12B3DE47B7061C0D5E24993E0C873CDBA6B3",
415                         xAlphaExpected: "BBC77CF42DC1E62D06227935379B4AA4D14FEA4F565DDF4CB4FA4D31579F9676",
416                         yAlphaExpected: "8E16604A4AFDF28246684D4996274781F6CB80ABBBA1414C1513EC988509DABF",
417                         beta:           "DC497D9EF6324912FD367840EE509A2032AEDB1C0A890D133B45F596FCCBD45D",
418                         xBetaExpected:  "6097341C1BE388E83E7CA2DF47FAB86E2271FD942E5B7B2EB2409E49F742BC29",
419                         yBetaExpected:  "C81AA48BDB4CA6FA0EF18B9788AE25FE30857AA681B3942217F9FED151BAB7D0",
420                 },
421                 vector{
422                         curve:          CurveIdGostR34102001CryptoProBParamSet(),
423                         qIndX:          "3D715A874A4B17CB3B517893A9794A2B36C89D2FFC693F01EE4CC27E7F49E399",
424                         qIndY:          "1C5A641FCF7CE7E87CDF8CEA38F3DB3096EACE2FAD158384B53953365F4FE7FE",
425                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067",
426                         xExpected:      "6DC2AE26BC691FCA5A73D9C452790D15E34BA5404D92955B914C8D2662ABB985",
427                         yExpected:      "3B02AAA9DD65AE30C335CED12F3154BBAC059F66B088306747453EDF6E5DB077",
428                         alpha:          "499D72B90299CAB0DA1F8BE19D9122F622A13B32B730C46BD0664044F2144FAD",
429                         xAlphaExpected: "61D6F916DB717222D74877F179F7EBEF7CD4D24D8C1F523C048E34A1DF30F8DD",
430                         yAlphaExpected: "3EC48863049CFCFE662904082E78503F4973A4E105E2F1B18C69A5E7FB209000",
431                         beta:           "0F69FF614957EF83668EDC2D7ED614BE76F7B253DB23C5CC9C52BF7DF8F4669D",
432                         xBetaExpected:  "33BC6F7E9C0BA10CFB2B72546C327171295508EA97F8C8BA9F890F2478AB4D6C",
433                         yBetaExpected:  "75D57B396C396F492F057E9222CCC686437A2AAD464E452EF426FC8EEED1A4A6",
434                 },
435                 vector{
436                         curve:          CurveIdGostR34102001CryptoProCParamSet(),
437                         qIndX:          "1E36383E43BB6CFA2917167D71B7B5DD3D6D462B43D7C64282AE67DFBEC2559D",
438                         qIndY:          "137478A9F721C73932EA06B45CF72E37EB78A63F29A542E563C614650C8B6399",
439                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067",
440                         xExpected:      "945821DAF91E158B839939630655A3B21FF3E146D27041E86C05650EB3B46B59",
441                         yExpected:      "3A0C2816AC97421FA0E879605F17F0C9C3EB734CFF196937F6284438D70BDC48",
442                         alpha:          "3A54AC3F19AD9D0B1EAC8ACDCEA70E581F1DAC33D13FEAFD81E762378639C1A8",
443                         xAlphaExpected: "96B7F09C94D297C257A7DA48364C0076E59E48D221CBA604AE111CA3933B446A",
444                         yAlphaExpected: "54E4953D86B77ECCEB578500931E822300F7E091F79592CA202A020D762C34A6",
445                         beta:           "448781782BF7C0E52A1DD9E6758FD3482D90D3CFCCF42232CF357E59A4D49FD4",
446                         xBetaExpected:  "4B9C0AB55A938121F282F48A2CC4396EB16E7E0068B495B0C1DD4667786A3EB7",
447                         yBetaExpected:  "223460AA8E09383E9DF9844C5A0F2766484738E5B30128A171B69A77D9509B96",
448                 },
449                 vector{
450                         curve:          CurveIdtc26gost341012512paramSetA(),
451                         qIndX:          "2A17F8833A32795327478871B5C5E88AEFB91126C64B4B8327289BEA62559425D18198F133F400874328B220C74497CD240586CB249E158532CB8090776CD61C",
452                         qIndY:          "728F0C4A73B48DA41CE928358FAD26B47A6E094E9362BAE82559F83CDDC4EC3A4676BD3707EDEAF4CD85E99695C64C241EDC622BE87DC0CF87F51F4367F723C5",
453                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F181270671C6213E3930EFDDA26451792C6208122EE60D200520D695DFD9F5F0FD5ABA702",
454                         xExpected:      "0C0AB53D0E0A9C607CAD758F558915A0A7DC5DC87B45E9A58FDDF30EC3385960283E030CD322D9E46B070637785FD49D2CD711F46807A24C40AF9A42C8E2D740",
455                         yExpected:      "DF93A8012B86D3A3D4F8A4D487DA15FC739EB31B20B3B0E8C8C032AAF8072C6337CF7D5B404719E5B4407C41D9A3216A08CA69C271484E9ED72B8AAA52E28B8B",
456                         alpha:          "3CE54325DB52FE798824AEAD11BB16FA766857D04A4AF7D468672F16D90E7396046A46F815693E85B1CE5464DA9270181F82333B0715057BBE8D61D400505F0E",
457                         xAlphaExpected: "B93093EB0FCC463239B7DF276E09E592FCFC9B635504EA4531655D76A0A3078E2B4E51CFE2FA400CC5DE9FBE369DB204B3E8ED7EDD85EE5CCA654C1AED70E396",
458                         yAlphaExpected: "809770B8D910EA30BD2FA89736E91DC31815D2D9B31128077EEDC371E9F69466F497DC64DD5B1FADC587F860EE256109138C4A9CD96B628E65A8F590520FC882",
459                         beta:           "B5C286A79AA8E97EC0E19BC1959A1D15F12F8C97870BA9D68CC12811A56A3BB11440610825796A49D468CDC9C2D02D76598A27973D5960C5F50BCE28D8D345F4",
460                         xBetaExpected:  "238B38644E440452A99FA6B93D9FD7DA0CB83C32D3C1E3CFE5DF5C3EB0F9DB91E588DAEDC849EA2FB867AE855A21B4077353C0794716A6480995113D8C20C7AF",
461                         yBetaExpected:  "B2273D5734C1897F8D15A7008B862938C8C74CA7E877423D95243EB7EBD02FD2C456CF9FC956F078A59AA86F19DD1075E5167E4ED35208718EA93161C530ED14",
462                 },
463                 vector{
464                         curve:          CurveIdtc26gost341012512paramSetB(),
465                         qIndX:          "7E1FAE8285E035BEC244BEF2D0E5EBF436633CF50E55231DEA9C9CF21D4C8C33DF85D4305DE92971F0A4B4C07E00D87BDBC720EB66E49079285AAF12E0171149",
466                         qIndY:          "2CC89998B875D4463805BA0D858A196592DB20AB161558FF2F4EF7A85725D20953967AE621AFDEAE89BB77C83A2528EF6FCE02F68BDA4679D7F2704947DBC408",
467                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F181270671C6213E3930EFDDA26451792C6208122EE60D200520D695DFD9F5F0FD5ABA702",
468                         xExpected:      "7D03E65B8050D1E12CBB601A17B9273B0E728F5021CD47C8A4DD822E4627BA5F9C696286A2CDDA9A065509866B4DEDEDC4A118409604AD549F87A60AFA621161",
469                         yExpected:      "16037DAD45421EC50B00D50BDC6AC3B85348BC1D3A2F85DB27C3373580FEF87C2C743B7ED30F22BE22958044E716F93A61CA3213A361A2797A16A3AE62957377",
470                         alpha:          "715E893FA639BF341296E0623E6D29DADF26B163C278767A7982A989462A3863FE12AEF8BD403D59C4DC4720570D4163DB0805C7C10C4E818F9CB785B04B9997",
471                         xAlphaExpected: "10C479EA1C04D3C2C02B0576A9C42D96226FF033C1191436777F66916030D87D02FB93738ED7669D07619FFCE7C1F3C4DB5E5DF49E2186D6FA1E2EB5767602B9",
472                         yAlphaExpected: "039F6044191404E707F26D59D979136A831CCE43E1C5F0600D1DDF8F39D0CA3D52FBD943BF04DDCED1AA2CE8F5EBD7487ACDEF239C07D015084D796784F35436",
473                         beta:           "30FA8C2B4146C2DBBE82BED04D7378877E8C06753BD0A0FF71EBF2BEFE8DA8F3DC0836468E2CE7C5C961281B6505140F8407413F03C2CB1D201EA1286CE30E6D",
474                         xBetaExpected:  "34C0149E7BB91AE377B02573FCC48AF7BFB7B16DEB8F9CE870F384688E3241A3A868588CC0EF4364CCA67D17E3260CD82485C202ADC76F895D5DF673B1788E67",
475                         yBetaExpected:  "608E944929BD643569ED5189DB871453F13333A1EAF82B2FE1BE8100E775F13DD9925BD317B63BFAF05024D4A738852332B64501195C1B2EF789E34F23DDAFC5",
476                 },
477                 vector{
478                         curve:          CurveIdtc26gost34102012256paramSetA(),
479                         qIndX:          "B51ADF93A40AB15792164FAD3352F95B66369EB2A4EF5EFAE32829320363350E",
480                         qIndY:          "74A358CC08593612F5955D249C96AFB7E8B0BB6D8BD2BBE491046650D822BE18",
481                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F18127067",
482                         xExpected:      "DBF99827078956812FA48C6E695DF589DEF1D18A2D4D35A96D75BF6854237629",
483                         yExpected:      "9FDDD48BFBC57BEE1DA0CFF282884F284D471B388893C48F5ECB02FC18D67589",
484                         alpha:          "147B72F6684FB8FD1B418A899F7DBECAF5FCE60B13685BAA95328654A7F0707F",
485                         xAlphaExpected: "33FBAC14EAE538275A769417829C431BD9FA622B6F02427EF55BD60EE6BC2888",
486                         yAlphaExpected: "22F2EBCF960A82E6CDB4042D3DDDA511B2FBA925383C2273D952EA2D406EAE46",
487                         beta:           "30D5CFADAA0E31B405E6734C03EC4C5DF0F02F4BA25C9A3B320EE6453567B4CB",
488                         xBetaExpected:  "2B2D89FAB735433970564F2F28CFA1B57D640CB902BC6334A538F44155022CB2",
489                         yBetaExpected:  "10EF6A82EEF1E70F942AA81D6B4CE5DEC0DDB9447512962874870E6F2849A96F",
490                 },
491                 vector{
492                         curve:          CurveIdtc26gost34102012512paramSetC(),
493                         qIndX:          "489C91784E02E98F19A803ABCA319917F37689E5A18965251CE2FF4E8D8B298F5BA7470F9E0E713487F96F4A8397B3D09A270C9D367EB5E0E6561ADEEB51581D",
494                         qIndY:          "684EA885ACA64EAF1B3FEE36C0852A3BE3BD8011B0EF18E203FF87028D6EB5DB2C144A0DCC71276542BFD72CA2A43FA4F4939DA66D9A60793C704A8C94E16F18",
495                         fPW:            "BD04673F7149B18E98155BD1E2724E71D0099AA25174F792D3326C6F181270671C6213E3930EFDDA26451792C6208122EE60D200520D695DFD9F5F0FD5ABA702",
496                         xExpected:      "0185AE6271A81BB7F236A955F7CAA26FB63849813C0287D96C83A15AE6B6A86467AB13B6D88CE8CD7DC2E5B97FF5F28FAC2C108F2A3CF3DB5515C9E6D7D210E8",
497                         yExpected:      "ED0220F92EF771A71C64ECC77986DB7C03D37B3E2AB3E83F32CE5E074A762EC08253C9E2102B87532661275C4B1D16D2789CDABC58ACFDF7318DE70AB64F09B8",
498                         alpha:          "332F930421D14CFE260042159F18E49FD5A54167E94108AD80B1DE60B13DE7999A34D611E63F3F870E5110247DF8EC7466E648ACF385E52CCB889ABF491EDFF0",
499                         xAlphaExpected: "561655966D52952E805574F4281F1ED3A2D498932B00CBA9DECB42837F09835BFFBFE2D84D6B6B242FE7B57F92E1A6F2413E12DDD6383E4437E13D72693469AD",
500                         yAlphaExpected: "F6B18328B2715BD7F4178615273A36135BC0BF62F7D8BB9F080164AD36470AD03660F51806C64C6691BADEF30F793720F8E3FEAED631D6A54A4C372DCBF80E82",
501                         beta:           "38481771E7D054F96212686B613881880BD8A6C89DDBC656178F014D2C093432A033EE10415F13A160D44C2AD61E6E2E05A7F7EC286BCEA3EA4D4D53F8634FA2",
502                         xBetaExpected:  "B7C5818687083433BC1AFF61CB5CA79E38232025E0C1F123B8651E62173CE6873F3E6FFE7281C2E45F4F524F66B0C263616ED08FD210AC4355CA3292B51D71C3",
503                         yBetaExpected:  "497F14205DBDC89BDDAF50520ED3B1429AD30777310186BE5E68070F016A44E0C766DB08E8AC23FBDFDE6D675AA4DF591EB18BA0D348DF7AA40973A2F1DCFA55",
504                 },
505         }
506         for _, vector := range vectors {
507                 raw, _ := hex.DecodeString(vector.qIndX)
508                 qIndX := bytes2big(raw)
509                 raw, _ = hex.DecodeString(vector.qIndY)
510                 qIndY := bytes2big(raw)
511                 raw, _ = hex.DecodeString(vector.fPW)
512                 reverse(raw)
513                 f := bytes2big(raw)
514                 x, y, err := vector.curve.Exp(f, qIndX, qIndY)
515                 if err != nil {
516                         t.FailNow()
517                 }
518                 raw, _ = hex.DecodeString(vector.xExpected)
519                 if bytes.Compare(x.Bytes(), raw) != 0 {
520                         t.FailNow()
521                 }
522                 raw, _ = hex.DecodeString(vector.yExpected)
523                 if bytes.Compare(y.Bytes(), raw) != 0 {
524                         t.FailNow()
525                 }
526
527                 raw, _ = hex.DecodeString(vector.alpha)
528                 alpha := bytes2big(raw)
529                 x, y, err = vector.curve.Exp(alpha, vector.curve.X, vector.curve.Y)
530                 raw, _ = hex.DecodeString(vector.xAlphaExpected)
531                 if bytes.Compare(x.Bytes(), raw) != 0 {
532                         t.FailNow()
533                 }
534                 raw, _ = hex.DecodeString(vector.yAlphaExpected)
535                 if bytes.Compare(y.Bytes(), raw) != 0 {
536                         t.FailNow()
537                 }
538
539                 raw, _ = hex.DecodeString(vector.beta)
540                 beta := bytes2big(raw)
541                 x, y, err = vector.curve.Exp(beta, vector.curve.X, vector.curve.Y)
542                 raw, _ = hex.DecodeString(vector.xBetaExpected)
543                 if bytes.Compare(x.Bytes(), raw) != 0 {
544                         t.FailNow()
545                 }
546                 raw, _ = hex.DecodeString(vector.yBetaExpected)
547                 if bytes.Compare(y.Bytes(), raw) != 0 {
548                         t.FailNow()
549                 }
550         }
551 }
552
553 // Twisted Edwards to Weierstrass coordinates conversion and vice versa
554 func TestUVXYConversion(t *testing.T) {
555         f := func(c *Curve, uRaw, vRaw []byte) {
556                 u := bytes2big(uRaw)
557                 v := bytes2big(vRaw)
558                 x, y := UV2XY(c, u, v)
559                 if x.Cmp(c.X) != 0 {
560                         t.FailNow()
561                 }
562                 if y.Cmp(c.Y) != 0 {
563                         t.FailNow()
564                 }
565                 uGot, vGot := XY2UV(c, c.X, c.Y)
566                 if u.Cmp(uGot) != 0 {
567                         t.FailNow()
568                 }
569                 if v.Cmp(vGot) != 0 {
570                         t.FailNow()
571                 }
572         }
573         raw, _ := hex.DecodeString("60CA1E32AA475B348488C38FAB07649CE7EF8DBE87F22E81F92B2592DBA300E7")
574         f(CurveIdtc26gost34102012256paramSetA(), []byte{0x0D}, raw)
575         raw, _ = hex.DecodeString("469AF79D1FB1F5E16B99592B77A01E2A0FDFB0D01794368D9A56117F7B38669522DD4B650CF789EEBF068C5D139732F0905622C04B2BAAE7600303EE73001A3D")
576         f(CurveIdtc26gost34102012512paramSetC(), []byte{0x12}, raw)
577 }
578
579 func BenchmarkSign2012(b *testing.B) {
580         c := CurveIdtc26gost341012512paramSetA()
581         prv, err := GenPrivateKey(c, rand.Reader)
582         if err != nil {
583                 b.FailNow()
584         }
585         digest := make([]byte, 64)
586         rand.Read(digest)
587         b.ResetTimer()
588         for i := 0; i < b.N; i++ {
589                 prv.SignDigest(digest, rand.Reader)
590         }
591 }
592
593 func BenchmarkVerify2012(b *testing.B) {
594         c := CurveIdtc26gost341012512paramSetA()
595         prv, err := GenPrivateKey(c, rand.Reader)
596         if err != nil {
597                 b.FailNow()
598         }
599         digest := make([]byte, 64)
600         rand.Read(digest)
601         sign, err := prv.SignDigest(digest, rand.Reader)
602         if err != nil {
603                 b.FailNow()
604         }
605         pub, err := prv.PublicKey()
606         if err != nil {
607                 b.FailNow()
608         }
609         b.ResetTimer()
610         for i := 0; i < b.N; i++ {
611                 pub.VerifyDigest(digest, sign)
612         }
613 }