SuperTuxKart 1.5 upstream source (from official release tarball)
This commit is contained in:
@@ -0,0 +1,417 @@
|
||||
/* MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(SIMDE_X86_AES_H)
|
||||
#define SIMDE_X86_AES_H
|
||||
|
||||
/*
|
||||
* Advanced Encryption Standard
|
||||
* @author Dani Huertas
|
||||
* @email huertas.dani@gmail.com
|
||||
*
|
||||
* Based on the document FIPS PUB 197
|
||||
*/
|
||||
|
||||
#include "sse2.h"
|
||||
|
||||
/*
|
||||
* Multiplication in GF(2^8)
|
||||
* http://en.wikipedia.org/wiki/Finite_field_arithmetic
|
||||
* Irreducible polynomial m(x) = x8 + x4 + x3 + x + 1
|
||||
*
|
||||
* NOTE: This function can be easily replaced with a look up table for a speed
|
||||
* boost, at the expense of an increase in memory size.
|
||||
|
||||
SIMDE_FUNCTION_ATTRIBUTES
|
||||
uint8_t gmult(uint8_t a, uint8_t b) {
|
||||
uint8_t p = 0, i = 0, hbs = 0;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (b & 1) {
|
||||
p ^= a;
|
||||
}
|
||||
|
||||
hbs = a & 0x80;
|
||||
a <<= 1;
|
||||
if (hbs) a ^= 0x1b; // 0000 0001 0001 1011
|
||||
b >>= 1;
|
||||
}
|
||||
|
||||
return (uint8_t)p;
|
||||
}
|
||||
*/
|
||||
|
||||
#if !(defined(SIMDE_ARM_NEON_A32V7_NATIVE) && defined(SIMDE_ARCH_ARM_CRYPTO))
|
||||
|
||||
#include "../simde-aes.h"
|
||||
|
||||
/*
|
||||
* Transformation in the Cipher and Inverse Cipher in which a Round
|
||||
* Key is added to the State using an XOR operation. The length of a
|
||||
* Round Key equals the size of the State (i.e., for Nb = 4, the Round
|
||||
* Key length equals 128 bits/16 bytes).
|
||||
*/
|
||||
SIMDE_FUNCTION_ATTRIBUTES
|
||||
void simde_x_aes_add_round_key(uint8_t *state, simde__m128i_private w, uint8_t r) {
|
||||
|
||||
int Nb = simde_x_aes_Nb;
|
||||
uint8_t c;
|
||||
|
||||
for (c = 0; c < Nb; c++) {
|
||||
state[Nb*0+c] = state[Nb*0+c]^w.u8[4*Nb*r+4*c+0];
|
||||
state[Nb*1+c] = state[Nb*1+c]^w.u8[4*Nb*r+4*c+1];
|
||||
state[Nb*2+c] = state[Nb*2+c]^w.u8[4*Nb*r+4*c+2];
|
||||
state[Nb*3+c] = state[Nb*3+c]^w.u8[4*Nb*r+4*c+3];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Transformation in the Cipher that takes all of the columns of the
|
||||
* State and mixes their data (independently of one another) to
|
||||
* produce new columns.
|
||||
*/
|
||||
SIMDE_FUNCTION_ATTRIBUTES
|
||||
void simde_x_aes_mix_columns(uint8_t *state) {
|
||||
|
||||
int Nb = simde_x_aes_Nb;
|
||||
// uint8_t k[] = {0x02, 0x01, 0x01, 0x03}; // a(x) = {02} + {01}x + {01}x2 + {03}x3
|
||||
uint8_t i, j, col[4], res[4];
|
||||
|
||||
for (j = 0; j < Nb; j++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
col[i] = state[Nb*i+j];
|
||||
}
|
||||
|
||||
//coef_mult(k, col, res);
|
||||
simde_x_aes_coef_mult_lookup(0, col, res);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
state[Nb*i+j] = res[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Transformation in the Inverse Cipher that is the inverse of
|
||||
* MixColumns().
|
||||
*/
|
||||
SIMDE_FUNCTION_ATTRIBUTES
|
||||
void simde_x_aes_inv_mix_columns(uint8_t *state) {
|
||||
|
||||
int Nb = simde_x_aes_Nb;
|
||||
// uint8_t k[] = {0x0e, 0x09, 0x0d, 0x0b}; // a(x) = {0e} + {09}x + {0d}x2 + {0b}x3
|
||||
uint8_t i, j, col[4], res[4];
|
||||
|
||||
for (j = 0; j < Nb; j++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
col[i] = state[Nb*i+j];
|
||||
}
|
||||
|
||||
//coef_mult(k, col, res);
|
||||
simde_x_aes_coef_mult_lookup(4, col, res);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
state[Nb*i+j] = res[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Transformation in the Cipher that processes the State by cyclically
|
||||
* shifting the last three rows of the State by different offsets.
|
||||
*/
|
||||
SIMDE_FUNCTION_ATTRIBUTES
|
||||
void simde_x_aes_shift_rows(uint8_t *state) {
|
||||
|
||||
int Nb = simde_x_aes_Nb;
|
||||
uint8_t i, k, s, tmp;
|
||||
|
||||
for (i = 1; i < 4; i++) {
|
||||
// shift(1,4)=1; shift(2,4)=2; shift(3,4)=3
|
||||
// shift(r, 4) = r;
|
||||
s = 0;
|
||||
while (s < i) {
|
||||
tmp = state[Nb*i+0];
|
||||
|
||||
for (k = 1; k < Nb; k++) {
|
||||
state[Nb*i+k-1] = state[Nb*i+k];
|
||||
}
|
||||
|
||||
state[Nb*i+Nb-1] = tmp;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Transformation in the Inverse Cipher that is the inverse of
|
||||
* ShiftRows().
|
||||
*/
|
||||
SIMDE_FUNCTION_ATTRIBUTES
|
||||
void simde_x_aes_inv_shift_rows(uint8_t *state) {
|
||||
|
||||
uint8_t Nb = simde_x_aes_Nb;
|
||||
uint8_t i, k, s, tmp;
|
||||
|
||||
for (i = 1; i < 4; i++) {
|
||||
s = 0;
|
||||
while (s < i) {
|
||||
tmp = state[Nb*i+Nb-1];
|
||||
|
||||
for (k = Nb-1; k > 0; k--) {
|
||||
state[Nb*i+k] = state[Nb*i+k-1];
|
||||
}
|
||||
|
||||
state[Nb*i+0] = tmp;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Transformation in the Cipher that processes the State using a non
|
||||
* linear byte substitution table (S-box) that operates on each of the
|
||||
* State bytes independently.
|
||||
*/
|
||||
SIMDE_FUNCTION_ATTRIBUTES
|
||||
void simde_x_aes_sub_bytes(uint8_t *state) {
|
||||
|
||||
int Nb = simde_x_aes_Nb;
|
||||
uint8_t i, j;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < Nb; j++) {
|
||||
// s_box row: yyyy ----
|
||||
// s_box col: ---- xxxx
|
||||
// s_box[16*(yyyy) + xxxx] == s_box[yyyyxxxx]
|
||||
state[Nb*i+j] = simde_x_aes_s_box[state[Nb*i+j]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Transformation in the Inverse Cipher that is the inverse of
|
||||
* SubBytes().
|
||||
*/
|
||||
SIMDE_FUNCTION_ATTRIBUTES
|
||||
void simde_x_aes_inv_sub_bytes(uint8_t *state) {
|
||||
|
||||
int Nb = simde_x_aes_Nb;
|
||||
uint8_t i, j;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < Nb; j++) {
|
||||
state[Nb*i+j] = simde_x_aes_inv_s_box[state[Nb*i+j]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Performs the AES cipher operation
|
||||
*/
|
||||
SIMDE_FUNCTION_ATTRIBUTES
|
||||
void simde_x_aes_enc(simde__m128i_private in, simde__m128i_private *out, simde__m128i_private w, int is_last) {
|
||||
|
||||
int Nb = simde_x_aes_Nb;
|
||||
uint8_t state[4*simde_x_aes_Nb];
|
||||
uint8_t r = 0, i, j;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < Nb; j++) {
|
||||
state[Nb*i+j] = in.u8[i+4*j];
|
||||
}
|
||||
}
|
||||
|
||||
simde_x_aes_sub_bytes(state);
|
||||
simde_x_aes_shift_rows(state);
|
||||
|
||||
if (!is_last)
|
||||
simde_x_aes_mix_columns(state);
|
||||
|
||||
simde_x_aes_add_round_key(state, w, r);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < Nb; j++) {
|
||||
out->u8[i+4*j] = state[Nb*i+j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Performs the AES inverse cipher operation
|
||||
*/
|
||||
SIMDE_FUNCTION_ATTRIBUTES
|
||||
void simde_x_aes_dec(simde__m128i_private in, simde__m128i_private *out, simde__m128i_private w, int is_last) {
|
||||
|
||||
int Nb = simde_x_aes_Nb;
|
||||
uint8_t state[4*simde_x_aes_Nb];
|
||||
uint8_t r = 0, i, j;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < Nb; j++) {
|
||||
state[Nb*i+j] = in.u8[i+4*j];
|
||||
}
|
||||
}
|
||||
|
||||
simde_x_aes_inv_shift_rows(state);
|
||||
simde_x_aes_inv_sub_bytes(state);
|
||||
|
||||
if (!is_last)
|
||||
simde_x_aes_inv_mix_columns(state);
|
||||
|
||||
simde_x_aes_add_round_key(state, w, r);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < Nb; j++) {
|
||||
out->u8[i+4*j] = state[Nb*i+j];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // if !(defined(SIMDE_ARM_NEON_A32V7_NATIVE) && defined(SIMDE_ARCH_ARM_CRYPTO))
|
||||
|
||||
SIMDE_FUNCTION_ATTRIBUTES
|
||||
simde__m128i simde_mm_aesenc_si128(simde__m128i a, simde__m128i round_key) {
|
||||
#if defined(SIMDE_X86_AES_NATIVE)
|
||||
return _mm_aesenc_si128(a, round_key);
|
||||
#else
|
||||
simde__m128i_private result_;
|
||||
simde__m128i_private a_ = simde__m128i_to_private(a);
|
||||
simde__m128i_private round_key_ = simde__m128i_to_private(round_key);
|
||||
#if defined(SIMDE_ARM_NEON_A32V8_NATIVE) && defined(SIMDE_ARCH_ARM_CRYPTO)
|
||||
result_.neon_u8 = veorq_u8(
|
||||
vaesmcq_u8(vaeseq_u8(a_.neon_u8, vdupq_n_u8(0))),
|
||||
round_key_.neon_u8);
|
||||
#else
|
||||
simde_x_aes_enc(a_, &result_, round_key_, 0);
|
||||
#endif
|
||||
return simde__m128i_from_private(result_);
|
||||
#endif
|
||||
}
|
||||
#if defined(SIMDE_X86_AES_ENABLE_NATIVE_ALIASES)
|
||||
#define _mm_aesenc_si128(a, b) simde_mm_aesenc_si128(a, b)
|
||||
#endif
|
||||
|
||||
SIMDE_FUNCTION_ATTRIBUTES
|
||||
simde__m128i simde_mm_aesdec_si128(simde__m128i a, simde__m128i round_key) {
|
||||
#if defined(SIMDE_X86_AES_NATIVE)
|
||||
return _mm_aesdec_si128(a, round_key);
|
||||
#else
|
||||
simde__m128i_private result_;
|
||||
simde__m128i_private a_ = simde__m128i_to_private(a);
|
||||
simde__m128i_private round_key_ = simde__m128i_to_private(round_key);
|
||||
#if defined(SIMDE_ARM_NEON_A32V8_NATIVE) && defined(SIMDE_ARCH_ARM_CRYPTO)
|
||||
result_.neon_u8 = veorq_u8(
|
||||
vaesimcq_u8(vaesdq_u8(a_.neon_u8, vdupq_n_u8(0))),
|
||||
round_key_.neon_u8);
|
||||
#else
|
||||
simde_x_aes_dec(a_, &result_, round_key_, 0);
|
||||
#endif
|
||||
return simde__m128i_from_private(result_);
|
||||
#endif
|
||||
}
|
||||
#if defined(SIMDE_X86_AES_ENABLE_NATIVE_ALIASES)
|
||||
#define _mm_aesdec_si128(a, b) simde_mm_aesdec_si128(a, b)
|
||||
#endif
|
||||
|
||||
SIMDE_FUNCTION_ATTRIBUTES
|
||||
simde__m128i simde_mm_aesenclast_si128(simde__m128i a, simde__m128i round_key) {
|
||||
#if defined(SIMDE_X86_AES_NATIVE)
|
||||
return _mm_aesenclast_si128(a, round_key);
|
||||
#else
|
||||
simde__m128i_private result_;
|
||||
simde__m128i_private a_ = simde__m128i_to_private(a);
|
||||
simde__m128i_private round_key_ = simde__m128i_to_private(round_key);
|
||||
#if defined(SIMDE_ARM_NEON_A32V8_NATIVE) && defined(SIMDE_ARCH_ARM_CRYPTO)
|
||||
result_.neon_u8 = vaeseq_u8(a_.neon_u8, vdupq_n_u8(0));
|
||||
result_.neon_i32 = veorq_s32(result_.neon_i32, round_key_.neon_i32); // _mm_xor_si128
|
||||
#else
|
||||
simde_x_aes_enc(a_, &result_, round_key_, 1);
|
||||
#endif
|
||||
return simde__m128i_from_private(result_);
|
||||
#endif
|
||||
}
|
||||
#if defined(SIMDE_X86_AES_ENABLE_NATIVE_ALIASES)
|
||||
#define _mm_aesenclast_si128(a, b) simde_mm_aesenclast_si128(a, b)
|
||||
#endif
|
||||
|
||||
SIMDE_FUNCTION_ATTRIBUTES
|
||||
simde__m128i simde_mm_aesdeclast_si128(simde__m128i a, simde__m128i round_key) {
|
||||
#if defined(SIMDE_X86_AES_NATIVE)
|
||||
return _mm_aesdeclast_si128(a, round_key);
|
||||
#else
|
||||
simde__m128i_private result_;
|
||||
simde__m128i_private a_ = simde__m128i_to_private(a);
|
||||
simde__m128i_private round_key_ = simde__m128i_to_private(round_key);
|
||||
#if defined(SIMDE_ARM_NEON_A32V8_NATIVE) && defined(SIMDE_ARCH_ARM_CRYPTO)
|
||||
result_.neon_u8 = veorq_u8(
|
||||
vaesdq_u8(a_.neon_u8, vdupq_n_u8(0)),
|
||||
round_key_.neon_u8);
|
||||
#else
|
||||
simde_x_aes_dec(a_, &result_, round_key_, 1);
|
||||
#endif
|
||||
return simde__m128i_from_private(result_);
|
||||
#endif
|
||||
}
|
||||
#if defined(SIMDE_X86_AES_ENABLE_NATIVE_ALIASES)
|
||||
#define _mm_aesdeclast_si128(a, b) simde_mm_aesdeclast_si128(a, b)
|
||||
#endif
|
||||
|
||||
SIMDE_FUNCTION_ATTRIBUTES
|
||||
simde__m128i simde_mm_aesimc_si128(simde__m128i a) {
|
||||
#if defined(SIMDE_X86_AES_NATIVE)
|
||||
return _mm_aesimc_si128(a);
|
||||
#else
|
||||
simde__m128i_private result_ = simde__m128i_to_private(simde_mm_setzero_si128());
|
||||
simde__m128i_private a_ = simde__m128i_to_private(a);
|
||||
|
||||
#if defined(SIMDE_ARM_NEON_A32V8_NATIVE) && defined(SIMDE_ARCH_ARM_CRYPTO)
|
||||
result_.neon_u8 = vaesimcq_u8(a_.neon_u8);
|
||||
#else
|
||||
int Nb = simde_x_aes_Nb;
|
||||
// uint8_t k[] = {0x0e, 0x09, 0x0d, 0x0b}; // a(x) = {0e} + {09}x + {0d}x2 + {0b}x3
|
||||
uint8_t i, j, col[4], res[4];
|
||||
|
||||
for (j = 0; j < Nb; j++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
col[i] = a_.u8[Nb*j+i];
|
||||
}
|
||||
|
||||
//coef_mult(k, col, res);
|
||||
simde_x_aes_coef_mult_lookup(4, col, res);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
result_.u8[Nb*j+i] = res[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return simde__m128i_from_private(result_);
|
||||
#endif
|
||||
}
|
||||
#if defined(SIMDE_X86_AES_ENABLE_NATIVE_ALIASES)
|
||||
#define _mm_aesimc_si128(a) simde_mm_aesimc_si128(a)
|
||||
#endif
|
||||
|
||||
#undef simde_x_aes_Nb
|
||||
|
||||
#endif /* !defined(SIMDE_X86_AES_H) */
|
||||
Reference in New Issue
Block a user