Botan  1.11.15
src/lib/block/xtea_simd/xtea_simd.cpp
Go to the documentation of this file.
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 }