Home | History | Annotate | Line # | Download | only in ref10
      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