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

📄 twofish.cpp

📁 一款密码保险箱源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
 * and if bit 8 is set then xor the result with 0x169. 
 *
 * The MDS coefficients use a multiplication by 1/x,
 * or rather a division by x. This is easy too: first make the
 * value 'even' (i.e. bit 0 is zero) by xorring with 0x169 if necessary, 
 * and then shift right one position. 
 * Even easier: shift right and xor with 0xb4 if the lsbit was set.
 *
 * The MDS coefficients are 1, EF, and 5B, and we use the fact that
 *   EF = 1 + 1/x + 1/x^2
 *   5B = 1       + 1/x^2
 * in this field. This makes multiplication by EF and 5B relatively easy.
 *
 * This property is no accident, the MDS matrix was designed to allow
 * this implementation technique to be used.
 *
 * We have four MDS tables, each mapping 8 bits to 32 bits.
 * Each table performs one column of the matrix multiplication. 
 * As the MDS is always preceded by q-boxes, each of these tables
 * also implements the q-box just previous to that column.
 */

/* The actual MDS tables. */
static Twofish_UInt32 MDS_table[4][256];

/* A small table to get easy conditional access to the 0xb4 constant. */
static Twofish_UInt32 mds_poly_divx_const[] = {0,0xb4};

/* Function to initialise the MDS tables. */
static void initialise_mds_tables()
    {
    int i;
    Twofish_UInt32 q,qef,q5b;       /* Temporary variables. */

    /* Loop over all 8-bit input values */
    for( i=0; i<256; i++ ) 
        {
        /* 
         * To save some work during the key expansion we include the last
         * of the q-box layers from the h() function in these MDS tables.
         */

        /* We first do the inputs that are mapped through the q0 table. */
        q = q_table[0][i];
        /*
         * Here we divide by x, note the table to get 0xb4 only if the 
         * lsbit is set. 
         * This sets qef = (1/x)*q in the finite field
         */
        qef = (q >> 1) ^ mds_poly_divx_const[ q & 1 ];
        /*
         * Divide by x again, and add q to get (1+1/x^2)*q. 
         * Note that (1+1/x^2) =  5B in the field, and addition in the field
         * is exclusive or on the bits.
         */
        q5b = (qef >> 1) ^ mds_poly_divx_const[ qef & 1 ] ^ q;
        /* 
         * Add q5b to qef to set qef = (1+1/x+1/x^2)*q.
         * Again, (1+1/x+1/x^2) = EF in the field.
         */
        qef ^= q5b;

        /* 
         * Now that we have q5b = 5B * q and qef = EF * q 
         * we can fill two of the entries in the MDS matrix table. 
         * See the Twofish specifications for the order of the constants.
         */
        MDS_table[1][i] = (q  <<24) | (q5b<<16) | (qef<<8) | qef;
        MDS_table[3][i] = (q5b<<24) | (qef<<16) | (q  <<8) | q5b;

        /* Now we do it all again for the two columns that have a q1 box. */
        q = q_table[1][i];
        qef = (q >> 1) ^ mds_poly_divx_const[ q & 1 ];
        q5b = (qef >> 1) ^ mds_poly_divx_const[ qef & 1 ] ^ q;
        qef ^= q5b;

        /* The other two columns use the coefficient in a different order. */
        MDS_table[0][i] = (qef<<24) | (qef<<16) | (q5b<<8) | q  ;
        MDS_table[2][i] = (qef<<24) | (q  <<16) | (qef<<8) | q5b;
        }
    }


/*
 * The h() function is the heart of the Twofish cipher. 
 * It is a complicated sequence of q-box lookups, key material xors, 
 * and finally the MDS matrix.
 * We use lots of macros to make this reasonably fast.
 */

/* First a shorthand for the two q-tables */
#define q0  q_table[0]
#define q1  q_table[1]

/*
 * Each macro computes one column of the h for either 2, 3, or 4 stages.
 * As there are 4 columns, we have 12 macros in all.
 * 
 * The key bytes are stored in the Byte array L at offset 
 * 0,1,2,3,  8,9,10,11,  [16,17,18,19,   [24,25,26,27]] as this is the
 * order we get the bytes from the user. If you look at the Twofish 
 * specs, you'll see that h() is applied to the even key words or the
 * odd key words. The bytes of the even words appear in this spacing,
 * and those of the odd key words too.
 *
 * These macros are the only place where the q-boxes and the MDS table
 * are used.
 */
