1 
2 #include <string.h>
3 
4 #include "crypto_scalarmult_ed25519.h"
5 #include "private/ed25519_ref10.h"
6 #include "utils.h"
7 
8 static int
9 _crypto_scalarmult_ed25519_is_inf(const unsigned char s[32])
10 {
11     unsigned char c;
12     unsigned int  i;
13 
14     c = s[0] ^ 0x01;
15     for (i = 1; i < 31; i++) {
16         c |= s[i];
17     }
18     c |= s[31] & 0x7f;
19 
20     return ((((unsigned int) c) - 1U) >> 8) & 1;
21 }
22 
23 static inline void
24 _crypto_scalarmult_ed25519_clamp(unsigned char k[32])
25 {
26     k[0] &= 248;
27     k[31] &= 127;
28     k[31] |= 64;
29 }
30 
31 int
32 crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n,
33                           const unsigned char *p)
34 {
35     unsigned char *t = q;
36     ge25519_p3     Q;
37     ge25519_p3     P;
38     unsigned int   i;
39 
40     if (ge25519_is_canonical(p) == 0 || ge25519_has_small_order(p) != 0 ||
41         ge25519_frombytes(&P, p) != 0 || ge25519_is_on_main_subgroup(&P) == 0) {
42         return -1;
43     }
44     for (i = 0; i < 32; ++i) {
45         t[i] = n[i];
46     }
47     _crypto_scalarmult_ed25519_clamp(t);
48     ge25519_scalarmult(&Q, t, &P);
49     ge25519_p3_tobytes(q, &Q);
50     if (_crypto_scalarmult_ed25519_is_inf(q) != 0 || sodium_is_zero(n, 32)) {
51         return -1;
52     }
53     return 0;
54 }
55 
56 int
57 crypto_scalarmult_ed25519_base(unsigned char *q,
58                                const unsigned char *n)
59 {
60     unsigned char *t = q;
61     ge25519_p3     Q;
62     unsigned int   i;
63 
64     for (i = 0; i < 32; ++i) {
65         t[i] = n[i];
66     }
67     _crypto_scalarmult_ed25519_clamp(t);
68     ge25519_scalarmult_base(&Q, t);
69     ge25519_p3_tobytes(q, &Q);
70     if (sodium_is_zero(n, 32) != 0) {
71         return -1;
72     }
73     return 0;
74 }
75 
76 size_t
77 crypto_scalarmult_ed25519_bytes(void)
78 {
79     return crypto_scalarmult_ed25519_BYTES;
80 }
81 
82 size_t
83 crypto_scalarmult_ed25519_scalarbytes(void)
84 {
85     return crypto_scalarmult_ed25519_SCALARBYTES;
86 }
87