Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

blowfish.cpp

00001 // blowfish.cpp - written and placed in the public domain by Wei Dai 00002 00003 #include "pch.h" 00004 #include "blowfish.h" 00005 #include "misc.h" 00006 00007 NAMESPACE_BEGIN(CryptoPP) 00008 00009 void Blowfish::Base::UncheckedSetKey(CipherDir dir, const byte *key_string, unsigned int keylength) 00010 { 00011 AssertValidKeyLength(keylength); 00012 00013 unsigned i, j=0, k; 00014 word32 data, dspace[2] = {0, 0}; 00015 00016 memcpy(pbox, p_init, sizeof(p_init)); 00017 memcpy(sbox, s_init, sizeof(s_init)); 00018 00019 // Xor key string into encryption key vector 00020 for (i=0 ; i<ROUNDS+2 ; ++i) 00021 { 00022 data = 0 ; 00023 for (k=0 ; k<4 ; ++k ) 00024 data = (data << 8) | key_string[j++ % keylength]; 00025 pbox[i] ^= data; 00026 } 00027 00028 crypt_block(dspace, pbox); 00029 00030 for (i=0; i<ROUNDS; i+=2) 00031 crypt_block(pbox+i, pbox+i+2); 00032 00033 crypt_block(pbox+ROUNDS, sbox); 00034 00035 for (i=0; i<4*256-2; i+=2) 00036 crypt_block(sbox+i, sbox+i+2); 00037 00038 if (dir==DECRYPTION) 00039 for (i=0; i<(ROUNDS+2)/2; i++) 00040 std::swap(pbox[i], pbox[ROUNDS+1-i]); 00041 } 00042 00043 // this version is only used to make pbox and sbox 00044 void Blowfish::Base::crypt_block(const word32 in[2], word32 out[2]) const 00045 { 00046 word32 left = in[0]; 00047 word32 right = in[1]; 00048 00049 const word32 *const s=sbox; 00050 const word32 *p=pbox; 00051 00052 left ^= p[0]; 00053 00054 for (unsigned i=0; i<ROUNDS/2; i++) 00055 { 00056 right ^= (((s[GETBYTE(left,3)] + s[256+GETBYTE(left,2)]) 00057 ^ s[2*256+GETBYTE(left,1)]) + s[3*256+GETBYTE(left,0)]) 00058 ^ p[2*i+1]; 00059 00060 left ^= (((s[GETBYTE(right,3)] + s[256+GETBYTE(right,2)]) 00061 ^ s[2*256+GETBYTE(right,1)]) + s[3*256+GETBYTE(right,0)]) 00062 ^ p[2*i+2]; 00063 } 00064 00065 right ^= p[ROUNDS+1]; 00066 00067 out[0] = right; 00068 out[1] = left; 00069 } 00070 00071 void Blowfish::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 00072 { 00073 typedef BlockGetAndPut<word32, BigEndian> Block; 00074 00075 word32 left, right; 00076 Block::Get(inBlock)(left)(right); 00077 00078 const word32 *const s=sbox; 00079 const word32 *p=pbox; 00080 00081 left ^= p[0]; 00082 00083 for (unsigned i=0; i<ROUNDS/2; i++) 00084 { 00085 right ^= (((s[GETBYTE(left,3)] + s[256+GETBYTE(left,2)]) 00086 ^ s[2*256+GETBYTE(left,1)]) + s[3*256+GETBYTE(left,0)]) 00087 ^ p[2*i+1]; 00088 00089 left ^= (((s[GETBYTE(right,3)] + s[256+GETBYTE(right,2)]) 00090 ^ s[2*256+GETBYTE(right,1)]) + s[3*256+GETBYTE(right,0)]) 00091 ^ p[2*i+2]; 00092 } 00093 00094 right ^= p[ROUNDS+1]; 00095 00096 Block::Put(xorBlock, outBlock)(right)(left); 00097 } 00098 00099 NAMESPACE_END

Generated on Wed Jul 21 19:15:21 2004 for Crypto++ by doxygen 1.3.7-20040704