#define H02( y, L )  MDS_table[0][q0[q0[y]^L[ 8]]^L[0]]
#define H12( y, L )  MDS_table[1][q0[q1[y]^L[ 9]]^L[1]]
#define H22( y, L )  MDS_table[2][q1[q0[y]^L[10]]^L[2]]
#define H32( y, L )  MDS_table[3][q1[q1[y]^L[11]]^L[3]]
#define H03( y, L )  H02( q1[y]^L[16], L )
#define H13( y, L )  H12( q1[y]^L[17], L )
#define H23( y, L )  H22( q0[y]^L[18], L )
#define H33( y, L )  H32( q0[y]^L[19], L )
#define H04( y, L )  H03( q1[y]^L[24], L )
#define H14( y, L )  H13( q0[y]^L[25], L )
#define H24( y, L )  H23( q0[y]^L[26], L )
#define H34( y, L )  H33( q1[y]^L[27], L )

/*
 * Now we can define the h() function given an array of key bytes. 
 * This function is only used in the key schedule, and not to pre-compute
 * the keyed S-boxes.
 *
 * In the key schedule, the input is always of the form k*(1+2^8+2^16+2^24)
 * so we only provide k as an argument.
 *
 * Arguments:
 * k        input to the h() function.
 * L        pointer to array of key bytes at 
 *          offsets 0,1,2,3, ... 8,9,10,11, [16,17,18,19, [24,25,26,27]]
 * kCycles  # key cycles, 2, 3, or 4.
 */
static Twofish_UInt32 h( int k, Twofish_Byte L[], int kCycles )
    {
    switch( kCycles ) {
        /* We code all 3 cases separately for speed reasons. */
    case 2:
        return H02(k,L) ^ H12(k,L) ^ H22(k,L) ^ H32(k,L);
    case 3:
        return H03(k,L) ^ H13(k,L) ^ H23(k,L) ^ H33(k,L);
    case 4:
        return H04(k,L) ^ H14(k,L) ^ H24(k,L) ^ H34(k,L);
    default: 
        /* This is always a coding error, which is fatal. */
        Twofish_fatal( "Twofish h(): Illegal argument" );
		return 0;
        }
    }


/*
 * Pre-compute the keyed S-boxes.
 * Fill the pre-computed S-box array in the expanded key structure.
 * Each pre-computed S-box maps 8 bits to 32 bits.
 *
 * The S argument contains half the number of bytes of the full key, but is
 * derived from the full key. (See Twofish specifications for details.)
 * S has the weird byte input order used by the Hxx macros.
 *
 * This function takes most of the time of a key expansion.
 *
 * Arguments:
 * S        pointer to array of 8*kCycles Bytes containing the S vector.
 * kCycles  number of key words, must be in the set {2,3,4}
 * xkey     pointer to Twofish_key structure that will contain the S-boxes.
 */
static void fill_keyed_sboxes( Twofish_Byte S[], int kCycles, Twofish_key * xkey )
    {
    int i;
    switch( kCycles ) {
        /* We code all 3 cases separately for speed reasons. */
    case 2:
        for( i=0; i<256; i++ )
            {
            xkey->s[0][i]= H02( i, S );
            xkey->s[1][i]= H12( i, S );
            xkey->s[2][i]= H22( i, S );
            xkey->s[3][i]= H32( i, S );
            }
        break;
    case 3:
        for( i=0; i<256; i++ )
            {
            xkey->s[0][i]= H03( i, S );
            xkey->s[1][i]= H13( i, S );
            xkey->s[2][i]= H23( i, S );
            xkey->s[3][i]= H33( i, S );
            }
        break;
    case 4:
        for( i=0; i<256; i++ )
            {
            xkey->s[0][i]= H04( i, S );
            xkey->s[1][i]= H14( i, S );
            xkey->s[2][i]= H24( i, S );
            xkey->s[3][i]= H34( i, S );
            }
        break;
    default: 
        /* This is always a coding error, which is fatal. */
        Twofish_fatal( "Twofish fill_keyed_sboxes(): Illegal argument" );
        }
    }


/* A flag to keep track of whether we have been initialised or not. */
static int Twofish_initialised = 0;

/*
 * Initialise the Twofish implementation.
 * This function must be called before any other function in the
 * Twofish implementation is called.
 * This routine also does some sanity checks, to make sure that
 * all the macros behave, and it tests the whole cipher.
 */
void Twofish_initialise()
    {
    /* First test the various platform-specific definitions. */
    test_platform();

    /* We can now generate our tables, in the right order of course. */
    initialise_q_boxes();
    initialise_mds_tables();

    /* We're finished with the initialisation itself. */
    Twofish_initialised = 1;

    /* 
     * And run some tests on the whole cipher. 
     * Yes, you need to do this every time you start your program. 
     * It is called assurance; you have to be certain that your program
     * still works properly. 
     */
    self_test();
    }


/*
 * The Twofish key schedule uses an Reed-Solomon code matrix multiply.
 * Just like the MDS matrix, the RS-matrix is designed to be easy
 * to implement. Details are below in the code. 
 *
 * These constants make it easy to compute in the finite field used 
 * for the RS code.
 *
 * We use Bytes for the RS computation, but these are automatically
 * widened to unsigned integers in the expressions. Having unsigned
 * ints in these tables therefore provides the fastest access.
 */
static unsigned int rs_poly_const[] = {0, 0x14d};
static unsigned int rs_poly_div_const[] = {0, 0xa6 };


/*
 * Prepare a key for use in encryption and decryption.
 * Like most block ciphers, Twofish allows the key schedule 
 * to be pre-computed given only the key. 
 * Twofish has a fairly 'heavy' key schedule that takes a lot of time 
 * to compute. The main work is pre-computing the S-boxes used in the 
 * encryption and decryption. We feel that this makes the cipher much 
 * harder to attack. The attacker doesn't even know what the S-boxes 
 * contain without including the entire key schedule in the analysis. 
 *
 * Unlike most Twofish implementations, this one allows any key size from
 * 0 to 32 bytes. Odd key sizes are defined for Twofish (see the 
 * specifications); the key is simply padded with zeroes to the next real 
 * key size of 16, 24, or 32 bytes.
 * Each odd-sized key is thus equivalent to a single normal-sized key.
 *
 * Arguments:
 * key      array of key bytes
 * key_len  number of bytes in the key, must be in the range 0,...,32.
 * xkey     Pointer to an Twofish_key structure that will be filled 
 *             with the internal form of the cipher key.
 */
void Twofish_prepare_key( Twofish_Byte key[], int key_len, Twofish_key * xkey )
    {
    /* We use a single array to store all key material in, 
     * to simplify the wiping of the key material at the end.
     * The first 32 bytes contain the actual (padded) cipher key.
     * The next 32 bytes contain the S-vector in its weird format,
     * and we have 4 bytes of overrun necessary for the RS-reduction.
     */
    Twofish_Byte K[32+32+4]; 

    int kCycles;        /* # key cycles, 2,3, or 4. */

    int i;
    Twofish_UInt32 A, B;        /* Used to compute the round keys. */

    Twofish_Byte * kptr;        /* Three pointers for the RS computation. */
    Twofish_Byte * sptr;
    Twofish_Byte * t;

    Twofish_Byte b,bx,bxx;      /* Some more temporaries for the RS computation. */

    /* Check that the Twofish implementation was initialised. */
    if( Twofish_initialised == 0 )
        {
        /* 
         * You didn't call Twofish_initialise before calling this routine.
         * This is a programming error, and therefore we call the fatal
         * routine. 
         *
         * I could of course call the initialisation routine here,
         * but there are a few reasons why I don't. First of all, the 
         * self-tests have to be done at startup. It is no good to inform
         * the user that the cipher implementation fails when he wants to
         * write his data to disk in encrypted form. You have to warn him
         * before he spends time typing his data. Second, the initialisation
         * and self test are much slower than a single key expansion.
         * Calling the initialisation here makes the performance of the
         * cipher unpredictable. This can lead to really weird problems 
         * if you use the cipher for a real-time task. Suddenly it fails 
         * once in a while the first time you try to use it. Things like 
         * that are almost impossible to debug.
         */
        Twofish_fatal( "Twofish implementation was not initialised." );
        
        /*
         * There is always a danger that the Twofish_fatal routine returns,
         * in spite of the specifications that it should not. 
         * (A good programming rule: don't trust the rest of the code.)
         * This would be disasterous. If the q-tables and MDS-tables have
         * not been initialised, they are probably still filled with zeroes.
         * Suppose the MDS-tables are all zero. The key expansion would then
         * generate all-zero round keys, and all-zero s-boxes. The danger
         * is that nobody would notice as the encryption function still
         * mangles the input, and the decryption still 'decrypts' it,
         * but now in a completely key-independent manner. 
         * To stop such security disasters, we use blunt force.
         * If your program hangs here: fix the fatal routine!
         */
        for(;;);        /* Infinite loop, which beats being insecure. */
        }

    /* Check for valid key length. */

⌨️ 快捷键说明

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