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

📄 twofish.cpp

📁 一款密码保险箱源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    static Twofish_Byte p128[] = {
        0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E, 
        0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19
        };
    static Twofish_Byte c128[] = {
        0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85, 
        0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3
        };

    /* 192-bit test is the I=4 case of section B.2 of the Twofish book. */
    static Twofish_Byte k192[] = {
        0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36, 
        0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88, 
        0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44
        };
    static Twofish_Byte p192[] = {
        0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5,
        0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2
        };
    static Twofish_Byte c192[] = {
        0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45,
        0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65
        };

    /* 256-bit test is the I=4 case of section B.2 of the Twofish book. */
    static Twofish_Byte k256[] = {
        0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, 
        0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
        0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B,
        0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F
        };
    static Twofish_Byte p256[] = {
        0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F,
        0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6
        };
    static Twofish_Byte c256[] = {
        0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97,
        0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA
        };

    /* Run the actual tests. */
    test_vector( k128, 16, p128, c128 );
    test_vector( k192, 24, p192, c192 );
    test_vector( k256, 32, p256, c256 );
    }   


/*
 * Perform extensive test for a single key size.
 * 
 * Test a single key size against the test vectors from section
 * B.2 in the Twofish book. This is a sequence of 49 encryptions
 * and decryptions. Each plaintext is equal to the ciphertext of
 * the previous encryption. The key is made up from the ciphertext
 * two and three encryptions ago. Both plaintext and key start
 * at the zero value. 
 * We should have designed a cleaner recurrence relation for
 * these tests, but it is too late for that now. At least we learned
 * how to do it better next time.
 * For details see appendix B of the book.
 *
 * Arguments:
 * key_len      Number of bytes of key
 * final_value  Final plaintext value after 49 iterations
 */
static void test_sequence( int key_len, Twofish_Byte final_value[] )
    {
    Twofish_Byte buf[ (50+3)*16 ];      /* Buffer to hold our computation values. */
    Twofish_Byte tmp[16];               /* Temp for testing the decryption. */
    Twofish_key xkey;           /* The expanded key */
    int i;                      
    Twofish_Byte * p;

    /* Wipe the buffer */
    memset( buf, 0, sizeof( buf ) );

    /*
     * Because the recurrence relation is done in an inconvenient manner
     * we end up looping backwards over the buffer.
     */

    /* Pointer in buffer points to current plaintext. */
    p = &buf[50*16];
    for( i=1; i<50; i++ )
        {
        /* 
         * Prepare a key.
         * This automatically checks that key_len is valid.
         */
        Twofish_prepare_key( p+16, key_len, &xkey );

        /* Compute the next 16 bytes in the buffer */
        Twofish_encrypt( &xkey, p, p-16 );

        /* Check that the decryption is correct. */
        Twofish_decrypt( &xkey, p-16, tmp );
        if( memcmp( tmp, p, 16 ) != 0 )
            {
            Twofish_fatal( "Twofish decryption failure in sequence" );
            }
        /* Move on to next 16 bytes in the buffer. */
        p -= 16;
        }

    /* And check the final value. */
    if( memcmp( p, final_value, 16 ) != 0 ) 
        {
        Twofish_fatal( "Twofish encryption failure in sequence" );
        }

    /* None of the data was secret, so there is no need to wipe anything. */
    }


/* 
 * Run all three sequence tests from the Twofish test vectors. 
 *
 * This checks the most extensive test vectors currently available 
 * for Twofish. The data is from the Twofish book, appendix B.2.
 */
static void test_sequences()
    {
    static Twofish_Byte r128[] = {
        0x5D, 0x9D, 0x4E, 0xEF, 0xFA, 0x91, 0x51, 0x57,
        0x55, 0x24, 0xF1, 0x15, 0x81, 0x5A, 0x12, 0xE0
        };
    static Twofish_Byte r192[] = {
        0xE7, 0x54, 0x49, 0x21, 0x2B, 0xEE, 0xF9, 0xF4,
        0xA3, 0x90, 0xBD, 0x86, 0x0A, 0x64, 0x09, 0x41
        };
    static Twofish_Byte r256[] = {
        0x37, 0xFE, 0x26, 0xFF, 0x1C, 0xF6, 0x61, 0x75,
        0xF5, 0xDD, 0xF4, 0xC3, 0x3B, 0x97, 0xA2, 0x05
        };

    /* Run the three sequence test vectors */
    test_sequence( 16, r128 );
    test_sequence( 24, r192 );
    test_sequence( 32, r256 );
    }


/*
 * Test the odd-sized keys.
 *
 * Every odd-sized key is equivalent to a one of 128, 192, or 256 bits.
 * The equivalent key is found by padding at the end with zero bytes
 * until a regular key size is reached.
 *
 * We just test that the key expansion routine behaves properly.
 * If the expanded keys are identical, then the encryptions and decryptions
 * will behave the same.
 */
static void test_odd_sized_keys()
    {
    Twofish_Byte buf[32];
    Twofish_key xkey;
    Twofish_key xkey_two;
    int i;

    /* 
     * We first create an all-zero key to use as PRNG key. 
     * Normally we would not have to fill the buffer with zeroes, as we could
     * just pass a zero key length to the Twofish_prepare_key function.
     * However, this relies on using odd-sized keys, and those are just the
     * ones we are testing here. We can't use an untested function to test 
     * itself. 
     */
    memset( buf, 0, sizeof( buf ) );
    Twofish_prepare_key( buf, 16, &xkey );

    /* Fill buffer with pseudo-random data derived from two encryptions */
    Twofish_encrypt( &xkey, buf, buf );
    Twofish_encrypt( &xkey, buf, buf+16 );

    /* Create all possible shorter keys that are prefixes of the buffer. */
    for( i=31; i>=0; i-- )
        {
        /* Set a byte to zero. This is the new padding byte */
        buf[i] = 0;

        /* Expand the key with only i bytes of length */
        Twofish_prepare_key( buf, i, &xkey );

        /* Expand the corresponding padded key of regular length */
        Twofish_prepare_key( buf, i<=16 ? 16 : (i<= 24 ? 24 : 32), &xkey_two );

        /* Compare the two */
        if( memcmp( &xkey, &xkey_two, sizeof( xkey ) ) != 0 )
            {
            Twofish_fatal( "Odd sized keys do not expand properly" );
            }
        }

    /* None of the key values are secret, so we don't need to wipe them. */
    }


/*
 * Test the Twofish implementation.
 *
 * This routine runs all the self tests, in order of importance.
 * It is called by the Twofish_initialise routine.
 * 
 * In almost all applications the cost of running the self tests during
 * initialisation is insignificant, especially
 * compared to the time it takes to load the application from disk. 
 * If you are very pressed for initialisation performance, 
 * you could remove some of the tests. Make sure you did run them
 * once in the software and hardware configuration you are using.
 */
static void self_test()
    {
    /* The three test vectors form an absolute minimal test set. */
    test_vectors();

    /* 
     * If at all possible you should run these tests too. They take
     * more time, but provide a more thorough coverage.
     */
    test_sequences();

    /* Test the odd-sized keys. */
    test_odd_sized_keys();
    }


/*
 * And now, the actual Twofish implementation.
 *
 * This implementation generates all the tables during initialisation. 
 * I don't like large tables in the code, especially since they are easily 
 * damaged in the source without anyone noticing it. You need code to 
 * generate them anyway, and this way all the code is close together.
 * Generating them in the application leads to a smaller executable 
 * (the code is smaller than the tables it generates) and a 
 * larger static memory footprint.
 *
 * Twofish can be implemented in many ways. I have chosen to 
 * use large tables with a relatively long key setup time.
 * If you encrypt more than a few blocks of data it pays to pre-compute 
 * as much as possible. This implementation is relatively inefficient for 
 * applications that need to re-key every block or so.
 */

/* 
 * We start with the t-tables, directly from the Twofish definition. 
 * These are nibble-tables, but merging them and putting them two nibbles 
 * in one byte is more work than it is worth.
 */
