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(const byte *key_string, unsigned int keylength, const NameValuePairs &)
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 (!IsForwardTransformation())
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 Sat Dec 23 02:07:06 2006 for Crypto++ by  doxygen 1.5.1-p1