Botan  1.11.15
src/lib/block/xtea/xtea.cpp
Go to the documentation of this file.
00001 /*
00002 * XTEA
00003 * (C) 1999-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.h>
00010 
00011 namespace Botan {
00012 
00013 BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(XTEA);
00014 
00015 namespace {
00016 
00017 void xtea_encrypt_4(const byte in[32], byte out[32], const u32bit EK[64])
00018    {
00019    u32bit L0, R0, L1, R1, L2, R2, L3, R3;
00020    load_be(in, L0, R0, L1, R1, L2, R2, L3, R3);
00021 
00022    for(size_t i = 0; i != 32; ++i)
00023       {
00024       L0 += (((R0 << 4) ^ (R0 >> 5)) + R0) ^ EK[2*i];
00025       L1 += (((R1 << 4) ^ (R1 >> 5)) + R1) ^ EK[2*i];
00026       L2 += (((R2 << 4) ^ (R2 >> 5)) + R2) ^ EK[2*i];
00027       L3 += (((R3 << 4) ^ (R3 >> 5)) + R3) ^ EK[2*i];
00028 
00029       R0 += (((L0 << 4) ^ (L0 >> 5)) + L0) ^ EK[2*i+1];
00030       R1 += (((L1 << 4) ^ (L1 >> 5)) + L1) ^ EK[2*i+1];
00031       R2 += (((L2 << 4) ^ (L2 >> 5)) + L2) ^ EK[2*i+1];
00032       R3 += (((L3 << 4) ^ (L3 >> 5)) + L3) ^ EK[2*i+1];
00033       }
00034 
00035    store_be(out, L0, R0, L1, R1, L2, R2, L3, R3);
00036    }
00037 
00038 void xtea_decrypt_4(const byte in[32], byte out[32], const u32bit EK[64])
00039    {
00040    u32bit L0, R0, L1, R1, L2, R2, L3, R3;
00041    load_be(in, L0, R0, L1, R1, L2, R2, L3, R3);
00042 
00043    for(size_t i = 0; i != 32; ++i)
00044       {
00045       R0 -= (((L0 << 4) ^ (L0 >> 5)) + L0) ^ EK[63 - 2*i];
00046       R1 -= (((L1 << 4) ^ (L1 >> 5)) + L1) ^ EK[63 - 2*i];
00047       R2 -= (((L2 << 4) ^ (L2 >> 5)) + L2) ^ EK[63 - 2*i];
00048       R3 -= (((L3 << 4) ^ (L3 >> 5)) + L3) ^ EK[63 - 2*i];
00049 
00050       L0 -= (((R0 << 4) ^ (R0 >> 5)) + R0) ^ EK[62 - 2*i];
00051       L1 -= (((R1 << 4) ^ (R1 >> 5)) + R1) ^ EK[62 - 2*i];
00052       L2 -= (((R2 << 4) ^ (R2 >> 5)) + R2) ^ EK[62 - 2*i];
00053       L3 -= (((R3 << 4) ^ (R3 >> 5)) + R3) ^ EK[62 - 2*i];
00054       }
00055 
00056    store_be(out, L0, R0, L1, R1, L2, R2, L3, R3);
00057    }
00058 
00059 }
00060 
00061 /*
00062 * XTEA Encryption
00063 */
00064 void XTEA::encrypt_n(const byte in[], byte out[], size_t blocks) const
00065    {
00066    while(blocks >= 4)
00067       {
00068       xtea_encrypt_4(in, out, &(this->EK[0]));
00069       in += 4 * BLOCK_SIZE;
00070       out += 4 * BLOCK_SIZE;
00071       blocks -= 4;
00072       }
00073 
00074    for(size_t i = 0; i != blocks; ++i)
00075       {
00076       u32bit L = load_be<u32bit>(in, 0);
00077       u32bit R = load_be<u32bit>(in, 1);
00078 
00079       for(size_t j = 0; j != 32; ++j)
00080          {
00081          L += (((R << 4) ^ (R >> 5)) + R) ^ EK[2*j];
00082          R += (((L << 4) ^ (L >> 5)) + L) ^ EK[2*j+1];
00083          }
00084 
00085       store_be(out, L, R);
00086 
00087       in += BLOCK_SIZE;
00088       out += BLOCK_SIZE;
00089       }
00090    }
00091 
00092 /*
00093 * XTEA Decryption
00094 */
00095 void XTEA::decrypt_n(const byte in[], byte out[], size_t blocks) const
00096    {
00097    while(blocks >= 4)
00098       {
00099       xtea_decrypt_4(in, out, &(this->EK[0]));
00100       in += 4 * BLOCK_SIZE;
00101       out += 4 * BLOCK_SIZE;
00102       blocks -= 4;
00103       }
00104 
00105    for(size_t i = 0; i != blocks; ++i)
00106       {
00107       u32bit L = load_be<u32bit>(in, 0);
00108       u32bit R = load_be<u32bit>(in, 1);
00109 
00110       for(size_t j = 0; j != 32; ++j)
00111          {
00112          R -= (((L << 4) ^ (L >> 5)) + L) ^ EK[63 - 2*j];
00113          L -= (((R << 4) ^ (R >> 5)) + R) ^ EK[62 - 2*j];
00114          }
00115 
00116       store_be(out, L, R);
00117 
00118       in += BLOCK_SIZE;
00119       out += BLOCK_SIZE;
00120       }
00121    }
00122 
00123 /*
00124 * XTEA Key Schedule
00125 */
00126 void XTEA::key_schedule(const byte key[], size_t)
00127    {
00128    EK.resize(64);
00129 
00130    secure_vector<u32bit> UK(4);
00131    for(size_t i = 0; i != 4; ++i)
00132       UK[i] = load_be<u32bit>(key, i);
00133 
00134    u32bit D = 0;
00135    for(size_t i = 0; i != 64; i += 2)
00136       {
00137       EK[i  ] = D + UK[D % 4];
00138       D += 0x9E3779B9;
00139       EK[i+1] = D + UK[(D >> 11) % 4];
00140       }
00141    }
00142 
00143 void XTEA::clear()
00144    {
00145    zap(EK);
00146    }
00147 
00148 }