x25519 1.0.6 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,11 +20,16 @@
20
20
 
21
21
  #include <stdint.h>
22
22
 
23
+ #ifndef ALIGN_BYTES
23
24
  #define ALIGN_BYTES 32
25
+ #endif
26
+
27
+ #ifndef ALIGN
24
28
  #ifdef __INTEL_COMPILER
25
29
  #define ALIGN __declspec(align(ALIGN_BYTES))
26
30
  #else
27
- #define ALIGN __attribute__ ((aligned (ALIGN_BYTES)))
31
+ #define ALIGN __attribute__((aligned(ALIGN_BYTES)))
32
+ #endif
28
33
  #endif
29
34
 
30
35
  #define X25519_KEYSIZE_BYTES 32
@@ -1,11 +1,11 @@
1
1
  /**
2
- * Copyright (c) 2017 Armando Faz <armfazh@ic.unicamp.br>.
2
+ * Copyright (c) 2017 Armando Faz <armfazh@ic.unicamp.br>. All Rights Reserved.
3
3
  * Institute of Computing.
4
4
  * University of Campinas, Brazil.
5
5
  *
6
6
  * This program is free software: you can redistribute it and/or modify
7
7
  * it under the terms of the GNU Lesser General Public License as
8
- * published by the Free Software Foundation, version 3.
8
+ * published by the Free Software Foundation, version 2 or greater.
9
9
  *
10
10
  * This program is distributed in the hope that it will be useful, but
11
11
  * WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,217 +15,219 @@
15
15
  * You should have received a copy of the GNU Lesser General Public License
16
16
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
+ #include <string.h>
18
19
  #include "fp25519_x64.h"
19
- #include "table_ladder_x25519.h"
20
20
  #include "x25519_precomputed.h"
21
+ #include "table_ladder_x25519.h"
21
22
 
22
- /****** Implementation of Montgomery Ladder Algorithm ************/
23
- static inline void cswap_x64(uint64_t bit, uint64_t *const px, uint64_t *const py)
24
- {
25
- int i=0;
26
- uint64_t mask = (uint64_t)0-bit;
27
- for(i=0;i<NUM_WORDS_ELTFP25519_X64;i++)
28
- {
29
- uint64_t t = mask & (px[i] ^ py[i]);
30
- px[i] = px[i] ^ t;
31
- py[i] = py[i] ^ t;
32
- }
23
+ static inline void cswap_x64(uint64_t bit, uint64_t *const px,
24
+ uint64_t *const py) {
25
+ int i = 0;
26
+ uint64_t mask = (uint64_t)0 - bit;
27
+ for (i = 0; i < NUM_WORDS_ELTFP25519_X64; i++) {
28
+ uint64_t t = mask & (px[i] ^ py[i]);
29
+ px[i] = px[i] ^ t;
30
+ py[i] = py[i] ^ t;
31
+ }
33
32
  }
34
33
 
35
- void x25519_precomputed_scalarmult(uint8_t *shared, uint8_t *private_key, uint8_t *session_key)
36
- {
37
- ALIGN uint64_t buffer[4*NUM_WORDS_ELTFP25519_X64];
38
- ALIGN uint64_t coordinates[4*NUM_WORDS_ELTFP25519_X64];
39
- ALIGN uint64_t workspace[6*NUM_WORDS_ELTFP25519_X64];
40
- uint64_t save=0;
41
-
42
- int i=0, j=0;
43
- uint64_t prev = 0;
44
- uint64_t *const X1 = (uint64_t*)session_key;
45
- uint64_t *const key = (uint64_t*)private_key;
46
- uint64_t *const Px = coordinates+0;
47
- uint64_t *const Pz = coordinates+4;
48
- uint64_t *const Qx = coordinates+8;
49
- uint64_t *const Qz = coordinates+12;
50
- uint64_t *const X2 = Qx;
51
- uint64_t *const Z2 = Qz;
52
- uint64_t *const X3 = Px;
53
- uint64_t *const Z3 = Pz;
54
- uint64_t *const X2Z2 = Qx;
55
- uint64_t *const X3Z3 = Px;
56
-
57
- uint64_t *const A = workspace+0;
58
- uint64_t *const B = workspace+4;
59
- uint64_t *const D = workspace+8;
60
- uint64_t *const C = workspace+12;
61
- uint64_t *const DA = workspace+16;
62
- uint64_t *const CB = workspace+20;
63
- uint64_t *const AB = A;
64
- uint64_t *const DC = D;
65
- uint64_t *const DACB = DA;
66
- uint64_t *const buffer_1w = buffer;
67
- uint64_t *const buffer_2w = buffer;
68
-
69
- /* clampC function */
70
- save = private_key[X25519_KEYSIZE_BYTES-1]<<16 | private_key[0];
71
- private_key[0] = private_key[0] & (~(uint8_t)0x7);
72
- private_key[X25519_KEYSIZE_BYTES-1] = (uint8_t)64 | (private_key[X25519_KEYSIZE_BYTES-1] & (uint8_t)0x7F);
73
-
74
- /**
75
- * As in the draft:
76
- * When receiving such an array, implementations of curve25519
77
- * MUST mask the most-significant bit in the final byte. This
78
- * is done to preserve compatibility with point formats which
79
- * reserve the sign bit for use in other protocols and to
80
- * increase resistance to implementation fingerprinting
81
- **/
82
- session_key[X25519_KEYSIZE_BYTES-1] &= (1<<(255%8))-1;
83
-
84
- copy_EltFp25519_1w_x64(Px,(uint64_t*)session_key);
85
- setzero_EltFp25519_1w_x64(Pz);
86
- setzero_EltFp25519_1w_x64(Qx);
87
- setzero_EltFp25519_1w_x64(Qz);
88
-
89
- Pz[0] = 1;
90
- Qx[0] = 1;
91
-
92
- /* main-loop */
93
- prev = 0;
94
- j = 62;
95
- for(i=3;i>=0;i--)
96
- {
97
- while(j >= 0)
98
- {
99
- uint64_t bit = (key[i]>>j)&0x1;
100
- uint64_t swap = bit^prev;
101
- prev = bit;
102
-
103
- add_EltFp25519_1w_x64(A, X2, Z2); /* A = (X2+Z2) */
104
- sub_EltFp25519_1w_x64(B, X2, Z2); /* B = (X2-Z2) */
105
- add_EltFp25519_1w_x64(C, X3, Z3); /* C = (X3+Z3) */
106
- sub_EltFp25519_1w_x64(D, X3, Z3); /* D = (X3-Z3) */
107
- mul_EltFp25519_2w_x64(DACB,AB,DC); /* [DA|CB] = [A|B]*[D|C] */
108
-
109
- cswap_x64(swap, A, C);
110
- cswap_x64(swap, B, D);
111
-
112
- sqr_EltFp25519_2w_x64(AB); /* [AA|BB] = [A^2|B^2] */
113
- add_EltFp25519_1w_x64(X3, DA, CB); /* X3 = (DA+CB) */
114
- sub_EltFp25519_1w_x64(Z3, DA, CB); /* Z3 = (DA-CB) */
115
- sqr_EltFp25519_2w_x64(X3Z3); /* [X3|Z3] = [(DA+CB)|(DA+CB)]^2 */
116
-
117
- copy_EltFp25519_1w_x64(X2,B); /* X2 = B^2 */
118
- sub_EltFp25519_1w_x64(Z2, A, B); /* Z2 = E = AA-BB */
119
- mul_a24_EltFp25519_1w_x64(B, Z2); /* B = a24*E */
120
- add_EltFp25519_1w_x64(B, B, X2); /* B = a24*E+B */
121
- mul_EltFp25519_2w_x64(X2Z2,X2Z2,AB); /* [X2|Z2] = [B|E]*[A|a24*E+B] */
122
- mul_EltFp25519_1w_x64(Z3,Z3,X1); /* Z3 = Z3*X1 */
123
-
124
- j--;
125
- }
126
- j = 63;
127
- }
128
-
129
- inv_EltFp25519_1w_x64(A, Qz);
130
- mul_EltFp25519_1w_x64((uint64_t*)shared,Qx,A);
131
- fred_EltFp25519_1w_x64((uint64_t *) shared);
132
- private_key[X25519_KEYSIZE_BYTES-1] = (uint8_t)((save>>16) & 0xFF);
133
- private_key[0] = (uint8_t)(save & 0xFF);
34
+
35
+ /** Original rfc7748_precomputed name: 'x25519_shared_secret_x64' */
36
+ void x25519_precomputed_scalarmult(uint8_t *shared, uint8_t *private_key,
37
+ uint8_t *session_key) {
38
+ ALIGN uint64_t buffer[4 * NUM_WORDS_ELTFP25519_X64];
39
+ ALIGN uint64_t coordinates[4 * NUM_WORDS_ELTFP25519_X64];
40
+ ALIGN uint64_t workspace[6 * NUM_WORDS_ELTFP25519_X64];
41
+ ALIGN uint8_t session[X25519_KEYSIZE_BYTES];
42
+ ALIGN uint8_t private[X25519_KEYSIZE_BYTES];
43
+
44
+ int i = 0, j = 0;
45
+ uint64_t prev = 0;
46
+ uint64_t *const X1 = (uint64_t *)session;
47
+ uint64_t *const key = (uint64_t *)private;
48
+ uint64_t *const Px = coordinates + 0;
49
+ uint64_t *const Pz = coordinates + 4;
50
+ uint64_t *const Qx = coordinates + 8;
51
+ uint64_t *const Qz = coordinates + 12;
52
+ uint64_t *const X2 = Qx;
53
+ uint64_t *const Z2 = Qz;
54
+ uint64_t *const X3 = Px;
55
+ uint64_t *const Z3 = Pz;
56
+ uint64_t *const X2Z2 = Qx;
57
+ uint64_t *const X3Z3 = Px;
58
+
59
+ uint64_t *const A = workspace + 0;
60
+ uint64_t *const B = workspace + 4;
61
+ uint64_t *const D = workspace + 8;
62
+ uint64_t *const C = workspace + 12;
63
+ uint64_t *const DA = workspace + 16;
64
+ uint64_t *const CB = workspace + 20;
65
+ uint64_t *const AB = A;
66
+ uint64_t *const DC = D;
67
+ uint64_t *const DACB = DA;
68
+ uint64_t *const buffer_1w = buffer;
69
+ uint64_t *const buffer_2w = buffer;
70
+
71
+ memcpy(private, private_key, sizeof(private));
72
+ memcpy(session, session_key, sizeof(session));
73
+
74
+ /* clampC function */
75
+ private
76
+ [0] = private[0] & (~(uint8_t)0x7);
77
+ private
78
+ [X25519_KEYSIZE_BYTES - 1] =
79
+ (uint8_t)64 | (private[X25519_KEYSIZE_BYTES - 1] & (uint8_t)0x7F);
80
+
81
+ /**
82
+ * As in the draft:
83
+ * When receiving such an array, implementations of curve25519
84
+ * MUST mask the most-significant bit in the final byte. This
85
+ * is done to preserve compatibility with point formats which
86
+ * reserve the sign bit for use in other protocols and to
87
+ * increase resistance to implementation fingerprinting
88
+ **/
89
+ session[X25519_KEYSIZE_BYTES - 1] &= (1 << (255 % 8)) - 1;
90
+
91
+ copy_EltFp25519_1w_x64(Px, X1);
92
+ setzero_EltFp25519_1w_x64(Pz);
93
+ setzero_EltFp25519_1w_x64(Qx);
94
+ setzero_EltFp25519_1w_x64(Qz);
95
+
96
+ Pz[0] = 1;
97
+ Qx[0] = 1;
98
+
99
+ /* main-loop */
100
+ prev = 0;
101
+ j = 62;
102
+ for (i = 3; i >= 0; i--) {
103
+ while (j >= 0) {
104
+ uint64_t bit = (key[i] >> j) & 0x1;
105
+ uint64_t swap = bit ^ prev;
106
+ prev = bit;
107
+
108
+ add_EltFp25519_1w_x64(A, X2, Z2); /* A = (X2+Z2) */
109
+ sub_EltFp25519_1w_x64(B, X2, Z2); /* B = (X2-Z2) */
110
+ add_EltFp25519_1w_x64(C, X3, Z3); /* C = (X3+Z3) */
111
+ sub_EltFp25519_1w_x64(D, X3, Z3); /* D = (X3-Z3) */
112
+ mul_EltFp25519_2w_x64(DACB, AB, DC); /* [DA|CB] = [A|B]*[D|C] */
113
+
114
+ cswap_x64(swap, A, C);
115
+ cswap_x64(swap, B, D);
116
+
117
+ sqr_EltFp25519_2w_x64(AB); /* [AA|BB] = [A^2|B^2] */
118
+ add_EltFp25519_1w_x64(X3, DA, CB); /* X3 = (DA+CB) */
119
+ sub_EltFp25519_1w_x64(Z3, DA, CB); /* Z3 = (DA-CB) */
120
+ sqr_EltFp25519_2w_x64(X3Z3); /* [X3|Z3] = [(DA+CB)|(DA+CB)]^2 */
121
+
122
+ copy_EltFp25519_1w_x64(X2, B); /* X2 = B^2 */
123
+ sub_EltFp25519_1w_x64(Z2, A, B); /* Z2 = E = AA-BB */
124
+
125
+ mul_a24_EltFp25519_1w_x64(B, Z2); /* B = a24*E */
126
+ add_EltFp25519_1w_x64(B, B, X2); /* B = a24*E+B */
127
+ mul_EltFp25519_2w_x64(X2Z2, X2Z2, AB); /* [X2|Z2] = [B|E]*[A|a24*E+B] */
128
+ mul_EltFp25519_1w_x64(Z3, Z3, X1); /* Z3 = Z3*X1 */
129
+ j--;
130
+ }
131
+ j = 63;
132
+ }
133
+
134
+ inv_EltFp25519_1w_x64(A, Qz);
135
+ mul_EltFp25519_1w_x64((uint64_t *)shared, Qx, A);
136
+ fred_EltFp25519_1w_x64((uint64_t *)shared);
134
137
  }
135
138
 
136
- void x25519_precomputed_scalarmult_base(uint8_t *session_key, uint8_t *private_key)
137
- {
138
- ALIGN uint64_t buffer[4*NUM_WORDS_ELTFP25519_X64];
139
- ALIGN uint64_t coordinates[4*NUM_WORDS_ELTFP25519_X64];
140
- ALIGN uint64_t workspace[4*NUM_WORDS_ELTFP25519_X64];
141
- const int ite[4] = {64,64,64,63};
142
- const int q = 3;
143
- uint64_t swap = 1;
144
- uint64_t bit;
145
- uint64_t save;
146
-
147
- int i=0, j=0, k=0;
148
- uint64_t *const key = (uint64_t*)private_key;
149
- uint64_t *const Ur1 = coordinates+0;
150
- uint64_t *const Zr1 = coordinates+4;
151
- uint64_t *const Ur2 = coordinates+8;
152
- uint64_t *const Zr2 = coordinates+12;
153
-
154
- uint64_t *const UZr1 = coordinates+0;
155
- uint64_t *const ZUr2 = coordinates+8;
156
-
157
- uint64_t *const A = workspace+0;
158
- uint64_t *const B = workspace+4;
159
- uint64_t *const C = workspace+8;
160
- uint64_t *const D = workspace+12;
161
-
162
- uint64_t *const AB = workspace+0;
163
- uint64_t *const CD = workspace+8;
164
-
165
- uint64_t *const buffer_1w = buffer;
166
- uint64_t *const buffer_2w = buffer;
167
- uint64_t * P = (uint64_t *)Table_Ladder_8k;
168
-
169
- /* clampC function */
170
- save = private_key[X25519_KEYSIZE_BYTES-1]<<16 | private_key[0];
171
- private_key[0] = private_key[0] & (~(uint8_t)0x7);
172
- private_key[X25519_KEYSIZE_BYTES-1] = (uint8_t)64 | (private_key[X25519_KEYSIZE_BYTES-1] & (uint8_t)0x7F);
173
-
174
- setzero_EltFp25519_1w_x64(Ur1);
175
- setzero_EltFp25519_1w_x64(Zr1);
176
- setzero_EltFp25519_1w_x64(Zr2);
177
- Ur1[0] = 1;
178
- Zr1[0] = 1;
179
- Zr2[0] = 1;
180
-
181
- /* G-S */
182
- Ur2[3] = 0x1eaecdeee27cab34;
183
- Ur2[2] = 0xadc7a0b9235d48e2;
184
- Ur2[1] = 0xbbf095ae14b2edf8;
185
- Ur2[0] = 0x7e94e1fec82faabd;
186
-
187
- /* main-loop */
188
- j = q;
189
- for(i=0;i<NUM_WORDS_ELTFP25519_X64;i++)
190
- {
191
- while(j < ite[i])
192
- {
193
- k = (64*i+j-q);
194
- bit = (key[i]>>j)&0x1;
195
- swap = swap ^ bit;
196
- cswap_x64(swap, Ur1, Ur2);
197
- cswap_x64(swap, Zr1, Zr2);
198
- swap = bit;
199
- /** Addition */
200
- sub_EltFp25519_1w_x64(B, Ur1, Zr1); /* B = Ur1-Zr1 */
201
- add_EltFp25519_1w_x64(A, Ur1, Zr1); /* A = Ur1+Zr1 */
202
- mul_EltFp25519_1w_x64(C,&P[4*k],B); /* C = M0-B */
203
- sub_EltFp25519_1w_x64(B, A, C); /* B = (Ur1+Zr1) - M*(Ur1-Zr1) */
204
- add_EltFp25519_1w_x64(A, A, C); /* A = (Ur1+Zr1) + M*(Ur1-Zr1) */
205
- sqr_EltFp25519_2w_x64(AB); /* A = A^2 | B = B^2 */
206
- mul_EltFp25519_2w_x64(UZr1,ZUr2,AB); /* Ur1 = Zr2*A | Zr1 = Ur2*B */
207
- j++;
208
- }
209
- j = 0;
210
- }
211
-
212
- /** Doubling */
213
- for(i=0;i<q;i++)
214
- {
215
- add_EltFp25519_1w_x64(A, Ur1, Zr1); /* A = Ur1+Zr1 */
216
- sub_EltFp25519_1w_x64(B, Ur1, Zr1); /* B = Ur1-Zr1 */
217
- sqr_EltFp25519_2w_x64(AB); /* A = A**2 B = B**2 */
218
- copy_EltFp25519_1w_x64(C,B); /* C = B */
219
- sub_EltFp25519_1w_x64(B, A, B); /* B = A-B */
220
- mul_a24_EltFp25519_1w_x64(D, B); /* D = my_a24*B */
221
- add_EltFp25519_1w_x64(D, D, C); /* D = D+C */
222
- mul_EltFp25519_2w_x64(UZr1,AB,CD); /* Ur1 = A*B Zr1 = Zr1*A */
223
- }
224
-
225
- /* Convert to affine coordinates */
226
- inv_EltFp25519_1w_x64(A, Zr1);
227
- mul_EltFp25519_1w_x64((uint64_t*)session_key,Ur1,A);
228
- fred_EltFp25519_1w_x64((uint64_t *) session_key);
229
- private_key[X25519_KEYSIZE_BYTES-1] = (uint8_t)((save>>16) & 0xFF);
230
- private_key[0] = (uint8_t)(save & 0xFF);
139
+ /* Original rfc7748_precomputed name: 'x25519_keygen_precmp_x64' */
140
+ void x25519_precomputed_scalarmult_base(uint8_t *session_key, uint8_t *private_key) {
141
+ ALIGN uint64_t buffer[4 * NUM_WORDS_ELTFP25519_X64];
142
+ ALIGN uint64_t coordinates[4 * NUM_WORDS_ELTFP25519_X64];
143
+ ALIGN uint64_t workspace[4 * NUM_WORDS_ELTFP25519_X64];
144
+ ALIGN uint8_t private[X25519_KEYSIZE_BYTES];
145
+
146
+ int i = 0, j = 0, k = 0;
147
+ uint64_t *const key = (uint64_t *)private;
148
+ uint64_t *const Ur1 = coordinates + 0;
149
+ uint64_t *const Zr1 = coordinates + 4;
150
+ uint64_t *const Ur2 = coordinates + 8;
151
+ uint64_t *const Zr2 = coordinates + 12;
152
+
153
+ uint64_t *const UZr1 = coordinates + 0;
154
+ uint64_t *const ZUr2 = coordinates + 8;
155
+
156
+ uint64_t *const A = workspace + 0;
157
+ uint64_t *const B = workspace + 4;
158
+ uint64_t *const C = workspace + 8;
159
+ uint64_t *const D = workspace + 12;
160
+
161
+ uint64_t *const AB = workspace + 0;
162
+ uint64_t *const CD = workspace + 8;
163
+
164
+ uint64_t *const buffer_1w = buffer;
165
+ uint64_t *const buffer_2w = buffer;
166
+ uint64_t *P = (uint64_t *)Table_Ladder_8k;
167
+
168
+ memcpy(private, private_key, sizeof(private));
169
+
170
+ /* clampC function */
171
+ private
172
+ [0] = private[0] & (~(uint8_t)0x7);
173
+ private
174
+ [X25519_KEYSIZE_BYTES - 1] =
175
+ (uint8_t)64 | (private[X25519_KEYSIZE_BYTES - 1] & (uint8_t)0x7F);
176
+
177
+ setzero_EltFp25519_1w_x64(Ur1);
178
+ setzero_EltFp25519_1w_x64(Zr1);
179
+ setzero_EltFp25519_1w_x64(Zr2);
180
+ Ur1[0] = 1;
181
+ Zr1[0] = 1;
182
+ Zr2[0] = 1;
183
+
184
+ /* G-S */
185
+ Ur2[3] = 0x1eaecdeee27cab34;
186
+ Ur2[2] = 0xadc7a0b9235d48e2;
187
+ Ur2[1] = 0xbbf095ae14b2edf8;
188
+ Ur2[0] = 0x7e94e1fec82faabd;
189
+
190
+ /* main-loop */
191
+ const int ite[4] = {64, 64, 64, 63};
192
+ const int q = 3;
193
+ uint64_t swap = 1;
194
+
195
+ j = q;
196
+ for (i = 0; i < NUM_WORDS_ELTFP25519_X64; i++) {
197
+ while (j < ite[i]) {
198
+ k = (64 * i + j - q);
199
+ uint64_t bit = (key[i] >> j) & 0x1;
200
+ swap = swap ^ bit;
201
+ cswap_x64(swap, Ur1, Ur2);
202
+ cswap_x64(swap, Zr1, Zr2);
203
+ swap = bit;
204
+ /** Addition */
205
+ sub_EltFp25519_1w_x64(B, Ur1, Zr1); /* B = Ur1-Zr1 */
206
+ add_EltFp25519_1w_x64(A, Ur1, Zr1); /* A = Ur1+Zr1 */
207
+ mul_EltFp25519_1w_x64(C, &P[4 * k], B); /* C = M0-B */
208
+ sub_EltFp25519_1w_x64(B, A, C); /* B = (Ur1+Zr1) - M*(Ur1-Zr1) */
209
+ add_EltFp25519_1w_x64(A, A, C); /* A = (Ur1+Zr1) + M*(Ur1-Zr1) */
210
+ sqr_EltFp25519_2w_x64(AB); /* A = A^2 | B = B^2 */
211
+ mul_EltFp25519_2w_x64(UZr1, ZUr2, AB); /* Ur1 = Zr2*A | Zr1 = Ur2*B */
212
+ j++;
213
+ }
214
+ j = 0;
215
+ }
216
+
217
+ /** Doubling */
218
+ for (i = 0; i < q; i++) {
219
+ add_EltFp25519_1w_x64(A, Ur1, Zr1); /* A = Ur1+Zr1 */
220
+ sub_EltFp25519_1w_x64(B, Ur1, Zr1); /* B = Ur1-Zr1 */
221
+ sqr_EltFp25519_2w_x64(AB); /* A = A**2 B = B**2 */
222
+ copy_EltFp25519_1w_x64(C, B); /* C = B */
223
+ sub_EltFp25519_1w_x64(B, A, B); /* B = A-B */
224
+ mul_a24_EltFp25519_1w_x64(D, B); /* D = my_a24*B */
225
+ add_EltFp25519_1w_x64(D, D, C); /* D = D+C */
226
+ mul_EltFp25519_2w_x64(UZr1, AB, CD); /* Ur1 = A*B Zr1 = Zr1*A */
227
+ }
228
+
229
+ /* Convert to affine coordinates */
230
+ inv_EltFp25519_1w_x64(A, Zr1);
231
+ mul_EltFp25519_1w_x64((uint64_t *)session_key, Ur1, A);
232
+ fred_EltFp25519_1w_x64((uint64_t *)session_key);
231
233
  }