首页 > 解决方案 > 在 JavaCard 中的 64 位字字节数组上向左旋转

问题描述

我正在尝试对 64 位字上的任意旋转量执行左旋转 (ROTL) 操作,该 64 位字当前表示为 JavaCard 智能卡中的 8 个字节的字节数组。

丑陋的方法是将所有 64 种可能的 ROTL 排列硬编码在一个表示为 8 字节数组的 64 位字上,但这只会使整个代码库膨胀。

如何使其更精简,以便我可以在 64 位字(字节数组中)上按需执行任意数量的 ROTL 操作,仅使用byteshort类型(由于 JavaCard 无法识别更复杂的之类int的东西long),而不需要对所有 ROTL64 排列进行硬编码。

标签: bit-manipulation64-bitjavacard

解决方案


一个非常简单的实现,它在单独的参数中接收四个短裤

public static void rotateRight64(short x3, short x2, short x1, short x0,
                                 short rotAmount, short[] out)
{
    assert out.length() == 4;
    rotAmount &= (1 << 6) - 1;  // limit the range to 0..63
    if (rotAmount >= 16)
        rotateRight64(x0, x3, x2, x1, rotAmount - 16, out);
    else
    {
        out[0] = (short)((x0 >>> rotAmount) | (x1 << (16-rotAmount)));
        out[1] = (short)((x1 >>> rotAmount) | (x2 << (16-rotAmount)));
        out[2] = (short)((x2 >>> rotAmount) | (x3 << (16-rotAmount)));
        out[3] = (short)((x3 >>> rotAmount) | (x0 << (16-rotAmount)));
    }
}

这是一个向右旋转,但通过向右旋转很容易向左旋转64 - rotAmount

或者,它可以像这样完成,而无需粗调步骤

public static void rotateRight(short[] out, short[] in, short rotAmount) // in ror rotAmount
{
    assert out.length() == 4 && in.length() == 4 && rotAmount >= 0 && rotAmount < 64;

    const short shift     = (short)(rotAmount % 16);
    const short limbshift = (short)(rotAmount / 16);

    short tmp = in[0];
    for (short i = 0; i < 4; ++i)
    {
        short index = (short)((i + limbshift) % 4);
        out[i]  = (short)((in[index] >>> shift) | (in[index + 1] << (16 - shift)));
    }
}

这样它可以很容易地更改为任意精度的移位/旋转

如果输入数组是,byte那么您可以将所有常量从 16 → 8 和 4 → 8 更改short[4]byte[8]和更改。事实上,它们可以毫无问题地泛化,我只是进行硬编码以使其简单易懂


推荐阅读