Botan
1.11.15
|
00001 /* 00002 * Noekeon 00003 * (C) 1999-2008 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/noekeon.h> 00010 00011 namespace Botan { 00012 00013 BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Noekeon); 00014 00015 namespace { 00016 00017 /* 00018 * Noekeon's Theta Operation 00019 */ 00020 inline void theta(u32bit& A0, u32bit& A1, 00021 u32bit& A2, u32bit& A3, 00022 const u32bit EK[4]) 00023 { 00024 u32bit T = A0 ^ A2; 00025 T ^= rotate_left(T, 8) ^ rotate_right(T, 8); 00026 A1 ^= T; 00027 A3 ^= T; 00028 00029 A0 ^= EK[0]; 00030 A1 ^= EK[1]; 00031 A2 ^= EK[2]; 00032 A3 ^= EK[3]; 00033 00034 T = A1 ^ A3; 00035 T ^= rotate_left(T, 8) ^ rotate_right(T, 8); 00036 A0 ^= T; 00037 A2 ^= T; 00038 } 00039 00040 /* 00041 * Theta With Null Key 00042 */ 00043 inline void theta(u32bit& A0, u32bit& A1, 00044 u32bit& A2, u32bit& A3) 00045 { 00046 u32bit T = A0 ^ A2; 00047 T ^= rotate_left(T, 8) ^ rotate_right(T, 8); 00048 A1 ^= T; 00049 A3 ^= T; 00050 00051 T = A1 ^ A3; 00052 T ^= rotate_left(T, 8) ^ rotate_right(T, 8); 00053 A0 ^= T; 00054 A2 ^= T; 00055 } 00056 00057 /* 00058 * Noekeon's Gamma S-Box Layer 00059 */ 00060 inline void gamma(u32bit& A0, u32bit& A1, u32bit& A2, u32bit& A3) 00061 { 00062 A1 ^= ~A3 & ~A2; 00063 A0 ^= A2 & A1; 00064 00065 u32bit T = A3; 00066 A3 = A0; 00067 A0 = T; 00068 00069 A2 ^= A0 ^ A1 ^ A3; 00070 00071 A1 ^= ~A3 & ~A2; 00072 A0 ^= A2 & A1; 00073 } 00074 00075 } 00076 00077 /* 00078 * Noekeon Round Constants 00079 */ 00080 const byte Noekeon::RC[] = { 00081 0x80, 0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A, 00082 0x2F, 0x5E, 0xBC, 0x63, 0xC6, 0x97, 0x35, 0x6A, 00083 0xD4 }; 00084 00085 /* 00086 * Noekeon Encryption 00087 */ 00088 void Noekeon::encrypt_n(const byte in[], byte out[], size_t blocks) const 00089 { 00090 for(size_t i = 0; i != blocks; ++i) 00091 { 00092 u32bit A0 = load_be<u32bit>(in, 0); 00093 u32bit A1 = load_be<u32bit>(in, 1); 00094 u32bit A2 = load_be<u32bit>(in, 2); 00095 u32bit A3 = load_be<u32bit>(in, 3); 00096 00097 for(size_t j = 0; j != 16; ++j) 00098 { 00099 A0 ^= RC[j]; 00100 theta(A0, A1, A2, A3, &EK[0]); 00101 00102 A1 = rotate_left(A1, 1); 00103 A2 = rotate_left(A2, 5); 00104 A3 = rotate_left(A3, 2); 00105 00106 gamma(A0, A1, A2, A3); 00107 00108 A1 = rotate_right(A1, 1); 00109 A2 = rotate_right(A2, 5); 00110 A3 = rotate_right(A3, 2); 00111 } 00112 00113 A0 ^= RC[16]; 00114 theta(A0, A1, A2, A3, &EK[0]); 00115 00116 store_be(out, A0, A1, A2, A3); 00117 00118 in += BLOCK_SIZE; 00119 out += BLOCK_SIZE; 00120 } 00121 } 00122 00123 /* 00124 * Noekeon Encryption 00125 */ 00126 void Noekeon::decrypt_n(const byte in[], byte out[], size_t blocks) const 00127 { 00128 for(size_t i = 0; i != blocks; ++i) 00129 { 00130 u32bit A0 = load_be<u32bit>(in, 0); 00131 u32bit A1 = load_be<u32bit>(in, 1); 00132 u32bit A2 = load_be<u32bit>(in, 2); 00133 u32bit A3 = load_be<u32bit>(in, 3); 00134 00135 for(size_t j = 16; j != 0; --j) 00136 { 00137 theta(A0, A1, A2, A3, &DK[0]); 00138 A0 ^= RC[j]; 00139 00140 A1 = rotate_left(A1, 1); 00141 A2 = rotate_left(A2, 5); 00142 A3 = rotate_left(A3, 2); 00143 00144 gamma(A0, A1, A2, A3); 00145 00146 A1 = rotate_right(A1, 1); 00147 A2 = rotate_right(A2, 5); 00148 A3 = rotate_right(A3, 2); 00149 } 00150 00151 theta(A0, A1, A2, A3, &DK[0]); 00152 A0 ^= RC[0]; 00153 00154 store_be(out, A0, A1, A2, A3); 00155 00156 in += BLOCK_SIZE; 00157 out += BLOCK_SIZE; 00158 } 00159 } 00160 00161 /* 00162 * Noekeon Key Schedule 00163 */ 00164 void Noekeon::key_schedule(const byte key[], size_t) 00165 { 00166 u32bit A0 = load_be<u32bit>(key, 0); 00167 u32bit A1 = load_be<u32bit>(key, 1); 00168 u32bit A2 = load_be<u32bit>(key, 2); 00169 u32bit A3 = load_be<u32bit>(key, 3); 00170 00171 for(size_t i = 0; i != 16; ++i) 00172 { 00173 A0 ^= RC[i]; 00174 theta(A0, A1, A2, A3); 00175 00176 A1 = rotate_left(A1, 1); 00177 A2 = rotate_left(A2, 5); 00178 A3 = rotate_left(A3, 2); 00179 00180 gamma(A0, A1, A2, A3); 00181 00182 A1 = rotate_right(A1, 1); 00183 A2 = rotate_right(A2, 5); 00184 A3 = rotate_right(A3, 2); 00185 } 00186 00187 A0 ^= RC[16]; 00188 00189 DK.resize(4); 00190 DK[0] = A0; 00191 DK[1] = A1; 00192 DK[2] = A2; 00193 DK[3] = A3; 00194 00195 theta(A0, A1, A2, A3); 00196 00197 EK.resize(4); 00198 EK[0] = A0; 00199 EK[1] = A1; 00200 EK[2] = A2; 00201 EK[3] = A3; 00202 } 00203 00204 /* 00205 * Clear memory of sensitive data 00206 */ 00207 void Noekeon::clear() 00208 { 00209 zap(EK); 00210 zap(DK); 00211 } 00212 00213 }