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

📄 twofish2.cpp

📁 一个nc的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            for ( int i = 0; i < 16; i++, scanner++ ) {
                *scanner = *scanner ^ qBlockPlain[i];
            }
        }

        // save the input and output blocks, since CBC needs these for XOR
        // operations
        qBlockPush( in, out );
    } else {
        // cipher block stealing, we are at Pn,
        // but since Cn-1 must now be replaced with CnC'
        // we pop it off, and recalculate Cn-1
        //
        char PnMinusOne[16];
        char CnMinusOne[16];
        if ( decrypt ) {
            // We are on an odd block, and had to do cipher block stealing,
            // so the PnMinusOne has to be derived differently.
            qBlockPop( &CnMinusOne[0], &PnMinusOne[0] );

            // First we decrypt it into CBC and C'
            char CBCplusCprime[16];
            blockCrypt16( &CnMinusOne[0], &CBCplusCprime[0] );

            // we then xor the first few bytes with the "in" bytes (Cn)
            // to recover Pn, which we put in out
            char* scanner = in;
            char* outScanner = out;
            for ( int i = 0; i < size; i++, scanner++, outScanner++ ) {
                *outScanner = *scanner ^ CBCplusCprime[i];
            }

            // We now recover the original CnMinusOne, which consists of
            // the first "size" bytes of "in" data, followed by the
            // "Cprime" portion of CBCplusCprime
            scanner = in;
            for ( i = 0; i < size; i++, scanner++ ) {
                CnMinusOne[i] = *scanner;
            }
            for ( i = size; i < 16; i++ ) {
                CnMinusOne[i] = CBCplusCprime[i];
            }
            // we now decrypt CnMinusOne to get PnMinusOne xored with Cn-2
            blockCrypt16( &CnMinusOne[0], &PnMinusOne[0] );

            for ( i = 0; i < 16; i++ ) {
                PnMinusOne[i] = PnMinusOne[i] ^ prevCipher[i];
            }

            // So at this point, out has PnMinusOne
            qBlockPush( &CnMinusOne[0], &PnMinusOne[0] );
            qBlockFlush();
            flushOutput( out, size );
        } else {
            qBlockPop( &PnMinusOne[0], &CnMinusOne[0] );
			char Pn[16];
			bzero( &Pn[0], 16 );
			memcpy( &Pn[0], in, size );
			for ( int i = 0; i < 16; i++ ) {
				Pn[i] = CnMinusOne[i] ^ Pn[i];
			}
			blockCrypt16( &Pn[0], out );
			qBlockPush( &Pn[0], out );  // now we officially have Cn-1
			qBlockFlush();  // write them all out
			flushOutput( &CnMinusOne[0], size );  // old Cn-1 becomes new partial Cn
		}
		qBlockDefined = false;
	}
}

void TwoFish::qBlockPush( char* p, char* c ) {
	if ( qBlockDefined ) {
		qBlockFlush();
	}
	memcpy( &prevCipher[0], &qBlockPlain[0], 16 );
	memcpy( &qBlockPlain[0], p, 16 );
	memcpy( &qBlockCrypt[0], c, 16 );
	qBlockDefined = true;
}

void TwoFish::qBlockPop( char* p, char* c ) {
	memcpy( p, &qBlockPlain[0], 16 );
	memcpy( c, &qBlockCrypt[0], 16 );
	qBlockDefined = false;
}

//
//  flush a complete block to all active output areas
//  this occurs when we know the block does not need to be
//  re-encrypted or re-decrypted.  The redoing of encryption
//  and decryption is necessary for cipher text stealing technique
//  and is done on the last complete block.
//
void TwoFish::qBlockFlush() {
    flushOutput( &qBlockCrypt[0], 16 );
}

void TwoFish::flush() {
    if ( qBlockDefined ) {
        qBlockFlush();
    }
}

