diff options
author | lloyd <[email protected]> | 2006-05-18 18:33:19 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2006-05-18 18:33:19 +0000 |
commit | a2c99d3270eb73ef2db5704fc54356c6b75096f8 (patch) | |
tree | ad3d6c4fcc8dd0f403f8105598943616246fe172 /src/misty1.cpp |
Initial checkin1.5.6
Diffstat (limited to 'src/misty1.cpp')
-rw-r--r-- | src/misty1.cpp | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/src/misty1.cpp b/src/misty1.cpp new file mode 100644 index 000000000..53c12a5cf --- /dev/null +++ b/src/misty1.cpp @@ -0,0 +1,149 @@ +/************************************************* +* MISTY1 Source File * +* (C) 1999-2006 The Botan Project * +*************************************************/ + +#include <botan/misty1.h> +#include <botan/bit_ops.h> +#include <botan/parsing.h> + +namespace Botan { + +namespace { + +/************************************************* +* MISTY1 FI Function * +*************************************************/ +u16bit FI(u16bit input, u16bit key7, u16bit key9) + { + u16bit D9 = input >> 7, D7 = input & 0x7F; + D9 = MISTY1_SBOX_S9[D9] ^ D7; + D7 = (MISTY1_SBOX_S7[D7] ^ key7 ^ D9) & 0x7F; + D9 = MISTY1_SBOX_S9[D9 ^ key9] ^ D7; + return (u16bit)((D7 << 9) | D9); + } + +} + +/************************************************* +* MISTY1 Encryption * +*************************************************/ +void MISTY1::enc(const byte in[], byte out[]) const + { + u16bit B0 = make_u16bit(in[0], in[1]), B1 = make_u16bit(in[2], in[3]), + B2 = make_u16bit(in[4], in[5]), B3 = make_u16bit(in[6], in[7]); + + for(u32bit j = 0; j != 12; j += 3) + { + const u16bit* RK = EK + 8 * j; + + B1 ^= B0 & RK[0]; + B0 ^= B1 | RK[1]; + B3 ^= B2 & RK[2]; + B2 ^= B3 | RK[3]; + + u32bit T0, T1; + + T0 = FI(B0 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B1; + T1 = FI(B1 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0; + T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1; + + B2 ^= T1 ^ RK[13]; + B3 ^= T0; + + T0 = FI(B2 ^ RK[14], RK[15], RK[16]) ^ B3; + T1 = FI(B3 ^ RK[17], RK[18], RK[19]) ^ T0; + T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1; + + B0 ^= T1 ^ RK[23]; + B1 ^= T0; + } + + B1 ^= B0 & EK[96]; + B0 ^= B1 | EK[97]; + B3 ^= B2 & EK[98]; + B2 ^= B3 | EK[99]; + + out[0] = get_byte(0, B2); out[1] = get_byte(1, B2); + out[2] = get_byte(0, B3); out[3] = get_byte(1, B3); + out[4] = get_byte(0, B0); out[5] = get_byte(1, B0); + out[6] = get_byte(0, B1); out[7] = get_byte(1, B1); + } + +/************************************************* +* MISTY1 Decryption * +*************************************************/ +void MISTY1::dec(const byte in[], byte out[]) const + { + u16bit B0 = make_u16bit(in[4], in[5]), B1 = make_u16bit(in[6], in[7]), + B2 = make_u16bit(in[0], in[1]), B3 = make_u16bit(in[2], in[3]); + + for(u32bit j = 0; j != 12; j += 3) + { + const u16bit* RK = DK + 8 * j; + + B2 ^= B3 | RK[0]; + B3 ^= B2 & RK[1]; + B0 ^= B1 | RK[2]; + B1 ^= B0 & RK[3]; + + u32bit T0, T1; + + T0 = FI(B2 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B3; + T1 = FI(B3 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0; + T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1; + + B0 ^= T1 ^ RK[13]; + B1 ^= T0; + + T0 = FI(B0 ^ RK[14], RK[15], RK[16]) ^ B1; + T1 = FI(B1 ^ RK[17], RK[18], RK[19]) ^ T0; + T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1; + + B2 ^= T1 ^ RK[23]; + B3 ^= T0; + } + + B2 ^= B3 | DK[96]; + B3 ^= B2 & DK[97]; + B0 ^= B1 | DK[98]; + B1 ^= B0 & DK[99]; + + out[0] = get_byte(0, B0); out[1] = get_byte(1, B0); + out[2] = get_byte(0, B1); out[3] = get_byte(1, B1); + out[4] = get_byte(0, B2); out[5] = get_byte(1, B2); + out[6] = get_byte(0, B3); out[7] = get_byte(1, B3); + } + +/************************************************* +* MISTY1 Key Schedule * +*************************************************/ +void MISTY1::key(const byte key[], u32bit length) + { + SecureBuffer<u16bit, 32> KS; + for(u32bit j = 0; j != length / 2; ++j) + KS[j] = make_u16bit(key[2*j], key[2*j+1]); + for(u32bit j = 0; j != 8; ++j) + { + KS[j+ 8] = FI(KS[j], KS[(j+1) % 8] >> 9, KS[(j+1) % 8] & 0x1FF); + KS[j+16] = KS[j+8] >> 9; + KS[j+24] = KS[j+8] & 0x1FF; + } + for(u32bit j = 0; j != 100; ++j) + { + EK[j] = KS[EK_ORDER[j]]; + DK[j] = KS[DK_ORDER[j]]; + } + } + +/************************************************* +* MISTY1 Constructor * +*************************************************/ +MISTY1::MISTY1(u32bit rounds) : BlockCipher(8, 16) + { + if(rounds != 8) + throw Invalid_Argument("MISTY1: Invalid number of rounds: " + + to_string(rounds)); + } + +} |