xref: /openbsd-src/regress/lib/libcrypto/curve25519/ed25519test.c (revision d20a2f80d6c4d0bcee8d4e0093faa01ff0fddfed)
1 /*	$OpenBSD: ed25519test.c,v 1.10 2022/12/01 13:55:22 tb Exp $ */
2 /*
3  * Copyright (c) 2019, 2022 Theo Buehler <tb@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <err.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include <openssl/curve25519.h>
24 
25 struct testvector {
26 	const uint8_t sec_key[ED25519_PRIVATE_KEY_LENGTH];
27 	const uint8_t pub_key[ED25519_PUBLIC_KEY_LENGTH];
28 	const uint8_t signature[ED25519_SIGNATURE_LENGTH];
29 	const uint8_t message[1024];
30 	size_t message_len;
31 };
32 
33 /*
34  * Test vectors from https://tools.ietf.org/html/rfc8032#section-7.1.
35  */
36 static const struct testvector testvectors[] = {
37 	{
38 		.sec_key = {
39 			0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60,
40 			0xba, 0x84, 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4,
41 			0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32, 0x69, 0x19,
42 			0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60,
43 		},
44 		.pub_key = {
45 			0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7,
46 			0xd5, 0x4b, 0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a,
47 			0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23, 0x25,
48 			0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a,
49 		},
50 		.message = {
51 			0x0,	/* Windows has stupid compilers... */
52 		},
53 		.message_len = 0,
54 		.signature = {
55 			0xe5, 0x56, 0x43, 0x00, 0xc3, 0x60, 0xac, 0x72,
56 			0x90, 0x86, 0xe2, 0xcc, 0x80, 0x6e, 0x82, 0x8a,
57 			0x84, 0x87, 0x7f, 0x1e, 0xb8, 0xe5, 0xd9, 0x74,
58 			0xd8, 0x73, 0xe0, 0x65, 0x22, 0x49, 0x01, 0x55,
59 			0x5f, 0xb8, 0x82, 0x15, 0x90, 0xa3, 0x3b, 0xac,
60 			0xc6, 0x1e, 0x39, 0x70, 0x1c, 0xf9, 0xb4, 0x6b,
61 			0xd2, 0x5b, 0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24,
62 			0x65, 0x51, 0x41, 0x43, 0x8e, 0x7a, 0x10, 0x0b,
63 		},
64 	},
65 	{
66 		.sec_key = {
67 			0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda,
68 			0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e, 0x0f,
69 			0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24,
70 			0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8, 0xa6, 0xfb,
71 		},
72 		.pub_key =  {
73 			0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a,
74 			0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e, 0xbc,
75 			0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c,
76 			0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4, 0x66, 0x0c,
77 		},
78 		.message = {
79 			0x72,
80 		},
81 		.message_len = 1,
82 		.signature = {
83 			0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8,
84 			0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25, 0x40,
85 			0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f,
86 			0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb, 0x69, 0xda,
87 			0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e,
88 			0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c,
89 			0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee,
90 			0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00,
91 		},
92 	},
93 	{
94 		.sec_key = {
95 			0xc5, 0xaa, 0x8d, 0xf4, 0x3f, 0x9f, 0x83, 0x7b,
96 			0xed, 0xb7, 0x44, 0x2f, 0x31, 0xdc, 0xb7, 0xb1,
97 			0x66, 0xd3, 0x85, 0x35, 0x07, 0x6f, 0x09, 0x4b,
98 			0x85, 0xce, 0x3a, 0x2e, 0x0b, 0x44, 0x58, 0xf7,
99 		},
100 		.pub_key = {
101 			0xfc, 0x51, 0xcd, 0x8e, 0x62, 0x18, 0xa1, 0xa3,
102 			0x8d, 0xa4, 0x7e, 0xd0, 0x02, 0x30, 0xf0, 0x58,
103 			0x08, 0x16, 0xed, 0x13, 0xba, 0x33, 0x03, 0xac,
104 			0x5d, 0xeb, 0x91, 0x15, 0x48, 0x90, 0x80, 0x25,
105 		},
106 		.message = {
107 			0xaf, 0x82,
108 		},
109 		.message_len = 2,
110 		.signature = {
111 			0x62, 0x91, 0xd6, 0x57, 0xde, 0xec, 0x24, 0x02,
112 			0x48, 0x27, 0xe6, 0x9c, 0x3a, 0xbe, 0x01, 0xa3,
113 			0x0c, 0xe5, 0x48, 0xa2, 0x84, 0x74, 0x3a, 0x44,
114 			0x5e, 0x36, 0x80, 0xd7, 0xdb, 0x5a, 0xc3, 0xac,
115 			0x18, 0xff, 0x9b, 0x53, 0x8d, 0x16, 0xf2, 0x90,
116 			0xae, 0x67, 0xf7, 0x60, 0x98, 0x4d, 0xc6, 0x59,
117 			0x4a, 0x7c, 0x15, 0xe9, 0x71, 0x6e, 0xd2, 0x8d,
118 			0xc0, 0x27, 0xbe, 0xce, 0xea, 0x1e, 0xc4, 0x0a,
119 		},
120 	},
121 	{
122 		.sec_key = {
123 			0xf5, 0xe5, 0x76, 0x7c, 0xf1, 0x53, 0x31, 0x95,
124 			0x17, 0x63, 0x0f, 0x22, 0x68, 0x76, 0xb8, 0x6c,
125 			0x81, 0x60, 0xcc, 0x58, 0x3b, 0xc0, 0x13, 0x74,
126 			0x4c, 0x6b, 0xf2, 0x55, 0xf5, 0xcc, 0x0e, 0xe5,
127 		},
128 		.pub_key = {
129 			0x27, 0x81, 0x17, 0xfc, 0x14, 0x4c, 0x72, 0x34,
130 			0x0f, 0x67, 0xd0, 0xf2, 0x31, 0x6e, 0x83, 0x86,
131 			0xce, 0xff, 0xbf, 0x2b, 0x24, 0x28, 0xc9, 0xc5,
132 			0x1f, 0xef, 0x7c, 0x59, 0x7f, 0x1d, 0x42, 0x6e,
133 		},
134 		.message = {
135 			0x08, 0xb8, 0xb2, 0xb7, 0x33, 0x42, 0x42, 0x43,
136 			0x76, 0x0f, 0xe4, 0x26, 0xa4, 0xb5, 0x49, 0x08,
137 			0x63, 0x21, 0x10, 0xa6, 0x6c, 0x2f, 0x65, 0x91,
138 			0xea, 0xbd, 0x33, 0x45, 0xe3, 0xe4, 0xeb, 0x98,
139 			0xfa, 0x6e, 0x26, 0x4b, 0xf0, 0x9e, 0xfe, 0x12,
140 			0xee, 0x50, 0xf8, 0xf5, 0x4e, 0x9f, 0x77, 0xb1,
141 			0xe3, 0x55, 0xf6, 0xc5, 0x05, 0x44, 0xe2, 0x3f,
142 			0xb1, 0x43, 0x3d, 0xdf, 0x73, 0xbe, 0x84, 0xd8,
143 			0x79, 0xde, 0x7c, 0x00, 0x46, 0xdc, 0x49, 0x96,
144 			0xd9, 0xe7, 0x73, 0xf4, 0xbc, 0x9e, 0xfe, 0x57,
145 			0x38, 0x82, 0x9a, 0xdb, 0x26, 0xc8, 0x1b, 0x37,
146 			0xc9, 0x3a, 0x1b, 0x27, 0x0b, 0x20, 0x32, 0x9d,
147 			0x65, 0x86, 0x75, 0xfc, 0x6e, 0xa5, 0x34, 0xe0,
148 			0x81, 0x0a, 0x44, 0x32, 0x82, 0x6b, 0xf5, 0x8c,
149 			0x94, 0x1e, 0xfb, 0x65, 0xd5, 0x7a, 0x33, 0x8b,
150 			0xbd, 0x2e, 0x26, 0x64, 0x0f, 0x89, 0xff, 0xbc,
151 			0x1a, 0x85, 0x8e, 0xfc, 0xb8, 0x55, 0x0e, 0xe3,
152 			0xa5, 0xe1, 0x99, 0x8b, 0xd1, 0x77, 0xe9, 0x3a,
153 			0x73, 0x63, 0xc3, 0x44, 0xfe, 0x6b, 0x19, 0x9e,
154 			0xe5, 0xd0, 0x2e, 0x82, 0xd5, 0x22, 0xc4, 0xfe,
155 			0xba, 0x15, 0x45, 0x2f, 0x80, 0x28, 0x8a, 0x82,
156 			0x1a, 0x57, 0x91, 0x16, 0xec, 0x6d, 0xad, 0x2b,
157 			0x3b, 0x31, 0x0d, 0xa9, 0x03, 0x40, 0x1a, 0xa6,
158 			0x21, 0x00, 0xab, 0x5d, 0x1a, 0x36, 0x55, 0x3e,
159 			0x06, 0x20, 0x3b, 0x33, 0x89, 0x0c, 0xc9, 0xb8,
160 			0x32, 0xf7, 0x9e, 0xf8, 0x05, 0x60, 0xcc, 0xb9,
161 			0xa3, 0x9c, 0xe7, 0x67, 0x96, 0x7e, 0xd6, 0x28,
162 			0xc6, 0xad, 0x57, 0x3c, 0xb1, 0x16, 0xdb, 0xef,
163 			0xef, 0xd7, 0x54, 0x99, 0xda, 0x96, 0xbd, 0x68,
164 			0xa8, 0xa9, 0x7b, 0x92, 0x8a, 0x8b, 0xbc, 0x10,
165 			0x3b, 0x66, 0x21, 0xfc, 0xde, 0x2b, 0xec, 0xa1,
166 			0x23, 0x1d, 0x20, 0x6b, 0xe6, 0xcd, 0x9e, 0xc7,
167 			0xaf, 0xf6, 0xf6, 0xc9, 0x4f, 0xcd, 0x72, 0x04,
168 			0xed, 0x34, 0x55, 0xc6, 0x8c, 0x83, 0xf4, 0xa4,
169 			0x1d, 0xa4, 0xaf, 0x2b, 0x74, 0xef, 0x5c, 0x53,
170 			0xf1, 0xd8, 0xac, 0x70, 0xbd, 0xcb, 0x7e, 0xd1,
171 			0x85, 0xce, 0x81, 0xbd, 0x84, 0x35, 0x9d, 0x44,
172 			0x25, 0x4d, 0x95, 0x62, 0x9e, 0x98, 0x55, 0xa9,
173 			0x4a, 0x7c, 0x19, 0x58, 0xd1, 0xf8, 0xad, 0xa5,
174 			0xd0, 0x53, 0x2e, 0xd8, 0xa5, 0xaa, 0x3f, 0xb2,
175 			0xd1, 0x7b, 0xa7, 0x0e, 0xb6, 0x24, 0x8e, 0x59,
176 			0x4e, 0x1a, 0x22, 0x97, 0xac, 0xbb, 0xb3, 0x9d,
177 			0x50, 0x2f, 0x1a, 0x8c, 0x6e, 0xb6, 0xf1, 0xce,
178 			0x22, 0xb3, 0xde, 0x1a, 0x1f, 0x40, 0xcc, 0x24,
179 			0x55, 0x41, 0x19, 0xa8, 0x31, 0xa9, 0xaa, 0xd6,
180 			0x07, 0x9c, 0xad, 0x88, 0x42, 0x5d, 0xe6, 0xbd,
181 			0xe1, 0xa9, 0x18, 0x7e, 0xbb, 0x60, 0x92, 0xcf,
182 			0x67, 0xbf, 0x2b, 0x13, 0xfd, 0x65, 0xf2, 0x70,
183 			0x88, 0xd7, 0x8b, 0x7e, 0x88, 0x3c, 0x87, 0x59,
184 			0xd2, 0xc4, 0xf5, 0xc6, 0x5a, 0xdb, 0x75, 0x53,
185 			0x87, 0x8a, 0xd5, 0x75, 0xf9, 0xfa, 0xd8, 0x78,
186 			0xe8, 0x0a, 0x0c, 0x9b, 0xa6, 0x3b, 0xcb, 0xcc,
187 			0x27, 0x32, 0xe6, 0x94, 0x85, 0xbb, 0xc9, 0xc9,
188 			0x0b, 0xfb, 0xd6, 0x24, 0x81, 0xd9, 0x08, 0x9b,
189 			0xec, 0xcf, 0x80, 0xcf, 0xe2, 0xdf, 0x16, 0xa2,
190 			0xcf, 0x65, 0xbd, 0x92, 0xdd, 0x59, 0x7b, 0x07,
191 			0x07, 0xe0, 0x91, 0x7a, 0xf4, 0x8b, 0xbb, 0x75,
192 			0xfe, 0xd4, 0x13, 0xd2, 0x38, 0xf5, 0x55, 0x5a,
193 			0x7a, 0x56, 0x9d, 0x80, 0xc3, 0x41, 0x4a, 0x8d,
194 			0x08, 0x59, 0xdc, 0x65, 0xa4, 0x61, 0x28, 0xba,
195 			0xb2, 0x7a, 0xf8, 0x7a, 0x71, 0x31, 0x4f, 0x31,
196 			0x8c, 0x78, 0x2b, 0x23, 0xeb, 0xfe, 0x80, 0x8b,
197 			0x82, 0xb0, 0xce, 0x26, 0x40, 0x1d, 0x2e, 0x22,
198 			0xf0, 0x4d, 0x83, 0xd1, 0x25, 0x5d, 0xc5, 0x1a,
199 			0xdd, 0xd3, 0xb7, 0x5a, 0x2b, 0x1a, 0xe0, 0x78,
200 			0x45, 0x04, 0xdf, 0x54, 0x3a, 0xf8, 0x96, 0x9b,
201 			0xe3, 0xea, 0x70, 0x82, 0xff, 0x7f, 0xc9, 0x88,
202 			0x8c, 0x14, 0x4d, 0xa2, 0xaf, 0x58, 0x42, 0x9e,
203 			0xc9, 0x60, 0x31, 0xdb, 0xca, 0xd3, 0xda, 0xd9,
204 			0xaf, 0x0d, 0xcb, 0xaa, 0xaf, 0x26, 0x8c, 0xb8,
205 			0xfc, 0xff, 0xea, 0xd9, 0x4f, 0x3c, 0x7c, 0xa4,
206 			0x95, 0xe0, 0x56, 0xa9, 0xb4, 0x7a, 0xcd, 0xb7,
207 			0x51, 0xfb, 0x73, 0xe6, 0x66, 0xc6, 0xc6, 0x55,
208 			0xad, 0xe8, 0x29, 0x72, 0x97, 0xd0, 0x7a, 0xd1,
209 			0xba, 0x5e, 0x43, 0xf1, 0xbc, 0xa3, 0x23, 0x01,
210 			0x65, 0x13, 0x39, 0xe2, 0x29, 0x04, 0xcc, 0x8c,
211 			0x42, 0xf5, 0x8c, 0x30, 0xc0, 0x4a, 0xaf, 0xdb,
212 			0x03, 0x8d, 0xda, 0x08, 0x47, 0xdd, 0x98, 0x8d,
213 			0xcd, 0xa6, 0xf3, 0xbf, 0xd1, 0x5c, 0x4b, 0x4c,
214 			0x45, 0x25, 0x00, 0x4a, 0xa0, 0x6e, 0xef, 0xf8,
215 			0xca, 0x61, 0x78, 0x3a, 0xac, 0xec, 0x57, 0xfb,
216 			0x3d, 0x1f, 0x92, 0xb0, 0xfe, 0x2f, 0xd1, 0xa8,
217 			0x5f, 0x67, 0x24, 0x51, 0x7b, 0x65, 0xe6, 0x14,
218 			0xad, 0x68, 0x08, 0xd6, 0xf6, 0xee, 0x34, 0xdf,
219 			0xf7, 0x31, 0x0f, 0xdc, 0x82, 0xae, 0xbf, 0xd9,
220 			0x04, 0xb0, 0x1e, 0x1d, 0xc5, 0x4b, 0x29, 0x27,
221 			0x09, 0x4b, 0x2d, 0xb6, 0x8d, 0x6f, 0x90, 0x3b,
222 			0x68, 0x40, 0x1a, 0xde, 0xbf, 0x5a, 0x7e, 0x08,
223 			0xd7, 0x8f, 0xf4, 0xef, 0x5d, 0x63, 0x65, 0x3a,
224 			0x65, 0x04, 0x0c, 0xf9, 0xbf, 0xd4, 0xac, 0xa7,
225 			0x98, 0x4a, 0x74, 0xd3, 0x71, 0x45, 0x98, 0x67,
226 			0x80, 0xfc, 0x0b, 0x16, 0xac, 0x45, 0x16, 0x49,
227 			0xde, 0x61, 0x88, 0xa7, 0xdb, 0xdf, 0x19, 0x1f,
228 			0x64, 0xb5, 0xfc, 0x5e, 0x2a, 0xb4, 0x7b, 0x57,
229 			0xf7, 0xf7, 0x27, 0x6c, 0xd4, 0x19, 0xc1, 0x7a,
230 			0x3c, 0xa8, 0xe1, 0xb9, 0x39, 0xae, 0x49, 0xe4,
231 			0x88, 0xac, 0xba, 0x6b, 0x96, 0x56, 0x10, 0xb5,
232 			0x48, 0x01, 0x09, 0xc8, 0xb1, 0x7b, 0x80, 0xe1,
233 			0xb7, 0xb7, 0x50, 0xdf, 0xc7, 0x59, 0x8d, 0x5d,
234 			0x50, 0x11, 0xfd, 0x2d, 0xcc, 0x56, 0x00, 0xa3,
235 			0x2e, 0xf5, 0xb5, 0x2a, 0x1e, 0xcc, 0x82, 0x0e,
236 			0x30, 0x8a, 0xa3, 0x42, 0x72, 0x1a, 0xac, 0x09,
237 			0x43, 0xbf, 0x66, 0x86, 0xb6, 0x4b, 0x25, 0x79,
238 			0x37, 0x65, 0x04, 0xcc, 0xc4, 0x93, 0xd9, 0x7e,
239 			0x6a, 0xed, 0x3f, 0xb0, 0xf9, 0xcd, 0x71, 0xa4,
240 			0x3d, 0xd4, 0x97, 0xf0, 0x1f, 0x17, 0xc0, 0xe2,
241 			0xcb, 0x37, 0x97, 0xaa, 0x2a, 0x2f, 0x25, 0x66,
242 			0x56, 0x16, 0x8e, 0x6c, 0x49, 0x6a, 0xfc, 0x5f,
243 			0xb9, 0x32, 0x46, 0xf6, 0xb1, 0x11, 0x63, 0x98,
244 			0xa3, 0x46, 0xf1, 0xa6, 0x41, 0xf3, 0xb0, 0x41,
245 			0xe9, 0x89, 0xf7, 0x91, 0x4f, 0x90, 0xcc, 0x2c,
246 			0x7f, 0xff, 0x35, 0x78, 0x76, 0xe5, 0x06, 0xb5,
247 			0x0d, 0x33, 0x4b, 0xa7, 0x7c, 0x22, 0x5b, 0xc3,
248 			0x07, 0xba, 0x53, 0x71, 0x52, 0xf3, 0xf1, 0x61,
249 			0x0e, 0x4e, 0xaf, 0xe5, 0x95, 0xf6, 0xd9, 0xd9,
250 			0x0d, 0x11, 0xfa, 0xa9, 0x33, 0xa1, 0x5e, 0xf1,
251 			0x36, 0x95, 0x46, 0x86, 0x8a, 0x7f, 0x3a, 0x45,
252 			0xa9, 0x67, 0x68, 0xd4, 0x0f, 0xd9, 0xd0, 0x34,
253 			0x12, 0xc0, 0x91, 0xc6, 0x31, 0x5c, 0xf4, 0xfd,
254 			0xe7, 0xcb, 0x68, 0x60, 0x69, 0x37, 0x38, 0x0d,
255 			0xb2, 0xea, 0xaa, 0x70, 0x7b, 0x4c, 0x41, 0x85,
256 			0xc3, 0x2e, 0xdd, 0xcd, 0xd3, 0x06, 0x70, 0x5e,
257 			0x4d, 0xc1, 0xff, 0xc8, 0x72, 0xee, 0xee, 0x47,
258 			0x5a, 0x64, 0xdf, 0xac, 0x86, 0xab, 0xa4, 0x1c,
259 			0x06, 0x18, 0x98, 0x3f, 0x87, 0x41, 0xc5, 0xef,
260 			0x68, 0xd3, 0xa1, 0x01, 0xe8, 0xa3, 0xb8, 0xca,
261 			0xc6, 0x0c, 0x90, 0x5c, 0x15, 0xfc, 0x91, 0x08,
262 			0x40, 0xb9, 0x4c, 0x00, 0xa0, 0xb9, 0xd0,
263 		},
264 		.message_len = 1023,
265 		.signature = {
266 			0x0a, 0xab, 0x4c, 0x90, 0x05, 0x01, 0xb3, 0xe2,
267 			0x4d, 0x7c, 0xdf, 0x46, 0x63, 0x32, 0x6a, 0x3a,
268 			0x87, 0xdf, 0x5e, 0x48, 0x43, 0xb2, 0xcb, 0xdb,
269 			0x67, 0xcb, 0xf6, 0xe4, 0x60, 0xfe, 0xc3, 0x50,
270 			0xaa, 0x53, 0x71, 0xb1, 0x50, 0x8f, 0x9f, 0x45,
271 			0x28, 0xec, 0xea, 0x23, 0xc4, 0x36, 0xd9, 0x4b,
272 			0x5e, 0x8f, 0xcd, 0x4f, 0x68, 0x1e, 0x30, 0xa6,
273 			0xac, 0x00, 0xa9, 0x70, 0x4a, 0x18, 0x8a, 0x03,
274 		},
275 	},
276 	{
277 		.sec_key = {
278 			0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
279 			0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
280 			0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
281 			0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42,
282 		},
283 		.pub_key = {
284 			0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
285 			0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
286 			0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
287 			0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf,
288 		},
289 		.message = {
290 			0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
291 			0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
292 			0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
293 			0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
294 			0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
295 			0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
296 			0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
297 			0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f,
298 		},
299 		.message_len = 64,
300 		.signature = {
301 			0xdc, 0x2a, 0x44, 0x59, 0xe7, 0x36, 0x96, 0x33,
302 			0xa5, 0x2b, 0x1b, 0xf2, 0x77, 0x83, 0x9a, 0x00,
303 			0x20, 0x10, 0x09, 0xa3, 0xef, 0xbf, 0x3e, 0xcb,
304 			0x69, 0xbe, 0xa2, 0x18, 0x6c, 0x26, 0xb5, 0x89,
305 			0x09, 0x35, 0x1f, 0xc9, 0xac, 0x90, 0xb3, 0xec,
306 			0xfd, 0xfb, 0xc7, 0xc6, 0x64, 0x31, 0xe0, 0x30,
307 			0x3d, 0xca, 0x17, 0x9c, 0x13, 0x8a, 0xc1, 0x7a,
308 			0xd9, 0xbe, 0xf1, 0x17, 0x73, 0x31, 0xa7, 0x04,
309 		},
310 	},
311 };
312 
313 const size_t num_testvectors = sizeof(testvectors) / sizeof(testvectors[0]);
314 
315 static int
test_ED25519_verify(void)316 test_ED25519_verify(void)
317 {
318 	size_t i;
319 	int failed = 0;
320 
321 	for (i = 0; i < num_testvectors; i++) {
322 		const struct testvector *tc = &testvectors[i];
323 
324 		if (!ED25519_verify(tc->message, tc->message_len, tc->signature,
325 		    tc->pub_key)) {
326 			warnx("failed verification in test case %zu", i);
327 			failed = 1;
328 		}
329 	}
330 
331 	return failed;
332 }
333 
334 static int
test_ED25519_sign(void)335 test_ED25519_sign(void)
336 {
337 	size_t i;
338 	int failed = 0;
339 
340 	for (i = 0; i < num_testvectors; i++) {
341 		const struct testvector *tc = &testvectors[i];
342 		uint8_t signature[64];
343 
344 		if (!ED25519_sign(signature, tc->message, tc->message_len,
345 		    tc->pub_key, tc->sec_key)) {
346 			warnx("failed signature in test case %zu", i);
347 			failed = 1;
348 		}
349 
350 		if (memcmp(tc->signature, signature, sizeof signature) != 0) {
351 			warnx("signature mismatch in test case %zu", i);
352 			failed = 1;
353 		}
354 	}
355 
356 	return failed;
357 }
358 
359 static void
hexdump(const unsigned char * buf,size_t len)360 hexdump(const unsigned char *buf, size_t len)
361 {
362 	size_t i;
363 
364 	for (i = 1; i <= len; i++)
365 		fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
366 
367 	if (len % 8)
368 		fprintf(stderr, "\n");
369 }
370 
371 static void
dump_info(const uint8_t * message,size_t message_len,const uint8_t * public_key,const uint8_t * private_key,const uint8_t * signature)372 dump_info(const uint8_t *message, size_t message_len, const uint8_t *public_key,
373     const uint8_t *private_key, const uint8_t *signature)
374 {
375 
376 	fprintf(stderr, "message:\n");
377 	hexdump(message, message_len);
378 
379 	fprintf(stderr, "public key:\n");
380 	hexdump(public_key, ED25519_PUBLIC_KEY_LENGTH);
381 	fprintf(stderr, "private key:\n");
382 	hexdump(private_key, ED25519_PRIVATE_KEY_LENGTH);
383 
384 	if (signature != NULL) {
385 		fprintf(stderr, "signature:\n");
386 		hexdump(signature, ED25519_SIGNATURE_LENGTH);
387 	}
388 }
389 
390 /*
391  * Little-endian representation of the order of edwards25519,
392  * see https://www.rfc-editor.org/rfc/rfc7748#section-4.1
393  */
394 static const uint8_t order[] = {
395 	0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
396 	0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
397 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
399 };
400 
401 /*
402  * Modify signature by adding the group order to the upper half of the
403  * signature. This is caught by the check added in curve25519.c r1.14.
404  */
405 static void
modify_signature(uint8_t * signature)406 modify_signature(uint8_t *signature)
407 {
408 	uint16_t sum;
409 	uint8_t *upper_half = &signature[32];
410 	uint16_t carry = 0;
411 	size_t i;
412 
413 	for (i = 0; i < sizeof(order); i++) {
414 		sum = carry + order[i] + upper_half[i];
415 		carry = (sum > 0xff);
416 		upper_half[i] = sum & 0xff;
417 	}
418 
419 	/* carry == 0 since 0 <= upper_half < order and 2 * order < 2^256. */
420 }
421 
422 static int
test_ED25519_signature_malleability(void)423 test_ED25519_signature_malleability(void)
424 {
425 	uint8_t public_key[ED25519_PUBLIC_KEY_LENGTH];
426 	uint8_t private_key[ED25519_PRIVATE_KEY_LENGTH];
427 	uint8_t message[32];
428 	uint8_t signature[ED25519_SIGNATURE_LENGTH];
429 	int failed = 1;
430 
431 	ED25519_keypair(public_key, private_key);
432 	arc4random_buf(message, sizeof(message));
433 
434 	if (!ED25519_sign(signature, message, sizeof(message),
435 	    public_key, private_key)) {
436 		fprintf(stderr, "Failed to sign random message\n");
437 		dump_info(message, sizeof(message), public_key, private_key,
438 		    NULL);
439 		goto err;
440 	}
441 
442 	if (!ED25519_verify(message, sizeof(message), signature, public_key)) {
443 		fprintf(stderr, "Failed to verify random message\n");
444 		dump_info(message, sizeof(message), public_key, private_key,
445 		    signature);
446 		goto err;
447 	}
448 
449 	modify_signature(signature);
450 
451 	if (ED25519_verify(message, sizeof(message), signature, public_key)) {
452 		fprintf(stderr, "Verified with modified signature\n");
453 		dump_info(message, sizeof(message), public_key, private_key,
454 		    signature);
455 		goto err;
456 	}
457 
458 	failed = 0;
459 
460  err:
461 	return failed;
462 }
463 
464 int
main(int argc,char * argv[])465 main(int argc, char *argv[])
466 {
467 	int failed = 0;
468 
469 	failed |= test_ED25519_verify();
470 	failed |= test_ED25519_sign();
471 	failed |= test_ED25519_signature_malleability();
472 
473 	return failed;
474 }
475