C Число Байт представление - PullRequest
0 голосов
/ 20 июня 2011

У меня есть unsigned char vector mynumber[], который представляет bigint. Это положительное число, и я хочу преобразовать его в отрицательное число.

Я пытался таким образом

for(int i = 0; i < dimvector;i++)
 mynumber[i] = ~mynumber[i];

Я повторяю свой вектор, но мне нужно его сложить. Как подвести итог?

Если у меня переполнение, как решить?

Я работаю с GMP и после экспорта должен передать вектор в SHA256.

В конце я преобразовываю результат дайджеста в Большое число, используя импорт (GMP).

В импорте у меня та же проблема экспорта. Знак важен.

1 Ответ

2 голосов
/ 20 июня 2011

Crikey. Хорошо, во-первых, как реализованы bignums: в GMP и в других библиотеках обычно поле фиксированной ширины обозначается как «конечность» или часть числа. Вы до сих пор правильно поняли эту часть, за исключением того, что вы с большей вероятностью будете использовать uint32_t или uint64_t для 32- и 64-битных платформ соответственно, потому что это размер регистров и инструкции, такие как adc set a флаг переноса при добавлении двух регистров переполнения.

Во всяком случае, суть в том, что эти конечности представляют действительную величину bignum, а не его знак. Используя дополнение к двум, мы ожидаем, что где-то будет бит знака, но он становится беспорядочным, если вы хотите изменить размер числа (а adc не заботится о подписании, он просто добавляет двоичные числа), так как вам нужно найти старый знак немного, извлеки это, запомни это, и оно вернулось в нужное место ... очень медленно.

Я не уверен, чего вы пытаетесь добиться, инвертируя биты в каждой конечности. Если вы представляете себе такой набор конечностей (сокращение от простоты)

1011 0111 1010 1011 = 47019

В итоге вы получите:

0100 1000 0101 0100 = 18516

В любом случае, GMP не представляет знак в конечностях. Целочисленный тип со знаком в GMP - mpz_t, который определяется этой структурой:

typedef struct
{
    int _mp_alloc;        /* Number of *limbs* allocated and pointed
                             to by the _mp_d field.  */
    int _mp_size;         /* abs(_mp_size) is the number of limbs the
                             last field points to.  If _mp_size is
                             negative this is a negative number.  */
    mp_limb_t *_mp_d;     /* Pointer to the limbs.  */
} __mpz_struct;
typedef __mpz_struct mpz_t[1]; 

Итак, как вы можете видеть, _mp_size - это то, как GMP представляет числа со знаком.

В коде (в частности, mpz/aors.h) вы увидите, что используется:

usize = u->_mp_size;
vsize = VARIATION v->_mp_size;

// .....

if ((usize ^ vsize) < 0)
{
  /* U and V have different sign.  Need to compare them to determine
 which operand to subtract from which.  */

  // does subtraction instead of add.

Фактические операции выполняются серией функций mpn_, которые относятся к вашим типам без знака.

GMP имеет ряд функций импорта / экспорта из базовых типов, которые должны позволять вам правильно устанавливать размер. Я не совсем уверен, что вы пытаетесь сделать, но, если их недостаточно, вы должны быть в состоянии установить это самостоятельно.

...