Я скачал пакет кода Keccak (сейчас XKCP), потому что мне интересны все функции, которые он предоставляет, и я хотел бы использовать их в своем «проекте», так мы его назовем.
Проблема в том, что я программирую свой проект с использованием Microsoft Visual Studio Community 2017 ... Я объясню:
На самом деле, я пытаюсь внедрить Keyak Lake в свой проект и, особенно, реализацию Keyak Lake, которая использует ускорения SIMD. Но код, который поставляется с KCP (Keccak Code Package), предназначен для GCC, а не для VS, и, следовательно, его трудно скомпилировать в Visual Studio, и в основном из-за приведений (__m128d) и (__m128i) в макросы, используемые в реализации SIMD на озере Кейак. GCC разрешает такие виды приведения, но Visual Studio не делает так, чтобы код не работал как есть, вы должны переработать его, используя _mm_castpd_si128 и такие ...
Итак, вот что я попробовал:
Я заменил все макросы их эквивалентным кодом, используя -E в GCC. Фактически, я получил код после работы препроцессора, поэтому все макросы развернуты, полностью записаны, а затем я заменил все приведения, которые не были приняты Visual Studio, их внутренними эквивалентами.
И, наконец, я мог бы получить код для компиляции в Visual Studio, но он все еще не работает нормально.
Вот ошибка:
void KeccakP1600_Permute_12rounds(void *state)
{
//All the variables like Abae, Cae, Akimo etc... are ALL __m128i variables
//state is an unsigned char[200]
UINT64 *stateAsLanes = (UINT64*)state;
Abae = _mm_load_si128((const __m128i *)&(stateAsLanes[0]));
Aba = Abae;
Abe = _mm_unpackhi_epi64(Abae, Abae);
Cae = Abae;
Abio = _mm_load_si128((const __m128i *)&(stateAsLanes[2]));
Abi = Abio;
Abo = _mm_unpackhi_epi64(Abio, Abio);
Cio = Abio;
Abu = _mm_loadl_epi64((const __m128i *)&(stateAsLanes[4]));
Cua = Abu;
Agae = _mm_loadu_si128((const __m128i *)&(stateAsLanes[5]));
Aga = Agae;
Abuga = _mm_unpacklo_epi64(Abu, Aga);
Age = _mm_unpackhi_epi64(Agae, Agae);
Abage = _mm_unpacklo_epi64(Aba, Age);
Cae = _mm_xor_si128(Cae, Agae);
Agio = _mm_loadu_si128((const __m128i *)&(stateAsLanes[7]));
Agi = Agio;
Abegi = _mm_unpacklo_epi64(Abe, Agi);
Ago = _mm_unpackhi_epi64(Agio, Agio);
Abigo = _mm_unpacklo_epi64(Abi, Ago);
Cio = _mm_xor_si128(Cio, Agio);
Agu = _mm_loadl_epi64((const __m128i *)&(stateAsLanes[9]));
Abogu = _mm_unpacklo_epi64(Abo, Agu);
Cua = _mm_xor_si128(Cua, Agu);
Akae = _mm_load_si128((const __m128i *)&(stateAsLanes[10]));
Aka = Akae;
Ake = _mm_unpackhi_epi64(Akae, Akae);
Cae = _mm_xor_si128(Cae, Akae);
Akio = _mm_load_si128((const __m128i *)&(stateAsLanes[12]));
Aki = Akio;
Ako = _mm_unpackhi_epi64(Akio, Akio);
Cio = _mm_xor_si128(Cio, Akio);
Akuma = _mm_load_si128((const __m128i *)&(stateAsLanes[14]));
Cua = _mm_xor_si128(Cua, Akuma);
Ame = _mm_loadl_epi64((const __m128i *)&(stateAsLanes[16]));
Akame = _mm_unpacklo_epi64(Aka, Ame);
Cae = _mm_xor_si128(Cae, _mm_unpackhi_epi64(Akuma, Akame));
Amio = _mm_loadu_si128((const __m128i *)&(stateAsLanes[17]));
Ami = Amio;
Akemi = _mm_unpacklo_epi64(Ake, Ami);
Amo = _mm_unpackhi_epi64(Amio, Amio);
Akimo = _mm_unpacklo_epi64(Aki, Amo);
Cio = _mm_xor_si128(Cio, Amio);
Amu = _mm_loadl_epi64((const __m128i *)&(stateAsLanes[19]));
Akomu = _mm_unpacklo_epi64(Ako, Amu);
Cua = _mm_xor_si128(Cua, Amu);
Asase = _mm_load_si128((const __m128i *)&(stateAsLanes[20]));
Cae = _mm_xor_si128(Cae, Asase);
Asiso = _mm_load_si128((const __m128i *)&(stateAsLanes[22]));
//Error here, last line. Access violation reading location.
Дело в том, что когда оптимизация компилятора не включена, код работает нормально, без ошибок, но как только вы включаете Full Speed Optimization, появляется нарушение чтения при нарушении прав доступа. Не говоря уже о том, что этот код работает на GCC независимо от оптимизации.
У вас могут быть некоторые решения для нарушения чтения или даже некоторые решения о том, как превратить этот «только код GCC» в компилируемый код Visual Studio.