0

bigintをunsigned char vector mynumber[]表す があります。この数値は正であり、負の数値に変換したいと考えています。

私はこの方法で試しました

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

ベクトルを繰り返しますが、合計する必要があります。どのように合計しますか?

オーバーフローした場合、どうすれば解決できますか?

私は GMP を使用しており、エクスポート後にベクトルを SHA256 に渡す必要があります。

最後に、インポート (GMP) を使用して、ダイジェストの結果を Big Number に変換します。

インポートでは、エクスポートと同じ問題があります。サインは重要です。

4

1 に答える 1

2

クリキー。まず、bignum の実装方法について説明します。GMP やその他のライブラリでは、通常、固定幅フィールドを「リム」または数値の一部として指定します。これらはレジスタのサイズであり、 2 つのレジスタ オーバーフローを追加した場合にキャリー フラグを設定するような命令であるため、32 ビット プラットフォームと 64 ビット プラットフォームでそれぞれuint32_torを使用する可能性が高いことを除いて、これまでのところその部分は正しいです。uint64_tadc

とにかく、要点は、これらの手足はビッグナムの符号ではなく、実際の大きさを表すということです。2 の補数を使用すると、どこかに符号ビットがあることが予想されますが、数値のサイズを変更したい場合 (符号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 に答える