00001
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
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
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