试图将XTea加密算法从C移植到Python

时间:2017-06-06 19:45:47

标签: python c encryption

我在将一些C代码翻译成Python时遇到了麻烦。我已尽力模拟C中整数溢出的性质,但到目前为止还没有成功。如果有人有一些见解,那将是非常感谢,因为我是python的新手。加密&解密如下:

iterations = 32
delta = 0x9e3779b9
xTeaKey = [<some int32>, <some int32>, <some int32>, <some int32>]

def int_overflow(val):
    maxint = 2147483647

    if not -maxint-1 <= val <= maxint:
        val = (val + (maxint + 1)) % (2 * (maxint + 1)) - maxint - 1

    if not -maxint-1 <= val <= maxint:
        print "AAAAAH"

    return val

def xTeaShuffle(x, sum, sumOffset) :
    e1 = (x << 4) & 0xffffffff
    e2 = x >> 5
    e3 = e1 ^ e2
    e4 = int_overflow(e3 + x)

    e5a = int_overflow(sum + xTeaKey[(sum & 0x03)]);
    e5b = int_overflow(sum + xTeaKey[((sum >> 11) & 0x03)]);
    e5 = e5b if sumOffset else e5a

    result = e4 ^ e5

    return result

def xTeaEncode(data, length) :
    i = 0

    while i < length:
        sum = 0
        x1 = (data[i] << 16) + data[i + 1]
        x2 = (data[i + 2] << 16) + data[i + 3]

        iter = iterations

        while iter > 0 :
            x1 = int_overflow(x1 + xTeaShuffle(x2, sum, False))
            sum = int_overflow(sum + delta);
            x2 = int_overflow(x2 + xTeaShuffle(x1, sum, True))
            iter -= 1

        data[i] = (x1 >> 16) & 0xffff
        data[i + 1] = x1 & 0xffff
        data[i + 2] = (x2 >> 16) & 0xffff
        data[i + 3] = x2 & 0xffff

        i += 4

    return

def xTeaDecode(data, length) :
    i = 0

    while i < length:
        sum = int_overflow(delta * iterations)
        x1 = (data[i] << 16) + data[i + 1]
        x2 = (data[i + 2] << 16) + data[i + 3]

        while (sum != 0) :
            x2 = int_overflow(x2 - xTeaShuffle(x1, sum, True))
            sum = int_overflow(sum - delta)
            x1 = int_overflow(x1 - xTeaShuffle(x2, sum, False))

        data[i] = (x1 >> 16) & 0xffff
        data[i + 1] = x1 & 0xffff
        data[i + 2] = (x2 >> 16) & 0xffff
        data[i + 3] = x2 & 0xffff

        i += 4

    return

原始C代码

DllExport void _stdcall XTEAEncode16(unsigned short *data, unsigned char dataLength) 
{
    unsigned char i = 0;
    int x1;
    int x2;
    int sum;
    unsigned char iterationCount;

    while (i < dataLength) 
    {
        sum = 0;
        x1 = ((unsigned int)data[i] << 16) + (unsigned int)data[i+1];
        x2 = ((unsigned int)data[i+2] << 16) + (unsigned int)data[i+3];
        iterationCount = NUM_ITERATIONS;

        while (iterationCount > 0) 
        {
            x1 += (((x2 << 4) ^ (x2 >> 5)) + x2) ^ (sum + XTEAKey[(sum & 0x03)]);
            sum += DELTA;
            x2 += (((x1 << 4) ^ (x1 >> 5)) + x1) ^ (sum + XTEAKey[((sum >> 11) & 0x03)]);
            iterationCount--;
        }
        data[i]   = (unsigned short)((unsigned int)x1>>16);     /* take upper half as an int*/
        data[i+1] = (unsigned short)(unsigned int)x1;           /* take lower half */
        data[i+2] = (unsigned short)((unsigned int)x2>>16);     /* take upper half as an int*/
        data[i+3] = (unsigned short)(unsigned int)x2;           /* take lower half */

        i += 4;
    }
}

/**
 * Decodes (deciphers) data.
 * Note that data length must be a multiple of 4 words (64 bit). 
 *//* *< 16-bit data array *//* *< length of data array */
DllExport void _stdcall  XTEADecode16(unsigned short* data, unsigned char dataLength ) 
{
    unsigned char i = 0;
    int x1;
    int x2;
    int sum;
    unsigned char iterations;

    iterations = NUM_ITERATIONS;

    while (i < dataLength) 
    {
        sum = DELTA * iterations;
        x1 = ((unsigned int)data[i] << 16) + (unsigned int)data[i+1];
        x2 = ((unsigned int)data[i+2] << 16) + (unsigned int)data[i+3];

        while (sum != 0) 
        {
            x2 -= (((x1 << 4) ^ (x1 >> 5)) + x1) ^ (sum + XTEAKey[((sum >> 11) & 0x03)]);
            sum -= DELTA;
            x1 -= (((x2 << 4) ^ (x2 >> 5)) + x2) ^ (sum + XTEAKey[(sum & 0x03)]);
        }
        data[i]   = (unsigned short)((unsigned int)x1 >> 16);   /* take upper half as an int*/
        data[i+1] = (unsigned short)((unsigned int)x1);         /* take lower half */
        data[i+2] = (unsigned short)((unsigned int)x2 >> 16);   /* take upper half as an int*/
        data[i+3] = (unsigned short)((unsigned int)x2);         /* take lower half */

        i += 4;
    }
}

从我的实验中,加密似乎没问题,但我永远无法解密到正确的值。任何见解将不胜感激。

1 个答案:

答案 0 :(得分:0)

解决了!!!这是问题所在:

当向右移位(并且取决于实现)时,位可以用0或1填充,具体取决于最左边的位。这是为了保留两个恭维二进制数的符号。因此,当模拟c整数上的移位时,如果我们不模拟符号,我们必须用左边填充1,如果这是最左边的位。