Java BigInteger Недостаточно памяти, возможно, из-за длительного преобразования

1

Я пытаюсь преобразовать этот алгоритм KeeLoq из C в Java, но мой метод дешифрования, похоже, использует слишком много памяти для Java BigInteger. Мне было интересно, была ли эквивалентная операция, которая будет работать с Java BigInteger.

Исходные вычисления для переменных index и bitVal прокомментированы ниже.

Исходный исходный код, который я использую в качестве примера, можно найти здесь: https://github.com/franksmicro/Arduino/blob/master/libraries/Keeloq/Keeloq.cpp

Любая помощь приветствуется.

package keeloq;

/**
 *
 * @author 
 */
import java.math.BigInteger;

public class KeeLoq {

    BigInteger _keyHigh, _keyLow, keyHigh, keyLow;
    int KeeLoq_code = 0x3A5C742E;
    BigInteger KeeLoq_NLF = new BigInteger(Integer.toString(KeeLoq_code));

    public KeeLoq() {
    }

    public KeeLoq(BigInteger keyHigh, BigInteger keyLow) {
        _keyHigh = keyHigh;
        _keyLow = keyLow;
    }

    public BigInteger bitRead(BigInteger x, int n) {
        BigInteger temp = x.shiftRight(n);
        return temp;
    }

    public BigInteger multiplyBig(BigInteger x, BigInteger n) {
        BigInteger temp = x.multiply(n);
        return temp;
    }

    public BigInteger Encrypt(BigInteger data) {
        BigInteger x = data;
        int keyBitNo;
        long index;
        long position1, position2, position3, position4, position5;
        BigInteger keyBitVal, bitVal;
        BigInteger b1, b2, b3, b4, b5;

        for (int r = 0; r < 528; r++) {
            keyBitNo = r & 63;
            if (keyBitNo < 32) {
                keyBitVal = bitRead(_keyLow, keyBitNo);
            } else {
                keyBitVal = bitRead(_keyHigh, keyBitNo - 32);
            }

            position1 = bitRead(x, 1).longValue() * 1;
            position2 = bitRead(x, 9).longValue() * 2;
            position3 = bitRead(x, 20).longValue() * 4;
            position4 = bitRead(x, 26).longValue() * 8;
            position5 = bitRead(x, 31).longValue() * 16;

            index = position1 + position2 + position3 + position4 + position5;
            System.out.println("the encrypted index is " + index);

            b1 = bitRead(x, 0);
            b2 = bitRead(x, 16);
            int intIndex = (int) index;
            b3 = bitRead(KeeLoq_NLF, intIndex);
            b4 = keyBitVal;

            bitVal = b1.xor(b2).xor(b3).xor(b4);
            BigInteger tempx = x.shiftRight(1);
            x = tempx.xor(bitVal);
                        //bitVal = bitRead(x,0) ^ bitRead(x, 16) ^ bitRead(KeeLoq_NLF,index) ^ keyBitVal;
            //x = (x>>1) ^ bitVal<<31;
        }
        return x;
    }

    BigInteger Decrypt(BigInteger data) {
        BigInteger x = data;
        int keyBitNo;
        long index;
        long position1, position2, position3, position4, position5;
        BigInteger keyBitVal, bitVal;
        BigInteger b1, b2, b3, b4, b5;

        for (int r = 0; r < 528; r++) {
            keyBitNo = (15 - r) & 63;
            if (keyBitNo < 32) {
                keyBitVal = bitRead(_keyLow, keyBitNo);
            } else {
                keyBitVal = bitRead(_keyHigh, keyBitNo - 32);
            }

            position1 = bitRead(x, 0).longValue() * 1;
            position2 = bitRead(x, 8).longValue() * 2;
            position3 = bitRead(x, 19).longValue() * 4;
            position4 = bitRead(x, 25).longValue() * 8;
            position5 = bitRead(x, 30).longValue() * 16;

            index = position1 + position2 + position3 + position4 + position5;

            System.out.println("The Decrypted index is " + index);

            b1 = bitRead(x, 31);
            b2 = bitRead(x, 15);
            int intIndex = (int) index;
            b3 = bitRead(KeeLoq_NLF, intIndex);
            b4 = keyBitVal;

            bitVal = b1.xor(b2).xor(b3).xor(b4);
            BigInteger tempx = x.shiftLeft(1);
            x = tempx.xor(bitVal);


            //index = 1 * bitRead(x,0) + 2 * bitRead(x,8) + 4 * bitRead(x,19) + 8 * bitRead(x,25) + 16 * bitRead(x,30);
            // bitVal = bitRead(x,31) ^ bitRead(x, 15) ^ bitRead(KeeLoq_NLF,index) ^ keyBitVal;
            //   x = (x<<1) ^ bitVal;


        }
        return x;
    }

    public static void main(String[] args) {
        BigInteger highKey = new BigInteger(Integer.toString(66));
        BigInteger lowKey = new BigInteger(Integer.toString(35));
        KeeLoq KeeLoq_file = new KeeLoq(highKey, lowKey);
        System.out.println("The KeeLoq Code is " + KeeLoq_file.KeeLoq_code);
        BigInteger EncryptedBigInt = KeeLoq_file.Encrypt(KeeLoq_file.KeeLoq_NLF);
        System.out.println("The Encrypted BigIntegerValue is " + EncryptedBigInt);
        System.out.println("The Encrypted integer value is " + EncryptedBigInt.intValue());
        BigInteger DecryptedBigInt = KeeLoq_file.Decrypt(EncryptedBigInt);
        System.out.println("The Decrypted BigIntegerValue is " + DecryptedBigInt);
        System.out.println("The Decrypted integer value is " + DecryptedBigInt.intValue());
    }

}
  • 0
    Насколько большими должны быть расшифрованные индексы?
  • 0
    Это продолжалось несколько минут на моем компьютере, и я вполне уверен, что BigIntegers становятся достаточно большими, что напечатанные расшифрованные индексы переполняются ...
Показать ещё 8 комментариев
Теги:
encryption
cpu-registers

1 ответ

1

Редактировать: Я думаю, что понял! (или, по крайней мере, часть его)

Проблема, по крайней мере, частично в этой строке: (сначала ошибочная строка, извините)

 int intIndex = (int) index;

Когда index становится достаточно большим, (int) index будет переполняться до большого отрицательного значения. Угадайте, что произойдет, когда вы передадите это в bitRead()?

Теперь, почему это переполнение происходит в Decrypt() а не в Encrypt(), я не уверен... Я посмотрю позже, как только получу немного отдохнуть, но, надеюсь, это начало.

Вы можете увеличить доступное пространство памяти, запустив программу с помощью флага -Xmx. Например, для работы с максимальным объемом 4 гигабайта вы должны использовать -Xmx 4G

В Eclipse это можно сделать, щелкнув правой кнопкой мыши по файлу, выбрав "Свойства" - "Параметры запуска/отладки" → щелкните по конфигурации запуска → "Редактировать" → "Вкладки аргументов" → "Параметры VM" → введите флаг.

Если у вас закончилась нехватка памяти с классом Java BigInteger, я не уверен, что использование любой другой библиотеки с произвольной точностью приведет вас к очень далеко, если числа на самом деле станут такими большими.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню