0

我有一个unsigned char vector mynumber[]代表 bigint 的。这个数字是正数,我想把它转换成负数。

我试过这种方式

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

我迭代了我的向量,但我需要求和一个。一个怎么加起来?

如果我有溢出,如何解决?

我使用 GMP,导出后我必须将向量传递给 SHA256。

最后,我使用导入(GMP)将摘要的结果转换为大数。

在导入中,我遇到了与导出相同的问题。标志很重要。

4

1 回答 1

2

克里基。好的,首先,bignums 是如何实现的:在 GMP 和其他库中,通常您将固定宽度的字段指定为“肢体”或数字的一部分。到目前为止,您已经掌握了该部分,除了您更有可能分别使用uint32_toruint64_t用于 32 位和 64 位平台,因为这些是寄存器的大小和指令,例如adc在添加两个寄存器溢出时设置进位标志。

无论如何,重点是,这些肢体代表的是大元的实际大小,而不是它的符号。使用二进制补码,我们希望在某个地方有一个符号位,但是如果你想调整一个数字的大小(并且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_sizeGMP 是如何表示有符号数的。

在代码中(特别是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 具有许多基本类型的导入/导出功能,它们应该允许您正确设置大小。我不太确定您要做什么,但是假设它们还不够,您应该可以自己设置。

于 2011-06-20T18:32:02.650 回答