1// blowfish.cpp - written and placed in the public domain by Wei Dai 2 3#include "pch.h" 4#include "blowfish.h" 5#include "misc.h" 6 7NAMESPACE_BEGIN(CryptoPP) 8 9void Blowfish::Base::UncheckedSetKey(const byte *key_string, unsigned int keylength, const NameValuePairs &) 10{ 11 AssertValidKeyLength(keylength); 12 13 unsigned i, j=0, k; 14 word32 data, dspace[2] = {0, 0}; 15 16 memcpy(pbox, p_init, sizeof(p_init)); 17 memcpy(sbox, s_init, sizeof(s_init)); 18 19 // Xor key string into encryption key vector 20 for (i=0 ; i<ROUNDS+2 ; ++i) 21 { 22 data = 0 ; 23 for (k=0 ; k<4 ; ++k ) 24 data = (data << 8) | key_string[j++ % keylength]; 25 pbox[i] ^= data; 26 } 27 28 crypt_block(dspace, pbox); 29 30 for (i=0; i<ROUNDS; i+=2) 31 crypt_block(pbox+i, pbox+i+2); 32 33 crypt_block(pbox+ROUNDS, sbox); 34 35 for (i=0; i<4*256-2; i+=2) 36 crypt_block(sbox+i, sbox+i+2); 37 38 if (!IsForwardTransformation()) 39 for (i=0; i<(ROUNDS+2)/2; i++) 40 std::swap(pbox[i], pbox[ROUNDS+1-i]); 41} 42 43// this version is only used to make pbox and sbox 44void Blowfish::Base::crypt_block(const word32 in[2], word32 out[2]) const 45{ 46 word32 left = in[0]; 47 word32 right = in[1]; 48 49 const word32 *const s=sbox; 50 const word32 *p=pbox; 51 52 left ^= p[0]; 53 54 for (unsigned i=0; i<ROUNDS/2; i++) 55 { 56 right ^= (((s[GETBYTE(left,3)] + s[256+GETBYTE(left,2)]) 57 ^ s[2*256+GETBYTE(left,1)]) + s[3*256+GETBYTE(left,0)]) 58 ^ p[2*i+1]; 59 60 left ^= (((s[GETBYTE(right,3)] + s[256+GETBYTE(right,2)]) 61 ^ s[2*256+GETBYTE(right,1)]) + s[3*256+GETBYTE(right,0)]) 62 ^ p[2*i+2]; 63 } 64 65 right ^= p[ROUNDS+1]; 66 67 out[0] = right; 68 out[1] = left; 69} 70 71void Blowfish::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 72{ 73 typedef BlockGetAndPut<word32, BigEndian> Block; 74 75 word32 left, right; 76 Block::Get(inBlock)(left)(right); 77 78 const word32 *const s=sbox; 79 const word32 *p=pbox; 80 81 left ^= p[0]; 82 83 for (unsigned i=0; i<ROUNDS/2; i++) 84 { 85 right ^= (((s[GETBYTE(left,3)] + s[256+GETBYTE(left,2)]) 86 ^ s[2*256+GETBYTE(left,1)]) + s[3*256+GETBYTE(left,0)]) 87 ^ p[2*i+1]; 88 89 left ^= (((s[GETBYTE(right,3)] + s[256+GETBYTE(right,2)]) 90 ^ s[2*256+GETBYTE(right,1)]) + s[3*256+GETBYTE(right,0)]) 91 ^ p[2*i+2]; 92 } 93 94 right ^= p[ROUNDS+1]; 95 96 Block::Put(xorBlock, outBlock)(right)(left); 97} 98 99NAMESPACE_END 100