This algorithm implementation is a part of my cryptography implementations project. The full project, along with licensing information and more detail, is hosted on GitHub.
This is an implementation of the Blowfish block cipher.
There are two steps to the cipher. First, five sets of tables are initialized using the user's key and the blowfish encryption algorithm itself (making the algorithm recursive). Second, the data is encrypted using the permutated tables initialized previously.
void key_schedule(uchar user_key, BLOWFISH_KEY *keystruct, int len)
This generates an encryption key from a user-supplied key.
This is the user-supplied key.
This is the key structure that will be used to encrypt data later in the encryption functions.
This is the length, in bytes, of the key in the first parameter. It may be any value up to 448.
blowfish_encrypt(uchar in, uchar out, BLOWFISH_KEY *keystruct)
blowfish_decrypt(uchar in, uchar out, BLOWFISH_KEY *keystruct)
These functions encrypt and decrypt data, accordingly, using a Blowfish key structure.
This is the data to be encrypted, for the blowfish_encrypt() function, and the data to be decrypted for the blowfish_decrypt() function.
This is where to store the output encrypted data, for the blowfish_encrypt() function, and the output decrypted data for the blowfish_decrypt() function.
This is the key structure that is generated by the key_schedule() function (above). It is the same for both encrypted and decryption.
- Create the arrays to hold both input and output data for the encryption and/or decryption functions and a BLOWFISH_KEY structure.
- Call the key_schedule() function with the key, the BLOWFISH_KEY structure, and the length of the key in bytes.
- To encrypt data, call the blowfish_encrypt() function passing the array with the plaintext, the array to hold the output ciphertext, and the key structure.
- Do decrypt data, call the blowfish_decrypt() function passing the array with the ciphertext, the array to hold the output plaintext, and the key structure.
In this implementation, all the initial P-Box and S-Box constants are stored in static memory location and copied to temporary memory locations for use in the key initialization step. This is because the S-Box and P-Box values will be altered during the key initialization for each key. If the implementor wishes to encrypt data using multiple keys in the same session, then the key initialization function must be called more than once, and each time it is called it must start with the same constant values.
Assuming the developer only needs to use one Blowfish key, this code could be slightly optimized to just use the one set of S/P-Boxes. These factors are only of practical concern for extremely computationally-weak machines (specialized hardware).
Cryptanalysis of the Blowfish algorithm itself to date has yielded but a few minor flaws, placing Blowfish as one of the best 64-bit block ciphers in existence. However, 64-bit block ciphers can leak information about the plaintext and should not be used if possible. So although no reasonable attacks exist against Blowfish itself, its 64-bit block size make it less than undesirable in the modern cryptographic world.