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