📄 twofish.cpp
字号:
/*
* Fast, portable, and easy-to-use Twofish implementation,
* Version 0.3.
* Copyright (c) 2002 by Niels Ferguson.
* (See further down for the almost-unrestricted licensing terms.)
*
* --------------------------------------------------------------------------
* There are two files for this implementation:
* - twofish.h, the header file.
* - twofish.c, the code file.
*
* To incorporate this code into your program you should:
* - Check the licensing terms further down in this comment.
* - Fix the two type definitions in twofish.h to suit your platform.
* - Fix a few definitions in twofish.c in the section marked
* PLATFORM FIXES. There is one important ones that affects
* functionality, and then a few definitions that you can optimise
* for efficiency but those have no effect on the functionality.
* Don't change anything else.
* - Put the code in your project and compile it.
*
* To use this library you should:
* - Call Twofish_initialise() in your program before any other function in
* this library.
* - Use Twofish_prepare_key(...) to convert a key to internal form.
* - Use Twofish_encrypt(...) and Twofish_decrypt(...) to encrypt and decrypt
* data.
* See the comments in the header file for details on these functions.
* --------------------------------------------------------------------------
*
* There are many Twofish implementation available for free on the web.
* Most of them are hard to integrate into your own program.
* As we like people to use our cipher, I thought I would make it easier.
* Here is a free and easy-to-integrate Twofish implementation in C.
* The latest version is always available from my personal home page at
* http://niels.ferguson.net/
*
* Integrating library code into a project is difficult because the library
* header files interfere with the project's header files and code.
* And of course the project's header files interfere with the library code.
* I've tried to resolve these problems here.
* The header file of this implementation is very light-weight.
* It contains two typedefs, a structure, and a few function declarations.
* All names it defines start with "Twofish_".
* The header file is therefore unlikely to cause problems in your project.
* The code file of this implementation doesn't need to include the header
* files of the project. There is thus no danger of the project interfering
* with all the definitions and macros of the Twofish code.
* In most situations, all you need to do is fill in a few platform-specific
* definitions in the header file and code file,
* and you should be able to run the Twofish code in your project.
* I estimate it should take you less than an hour to integrate this code
* into your project, most of it spent reading the comments telling you what
* to do.
*
* For people using C++: it is very easy to wrap this library into a
* TwofishKey class. One of the big advantages is that you can automate the
* wiping of the key material in the destructor. I have not provided a C++
* class because the interface depends too much on the abstract base class
* you use for block ciphers in your program, which I don't know about.
*
* This implementation is designed for use on PC-class machines. It uses the
* Twofish 'full' keying option which uses large tables. Total table size is
* around 5-6 kB for static tables plus 4.5 kB for each pre-processed key.
* If you need an implementation that uses less memory,
* take a look at Brian Gladman's code on his web site:
* http://fp.gladman.plus.com/cryptography_technology/aes/
* He has code for all AES candidates.
* His Twofish code has lots of options trading off table size vs. speed.
* You can also take a look at the optimised code by Doug Whiting on the
* Twofish web site
* http://www.counterpane.com/twofish.html
* which has loads of options.
* I believe these existing implementations are harder to re-use because they
* are not clean libraries and they impose requirements on the environment.
* This implementation is very careful to minimise those,
* and should be easier to integrate into any larger program.
*
* The default mode of this implementation is fully portable as it uses no
* behaviour not defined in the C standard. (This is harder than you think.)
* If you have any problems porting the default mode, please let me know
* so that I can fix the problem. (But only if this code is at fault, I
* don't fix compilers.)
* Most of the platform fixes are related to non-portable but faster ways
* of implementing certain functions.
*
* In general I've tried to make the code as fast as possible, at the expense
* of memory and code size. However, C does impose limits, and this
* implementation will be slower than an optimised assembler implementation.
* But beware of assembler implementations: a good Pentium implementation
* uses completely different code than a good Pentium II implementation.
* You basically have to re-write the assembly code for every generation of
* processor. Unless you are severely pressed for speed, stick with C.
*
* The initialisation routine of this implementation contains a self-test.
* If initialisation succeeds without calling the fatal routine, then
* the implementation works. I don't think you can break the implementation
* in such a way that it still passes the tests, unless you are malicious.
* In other words: if the initialisation routine returns,
* you have successfully ported the implementation.
* (Or not implemented the fatal routine properly, but that is your problem.)
*
* I'm indebted to many people who helped me in one way or another to write
* this code. During the design of Twofish and the AES process I had very
* extensive discussions of all implementation issues with various people.
* Doug Whiting in particular provided a wealth of information. The Twofish
* team spent untold hours discussion various cipher features, and their
* implementation. Brian Gladman implemented all AES candidates in C,
* and we had some fruitful discussions on how to implement Twofish in C.
* Jan Nieuwenhuizen tested this code on Linux using GCC.
*
* Now for the license:
* The author hereby grants a perpetual license to everybody to
* use this code for any purpose as long as the copyright message is included
* in the source code of this or any derived work.
*
* Yes, this means that you, your company, your club, and anyone else
* can use this code anywhere you want. You can change it and distribute it
* under the GPL, include it in your commercial product without releasing
* the source code, put it on the web, etc.
* The only thing you cannot do is remove my copyright message,
* or distribute any source code based on this implementation that does not
* include my copyright message.
*
* I appreciate a mention in the documentation or credits,
* but I understand if that is difficult to do.
* I also appreciate it if you tell me where and why you used my code.
*
* Please send any questions or comments to niels@ferguson.net
*
* Have Fun!
*
* Niels
*/
/*
* DISCLAIMER: As I'm giving away my work for free, I'm of course not going
* to accept any liability of any form. This code, or the Twofish cipher,
* might very well be flawed; you have been warned.
* This software is provided as-is, without any kind of warrenty or
* guarantee. And that is really all you can expect when you download
* code for free from the Internet.
*
* I think it is really sad that disclaimers like this seem to be necessary.
* If people only had a little bit more common sense, and didn't come
* whining like little children every time something happens....
*/
/*
* Version history:
* Version 0.0, 2002-08-30
* First written.
* Version 0.1, 2002-09-03
* Added disclaimer. Improved self-tests.
* Version 0.2, 2002-09-09
* Removed last non-portabilities. Default now works completely within
* the C standard. UInt32 can be larger than 32 bits without problems.
* Version 0.3, 2002-09-28
* Bugfix: use <string.h> instead of <memory.h> to adhere to ANSI/ISO.
* Rename BIG_ENDIAN macro to CPU_IS_BIG_ENDIAN. The gcc library
* header <string.h> already defines BIG_ENDIAN, even though it is not
* supposed to.
*/
/*
* Minimum set of include files.
* You should not need any application-specific include files for this code.
* In fact, adding you own header files could break one of the many macros or
* functions in this file. Be very careful.
* Standard include files will probably be ok.
*/
#include "StdAfx.h"
// #include <string.h> /* for memset(), memcpy(), and memcmp() */
#include "twofish.h"
/*
* PLATFORM FIXES
* ==============
*
* Fix the type definitions in twofish.h first!
*
* The following definitions have to be fixed for each particular platform
* you work on. If you have a multi-platform program, you no doubt have
* portable definitions that you can substitute here without changing the
* rest of the code.
*/
/*
* Function called if something is fatally wrong with the implementation.
* This fatal function is called when a coding error is detected in the
* Twofish implementation, or when somebody passes an obviously erroneous
* parameter to this implementation. There is not much you can do when
* the code contains bugs, so we just stop.
*
* The argument is a string. Ideally the fatal function prints this string
* as an error message. Whatever else this function does, it should never
* return. A typical implementation would stop the program completely after
* printing the error message.
*
* This default implementation is not very useful,
* but does not assume anything about your environment.
* It will at least let you know something is wrong....
* I didn't want to include any libraries to print and error or so,
* as this makes the code much harder to integrate in a project.
*
* Note that the Twofish_fatal function may not return to the caller.
* Unfortunately this is not something the self-test can test for,
* so you have to make sure of this yourself.
*
* If you want to call an external function, be careful about including
* your own header files here. This code uses a lot of macros, and your
* header file could easily break it. Maybe the best solution is to use
* a separate extern statement for your fatal function.
*/
#define Twofish_fatal(pmsgx) { MessageBox(GetDesktopWindow(), _T(pmsgx), _T("Twofish Fatal Error"), MB_OK); }
/*
* The rest of the settings are not important for the functionality
* of this Twofish implementation. That is, their default settings
* work on all platforms. You can change them to improve the
* speed of the implementation on your platform. Erroneous settings
* will result in erroneous implementations, but the self-test should
* catch those.
*/
/*
* Macros to rotate a Twofish_UInt32 value left or right by the
* specified number of bits. This should be a 32-bit rotation,
* and not rotation of, say, 64-bit values.
*
* Every encryption or decryption operation uses 32 of these rotations,
* so it is a good idea to make these macros efficient.
*
* This fully portable definition has one piece of tricky stuff.
* The UInt32 might be larger than 32 bits, so we have to mask
* any higher bits off. The simplest way to do this is to 'and' the
* value first with 0xffffffff and then shift it right. An optimising
* compiler that has a 32-bit type can optimise this 'and' away.
*
* Unfortunately there is no portable way of writing the constant
* 0xffffffff. You don't know which suffix to use (U, or UL?)
* The UINT32_MASK definition uses a bit of trickery. Shift-left
* is only defined if the shift amount is strictly less than the size
* of the UInt32, so we can't use (1<<32). The answer it to take the value
* 2, cast it to a UInt32, shift it left 31 positions, and subtract one.
* Another example of how to make something very simple extremely difficult.
* I hate C.
*
* The rotation macros are straightforward.
* They are only applied to UInt32 values, which are _unsigned_
* so the >> operator must do a logical shift that brings in zeroes.
* On most platforms you will only need to optimise the ROL32 macro; the
* ROR32 macro is not inefficient on an optimising compiler as all rotation
* amounts in this code are known at compile time.
*
* On many platforms there is a faster solution.
* For example, MS compilers have the __rotl and __rotr functions
* that generate x86 rotation instructions.
*/
#define UINT32_MASK ( (((Twofish_UInt32)2)<<31) - 1 )
#ifndef _MSC_VER
#define ROL32(x,n) ( (x)<<(n) | ((x) & UINT32_MASK) >> (32-(n)) )
#define ROR32(x,n) ( (x)>>(n) | ((x) & UINT32_MASK) << (32-(n)) )
#else
#define ROL32(x,n) (_lrotl((x), (n)))
#define ROR32(x,n) (_lrotr((x), (n)))
#endif
/*
* Select data type for q-table entries.
*
* Larger entry types cost more memory (1.5 kB), and might be faster
* or slower depending on the CPU and compiler details.
*
* This choice only affects the static data size and the key setup speed.
* Functionality, expanded key size, or encryption speed are not affected.
* Define to 1 to get large q-table entries.
*/
#define LARGE_Q_TABLE 0 /* default = 0 */
/*
* Method to select a single byte from a UInt32.
* WARNING: non-portable code if set; might not work on all platforms.
*
* Inside the inner loop of Twofish it is necessary to access the 4
* individual bytes of a UInt32. This can be done using either shifts
* and masks, or memory accesses.
*
* Set to 0 to use shift and mask operations for the byte selection.
* This is more ALU intensive. It is also fully portable.
*
* Set to 1 to use memory accesses. The UInt32 is stored in memory and
* the individual bytes are read from memory one at a time.
* This solution is more memory-intensive, and not fully portable.
* It might be faster on your platform, or not. If you use this option,
* make sure you set the CPU_IS_BIG_ENDIAN flag appropriately.
*
* This macro does not affect the conversion of the inputs and outputs
* of the cipher. See the CONVERT_USING_CASTS macro for that.
*/
#define SELECT_BYTE_FROM_UINT32_IN_MEMORY 0 /* default = 0 */
/*
* Method used to read the input and write the output.
* WARNING: non-portable code if set; might not work on all platforms.
*
* Twofish operates on 32-bit words. The input to the cipher is
* a byte array, as is the output. The portable method of doing the
* conversion is a bunch of rotate and mask operations, but on many
* platforms it can be done faster using a cast.
* This only works if your CPU allows UInt32 accesses to arbitrary Byte
* addresses.
*
* Set to 0 to use the shift and mask operations. This is fully
* portable. .
*
* Set to 1 to use a cast. The Byte * is cast to a UInt32 *, and a
* UInt32 is read. If necessary (as indicated by the CPU_IS_BIG_ENDIAN
* macro) the byte order in the UInt32 is swapped. The reverse is done
* to write the output of the encryption/decryption. Make sure you set
* the CPU_IS_BIG_ENDIAN flag appropriately.
* This option does not work unless a UInt32 is exactly 32 bits.
*
* This macro only changes the reading/writing of the plaintext/ciphertext.
* See the SELECT_BYTE_FROM_UINT32_IN_MEMORY to affect the way in which
* a UInt32 is split into 4 bytes for the S-box selection.
*/
#define CONVERT_USING_CASTS 0 /* default = 0 */
/*
* Endianness switch.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -