1 
2 #include <stdint.h>
3 
4 #include "crypto_core_ed25519.h"
5 #include "private/common.h"
6 #include "private/ed25519_ref10.h"
7 #include "randombytes.h"
8 #include "utils.h"
9 
10 int
11 crypto_core_ed25519_is_valid_point(const unsigned char *p)
12 {
13     ge25519_p3 p_p3;
14 
15     if (ge25519_is_canonical(p) == 0 ||
16         ge25519_has_small_order(p) != 0 ||
17         ge25519_frombytes(&p_p3, p) != 0 ||
18         ge25519_is_on_curve(&p_p3) == 0 ||
19         ge25519_is_on_main_subgroup(&p_p3) == 0) {
20         return 0;
21     }
22     return 1;
23 }
24 
25 int
26 crypto_core_ed25519_add(unsigned char *r,
27                         const unsigned char *p, const unsigned char *q)
28 {
29     ge25519_p3     p_p3, q_p3, r_p3;
30     ge25519_p1p1   r_p1p1;
31     ge25519_cached q_cached;
32 
33     if (ge25519_frombytes(&p_p3, p) != 0 || ge25519_is_on_curve(&p_p3) == 0 ||
34         ge25519_frombytes(&q_p3, q) != 0 || ge25519_is_on_curve(&q_p3) == 0) {
35         return -1;
36     }
37     ge25519_p3_to_cached(&q_cached, &q_p3);
38     ge25519_add(&r_p1p1, &p_p3, &q_cached);
39     ge25519_p1p1_to_p3(&r_p3, &r_p1p1);
40     ge25519_p3_tobytes(r, &r_p3);
41 
42     return 0;
43 }
44 
45 int
46 crypto_core_ed25519_sub(unsigned char *r,
47                         const unsigned char *p, const unsigned char *q)
48 {
49     ge25519_p3     p_p3, q_p3, r_p3;
50     ge25519_p1p1   r_p1p1;
51     ge25519_cached q_cached;
52 
53     if (ge25519_frombytes(&p_p3, p) != 0 || ge25519_is_on_curve(&p_p3) == 0 ||
54         ge25519_frombytes(&q_p3, q) != 0 || ge25519_is_on_curve(&q_p3) == 0) {
55         return -1;
56     }
57     ge25519_p3_to_cached(&q_cached, &q_p3);
58     ge25519_sub(&r_p1p1, &p_p3, &q_cached);
59     ge25519_p1p1_to_p3(&r_p3, &r_p1p1);
60     ge25519_p3_tobytes(r, &r_p3);
61 
62     return 0;
63 }
64 
65 int
66 crypto_core_ed25519_from_uniform(unsigned char *p, const unsigned char *r)
67 {
68     ge25519_from_uniform(p, r);
69 
70     return 0;
71 }
72 
73 int
74 crypto_core_ed25519_from_hash(unsigned char *p, const unsigned char *h)
75 {
76     ge25519_from_hash(p, h);
77 
78     return 0;
79 }
80 
81 void
82 crypto_core_ed25519_random(unsigned char *p)
83 {
84     unsigned char h[crypto_core_ed25519_HASHBYTES];
85 
86     randombytes_buf(h, sizeof h);
87     (void) crypto_core_ed25519_from_hash(p, h);
88 }
89 
90 void
91 crypto_core_ed25519_scalar_random(unsigned char *r)
92 {
93     do {
94         randombytes_buf(r, crypto_core_ed25519_SCALARBYTES);
95         r[crypto_core_ed25519_SCALARBYTES - 1] &= 0x1f;
96     } while (sc25519_is_canonical(r) == 0 ||
97              sodium_is_zero(r, crypto_core_ed25519_SCALARBYTES));
98 }
99 
100 int
101 crypto_core_ed25519_scalar_invert(unsigned char *recip, const unsigned char *s)
102 {
103     sc25519_invert(recip, s);
104 
105     return - sodium_is_zero(s, crypto_core_ed25519_SCALARBYTES);
106 }
107 
108 /* 2^252+27742317777372353535851937790883648493 */
109 static const unsigned char L[] = {
110     0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7,
111     0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
113 };
114 
115 void
116 crypto_core_ed25519_scalar_negate(unsigned char *neg, const unsigned char *s)
117 {
118     unsigned char t_[crypto_core_ed25519_NONREDUCEDSCALARBYTES];
119     unsigned char s_[crypto_core_ed25519_NONREDUCEDSCALARBYTES];
120 
121     COMPILER_ASSERT(crypto_core_ed25519_NONREDUCEDSCALARBYTES >=
122                     2 * crypto_core_ed25519_SCALARBYTES);
123     memset(t_, 0, sizeof t_);
124     memset(s_, 0, sizeof s_);
125     memcpy(t_ + crypto_core_ed25519_SCALARBYTES, L,
126            crypto_core_ed25519_SCALARBYTES);
127     memcpy(s_, s, crypto_core_ed25519_SCALARBYTES);
128     sodium_sub(t_, s_, sizeof t_);
129     sc25519_reduce(t_);
130     memcpy(neg, t_, crypto_core_ed25519_SCALARBYTES);
131 }
132 
133 void
134 crypto_core_ed25519_scalar_complement(unsigned char *comp,
135                                       const unsigned char *s)
136 {
137     unsigned char t_[crypto_core_ed25519_NONREDUCEDSCALARBYTES];
138     unsigned char s_[crypto_core_ed25519_NONREDUCEDSCALARBYTES];
139 
140     COMPILER_ASSERT(crypto_core_ed25519_NONREDUCEDSCALARBYTES >=
141                     2 * crypto_core_ed25519_SCALARBYTES);
142     memset(t_, 0, sizeof t_);
143     memset(s_, 0, sizeof s_);
144     t_[0]++;
145     memcpy(t_ + crypto_core_ed25519_SCALARBYTES, L,
146            crypto_core_ed25519_SCALARBYTES);
147     memcpy(s_, s, crypto_core_ed25519_SCALARBYTES);
148     sodium_sub(t_, s_, sizeof t_);
149     sc25519_reduce(t_);
150     memcpy(comp, t_, crypto_core_ed25519_SCALARBYTES);
151 }
152 
153 void
154 crypto_core_ed25519_scalar_add(unsigned char *z, const unsigned char *x,
155                                const unsigned char *y)
156 {
157     unsigned char x_[crypto_core_ed25519_NONREDUCEDSCALARBYTES];
158     unsigned char y_[crypto_core_ed25519_NONREDUCEDSCALARBYTES];
159 
160     memset(x_, 0, sizeof x_);
161     memset(y_, 0, sizeof y_);
162     memcpy(x_, x, crypto_core_ed25519_SCALARBYTES);
163     memcpy(y_, y, crypto_core_ed25519_SCALARBYTES);
164     sodium_add(x_, y_, crypto_core_ed25519_SCALARBYTES);
165     crypto_core_ed25519_scalar_reduce(z, x_);
166 }
167 
168 void
169 crypto_core_ed25519_scalar_sub(unsigned char *z, const unsigned char *x,
170                                const unsigned char *y)
171 {
172     unsigned char yn[crypto_core_ed25519_SCALARBYTES];
173 
174     crypto_core_ed25519_scalar_negate(yn, y);
175     crypto_core_ed25519_scalar_add(z, x, yn);
176 }
177 
178 void
179 crypto_core_ed25519_scalar_mul(unsigned char *z, const unsigned char *x,
180                                const unsigned char *y)
181 {
182     sc25519_mul(z, x, y);
183 }
184 
185 void
186 crypto_core_ed25519_scalar_reduce(unsigned char *r,
187                                   const unsigned char *s)
188 {
189     unsigned char t[crypto_core_ed25519_NONREDUCEDSCALARBYTES];
190 
191     memcpy(t, s, sizeof t);
192     sc25519_reduce(t);
193     memcpy(r, t, crypto_core_ed25519_SCALARBYTES);
194     sodium_memzero(t, sizeof t);
195 }
196 
197 size_t
198 crypto_core_ed25519_bytes(void)
199 {
200     return crypto_core_ed25519_BYTES;
201 }
202 
203 size_t
204 crypto_core_ed25519_nonreducedscalarbytes(void)
205 {
206     return crypto_core_ed25519_NONREDUCEDSCALARBYTES;
207 }
208 
209 size_t
210 crypto_core_ed25519_uniformbytes(void)
211 {
212     return crypto_core_ed25519_UNIFORMBYTES;
213 }
214 
215 size_t
216 crypto_core_ed25519_hashbytes(void)
217 {
218     return crypto_core_ed25519_HASHBYTES;
219 }
220 
221 size_t
222 crypto_core_ed25519_scalarbytes(void)
223 {
224     return crypto_core_ed25519_SCALARBYTES;
225 }
226