1#define TEST_NAME "core_ed25519"
2#include "cmptest.h"
3
4static 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};
8static 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};
12static 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
17static void
18add_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
37int
38main(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