使用Java中的BigIntegers进行BitShifting

The*_*Poo 7 java encryption des key biginteger

我正在使用BigIntegers在Java中实现DES加密.

我通过执行BigInteger.leftShift(int n)方法将Java二进制密钥与Java BigIntegers一起移位.N(Kn)的关键取决于Kn-1的移位结果.我得到的问题是,我在生成每个密钥后打印出结果,并且转移不是预期的输出.密钥分为2 Cn和Dn(分别为左和右).

我特意尝试这个:"要进行左移,将每个位移到左边一个位置,除了第一个位,循环到块的末尾."

根据转变,似乎最终会对O进行攻击.不知道如何纠正这个问题.

结果:

c0:11110101010100110011000011110

d0:11110001111001100110101010100

c1:111101010101001100110000111100

d1:111100011110011001101010101000

c2:11110101010100110011000011110000

d2:11110001111001100110101010100000

c3:1111010101010011001100001111000000

d3:1111000111100110011010101010000000

c4:111101010101001100110000111100000000

d4:111100011110011001101010101000000000

c5:11110101010100110011000011110000000000

d5:11110001111001100110101010100000000000

c6:1111010101010011001100001111000000000000

d6:1111000111100110011010101010000000000000

c7:111101010101001100110000111100000000000000

d7:111100011110011001101010101000000000000000

c8:1111010101010011001100001111000000000000000

d8:1111000111100110011010101010000000000000000

c9:111101010101001100110000111100000000000000000

d9:111100011110011001101010101000000000000000000

c10:11110101010100110011000011110000000000000000000

d10:11110001111001100110101010100000000000000000000

c11:1111010101010011001100001111000000000000000000000

d11:1111000111100110011010101010000000000000000000000

c12:111101010101001100110000111100000000000000000000000

d12:111100011110011001101010101000000000000000000000000

c13:11110101010100110011000011110000000000000000000000000

d13:11110001111001100110101010100000000000000000000000000

c14:1111010101010011001100001111000000000000000000000000000

d14:11110001111001100110101010100000000000000000000000000000000

c15:11110101010100110011000011110000000000000000000000000000

d15:111100011110011001101010101000000000000000000000000000000000

Bre*_*ail 10

BigInteger实现了无限精度的整数,因此向左移动将继续向左添加零.你需要一个旋转:

private static BigInteger rotateLeft(BigInteger bi) {
    BigInteger ret = bi.shiftLeft(1);
    if (ret.testBit(32)) {
        ret = ret.clearBit(32).setBit(0);
    }
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

对于32位数字来说,这将是相当低效的,所以你也可以使用原语来旋转DES的28位数.我不熟悉DES算法,所以我假设你需要BigInteger来做其他事情.

private static BigInteger rotateLeftPrimitive(BigInteger bi) {
    int value = bi.intValue();
    return BigInteger.valueOf(((value << 1) & 0xffffffe) | ((value >>> 27) & 1));
}
Run Code Online (Sandbox Code Playgroud)


pol*_*nts 4

看来你需要循环左移。BigInteger.shiftLeft不是循环的。您必须将shiftLeft, shiftRight,and和组合起来or,就像使用intand一样<<

static BigInteger allOnes(int L) {
    return BigInteger.ZERO
        .setBit(L)
        .subtract(BigInteger.ONE);
}

static BigInteger cyclicLeftShift(BigInteger n, int L, int k) {
    return n.shiftLeft(k)
        .or(n.shiftRight(L - k))
        .and(allOnes(L));
}
Run Code Online (Sandbox Code Playgroud)

现在,将循环移位的位cyclicLeftShift(n, L, k)返回到左侧,其中循环窗口为。nkL

其工作原理如下:

                               _________L__________
                              /                    \
n :                           [ABCDE][FG...........]
                              \__k__/\_____L-k_____/



n.shiftLeft(k) :       [ABCDE][FG...........][00000]
   .or
n.shiftRight(L - k) :                        [ABCDE]

   =                   [ABCDE][FG...........][ABCDE]

                               _________L__________
   .and                       /                    \
allOnes(L) :                  [111..............111]

   =                          [FG...........][ABCDE]
Run Code Online (Sandbox Code Playgroud)

也可以看看


注意:如果你有一个固定的L,你可以通过缓存来优化它,allOnes(L)而不是每次都计算它。