ReactOS
0.4.17-dev-1005-g171e1de
xtsaes_definitions.h
Go to the documentation of this file.
1
//
2
// xtsaes_definitions.h
3
//
4
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5
//
6
7
//
8
// Multiply by alpha
9
//
10
// <</>> indicate shifts on 128-bit values
11
// <<<</>>>> indicate shifts on 32-bit values (a word)
12
//
13
14
// Multiply by ALPHA
15
// Since there's no instruction to shift the 128 bit register left by one, the following shifts do the trick.
16
// All shifts are zero extended
17
// t1 = _in <<<< 1 words shifted left by 1, this is almost a _in << 1 but there are
18
// gaps at first bit of each word, the following two shifts fixes that.
19
// t2 = _in >>>> 31 words shifted right by 31
20
// t1 = t1 ^ (t2 << 32) t1 = _in << 1, note ^ could be |
21
// Do the special case for first byte of _in where last carry means xor with 135 for first byte.
22
// t2 = t2 >> 96 t2 = _in >> 127, i.e., last bit of _in is placed in first bit
23
// t2 = (t2 <<<< 7) + (t2 <<<<3) - (t2) t2 = 135 if last bit of t2 is set
24
// res = t1 ^ t2
25
#define XTS_MUL_ALPHA_old( _in, _res ) \
26
{\
27
__m128i _t1, _t2;\
28
\
29
_t1 = _mm_slli_epi32( _in, 1 ); \
30
_t2 = _mm_srli_epi32( _in, 31); \
31
_t1 = _mm_xor_si128( _t1, _mm_slli_si128( _t2, 4 )); \
32
_t2 = _mm_srli_si128( _t2, 12 ); \
33
_t2 = _mm_sub_epi32( _mm_add_epi32( _mm_slli_epi32( _t2, 7 ), _mm_slli_epi32( _t2, 3 ) ), _t2 ); \
34
_res = _mm_xor_si128( _t1, _t2 ); \
35
}
36
37
// An improved approach; use arithmetic shift-right to duplicate the carry-out, PSHUFD to re-arrange, and an AND to
38
// implement both the polynomial and mask the other words down to 1 bit again.
39
40
// __m128i XTS_ALPHA_MASK = _mm_set_epi32( 1, 1, 1, 0x87 );
41
#define XTS_MUL_ALPHA( _in, _res ) \
42
{\
43
__m128i _t1, _t2;\
44
\
45
_t1 = _mm_slli_epi32( _in, 1 ); \
46
_t2 = _mm_srai_epi32( _in, 31); \
47
_t2 = _mm_shuffle_epi32( _t2, _MM_SHUFFLE( 2, 1, 0, 3 ) ); \
48
_t2 = _mm_and_si128( _t2, XTS_ALPHA_MASK ); \
49
_res = _mm_xor_si128( _t1, _t2 ); \
50
}
51
52
// Like XTS_MUL_ALPHA_old but operate on __m512i for _in and _res.
53
// TODO: do this with VSHUFPS.
54
#define XTS_MUL_ALPHA_ZMM_old( _in, _res ) \
55
{\
56
__m512i _t1, _t2;\
57
\
58
_t1 = _mm512_slli_epi32( _in, 1 ); \
59
_t2 = _mm512_srli_epi32( _in, 31); \
60
_t1 = _mm512_xor_si512( _t1, _mm512_bslli_epi128( _t2, 4 )); \
61
_t2 = _mm512_bsrli_epi128( _t2, 12 ); \
62
_t2 = _mm512_sub_epi32( _mm512_add_epi32( _mm512_slli_epi32( _t2, 7 ), _mm512_slli_epi32( _t2, 3 ) ), _t2 ); \
63
_res = _mm512_xor_si512( _t1, _t2 ); \
64
}
65
66
// Multiply by ALPHA^2
67
// t1 = Input <<<< 2
68
// t2 = Input >>>> 30
69
// t1 = t1 ^ (t2 << 32)
70
// t2 = t2 >> 96
71
// t2 = (t2 <<<< 7) ^ (t2 <<<< 2) ^ (t2 <<<< 1) ^ t2
72
// res = t1 ^ t2
73
#define XTS_MUL_ALPHA2( _in, _res ) \
74
{\
75
__m128i _t1, _t2;\
76
\
77
_t1 = _mm_slli_epi32( _in, 2 ); \
78
_t2 = _mm_srli_epi32( _in, 30); \
79
_t1 = _mm_xor_si128( _t1, _mm_slli_si128( _t2, 4 )); \
80
_t2 = _mm_srli_si128( _t2, 12 ); \
81
_t2 = _mm_xor_si128( _mm_xor_si128( _mm_xor_si128( _mm_slli_epi32( _t2, 7 ), _mm_slli_epi32( _t2, 2 ) ), _mm_slli_epi32( _t2, 1 )), _t2 ); \
82
_res = _mm_xor_si128( _t1, _t2 ); \
83
}
84
85
// Multiply by ALPHA^4
86
// t1 = Input <<<< 4
87
// t2 = Input >>>> 28
88
// t1 = t1 ^ (t2 << 32)
89
// t2 = t2 >> 96
90
// t2 = (t2 <<<< 7) ^ (t2 <<<< 2) ^ (t2 <<<< 1) ^ t2
91
// res = t1 ^ t2
92
#define XTS_MUL_ALPHA4( _in, _res ) \
93
{\
94
__m128i _t1, _t2;\
95
\
96
_t1 = _mm_slli_epi32( _in, 4 ); \
97
_t2 = _mm_srli_epi32( _in, 28); \
98
_t1 = _mm_xor_si128( _t1, _mm_slli_si128( _t2, 4 )); \
99
_t2 = _mm_srli_si128( _t2, 12 ); \
100
_t2 = _mm_xor_si128( _mm_xor_si128( _mm_xor_si128( _mm_slli_epi32( _t2, 7 ), _mm_slli_epi32( _t2, 2 ) ), _mm_slli_epi32( _t2, 1 )), _t2 ); \
101
_res = _mm_xor_si128( _t1, _t2 ); \
102
}
103
104
#define XTS_MUL_ALPHA5( _in, _res ) \
105
{\
106
__m128i _t1, _t2;\
107
\
108
_t1 = _mm_slli_epi32( _in, 5 ); \
109
_t2 = _mm_srli_epi32( _in, 27); \
110
_t1 = _mm_xor_si128( _t1, _mm_slli_si128( _t2, 4 )); \
111
_t2 = _mm_srli_si128( _t2, 12 ); \
112
_t2 = _mm_xor_si128( _mm_xor_si128( _mm_xor_si128( _mm_slli_epi32( _t2, 7 ), _mm_slli_epi32( _t2, 2 ) ), _mm_slli_epi32( _t2, 1 )), _t2 ); \
113
_res = _mm_xor_si128( _t1, _t2 ); \
114
}
115
116
117
// Multiply by ALPHA^8
118
// t2 = Input >> 120
119
// t2 = (t2 <<<< 7) ^ (t2 <<<< 2) ^ (t2 <<<< 1) ^ t2
120
// res = (Input << 8) ^ t2
121
//
122
// Only currently used with VPCLMULQDQ (in Ymm / Zmm versions) as support for non-vectorized PCLMULQDQ is not always supported with AESNI,
123
// and is sometimes slower than shift+xor
124
125
// __m256i XTS_ALPHA_MULTIPLIER_Ymm = _mm256_set_epi64x( 0, 0x87, 0, 0x87);
126
#define XTS_MUL_ALPHA8_YMM( _in, _res ) \
127
{\
128
__m256i _t2;\
129
\
130
_t2 = _mm256_srli_si256( _in, 15 );
/* AVX2 */
\
131
_res = _mm256_slli_si256( _in, 1 ); \
132
_t2 = _mm256_clmulepi64_epi128( _t2, XTS_ALPHA_MULTIPLIER_Ymm, 0x00 ); \
133
_res = _mm256_xor_si256( _res, _t2 ); \
134
}
135
136
#define XTS_MUL_ALPHA16_YMM( _in, _res ) \
137
{\
138
__m256i _t2;\
139
\
140
_t2 = _mm256_srli_si256( _in, 14 );
/* AVX2 */
\
141
_res = _mm256_slli_si256( _in, 2 ); \
142
_t2 = _mm256_clmulepi64_epi128( _t2, XTS_ALPHA_MULTIPLIER_Ymm, 0x00 ); \
143
_res = _mm256_xor_si256( _res, _t2 ); \
144
}
145
146
// __m512i XTS_ALPHA_MULTIPLIER_Zmm = _mm512_set_epi64( 0, 0x87, 0, 0x87, 0, 0x87, 0, 0x87 );
147
#define XTS_MUL_ALPHA8_ZMM( _in, _res ) \
148
{\
149
__m512i _t2; \
150
\
151
_t2 = _mm512_bsrli_epi128( _in, 15 ); \
152
_res = _mm512_bslli_epi128( _in, 1 ); \
153
_t2 = _mm512_clmulepi64_epi128( _t2, XTS_ALPHA_MULTIPLIER_Zmm, 0x00 ); \
154
_res = _mm512_xor_si512( _res, _t2 ); \
155
}
156
157
#define XTS_MUL_ALPHA16_ZMM( _in, _res ) \
158
{\
159
__m512i _t2; \
160
\
161
_t2 = _mm512_bsrli_epi128( _in, 14 ); \
162
_res = _mm512_bslli_epi128( _in, 2 ); \
163
_t2 = _mm512_clmulepi64_epi128( _t2, XTS_ALPHA_MULTIPLIER_Zmm, 0x00 ); \
164
_res = _mm512_xor_si512( _res, _t2 ); \
165
}
166
167
// Currently only use UINT64 for x86 and amd64 - this does regress perf on x86
168
// but we don't expect a lot of XTS in x86. If the regression causes any real problems
169
// we can consider introducing another variant. Not doing this now to avoid code bloat
170
#define XTS_MUL_ALPHA_Scalar( _inout_low_u64, _inout_high_u64 ) \
171
{ \
172
UINT64 tmp = (UINT64) ((INT64)_inout_high_u64 >> 63); \
173
\
174
_inout_high_u64 = (_inout_high_u64 << 1) ^ (_inout_low_u64 >> 63); \
175
_inout_low_u64 = (_inout_low_u64 << 1) ^ (tmp & 0x87); \
176
}
sdk
lib
3rdparty
symcrypt
lib
xtsaes_definitions.h
Generated on Tue Oct 6 2026 06:20:11 for ReactOS by
1.9.6