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 24static int 25crypto_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 70static int 71crypto_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 108struct crypto_scalarmult_curve25519_implementation 109crypto_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