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