diff options
author | weidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0> | 2002-10-04 17:31:41 +0000 |
---|---|---|
committer | weidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0> | 2002-10-04 17:31:41 +0000 |
commit | b21162cf8e06f40baa1f58be6a8c17435cebc34d (patch) | |
tree | 8b045309c238226c32a563b1df6b9c30a2f0e0b3 /blowfish.cpp | |
download | cryptopp-b21162cf8e06f40baa1f58be6a8c17435cebc34d.tar.gz |
Initial revision
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@2 57ff6487-cd31-0410-9ec3-f628ee90f5f0
Diffstat (limited to 'blowfish.cpp')
-rw-r--r-- | blowfish.cpp | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/blowfish.cpp b/blowfish.cpp new file mode 100644 index 0000000..fa6c723 --- /dev/null +++ b/blowfish.cpp @@ -0,0 +1,99 @@ +// blowfish.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "blowfish.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +void Blowfish::Base::UncheckedSetKey(CipherDir dir, const byte *key_string, unsigned int keylength) +{ + AssertValidKeyLength(keylength); + + unsigned i, j=0, k; + word32 data, dspace[2] = {0, 0}; + + memcpy(pbox, p_init, sizeof(p_init)); + memcpy(sbox, s_init, sizeof(s_init)); + + // Xor key string into encryption key vector + for (i=0 ; i<ROUNDS+2 ; ++i) + { + data = 0 ; + for (k=0 ; k<4 ; ++k ) + data = (data << 8) | key_string[j++ % keylength]; + pbox[i] ^= data; + } + + crypt_block(dspace, pbox); + + for (i=0; i<ROUNDS; i+=2) + crypt_block(pbox+i, pbox+i+2); + + crypt_block(pbox+ROUNDS, sbox); + + for (i=0; i<4*256-2; i+=2) + crypt_block(sbox+i, sbox+i+2); + + if (dir==DECRYPTION) + for (i=0; i<(ROUNDS+2)/2; i++) + std::swap(pbox[i], pbox[ROUNDS+1-i]); +} + +// this version is only used to make pbox and sbox +void Blowfish::Base::crypt_block(const word32 in[2], word32 out[2]) const +{ + word32 left = in[0]; + word32 right = in[1]; + + const word32 *const s=sbox; + const word32 *p=pbox; + + left ^= p[0]; + + for (unsigned i=0; i<ROUNDS/2; i++) + { + right ^= (((s[GETBYTE(left,3)] + s[256+GETBYTE(left,2)]) + ^ s[2*256+GETBYTE(left,1)]) + s[3*256+GETBYTE(left,0)]) + ^ p[2*i+1]; + + left ^= (((s[GETBYTE(right,3)] + s[256+GETBYTE(right,2)]) + ^ s[2*256+GETBYTE(right,1)]) + s[3*256+GETBYTE(right,0)]) + ^ p[2*i+2]; + } + + right ^= p[ROUNDS+1]; + + out[0] = right; + out[1] = left; +} + +void Blowfish::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + typedef BlockGetAndPut<word32, BigEndian> Block; + + word32 left, right; + Block::Get(inBlock)(left)(right); + + const word32 *const s=sbox; + const word32 *p=pbox; + + left ^= p[0]; + + for (unsigned i=0; i<ROUNDS/2; i++) + { + right ^= (((s[GETBYTE(left,3)] + s[256+GETBYTE(left,2)]) + ^ s[2*256+GETBYTE(left,1)]) + s[3*256+GETBYTE(left,0)]) + ^ p[2*i+1]; + + left ^= (((s[GETBYTE(right,3)] + s[256+GETBYTE(right,2)]) + ^ s[2*256+GETBYTE(right,1)]) + s[3*256+GETBYTE(right,0)]) + ^ p[2*i+2]; + } + + right ^= p[ROUNDS+1]; + + Block::Put(xorBlock, outBlock)(right)(left); +} + +NAMESPACE_END |