Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | 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