📄 twofish.cpp
字号:
* CONVERT_USING_CASTS is set. * * Set to 1 on a big-endian machine, and to 0 on a little-endian machine. * Twofish uses the little-endian convention (least significant byte first) * and big-endian machines (using most significant byte first) * have to do a few conversions. * * CAUTION: This code has never been tested on a big-endian machine, * because I don't have access to one. Feedback appreciated. */#define CPU_IS_BIG_ENDIAN 0/* * Macro to reverse the order of the bytes in a UInt32. * Used to convert to little-endian on big-endian machines. * This macro is always tested, but only used in the encryption and * decryption if CONVERT_USING_CASTS, and CPU_IS_BIG_ENDIAN * are both set. In other words: this macro is only speed-critical if * both these flags have been set. * * This default definition of SWAP works, but on many platforms there is a * more efficient implementation. */#define BSWAP(x) (ROL32((x),8)&0x00ff00ff | ROR32((x),8) & 0xff00ff00)/* * END OF PLATFORM FIXES * ===================== * * You should not have to touch the rest of this file. *//* * Convert the external type names to some that are easier to use inside * this file. I didn't want to use the names Byte and UInt32 in the * header file, because many programs already define them and using two * conventions at once can be very difficult. * Don't change these definitions! Change the originals * in twofish.h instead. *//* A Byte must be an unsigned integer, 8 bits long. */// typedef Twofish_Byte Byte;/* A UInt32 must be an unsigned integer at least 32 bits long. */// typedef Twofish_UInt32 UInt32;/* * Define a macro ENDIAN_CONVERT. * * We define a macro ENDIAN_CONVERT that performs a BSWAP on big-endian * machines, and is the identity function on little-endian machines. * The code then uses this macro without considering the endianness. */#if CPU_IS_BIG_ENDIAN#define ENDIAN_CONVERT(x) BSWAP(x)#else#define ENDIAN_CONVERT(x) (x)#endif/* * Compute byte offset within a UInt32 stored in memory. * * This is only used when SELECT_BYTE_FROM_quint32_IN_MEMORY is set. * * The input is the byte number 0..3, 0 for least significant. * Note the use of sizeof() to support UInt32 types that are larger * than 4 bytes. */#if CPU_IS_BIG_ENDIAN#define BYTE_OFFSET( n ) (sizeof(Twofish_UInt32) - 1 - (n) )#else#define BYTE_OFFSET( n ) (n)#endif/* * Macro to get Byte no. b from UInt32 value X. * We use two different definition, depending on the settings. */#if SELECT_BYTE_FROM_quint32_IN_MEMORY /* Pick the byte from the memory in which X is stored. */#define SELECT_BYTE( X, b ) (((Twofish_Byte *)(&(X)))[BYTE_OFFSET(b)])#else /* Portable solution: Pick the byte directly from the X value. */#define SELECT_BYTE( X, b ) (((X) >> (8*(b))) & 0xff)#endif/* Some shorthands because we use byte selection in large formulae. */#define b0(X) SELECT_BYTE((X),0)#define b1(X) SELECT_BYTE((X),1)#define b2(X) SELECT_BYTE((X),2)#define b3(X) SELECT_BYTE((X),3)/* * We need macros to load and store UInt32 from/to byte arrays * using the least-significant-byte-first convention. * * GET32( p ) gets a UInt32 in lsb-first form from four bytes pointed to * by p. * PUT32( v, p ) writes the UInt32 value v at address p in lsb-first form. */#if CONVERT_USING_CASTS /* Get UInt32 from four bytes pointed to by p. */#define GET32( p ) ENDIAN_CONVERT( *((Twofish_UInt32 *)(p)) ) /* Put UInt32 into four bytes pointed to by p */#define PUT32( v, p ) *((Twofish_UInt32 *)(p)) = ENDIAN_CONVERT(v)#else /* Get UInt32 from four bytes pointed to by p. */#define GET32( p ) \ ( \ (Twofish_UInt32)((p)[0]) \ | (Twofish_UInt32)((p)[1])<< 8 \ | (Twofish_UInt32)((p)[2])<<16 \ | (Twofish_UInt32)((p)[3])<<24 \ ) /* Put UInt32 into four bytes pointed to by p */#define PUT32( v, p ) \ (p)[0] = (Twofish_Byte)(((v) ) & 0xff); \ (p)[1] = (Twofish_Byte)(((v) >> 8) & 0xff); \ (p)[2] = (Twofish_Byte)(((v) >> 16) & 0xff); \ (p)[3] = (Twofish_Byte)(((v) >> 24) & 0xff)#endifvoid Twofish_fatal(char* msg){ qCritical("Twofish: Fatal Error"); exit(1);}/* * Test the platform-specific macros. * This function tests the macros defined so far to make sure the * definitions are appropriate for this platform. * If you make any mistake in the platform configuration, this should detect * that and inform you what went wrong. * Somewhere, someday, this is going to save somebody a lot of time, * because misbehaving macros are hard to debug. */static void test_platform() { /* Buffer with test values. */ Twofish_Byte buf[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0}; Twofish_UInt32 C; Twofish_UInt32 x,y; int i; /* * Some sanity checks on the types that can't be done in compile time. * A smart compiler will just optimise these tests away. * The pre-processor doesn't understand different types, so we cannot * do these checks in compile-time. * * I hate C. * * The first check in each case is to make sure the size is correct. * The second check is to ensure that it is an unsigned type. */ if( ((Twofish_UInt32)((Twofish_UInt32)1 << 31) == 0) || ((Twofish_UInt32)-1 < 0 )) { Twofish_fatal( "Twofish code: Twofish_UInt32 type not suitable" ); } if( (sizeof( Twofish_Byte ) != 1) || (((Twofish_Byte)-1) < 0) ) { Twofish_fatal( "Twofish code: Twofish_Byte type not suitable" ); } /* * Sanity-check the endianness conversions. * This is just an aid to find problems. If you do the endianness * conversion macros wrong you will fail the full cipher test, * but that does not help you find the error. * Always make it easy to find the bugs! * * Detail: There is no fully portable way of writing UInt32 constants, * as you don't know whether to use the U or UL suffix. Using only U you * might only be allowed 16-bit constants. Using UL you might get 64-bit * constants which cannot be stored in a UInt32 without warnings, and * which generally behave subtly different from a true UInt32. * As long as we're just comparing with the constant, * we can always use the UL suffix and at worst lose some efficiency. * I use a separate '32-bit constant' macro in most of my other code. * * I hate C. * * Start with testing GET32. We test it on all positions modulo 4 * to make sure we can handly any position of inputs. (Some CPUs * do not allow non-aligned accesses which we would do if you used * the CONVERT_USING_CASTS option. */ if( (GET32( buf ) != 0x78563412UL) || (GET32(buf+1) != 0x9a785634UL) || (GET32( buf+2 ) != 0xbc9a7856UL) || (GET32(buf+3) != 0xdebc9a78UL) ) { Twofish_fatal( "Twofish code: GET32 not implemented properly" ); } /* * We can now use GET32 to test PUT32. * We don't test the shifted versions. If GET32 can do that then * so should PUT32. */ C = GET32( buf ); PUT32( 3*C, buf ); if( GET32( buf ) != 0x69029c36UL ) { Twofish_fatal( "Twofish code: PUT32 not implemented properly" ); } /* Test ROL and ROR */ for( i=1; i<32; i++ ) { /* Just a simple test. */ x = ROR32( C, i ); y = ROL32( C, i ); x ^= (C>>i) ^ (C<<(32-i)); y ^= (C<<i) ^ (C>>(32-i)); x |= y; /* * Now all we check is that x is zero in the least significant * 32 bits. Using the UL suffix is safe here, as it doesn't matter * if we get a larger type. */ if( (x & 0xffffffffUL) != 0 ) { Twofish_fatal( "Twofish ROL or ROR not properly defined." ); } } /* Test the BSWAP macro */ if( BSWAP(C) != 0x12345678UL ) { /* * The BSWAP macro should always work, even if you are not using it. * A smart optimising compiler will just remove this entire test. */ Twofish_fatal( "BSWAP not properly defined." ); } /* And we can test the b<i> macros which use SELECT_BYTE. */ if( (b0(C)!=0x12) || (b1(C) != 0x34) || (b2(C) != 0x56) || (b3(C) != 0x78) ) { /* * There are many reasons why this could fail. * Most likely is that CPU_IS_BIG_ENDIAN has the wrong value. */ Twofish_fatal( "Twofish code: SELECT_BYTE not implemented properly" ); } }/* * Finally, we can start on the Twofish-related code. * You really need the Twofish specifications to understand this code. The * best source is the Twofish book: * "The Twofish Encryption Algorithm", by Bruce Schneier, John Kelsey, * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson. * you can also use the AES submission document of Twofish, which is * available from my list of publications on my personal web site at * http://niels.ferguson.net/. * * The first thing we do is write the testing routines. This is what the * implementation has to satisfy in the end. We only test the external * behaviour of the implementation of course. *//* * Perform a single self test on a (plaintext,ciphertext,key) triple. * Arguments: * key array of key bytes * key_len length of key in bytes * p plaintext * c ciphertext */static void test_vector( Twofish_Byte key[], int key_len, Twofish_Byte p[16], Twofish_Byte c[16] ) { Twofish_Byte tmp[16]; /* scratch pad. */ Twofish_key xkey; /* The expanded key */ int i; /* Prepare the key */ Twofish_prepare_key( key, key_len, &xkey ); /* * We run the test twice to ensure that the xkey structure * is not damaged by the first encryption. * Those are hideous bugs to find if you get them in an application. */ for( i=0; i<2; i++ ) { /* Encrypt and test */ Twofish_encrypt( &xkey, p, tmp ); if( memcmp( c, tmp, 16 ) != 0 ) { Twofish_fatal( "Twofish encryption failure" ); } /* Decrypt and test */ Twofish_decrypt( &xkey, c, tmp ); if( memcmp( p, tmp, 16 ) != 0 ) { Twofish_fatal( "Twofish decryption failure" ); } } /* The test keys are not secret, so we don't need to wipe xkey. */ }/* * Check implementation using three (key,plaintext,ciphertext) * test vectors, one for each major key length. * * This is an absolutely minimal self-test. * This routine does not test odd-sized keys. */static void test_vectors() { /* * We run three tests, one for each major key length. * These test vectors come from the Twofish specification. * One encryption and one decryption using randomish data and key * will detect almost any error, especially since we generate the * tables ourselves, so we don't have the problem of a single * damaged table entry in the source. */ /* 128-bit test is the I=3 case of section B.2 of the Twofish book. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -