размер Xor BigIntegers - PullRequest
       45

размер Xor BigIntegers

0 голосов
/ 10 сентября 2018

Моя программа создает два случайных BigInteger с битовой длиной 255. Затем получается xor из этих двух BigInteger.

Проблема в том, что поскольку величина больших целых чисел минимальна, если первые биты равны 0, размер этого xor может быть меньше 255. И мне нужно, чтобы он был 32 байта, поэтому между 248 и 256 битами.

Вот мой код:

public class test {

    public static void main(String[] args) throws Exception {
        SecureRandom random;
        BigInteger randomBigInteger1;
        byte[] randomBytes;
        do {
            random = new SecureRandom();
            randomBytes = new byte[32];
            random.nextBytes(randomBytes);
            randomBigInteger1 = new BigInteger(randomBytes);
        }while(randomBigInteger1.bitLength() < 255);

        BigInteger randomBigInteger2;
        do {
            random = new SecureRandom();
            randomBytes = new byte[32];
            random.nextBytes(randomBytes);
            randomBigInteger2 = new BigInteger(randomBytes);
        }while(randomBigInteger2.bitLength() < 255);

        BigInteger finalXor = randomBigInteger1.xor(randomBigInteger2);
        System.out.println(finalXor.bitLength());

        byte[] key = finalXor.toByteArray();
        System.out.println(key.length);
    }

}

Вопрос: как убедиться, что ключ всегда будет 32 байта, даже если finalXor меньше 248 бит? (Я думаю, я могу сделать отступ с битами 0, но я не знаю как.)

Пример: давайте рассмотрим мои BigIntegers:

1111011010101101 ............. 11011100011

1111011001100111 ............. 01110011010

Тогда finalXor будет:

0000000011001010 ............. 10101111001

Все 8 старших битов равны нулю, поэтому длина finalXor составляет всего 255-8 = 247 бит. Когда я сделаю ключ byte [], он будет 31 байтом, а не 32. Мне нужно, чтобы это было 32 байта. И все же будь хорошим хором.

Вот почему я сказал, что должен сделать отступ, где все "отсутствующие старшие биты" равны 0, но я не знаю, как это сделать.

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

ISTM, что избегая BigInteger и хоринг байтовых массивов напрямую, может решить сразу несколько ваших проблем. Там, где это необходимо, есть заполнение, и вы всегда получаете 32-байтовый массив.

Если вы убедитесь, что старшие байты (с индексом 0 из-за big-endiannes) не совпадают, у вас всегда будет 248-255 битное значение.

Если требуется little-endiannes, то байты в индексе 31 не должны быть 0 и отличаться. Я предположил big-endian, потому что это то, что BigInteger также возвращает в вашем исходном коде.

public class test 
{    
    public static void main(String[] args) throws Exception 
    {
        SecureRandom random = new SecureRandom();

        // make "left" operand
        byte[] randomBytesLeft = new bytes[32];
        random.nextBytes(randomBytesLeft);

        // make "right" operand
        byte[] randomBytesRight = new byte[32];
        do 
        {
            random.nextBytes(randomBytesRight);
        } while (randomBytesRight[0] == randomBytesLeft[0]); // or [31] for little-endian

        // "xor" both operands
        byte[] key = new byte[32];
        for (int i = 0; i < 32; i++)
        {
            key[i] = randomBytesLeft[i] ^ randomBytesRight[i];
        }

        // if you really need a BigInteger:
        // BigInteger finalXor = new BigInteger(key);

        System.out.println(key.length);
    }
}

FWIW, мне кажется, что вы могли бы опустить xoring в целом и просто сделать:

        byte[] key = new byte[32];
        do
        {
            random.nextBytes(key);
        } while (key[0] == 0); // or key[31] for little-endian

Вероятно, это было бы так же хорошо и намного проще.

0 голосов
/ 10 сентября 2018

Заполнение 0 - вариант, и я нашел способ сделать это:

if(key.length != 32) {
    byte[] finalKey= new byte[32];
    byte a = Byte.parseByte("00000000", 2);
    for(int i =0; i<key.length; i++) 
        finalKey[i] = key[i];
    for (int i = key.length ; i<32 ; i++)
        finalKey[i] = a;
    key = finalKey;
}

Требуется цикл и другой байтовый массив, потому что по какой-то причине ключ [31] генерирует исключение ArrayOutOfBound, но он работает ... если кто-то может его улучшить, не стесняйтесь делать это.

РЕДАКТИРОВАТЬ: лучшее решение от OldCurmudgeon:

key = Arrays.copyOf(key, 32);

Он автоматически заполнит старшие биты 0.

...