void TwoFish::blockCrypt16( char* in, char* out ) {

	int inOffset = 0;
	int outOffset = 0;
    unsigned int x0 = (in[inOffset] & 0xFF)       |
             (in[inOffset+1] & 0xFF) <<  8 |
             (in[inOffset+2] & 0xFF) << 16 |
             (in[inOffset+3] & 0xFF) << 24;
	inOffset += 4;
    unsigned int x1 = (in[inOffset] & 0xFF)       |
             (in[inOffset+1] & 0xFF) <<  8 |
             (in[inOffset+2] & 0xFF) << 16 |
             (in[inOffset+3] & 0xFF) << 24;
	inOffset += 4;
    unsigned int x2 = (in[inOffset] & 0xFF)       |
             (in[inOffset+1] & 0xFF) <<  8 |
             (in[inOffset+2] & 0xFF) << 16 |
             (in[inOffset+3] & 0xFF) << 24;
	inOffset += 4;
    unsigned int x3 = (in[inOffset] & 0xFF)       |
             (in[inOffset+1] & 0xFF) <<  8 |
             (in[inOffset+2] & 0xFF) << 16 |
             (in[inOffset+3] & 0xFF) << 24;

/*	unsigned int x0;
	unsigned int x1;
	unsigned int x2;
	unsigned int x3;
	in += inOffset;
	memcpy( &x0, in, 4 );
	in += 4;
	memcpy( &x1, in, 4 );
	in += 4;
	memcpy( &x2, in, 4 );
	in += 4;
	memcpy( &x3, in, 4 );*/
    x0 ^= subKeys[0];
    x1 ^= subKeys[1];
    x2 ^= subKeys[2];
    x3 ^= subKeys[3];

    int k, t0, t1;
    if ( decrypt ) {
        k = 39;
        for (int R = 0; R < ROUNDS; R += 2) {
            t0 = Fe320( sBox, x0 );
            t1 = Fe323( sBox, x1 );
            x3 ^= t0 + (t1<<1) + subKeys[k--];
            x3  = x3 >> 1 | x3 << 31;
            x2  = x2 << 1 | x2 >> 31;
            x2 ^= t0 + t1 + subKeys[k--]; 

            t0 = Fe320( sBox, x2 );
            t1 = Fe323( sBox, x3 );
            x1 ^= t0 + (t1<<1) + subKeys[k--]; 
            x1  = x1 >> 1 | x1 << 31;
            x0  = x0 << 1 | x0 >> 31;
            x0 ^= t0 + t1 + subKeys[k--];
        }
    } else {
        k = 8;
        for (int R = 0; R < ROUNDS; R += 2) {
            t0 = Fe320( sBox, x0 );
            t1 = Fe323( sBox, x1 );
            x2 ^= t0 + t1 + subKeys[k++]; 
            x2  = x2 >> 1 | x2 << 31;
            x3  = x3 << 1 | x3 >> 31;
            x3 ^= t0 + (t1<<1) + subKeys[k++];

            t0 = Fe320( sBox, x2 );
            t1 = Fe323( sBox, x3 );
            x0 ^= t0 + t1 + subKeys[k++];
            x0  = x0 >> 1 | x0 << 31;
            x1  = x1 << 1 | x1 >> 31;
            x1 ^= t0 + (t1<<1) + subKeys[k++];
        }
    }

    x2 ^= subKeys[4];
    x3 ^= subKeys[5];
    x0 ^= subKeys[6];
    x1 ^= subKeys[7];

    out += outOffset;
	/*memcpy( out, &x2, 4 );
	out += 4;
	memcpy( out, &x3, 4 );
	out += 4;
	memcpy( out, &x0, 4 );
	out += 4;
	memcpy( out, &x1, 4 );*/
	
    *out++ = (x2       );
    *out++ = (x2 >>  8);
    *out++ = (x2 >> 16);
    *out++ = (x2 >> 24);

    *out++ = (x3       );
    *out++ = (x3 >>  8);
    *out++ = (x3 >> 16);
    *out++ = (x3 >> 24);

    *out++ = (x0       );
    *out++ = (x0 >>  8);
    *out++ = (x0 >> 16);
    *out++ = (x0 >> 24);

    *out++ = (x1       );
    *out++ = (x1 >>  8);
    *out++ = (x1 >> 16);
    *out++ = (x1 >> 24);
}


/**
 * Use (12, 8) Reed-Solomon code over GF(256) to produce a key S-box
 * 32-bit entity from two key material 32-bit entities.
 *
 * @param  k0  1st 32-bit entity.
 * @param  k1  2nd 32-bit entity.
 * @return  Remainder polynomial generated using RS code
 */
int TwoFish::RS_MDS_Encode( int k0, int k1 ) {
    int r = k1;
    for (int i = 0; i < 4; i++) // shift 1 byte at a time
        RS_rem( r );

    r ^= k0;
    for ( i = 0; i < 4; i++)
        RS_rem( r );

    return r;
}


int TwoFish::F32( int k64Cnt, int x, int* k32 ) {
    int b0 = b0(x);
    int b1 = b1(x);
    int b2 = b2(x);
    int b3 = b3(x);
    int k0 = k32[0];
    int k1 = k32[1];
    int k2 = k32[2];
    int k3 = k32[3];

    int result = 0;
    switch (k64Cnt & 3) {
    case 1:
        result =
              MDS[0][(P[P_01][b0] & 0xFF) ^ b0(k0)] ^
              MDS[1][(P[P_11][b1] & 0xFF) ^ b1(k0)] ^
              MDS[2][(P[P_21][b2] & 0xFF) ^ b2(k0)] ^
              MDS[3][(P[P_31][b3] & 0xFF) ^ b3(k0)];
        break;
    case 0:  // same as 4
        b0 = (P[P_04][b0] & 0xFF) ^ b0(k3);
        b1 = (P[P_14][b1] & 0xFF) ^ b1(k3);
        b2 = (P[P_24][b2] & 0xFF) ^ b2(k3);
        b3 = (P[P_34][b3] & 0xFF) ^ b3(k3);

    case 3:
        b0 = (P[P_03][b0] & 0xFF) ^ b0(k2);
        b1 = (P[P_13][b1] & 0xFF) ^ b1(k2);
        b2 = (P[P_23][b2] & 0xFF) ^ b2(k2);
        b3 = (P[P_33][b3] & 0xFF) ^ b3(k2);
    case 2:   
		// 128-bit keys (optimize for this case)
        result =
              MDS[0][(P[P_01][(P[P_02][b0] & 0xFF) ^ b0(k1)] & 0xFF) ^ b0(k0)] ^
              MDS[1][(P[P_11][(P[P_12][b1] & 0xFF) ^ b1(k1)] & 0xFF) ^ b1(k0)] ^
              MDS[2][(P[P_21][(P[P_22][b2] & 0xFF) ^ b2(k1)] & 0xFF) ^ b2(k0)] ^
              MDS[3][(P[P_31][(P[P_32][b3] & 0xFF) ^ b3(k1)] & 0xFF) ^ b3(k0)];
        break;
    }
    return result;
}

int TwoFish::Fe320( int* sBox, int x ) {
    return sBox[        b0(x) << 1      ] ^
           sBox[        (b1(x) << 1) | 1] ^
           sBox[0x200 + (b2(x) << 1)    ] ^
           sBox[0x200 + (b3(x) << 1) | 1];
}
int TwoFish::Fe323( int* sBox, int x ) {
    return sBox[        (b3(x) << 1)    ] ^
           sBox[        (b0(x) << 1) | 1] ^
           sBox[0x200 + (b1(x) << 1)    ] ^
           sBox[0x200 + (b2(x) << 1) | 1];
}
int TwoFish::Fe32( int* sBox, int x, int R ) {
    return sBox[        2*_b(x, R  )    ] ^
           sBox[        2*_b(x, R+1) + 1] ^
           sBox[0x200 + 2*_b(x, R+2)    ] ^
           sBox[0x200 + 2*_b(x, R+3) + 1];
}


