Home | History | Annotate | Line # | Download | only in sandy2x
      1 /*
      2    This file is adapted from ref10/scalarmult.c:
      3    The code for Mongomery ladder is replace by the ladder assembly function;
      4    Inversion is done in the same way as amd64-51/.
      5    (fe is first converted into fe51 after Mongomery ladder)
      6 */
      7 
      8 #include <stddef.h>
      9 
     10 #ifdef HAVE_AVX_ASM
     11 
     12 #include "utils.h"
     13 #include "curve25519_sandy2x.h"
     14 #include "../scalarmult_curve25519.h"
     15 #include "fe.h"
     16 #include "fe51.h"
     17 #include "ladder.h"
     18 #include "ladder_base.h"
     19 
     20 #define x1 var[0]
     21 #define x2 var[1]
     22 #define z2 var[2]
     23 
     24 static int
     25 crypto_scalarmult_curve25519_sandy2x(unsigned char *q, const unsigned char *n,
     26                                      const unsigned char *p)
     27 {
     28   unsigned char *t = q;
     29   fe             var[3];
     30   fe51           x_51;
     31   fe51           z_51;
     32   unsigned int   i;
     33 
     34   for (i = 0; i < 32; i++) {
     35       t[i] = n[i];
     36   }
     37   t[0] &= 248;
     38   t[31] &= 127;
     39   t[31] |= 64;
     40 
     41   fe_frombytes(x1, p);
     42 
     43   ladder(var, t);
     44 
     45   z_51.v[0] = (z2[1] << 26) + z2[0];
     46   z_51.v[1] = (z2[3] << 26) + z2[2];
     47   z_51.v[2] = (z2[5] << 26) + z2[4];
     48   z_51.v[3] = (z2[7] << 26) + z2[6];
     49   z_51.v[4] = (z2[9] << 26) + z2[8];
     50 
     51   x_51.v[0] = (x2[1] << 26) + x2[0];
     52   x_51.v[1] = (x2[3] << 26) + x2[2];
     53   x_51.v[2] = (x2[5] << 26) + x2[4];
     54   x_51.v[3] = (x2[7] << 26) + x2[6];
     55   x_51.v[4] = (x2[9] << 26) + x2[8];
     56 
     57   fe51_invert(&z_51, &z_51);
     58   fe51_mul(&x_51, &x_51, &z_51);
     59   fe51_pack(q, &x_51);
     60 
     61   return 0;
     62 }
     63 
     64 #undef x2
     65 #undef z2
     66 
     67 #define x2 var[0]
     68 #define z2 var[1]
     69 
     70 static int
     71 crypto_scalarmult_curve25519_sandy2x_base(unsigned char *q,
     72                                           const unsigned char *n)
     73 {
     74   unsigned char *t = q;
     75   fe             var[3];
     76   fe51           x_51;
     77   fe51           z_51;
     78   unsigned int   i;
     79 
     80   for (i = 0;i < 32; i++) {
     81       t[i] = n[i];
     82   }
     83   t[0] &= 248;
     84   t[31] &= 127;
     85   t[31] |= 64;
     86 
     87   ladder_base(var, t);
     88 
     89   z_51.v[0] = (z2[1] << 26) + z2[0];
     90   z_51.v[1] = (z2[3] << 26) + z2[2];
     91   z_51.v[2] = (z2[5] << 26) + z2[4];
     92   z_51.v[3] = (z2[7] << 26) + z2[6];
     93   z_51.v[4] = (z2[9] << 26) + z2[8];
     94 
     95   x_51.v[0] = (x2[1] << 26) + x2[0];
     96   x_51.v[1] = (x2[3] << 26) + x2[2];
     97   x_51.v[2] = (x2[5] << 26) + x2[4];
     98   x_51.v[3] = (x2[7] << 26) + x2[6];
     99   x_51.v[4] = (x2[9] << 26) + x2[8];
    100 
    101   fe51_invert(&z_51, &z_51);
    102   fe51_mul(&x_51, &x_51, &z_51);
    103   fe51_pack(q, &x_51);
    104 
    105   return 0;
    106 }
    107 
    108 struct crypto_scalarmult_curve25519_implementation
    109 crypto_scalarmult_curve25519_sandy2x_implementation = {
    110     SODIUM_C99(.mult = ) crypto_scalarmult_curve25519_sandy2x,
    111     SODIUM_C99(.mult_base = ) crypto_scalarmult_curve25519_sandy2x_base
    112 };
    113 
    114 #endif
    115