⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 twofish.cpp

📁 一款密码保险箱源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
 * Only relevant if SELECT_BYTE_FROM_UINT32_IN_MEMORY or
 * 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_UINT32_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_UINT32_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)

#endif


/*
 * 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. */
    static Twofish_Byte k128[] = {
        0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, 
        0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A,
        };

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -