Придумал более эффективную реализацию функции умножения в поле GF128, на которой строится фукнция POLYVAL и GHASH. Делюсь..
Записал с использованием макро определений инструкций.
// Алгоритм умножения на инструкциях умжножения без переноса (PCLMUL).
__m128i gmul128r(__m128i a, const __m128i b)
{
const __m128i poly = _mm_setr_epi32(0x1,0,0,0xc2000000);
__m128i M,L,H;
L = _mm_clmulepi64_si128(a, b, 0x00);
M = _mm_clmulepi64_si128(a, b, 0x01);
M^= _mm_clmulepi64_si128(a, b, 0x10);
H = _mm_clmulepi64_si128(a, b, 0x11);
// редуцирование poly = 1.C2...01
M^= _mm_shuffle_epi32(L, 78);
M^= _mm_clmulepi64_si128(L, poly, 0x10);
// редуцирование
H^= _mm_shuffle_epi32(M, 78);
H^= _mm_clmulepi64_si128(M, poly, 0x10);
return H;
}
// Функция расчета кода аутентификации
__m128i POLYVAL(__m128i y, __m128i h, const uint8_t *data, int len)
{
__m128i x;
int i=0;
int blocks = len>>4;
for (i=0; i<blocks; i++){
__builtin_memcpy(&x, data, 16); data+=16;
y = gmul128r((y^x), h);
}
if (len & 0xF){
x ^= x;
__builtin_memcpy(&x, data, len&0xF);
y = gmul128r((y^x), h);
}
return y;
}
// Функция расчета кода аутентификации
__m128i GHASH(__m128i y, __m128i h, const uint8_t *data, int len)
{
int i=0;
__m128i x;
h = SLM128(h);// -- сдвиг с редуцированием, можно вынести из функции
int blocks = len>>4;
for (i=0; i<blocks; i++){
__builtin_memcpy(&x, data, 16); data+=16;
y = gmul128r((y^x), h);
}
if (len &0xF){
x ^= x;
__builtin_memcpy((uint8_t*)&x +(16-(len&0xF)), data, len&0xF);
y = gmul128r((y^x), h);
}
return y;
}
Тут достижение в оптимизации фукнции редуцирования. Редуцирование выполняется по промежуточному значению M. Этот алгоритм меньше на три векторных инструкции, чем референсный [RFC8452]. Чтобы убедиться, надо лезть на github и сравнивать реализации[AES-GCM-SIV].
- [RFC 8452] AES-GCM-SIV, Gueron, et al., April 2019
- [AES-GCM-SIV] https://github.com/Shay-Gueron/AES-GCM-SIV
- [1] Enabling High-Performance Galois-Counter-Mode on Intel® Architecture Processors, 2012
- [2] Optimized Galois-Counter-Mode Implementation on Intel® Architecture Processors, 2010
- [3] Intel® Carry-Less Multiplication Instruction and its Usage for Computing the GCM Mode, 2009-2014
Комментариев нет:
Отправить комментарий