Botan
1.11.15
|
00001 /* 00002 * XTEA in SIMD 00003 * (C) 2009 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/internal/block_utils.h> 00009 #include <botan/xtea_simd.h> 00010 #include <botan/internal/simd_32.h> 00011 00012 namespace Botan { 00013 00014 BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(SIMD_32::enabled(), XTEA_SIMD, "XTEA", "simd32", 64); 00015 00016 namespace { 00017 00018 void xtea_encrypt_8(const byte in[64], byte out[64], const u32bit EK[64]) 00019 { 00020 SIMD_32 L0 = SIMD_32::load_be(in ); 00021 SIMD_32 R0 = SIMD_32::load_be(in + 16); 00022 SIMD_32 L1 = SIMD_32::load_be(in + 32); 00023 SIMD_32 R1 = SIMD_32::load_be(in + 48); 00024 00025 SIMD_32::transpose(L0, R0, L1, R1); 00026 00027 for(size_t i = 0; i != 32; i += 2) 00028 { 00029 SIMD_32 K0(EK[2*i ]); 00030 SIMD_32 K1(EK[2*i+1]); 00031 SIMD_32 K2(EK[2*i+2]); 00032 SIMD_32 K3(EK[2*i+3]); 00033 00034 L0 += (((R0 << 4) ^ (R0 >> 5)) + R0) ^ K0; 00035 L1 += (((R1 << 4) ^ (R1 >> 5)) + R1) ^ K0; 00036 00037 R0 += (((L0 << 4) ^ (L0 >> 5)) + L0) ^ K1; 00038 R1 += (((L1 << 4) ^ (L1 >> 5)) + L1) ^ K1; 00039 00040 L0 += (((R0 << 4) ^ (R0 >> 5)) + R0) ^ K2; 00041 L1 += (((R1 << 4) ^ (R1 >> 5)) + R1) ^ K2; 00042 00043 R0 += (((L0 << 4) ^ (L0 >> 5)) + L0) ^ K3; 00044 R1 += (((L1 << 4) ^ (L1 >> 5)) + L1) ^ K3; 00045 } 00046 00047 SIMD_32::transpose(L0, R0, L1, R1); 00048 00049 L0.store_be(out); 00050 R0.store_be(out + 16); 00051 L1.store_be(out + 32); 00052 R1.store_be(out + 48); 00053 } 00054 00055 void xtea_decrypt_8(const byte in[64], byte out[64], const u32bit EK[64]) 00056 { 00057 SIMD_32 L0 = SIMD_32::load_be(in ); 00058 SIMD_32 R0 = SIMD_32::load_be(in + 16); 00059 SIMD_32 L1 = SIMD_32::load_be(in + 32); 00060 SIMD_32 R1 = SIMD_32::load_be(in + 48); 00061 00062 SIMD_32::transpose(L0, R0, L1, R1); 00063 00064 for(size_t i = 0; i != 32; i += 2) 00065 { 00066 SIMD_32 K0(EK[63 - 2*i]); 00067 SIMD_32 K1(EK[62 - 2*i]); 00068 SIMD_32 K2(EK[61 - 2*i]); 00069 SIMD_32 K3(EK[60 - 2*i]); 00070 00071 R0 -= (((L0 << 4) ^ (L0 >> 5)) + L0) ^ K0; 00072 R1 -= (((L1 << 4) ^ (L1 >> 5)) + L1) ^ K0; 00073 00074 L0 -= (((R0 << 4) ^ (R0 >> 5)) + R0) ^ K1; 00075 L1 -= (((R1 << 4) ^ (R1 >> 5)) + R1) ^ K1; 00076 00077 R0 -= (((L0 << 4) ^ (L0 >> 5)) + L0) ^ K2; 00078 R1 -= (((L1 << 4) ^ (L1 >> 5)) + L1) ^ K2; 00079 00080 L0 -= (((R0 << 4) ^ (R0 >> 5)) + R0) ^ K3; 00081 L1 -= (((R1 << 4) ^ (R1 >> 5)) + R1) ^ K3; 00082 } 00083 00084 SIMD_32::transpose(L0, R0, L1, R1); 00085 00086 L0.store_be(out); 00087 R0.store_be(out + 16); 00088 L1.store_be(out + 32); 00089 R1.store_be(out + 48); 00090 } 00091 00092 } 00093 00094 /* 00095 * XTEA Encryption 00096 */ 00097 void XTEA_SIMD::encrypt_n(const byte in[], byte out[], size_t blocks) const 00098 { 00099 const u32bit* KS = &(this->get_EK()[0]); 00100 00101 while(blocks >= 8) 00102 { 00103 xtea_encrypt_8(in, out, KS); 00104 in += 8 * BLOCK_SIZE; 00105 out += 8 * BLOCK_SIZE; 00106 blocks -= 8; 00107 } 00108 00109 if(blocks) 00110 XTEA::encrypt_n(in, out, blocks); 00111 } 00112 00113 /* 00114 * XTEA Decryption 00115 */ 00116 void XTEA_SIMD::decrypt_n(const byte in[], byte out[], size_t blocks) const 00117 { 00118 const u32bit* KS = &(this->get_EK()[0]); 00119 00120 while(blocks >= 8) 00121 { 00122 xtea_decrypt_8(in, out, KS); 00123 in += 8 * BLOCK_SIZE; 00124 out += 8 * BLOCK_SIZE; 00125 blocks -= 8; 00126 } 00127 00128 if(blocks) 00129 XTEA::decrypt_n(in, out, blocks); 00130 } 00131 00132 }