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
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     unsigned char c = 0U;
27     unsigned int  i;
28     unsigned int  s;
29 
30     for (i = 0U; i < 32U; i++) {
31         s = S[i] + P[i] + c;
32         S[i] = (unsigned char) s;
33         c = (s >> 8) & 1;
34     }
35 }
36 
37 int
38 main(void)
39 {
40     unsigned char *h;
41     unsigned char *p, *p2, *p3;
42     unsigned char *sc;
43     int            i, j;
44 
45     h = (unsigned char *) sodium_malloc(crypto_core_ed25519_UNIFORMBYTES);
46     p = (unsigned char *) sodium_malloc(crypto_core_ed25519_BYTES);
47     for (i = 0; i < 1000; i++) {
48         randombytes_buf(h, crypto_core_ed25519_UNIFORMBYTES);
49         if (crypto_core_ed25519_from_uniform(p, h) != 0) {
50             printf("crypto_core_ed25519_from_uniform() failed\n");
51         }
52         if (crypto_core_ed25519_is_valid_point(p) == 0) {
53             printf("crypto_core_ed25519_from_uniform() returned an invalid point\n");
54         }
55     }
56 
57     p2 = (unsigned char *) sodium_malloc(crypto_core_ed25519_BYTES);
58     p3 = (unsigned char *) sodium_malloc(crypto_core_ed25519_BYTES);
59     randombytes_buf(h, crypto_core_ed25519_UNIFORMBYTES);
60     crypto_core_ed25519_from_uniform(p2, h);
61 
62     j = 1 + (int) randombytes_uniform(100);
63     memcpy(p3, p, crypto_core_ed25519_BYTES);
64     for (i = 0; i < j; i++) {
65         crypto_core_ed25519_add(p, p, p2);
66         if (crypto_core_ed25519_is_valid_point(p) != 1) {
67             printf("crypto_core_add() returned an invalid point\n");
68         }
69     }
70     if (memcmp(p, p3, crypto_core_ed25519_BYTES) == 0) {
71         printf("crypto_core_add() failed\n");
72     }
73     for (i = 0; i < j; i++) {
74         crypto_core_ed25519_sub(p, p, p2);
75     }
76     if (memcmp(p, p3, crypto_core_ed25519_BYTES) != 0) {
77         printf("crypto_core_add() or crypto_core_sub() failed\n");
78     }
79     sc = (unsigned char *) sodium_malloc(crypto_scalarmult_ed25519_SCALARBYTES);
80     memset(sc, 0, crypto_scalarmult_ed25519_SCALARBYTES);
81     sc[0] = 8;
82     memcpy(p2, p, crypto_core_ed25519_BYTES);
83     memcpy(p3, p, crypto_core_ed25519_BYTES);
84 
85     for (i = 0; i < 254; i++) {
86         crypto_core_ed25519_add(p2, p2, p2);
87     }
88     for (i = 0; i < 8; i++) {
89         crypto_core_ed25519_add(p2, p2, p);
90     }
91     if (crypto_scalarmult_ed25519(p3, sc, p) != 0) {
92         printf("crypto_scalarmult_ed25519() failed\n");
93     }
94     if (memcmp(p2, p3, crypto_core_ed25519_BYTES) != 0) {
95         printf("crypto_scalarmult_ed25519() is inconsistent with crypto_core_ed25519_add()\n");
96     }
97 
98     assert(crypto_core_ed25519_is_valid_point(p) == 1);
99 
100     memset(p, 0, crypto_core_ed25519_BYTES);
101     assert(crypto_core_ed25519_is_valid_point(p) == 0);
102 
103     p[0] = 1;
104     assert(crypto_core_ed25519_is_valid_point(p) == 0);
105 
106     p[0] = 2;
107     assert(crypto_core_ed25519_is_valid_point(p) == 0);
108 
109     p[0] = 9;
110     assert(crypto_core_ed25519_is_valid_point(p) == 1);
111 
112     assert(crypto_core_ed25519_is_valid_point(max_canonical_p) == 1);
113     assert(crypto_core_ed25519_is_valid_point(non_canonical_invalid_p) == 0);
114     assert(crypto_core_ed25519_is_valid_point(non_canonical_p) == 0);
115 
116     memcpy(p2, p, crypto_core_ed25519_BYTES);
117     add_P(p2);
118     crypto_core_ed25519_add(p3, p2, p2);
119     crypto_core_ed25519_sub(p3, p3, p2);
120     assert(memcmp(p2, p, crypto_core_ed25519_BYTES) != 0);
121     assert(memcmp(p3, p, crypto_core_ed25519_BYTES) == 0);
122 
123     p[0] = 2;
124     assert(crypto_core_ed25519_add(p3, p2, p) == -1);
125     assert(crypto_core_ed25519_add(p3, p2, non_canonical_p) == 0);
126     assert(crypto_core_ed25519_add(p3, p2, non_canonical_invalid_p) == -1);
127     assert(crypto_core_ed25519_add(p3, p, p3) == -1);
128     assert(crypto_core_ed25519_add(p3, non_canonical_p, p3) == 0);
129     assert(crypto_core_ed25519_add(p3, non_canonical_invalid_p, p3) == -1);
130 
131     assert(crypto_core_ed25519_sub(p3, p2, p) == -1);
132     assert(crypto_core_ed25519_sub(p3, p2, non_canonical_p) == 0);
133     assert(crypto_core_ed25519_sub(p3, p2, non_canonical_invalid_p) == -1);
134     assert(crypto_core_ed25519_sub(p3, p, p3) == -1);
135     assert(crypto_core_ed25519_sub(p3, non_canonical_p, p3) == 0);
136     assert(crypto_core_ed25519_sub(p3, non_canonical_invalid_p, p3) == -1);
137 
138     sodium_free(sc);
139     sodium_free(p3);
140     sodium_free(p2);
141     sodium_free(p);
142     sodium_free(h);
143 
144     assert(crypto_core_ed25519_BYTES == crypto_core_ed25519_bytes());
145     assert(crypto_core_ed25519_UNIFORMBYTES == crypto_core_ed25519_uniformbytes());
146     assert(crypto_core_ed25519_UNIFORMBYTES >= crypto_core_ed25519_BYTES);
147 
148     printf("OK\n");
149 
150     return 0;
151 }
152