static Twofish_Byte t_table[2][4][16] = {
    {
        {0x8,0x1,0x7,0xD,0x6,0xF,0x3,0x2,0x0,0xB,0x5,0x9,0xE,0xC,0xA,0x4},
        {0xE,0xC,0xB,0x8,0x1,0x2,0x3,0x5,0xF,0x4,0xA,0x6,0x7,0x0,0x9,0xD},
        {0xB,0xA,0x5,0xE,0x6,0xD,0x9,0x0,0xC,0x8,0xF,0x3,0x2,0x4,0x7,0x1},
        {0xD,0x7,0xF,0x4,0x1,0x2,0x6,0xE,0x9,0xB,0x3,0x0,0x8,0x5,0xC,0xA}
    },
    {
        {0x2,0x8,0xB,0xD,0xF,0x7,0x6,0xE,0x3,0x1,0x9,0x4,0x0,0xA,0xC,0x5},
        {0x1,0xE,0x2,0xB,0x4,0xC,0x3,0x7,0x6,0xD,0xA,0x5,0xF,0x9,0x0,0x8},
        {0x4,0xC,0x7,0x5,0x1,0x6,0x9,0xA,0x0,0xE,0xD,0x8,0x2,0xB,0x3,0xF},
        {0xB,0x9,0x5,0x1,0xC,0x3,0xD,0xE,0x6,0x4,0x7,0xF,0x2,0x0,0x8,0xA}
    }
};


/* A 1-bit rotation of 4-bit values. Input must be in range 0..15 */
#define ROR4BY1( x ) (((x)>>1) | (((x)<<3) & 0x8) )

/*
 * The q-boxes are only used during the key schedule computations. 
 * These are 8->8 bit lookup tables. Some CPUs prefer to have 8->32 bit 
 * lookup tables as it is faster to load a 32-bit value than to load an 
 * 8-bit value and zero the rest of the register.
 * The LARGE_Q_TABLE switch allows you to choose 32-bit entries in 
 * the q-tables. Here we just define the Qtype which is used to store 
 * the entries of the q-tables.
 */
#if LARGE_Q_TABLE
typedef Twofish_UInt32      Qtype;
#else
typedef Twofish_Byte        Qtype;
#endif

/* 
 * The actual q-box tables. 
 * There are two q-boxes, each having 256 entries.
 */
static Qtype q_table[2][256];


/*
 * Now the function that converts a single t-table into a q-table.
 *
 * Arguments:
 * t[4][16] : four 4->4bit lookup tables that define the q-box
 * q[256]   : output parameter: the resulting q-box as a lookup table.
 */
static void make_q_table( Twofish_Byte t[4][16], Qtype q[256] )
    {
    int ae,be,ao,bo;        /* Some temporaries. */
    int i;
    /* Loop over all input values and compute the q-box result. */
    for( i=0; i<256; i++ ) {
        /* 
         * This is straight from the Twofish specifications. 
         * 
         * The ae variable is used for the a_i values from the specs
         * with even i, and ao for the odd i's. Similarly for the b's.
         */
        ae = i>>4; be = i&0xf;
        ao = ae ^ be; bo = ae ^ ROR4BY1(be) ^ ((ae<<3)&8);
        ae = t[0][ao]; be = t[1][bo];
        ao = ae ^ be; bo = ae ^ ROR4BY1(be) ^ ((ae<<3)&8);
        ae = t[2][ao]; be = t[3][bo];

        /* Store the result in the q-box table, the cast avoids a warning. */
        q[i] = (Qtype) ((be<<4) | ae);
        }
    }


/* 
 * Initialise both q-box tables. 
 */
static void initialise_q_boxes() {
    /* Initialise each of the q-boxes using the t-tables */
    make_q_table( t_table[0], q_table[0] );
    make_q_table( t_table[1], q_table[1] );
    }


/*
 * Next up is the MDS matrix multiplication.
 * The MDS matrix multiplication operates in the field
 * GF(2)[x]/p(x) with p(x)=x^8+x^6+x^5+x^3+1.
 * If you don't understand this, read a book on finite fields. You cannot
 * follow the finite-field computations without some background.
 * 
 * In this field, multiplication by x is easy: shift left one bit 

⌨️ 快捷键说明

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