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