Как использовать отрицательное число с BIGNUM openssl?

Я хочу версию C ++ следующего кода Java.

BigInteger x = new BigInteger("00afd72b5835ad22ea5d68279ffac0b6527c1ab0fb31f1e646f728d75cbd3ae65d", 16);
BigInteger y = x.multiply(BigInteger.valueOf(-1));

//prints y = ff5028d4a7ca52dd15a297d860053f49ad83e54f04ce0e19b908d728a342c519a3
System.out.println("y = " + new String(Hex.encode(y.toByteArray())));

И вот моя попытка решения.

BIGNUM* x = BN_new();
BN_CTX* ctx = BN_CTX_new();
std::vector<unsigned char> xBytes = hexStringToBytes(“00afd72b5835ad22ea5d68279ffac0b6527c1ab0fb31f1e646f728d75cbd3ae65d");
BN_bin2bn(&xBytes[0], xBytes.size(), x);

BIGNUM* negative1 = BN_new();
std::vector<unsigned char> negative1Bytes = hexStringToBytes("ff");
BN_bin2bn(&negative1Bytes[0], negative1Bytes.size(), negative1);

BIGNUM* y = BN_new();
BN_mul(y, x, negative1, ctx);

char* yHex = BN_bn2hex(y);
std::string yStr(yHex);
//prints y = AF27542CDD7775C7730ABF785AC5F59C299E964A36BFF460B031AE85607DAB76A3
std::cout <<"y = " << yStr << std::endl;

(Проигнорировал случай.) Что я делаю не так? Как получить код C ++ для вывода правильного значения «ff5028d4a7ca52dd15a297d860053f49ad83e54f04ce0e19b908d728a342c519a3». Я также попытался установить негатив 1, выполнив BN_set_word (негатив 1, -1), но это также дает мне неправильный ответ.

3

Решение

BN_set_negative Функция устанавливает отрицательное число.

Негатив afd72b5835ad22ea5d68279ffac0b6527c1ab0fb31f1e646f728d75cbd3ae65d на самом деле -afd72b5835ad22ea5d68279ffac0b6527c1ab0fb31f1e646f728d75cbd3ae65d так же, как -2 является негативом 2,

ff5028d4a7ca52dd15a297d860053f49ad83e54f04ce0e19b908d728a342c519a3 большое положительное число.

Причина, по которой вы видите это число в Java, связана с toByteArray вызов . Согласно его документации, он выбирает минимальную ширину поля, которая представляет собой целое число байтов, а также может содержать отрицательное число в виде дополнения до двух.

Другими словами, используя toByteArray Функция на число, что ток имеет 1 знаковый бит и 256 бит значения, в результате вы получите ширину поля 264 бит. Однако, если первый клев вашего отрицательного числа был 7 например, а не aзатем (в соответствии с этой документацией — я на самом деле не пробовал) вы получите 256-битную ширину поля (т.е. 8028d4...не ff8028d4,

Ведущий 00 вы использовали в своем коде незначительно в OpenSSL BN. Я не уверен, что это важно в BigInteger, хотя документация для этого конструктора гласит: «Представление String состоит из необязательного знака минус или плюс, за которым следует последовательность из одной или нескольких цифр в указанном основании.»; поэтому тот факт, что он принимает знак минус, говорит о том, что если знак минус отсутствует, то вход обрабатывается как большое положительное число, даже если его MSB установлен. (Надеюсь, программист на Java сможет прояснить этот абзац для меня).

Убедитесь, что вы помните различие между большое отрицательное значение, и большое положительное число, полученное модульной арифметикой для этого отрицательного значения, такого как результат toByteArray,


Итак, ваш вопрос действительно: есть ли в Openssl BN функция, которая имитирует поведение BigInteger.toByteArray ()?

Я не знаю, существует ли такая функция (библиотека BN имеет довольно плохую документацию IMHO, и я никогда не слышал о том, чтобы она использовалась вне OpenSSL, особенно не в программе на C ++). Я ожидаю, что это не так, так как toByteArrayповедение странное; и в любом случае все функции вывода BN, по-видимому, выводятся с использованием формата знака, а не формата двоичного дополнения.

Но чтобы воспроизвести этот вывод, вы можете добавить либо 2^256 или же 2^264 на большое отрицательное число, а затем сделать BN_bn2hex , В этом конкретном случае добавьте 2^264В общем случае вам нужно измерить текущую длину в битах сохраняемого числа и округлить экспоненту до ближайшего кратного 8.

Или вы могли бы даже вывести в формате знаковых величин (используя BN_bn2hex или же BN_bn2mpi), а затем перебираем каждый клочок и исправляем начало!

NB. Есть ли какая-то особая причина, по которой вы хотите использовать OpenSSL BN? Есть много альтернатив.

4

Другие решения


По вопросам рекламы [email protected]