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
crypto_scalarmult_curve25519_sandy2x(unsigned char * q,const unsigned char * n,const unsigned char * p)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
crypto_scalarmult_curve25519_sandy2x_base(unsigned char * q,const unsigned char * n)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