1 #define TEST_NAME "core_ed25519"
2 #include "cmptest.h"
3
4 static const unsigned char non_canonical_p[32] = {
5 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
6 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
7 };
8 static const unsigned char non_canonical_invalid_p[32] = {
9 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
10 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
11 };
12 static const unsigned char max_canonical_p[32] = {
13 0xe4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
14 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
15 };
16
17 static void
add_P(unsigned char * const S)18 add_P(unsigned char * const S)
19 {
20 static const unsigned char P[32] = {
21 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
22 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
23 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
24 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
25 };
26
27 sodium_add(S, P, sizeof P);
28 }
29
30 static void
add_l64(unsigned char * const S)31 add_l64(unsigned char * const S)
32 {
33 static const unsigned char l[crypto_core_ed25519_NONREDUCEDSCALARBYTES] =
34 { 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
35 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
36 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
40
41 sodium_add(S, l, sizeof l);
42 }
43
44 int
main(void)45 main(void)
46 {
47 unsigned char *h, *r;
48 unsigned char *p, *p2, *p3;
49 unsigned char *sc, *sc2, *sc3;
50 unsigned char *sc64;
51 char *hex;
52 unsigned int i, j;
53
54 h = (unsigned char *) sodium_malloc(crypto_core_ed25519_HASHBYTES);
55 r = (unsigned char *) sodium_malloc(crypto_core_ed25519_UNIFORMBYTES);
56 p = (unsigned char *) sodium_malloc(crypto_core_ed25519_BYTES);
57 for (i = 0; i < 500; i++) {
58 randombytes_buf(r, crypto_core_ed25519_UNIFORMBYTES);
59 if (crypto_core_ed25519_from_uniform(p, r) != 0) {
60 printf("crypto_core_ed25519_from_uniform() failed\n");
61 }
62 if (crypto_core_ed25519_is_valid_point(p) == 0) {
63 printf("crypto_core_ed25519_from_uniform() returned an invalid point\n");
64 }
65
66 randombytes_buf(h, crypto_core_ed25519_HASHBYTES);
67 if (crypto_core_ed25519_from_hash(p, h) != 0) {
68 printf("crypto_core_ed25519_from_hash() failed\n");
69 }
70 if (crypto_core_ed25519_is_valid_point(p) == 0) {
71 printf("crypto_core_ed25519_from_hash() returned an invalid point\n");
72 }
73
74 crypto_core_ed25519_random(p);
75 if (crypto_core_ed25519_is_valid_point(p) == 0) {
76 printf("crypto_core_ed25519_random() returned an invalid point\n");
77 }
78 }
79
80 p2 = (unsigned char *) sodium_malloc(crypto_core_ed25519_BYTES);
81 p3 = (unsigned char *) sodium_malloc(crypto_core_ed25519_BYTES);
82
83 crypto_core_ed25519_random(p2);
84
85 j = 1 + (unsigned int) randombytes_uniform(100);
86 memcpy(p3, p, crypto_core_ed25519_BYTES);
87 for (i = 0; i < j; i++) {
88 crypto_core_ed25519_add(p, p, p2);
89 if (crypto_core_ed25519_is_valid_point(p) != 1) {
90 printf("crypto_core_add() returned an invalid point\n");
91 }
92 }
93 if (memcmp(p, p3, crypto_core_ed25519_BYTES) == 0) {
94 printf("crypto_core_add() failed\n");
95 }
96 for (i = 0; i < j; i++) {
97 crypto_core_ed25519_sub(p, p, p2);
98 }
99 if (memcmp(p, p3, crypto_core_ed25519_BYTES) != 0) {
100 printf("crypto_core_add() or crypto_core_sub() failed\n");
101 }
102 sc = (unsigned char *) sodium_malloc(crypto_scalarmult_ed25519_SCALARBYTES);
103 memset(sc, 0, crypto_scalarmult_ed25519_SCALARBYTES);
104 sc[0] = 8;
105 memcpy(p2, p, crypto_core_ed25519_BYTES);
106 memcpy(p3, p, crypto_core_ed25519_BYTES);
107
108 for (i = 0; i < 254; i++) {
109 crypto_core_ed25519_add(p2, p2, p2);
110 }
111 for (i = 0; i < 8; i++) {
112 crypto_core_ed25519_add(p2, p2, p);
113 }
114 if (crypto_scalarmult_ed25519(p3, sc, p) != 0) {
115 printf("crypto_scalarmult_ed25519() failed\n");
116 }
117 if (memcmp(p2, p3, crypto_core_ed25519_BYTES) != 0) {
118 printf("crypto_scalarmult_ed25519() is inconsistent with crypto_core_ed25519_add()\n");
119 }
120
121 assert(crypto_core_ed25519_is_valid_point(p) == 1);
122
123 memset(p, 0, crypto_core_ed25519_BYTES);
124 assert(crypto_core_ed25519_is_valid_point(p) == 0);
125
126 p[0] = 1;
127 assert(crypto_core_ed25519_is_valid_point(p) == 0);
128
129 p[0] = 2;
130 assert(crypto_core_ed25519_is_valid_point(p) == 0);
131
132 p[0] = 9;
133 assert(crypto_core_ed25519_is_valid_point(p) == 1);
134
135 assert(crypto_core_ed25519_is_valid_point(max_canonical_p) == 1);
136 assert(crypto_core_ed25519_is_valid_point(non_canonical_invalid_p) == 0);
137 assert(crypto_core_ed25519_is_valid_point(non_canonical_p) == 0);
138
139 memcpy(p2, p, crypto_core_ed25519_BYTES);
140 add_P(p2);
141 crypto_core_ed25519_add(p3, p2, p2);
142 crypto_core_ed25519_sub(p3, p3, p2);
143 assert(memcmp(p2, p, crypto_core_ed25519_BYTES) != 0);
144 assert(memcmp(p3, p, crypto_core_ed25519_BYTES) == 0);
145
146 p[0] = 2;
147 assert(crypto_core_ed25519_add(p3, p2, p) == -1);
148 assert(crypto_core_ed25519_add(p3, p2, non_canonical_p) == 0);
149 assert(crypto_core_ed25519_add(p3, p2, non_canonical_invalid_p) == -1);
150 assert(crypto_core_ed25519_add(p3, p, p3) == -1);
151 assert(crypto_core_ed25519_add(p3, non_canonical_p, p3) == 0);
152 assert(crypto_core_ed25519_add(p3, non_canonical_invalid_p, p3) == -1);
153
154 assert(crypto_core_ed25519_sub(p3, p2, p) == -1);
155 assert(crypto_core_ed25519_sub(p3, p2, non_canonical_p) == 0);
156 assert(crypto_core_ed25519_sub(p3, p2, non_canonical_invalid_p) == -1);
157 assert(crypto_core_ed25519_sub(p3, p, p3) == -1);
158 assert(crypto_core_ed25519_sub(p3, non_canonical_p, p3) == 0);
159 assert(crypto_core_ed25519_sub(p3, non_canonical_invalid_p, p3) == -1);
160
161 for (i = 0; i < 1000; i++) {
162 crypto_core_ed25519_random(p);
163 do {
164 crypto_core_ed25519_scalar_random(sc);
165 } while (sodium_is_zero(sc, crypto_core_ed25519_SCALARBYTES));
166 if (crypto_scalarmult_ed25519_noclamp(p2, sc, p) != 0) {
167 printf("crypto_scalarmult_ed25519_noclamp() failed\n");
168 }
169 assert(crypto_core_ed25519_is_valid_point(p2));
170 if (crypto_core_ed25519_scalar_invert(sc, sc) != 0) {
171 printf("crypto_core_ed25519_scalar_invert() failed\n");
172 }
173 if (crypto_scalarmult_ed25519_noclamp(p3, sc, p2) != 0) {
174 printf("crypto_scalarmult_ed25519_noclamp() failed\n");
175 }
176 assert(memcmp(p3, p, crypto_core_ed25519_BYTES) == 0);
177 }
178
179 sc64 = (unsigned char *) sodium_malloc(64);
180 crypto_core_ed25519_scalar_random(sc);
181 memcpy(sc64, sc, crypto_core_ed25519_BYTES);
182 memset(sc64 + crypto_core_ed25519_BYTES, 0,
183 64 - crypto_core_ed25519_BYTES);
184 i = (unsigned int) randombytes_uniform(100);
185 do {
186 add_l64(sc64);
187 } while (i-- > 0);
188 crypto_core_ed25519_scalar_reduce(sc64, sc64);
189 if (memcmp(sc64, sc, crypto_core_ed25519_BYTES) != 0) {
190 printf("crypto_core_ed25519_scalar_reduce() failed\n");
191 }
192
193 randombytes_buf(r, crypto_core_ed25519_UNIFORMBYTES);
194 crypto_core_ed25519_from_uniform(p, r);
195 memcpy(p2, p, crypto_core_ed25519_BYTES);
196 crypto_core_ed25519_scalar_random(sc);
197 if (crypto_scalarmult_ed25519_noclamp(p, sc, p) != 0) {
198 printf("crypto_scalarmult_ed25519_noclamp() failed (1)\n");
199 }
200 crypto_core_ed25519_scalar_complement(sc, sc);
201 if (crypto_scalarmult_ed25519_noclamp(p2, sc, p2) != 0) {
202 printf("crypto_scalarmult_ed25519_noclamp() failed (2)\n");
203 }
204 crypto_core_ed25519_add(p3, p, p2);
205 crypto_core_ed25519_from_uniform(p, r);
206 crypto_core_ed25519_sub(p, p, p3);
207 assert(p[0] == 0x01);
208 for (i = 1; i < crypto_core_ed25519_BYTES; i++) {
209 assert(p[i] == 0);
210 }
211
212 crypto_core_ed25519_random(p);
213 memcpy(p2, p, crypto_core_ed25519_BYTES);
214 crypto_core_ed25519_scalar_random(sc);
215 if (crypto_scalarmult_ed25519_noclamp(p, sc, p) != 0) {
216 printf("crypto_scalarmult_ed25519_noclamp() failed (3)\n");
217 }
218 crypto_core_ed25519_scalar_negate(sc, sc);
219 if (crypto_scalarmult_ed25519_noclamp(p2, sc, p2) != 0) {
220 printf("crypto_scalarmult_ed25519_noclamp() failed (4)\n");
221 }
222 crypto_core_ed25519_add(p, p, p2);
223 assert(p[0] == 0x01);
224 for (i = 1; i < crypto_core_ed25519_BYTES; i++) {
225 assert(p[i] == 0);
226 }
227
228 hex = (char *) sodium_malloc(crypto_core_ed25519_SCALARBYTES * 2 + 1);
229
230 for (i = 0; i < crypto_core_ed25519_SCALARBYTES; i++) {
231 sc[i] = 255 - i;
232 }
233 if (crypto_core_ed25519_scalar_invert(sc, sc) != 0) {
234 printf("crypto_core_ed25519_scalar_invert() failed\n");
235 }
236 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
237 sc, crypto_core_ed25519_SCALARBYTES);
238 printf("inv1: %s\n", hex);
239 if (crypto_core_ed25519_scalar_invert(sc, sc) != 0) {
240 printf("crypto_core_ed25519_scalar_invert() failed\n");
241 }
242 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
243 sc, crypto_core_ed25519_SCALARBYTES);
244 printf("inv2: %s\n", hex);
245 for (i = 0; i < crypto_core_ed25519_SCALARBYTES; i++) {
246 sc[i] = 32 - i;
247 }
248 if (crypto_core_ed25519_scalar_invert(sc, sc) != 0) {
249 printf("crypto_core_ed25519_scalar_invert() failed\n");
250 }
251
252 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
253 sc, crypto_core_ed25519_SCALARBYTES);
254 printf("inv3: %s\n", hex);
255 if (crypto_core_ed25519_scalar_invert(sc, sc) != 0) {
256 printf("crypto_core_ed25519_scalar_invert() failed\n");
257 }
258 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
259 sc, crypto_core_ed25519_SCALARBYTES);
260 printf("inv4: %s\n", hex);
261
262 for (i = 0; i < crypto_core_ed25519_SCALARBYTES; i++) {
263 sc[i] = 255 - i;
264 }
265 crypto_core_ed25519_scalar_negate(sc, sc);
266 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
267 sc, crypto_core_ed25519_SCALARBYTES);
268 printf("neg1: %s\n", hex);
269 crypto_core_ed25519_scalar_negate(sc, sc);
270 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
271 sc, crypto_core_ed25519_SCALARBYTES);
272 printf("neg2: %s\n", hex);
273 for (i = 0; i < crypto_core_ed25519_SCALARBYTES; i++) {
274 sc[i] = 32 - i;
275 }
276 crypto_core_ed25519_scalar_negate(sc, sc);
277 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
278 sc, crypto_core_ed25519_SCALARBYTES);
279 printf("neg3: %s\n", hex);
280 crypto_core_ed25519_scalar_negate(sc, sc);
281 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
282 sc, crypto_core_ed25519_SCALARBYTES);
283 printf("neg4: %s\n", hex);
284
285 for (i = 0; i < crypto_core_ed25519_SCALARBYTES; i++) {
286 sc[i] = 255 - i;
287 }
288 crypto_core_ed25519_scalar_complement(sc, sc);
289 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
290 sc, crypto_core_ed25519_SCALARBYTES);
291 printf("comp1: %s\n", hex);
292 crypto_core_ed25519_scalar_complement(sc, sc);
293 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
294 sc, crypto_core_ed25519_SCALARBYTES);
295 printf("comp2: %s\n", hex);
296 for (i = 0; i < crypto_core_ed25519_SCALARBYTES; i++) {
297 sc[i] = 32 - i;
298 }
299 crypto_core_ed25519_scalar_complement(sc, sc);
300 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
301 sc, crypto_core_ed25519_SCALARBYTES);
302 printf("comp3: %s\n", hex);
303 crypto_core_ed25519_scalar_complement(sc, sc);
304 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
305 sc, crypto_core_ed25519_SCALARBYTES);
306 printf("comp4: %s\n", hex);
307
308 sc2 = (unsigned char *) sodium_malloc(crypto_core_ed25519_SCALARBYTES);
309 sc3 = (unsigned char *) sodium_malloc(crypto_core_ed25519_SCALARBYTES);
310 for (i = 0; i < 1000; i++) {
311 randombytes_buf(sc, crypto_core_ed25519_SCALARBYTES);
312 randombytes_buf(sc2, crypto_core_ed25519_SCALARBYTES);
313 sc[crypto_core_ed25519_SCALARBYTES - 1] &= 0x7f;
314 sc2[crypto_core_ed25519_SCALARBYTES - 1] &= 0x7f;
315 crypto_core_ed25519_scalar_add(sc3, sc, sc2);
316 assert(!sodium_is_zero(sc, crypto_core_ed25519_SCALARBYTES));
317 crypto_core_ed25519_scalar_sub(sc3, sc3, sc2);
318 assert(!sodium_is_zero(sc, crypto_core_ed25519_SCALARBYTES));
319 crypto_core_ed25519_scalar_sub(sc3, sc3, sc);
320 assert(sodium_is_zero(sc3, crypto_core_ed25519_SCALARBYTES));
321 }
322
323 memset(sc, 0x69, crypto_core_ed25519_SCALARBYTES);
324 memset(sc2, 0x42, crypto_core_ed25519_SCALARBYTES);
325 crypto_core_ed25519_scalar_add(sc, sc, sc2);
326 crypto_core_ed25519_scalar_add(sc, sc2, sc);
327 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
328 sc, crypto_core_ed25519_SCALARBYTES);
329 printf("add1: %s\n", hex);
330
331 crypto_core_ed25519_scalar_sub(sc, sc2, sc);
332 crypto_core_ed25519_scalar_sub(sc, sc, sc2);
333 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
334 sc, crypto_core_ed25519_SCALARBYTES);
335 printf("sub1: %s\n", hex);
336
337 memset(sc, 0xcd, crypto_core_ed25519_SCALARBYTES);
338 memset(sc2, 0x42, crypto_core_ed25519_SCALARBYTES);
339 crypto_core_ed25519_scalar_add(sc, sc, sc2);
340 crypto_core_ed25519_scalar_add(sc, sc2, sc);
341 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
342 sc, crypto_core_ed25519_SCALARBYTES);
343 printf("add2: %s\n", hex);
344
345 crypto_core_ed25519_scalar_sub(sc, sc2, sc);
346 crypto_core_ed25519_scalar_sub(sc, sc, sc2);
347 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
348 sc, crypto_core_ed25519_SCALARBYTES);
349 printf("sub2: %s\n", hex);
350
351 memset(sc, 0x69, crypto_core_ed25519_SCALARBYTES);
352 memset(sc2, 0x42, crypto_core_ed25519_SCALARBYTES);
353 for (i = 0; i < 100; i++) {
354 crypto_core_ed25519_scalar_mul(sc, sc, sc2);
355 crypto_core_ed25519_scalar_mul(sc2, sc, sc2);
356 }
357 sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1,
358 sc2, crypto_core_ed25519_SCALARBYTES);
359 printf("mul: %s\n", hex);
360 for (i = 0; i < 1000; i++) {
361 crypto_core_ed25519_scalar_random(sc);
362 memset(sc2, 0, crypto_core_ed25519_SCALARBYTES);
363 crypto_core_ed25519_scalar_mul(sc3, sc, sc2);
364 assert(sodium_is_zero(sc3, crypto_core_ed25519_SCALARBYTES));
365
366 sc2[0]++;
367 crypto_core_ed25519_scalar_mul(sc3, sc, sc2);
368 assert(memcmp(sc3, sc, crypto_core_ed25519_SCALARBYTES) == 0);
369
370 sc2[0]++;
371 crypto_core_ed25519_scalar_mul(sc3, sc, sc2);
372 crypto_core_ed25519_scalar_sub(sc3, sc3, sc);
373 crypto_core_ed25519_scalar_sub(sc3, sc3, sc);
374 assert(sodium_is_zero(sc3, crypto_core_ed25519_SCALARBYTES));
375
376 do {
377 crypto_core_ed25519_scalar_random(sc2);
378 } while (sodium_is_zero(sc2, crypto_core_ed25519_SCALARBYTES));
379 crypto_core_ed25519_scalar_mul(sc3, sc, sc2);
380 crypto_core_ed25519_scalar_invert(sc2, sc2);
381 crypto_core_ed25519_scalar_mul(sc3, sc3, sc2);
382 assert(memcmp(sc3, sc, crypto_core_ed25519_SCALARBYTES) == 0);
383
384 sc[31] |= 0x11;
385 memset(sc2, 0, crypto_core_ed25519_SCALARBYTES);
386 sc2[0] = 1;
387 crypto_core_ed25519_scalar_mul(sc3, sc, sc2);
388 assert(memcmp(sc3, sc, crypto_core_ed25519_SCALARBYTES) != 0);
389 }
390 sodium_free(hex);
391 sodium_free(sc64);
392 sodium_free(sc3);
393 sodium_free(sc2);
394 sodium_free(sc);
395 sodium_free(p3);
396 sodium_free(p2);
397 sodium_free(p);
398 sodium_free(r);
399 sodium_free(h);
400
401 assert(crypto_core_ed25519_BYTES == crypto_core_ed25519_bytes());
402 assert(crypto_core_ed25519_SCALARBYTES == crypto_core_ed25519_scalarbytes());
403 assert(crypto_core_ed25519_NONREDUCEDSCALARBYTES == crypto_core_ed25519_nonreducedscalarbytes());
404 assert(crypto_core_ed25519_NONREDUCEDSCALARBYTES >= crypto_core_ed25519_SCALARBYTES);
405 assert(crypto_core_ed25519_UNIFORMBYTES == crypto_core_ed25519_uniformbytes());
406 assert(crypto_core_ed25519_UNIFORMBYTES >= crypto_core_ed25519_BYTES);
407 assert(crypto_core_ed25519_HASHBYTES == crypto_core_ed25519_hashbytes());
408 assert(crypto_core_ed25519_HASHBYTES >= 2 * crypto_core_ed25519_BYTES);
409
410 printf("OK\n");
411
412 return 0;
413 }
414