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
_crypto_scalarmult_ed25519_is_inf(const unsigned char s[32])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
_crypto_scalarmult_ed25519_clamp(unsigned char k[32])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
crypto_scalarmult_ed25519(unsigned char * q,const unsigned char * n,const unsigned char * p)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
crypto_scalarmult_ed25519_base(unsigned char * q,const unsigned char * n)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
crypto_scalarmult_ed25519_bytes(void)77 crypto_scalarmult_ed25519_bytes(void)
78 {
79 return crypto_scalarmult_ed25519_BYTES;
80 }
81
82 size_t
crypto_scalarmult_ed25519_scalarbytes(void)83 crypto_scalarmult_ed25519_scalarbytes(void)
84 {
85 return crypto_scalarmult_ed25519_SCALARBYTES;
86 }
87