static char key[32];
char* generateKey( char* s ) {
    int sIdx = 0;
    for ( int i = 0; i < 32; i++ ) {
        char sval = *( s + sIdx );
        if (( sval >= '0' ) && ( sval <= '9' )) {
            key[i] = sval;
        } else if (( sval >= 'a' ) && ( sval <= 'f' )) {
            key[i] = sval;
        } else {
            int q = sval%16;
            if ( q < 10 ) {
                key[i] = ('0' + q);
            } else {
                key[i] = ('a' + q - 10);
            }
        }
        sIdx++;
        if ( *( s + sIdx ) == 0 ) {
            sIdx = 0;
        }
    }
    return( &key[0] );
}


AsciiTwofish::AsciiTwofish( TwoFish* e ) {
    engine = e;
}

void AsciiTwofish::encryptAscii( char* in, char* out, int outBufferSize ) {
    engine->setDecrypt( false );
    engine->resetCBC();

    unsigned char byteBuf[200];
    char* originalOut = out;
       
    // encrypt one block at a time with twofish
    char inList[16];
    unsigned char outList[16];
    engine->setOutputBuffer( byteBuf );    
    int remaining = strlen( in );
    int len = remaining;
    int bidx = 0;
    while ( remaining > 0 ) {
        if ( remaining > 16 ) {
            memcpy( inList, in + bidx, 16 );
            engine->blockCrypt( inList, (char*)outList, 16 );
        } else {
            memcpy( inList, in + bidx, remaining );
            engine->blockCrypt( inList, (char*)outList, remaining );
        }
        bidx += 16;
        remaining -= 16;
    }
    engine->flush();

    // now do totally stupid ascii encoding of bytes
    if ( outBufferSize < len*3 ) {
        printf( "Hey, outBufferSize is %d, but len*3 is %d\n", outBufferSize, len*3 );
    } else {
       for ( int i = 0; i < len; i++ ) {
          sprintf( out, "%03d", byteBuf[i] );
          out += 3;
       }
    }
    engine->setOutputBuffer( NULL );    
}

#define BOGUS_ASCII_BUFLEN 2000

void AsciiTwofish::decryptAscii( char* in, char* out ) {
    engine->setDecrypt( true );
    engine->resetCBC();
    engine->setOutputBuffer( (unsigned char*)out );

    int inLen = strlen( in );
    if (( *( in + inLen - 1 ) == '\n' ) ||
        ( *( in + inLen - 1 ) == '\r' )) {
        *( in + inLen - 1 ) = 0;
        inLen = strlen( in );
    }
    unsigned char byteBuf[BOGUS_ASCII_BUFLEN];
    int byteBufIdx = 0;
	if ( inLen*3 > BOGUS_ASCII_BUFLEN ) {
		printf( "inLength %d is too big!\n", inLen );
		exit( 0 );
	}

    // first convert ascii to bytes, placing in another buffer
    for ( int i = 0; i < inLen; i += 3 ) {
       unsigned int x = 0;
       x = x * 10 + ( *in++ - '0' );
       x = x * 10 + ( *in++ - '0' );
       x = x * 10 + ( *in++ - '0' );
       byteBuf[ byteBufIdx++ ] = x;
       byteBuf[ byteBufIdx ] = 0;
    }
       
    // then run it through twofish placing result into command buffer
    char inList[16];
    unsigned char outList[16];
    int remaining = byteBufIdx;
    *( out + byteBufIdx ) = 0;
    int bidx = 0;
    while ( remaining > 0 ) {
        if ( remaining > 16 ) {
            memcpy( inList, &byteBuf[bidx], 16 );
            engine->blockCrypt( inList, (char*)outList, 16 );
        } else {
            memcpy( inList, &byteBuf[bidx], remaining );
            engine->blockCrypt( inList, (char*)outList, remaining );
        }
        bidx += 16;
        remaining -= 16;
    }
    engine->flush();
    engine->setOutputBuffer( NULL );    
    *( out + byteBufIdx ) = 0;
}

⌨️ 快捷键说明

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