14

この行を C++ から C# に移植していますが、経験豊富な C++ プログラマーではありません。

 unsigned int nSize = BN_num_bytes(this); 

.NET ではSystem.Numerics.BigInteger を使用しています

 BigInteger num = originalBigNumber;
 byte[] numAsBytes = num.ToByteArray();
 uint compactBitsRepresentation = 0;
 uint size2 = (uint)numAsBytes.Length;

BigInt が等しい場合、ソースの単体テストの結果が一致しないため、内部での動作方法に根本的な違いがあると思います。

  • 0
  • 任意の負の数
  • 0x00123456

私は文字通り何も知りませんBN_num_bytes(編集: コメントは、それが BN_num_bits のマクロであることを教えてくれました)

質問

コードに関するこれらの推測を​​検証しますか?

  • BN_num_bytesマクロであるポートを移植する必要があり((BN_num_bits(bn)+7)/8)ます(ありがとう@WhozCraig)

  • 私は移植する必要がありBN_num_bitsますfloor(log2(w))+1

次に、先頭と末尾のバイトがカウントされない可能性がある場合、ビッグ/リトル エンディアン マシンではどうなりますか? それは問題ですか?

Security.StackExchangeに関するこれらの回答に基づいて、私のアプリケーションはパフォーマンスが重要ではないため、.NET の既定の実装を使用し、同等の回避策を既に実装している可能性のある代替ライブラリを使用しない場合があります。


編集:これまでのところ、私の実装は次のようになっていますが、コメントに記載されている「LookupTable」が何であるかはわかりません。

   private static int BN_num_bytes(byte[] numAsBytes)
    {
        int bits = BN_num_bits(numAsBytes);
        return (bits + 7) / 8; 
    }

    private static int BN_num_bits(byte[] numAsBytes)
    {
        var log2 = Math.Log(numAsBytes.Length, 2);
        var floor = Math.Floor(log2);
        return (uint)floor + 1;
    }

編集2:

さらに検索した結果、次のことがわかりました。

BN_num_bits は、指定された bignum の有効ビット数を返すのではなく、最上位 1 ビットの位置を返します。これは必ずしも同じではありません。

そのソースがどうなっているのかはまだわかりませんが…。

4

2 に答える 2

8

BN_num_bitsのman ページ(OpenSSL プロジェクト) には、「基本的に、ゼロを除いて、floor(log2(w))+1. を返す」と記載されています。したがって、これらは.Net のBN_num_bytesおよび関数の正しい実装です。BN_num_bitsBigInteger

public static int BN_num_bytes(BigInteger number) {
    if (number == 0) {
        return 0;
    }
    return 1 + (int)Math.Floor(BigInteger.Log(BigInteger.Abs(number), 2)) / 8;
}

public static int BN_num_bits(BigInteger number) {
    if (number == 0) {
        return 0;
    }
    return 1 + (int)Math.Floor(BigInteger.Log(BigInteger.Abs(number), 2));
}

便宜上、おそらくこれらを拡張メソッドに変更する必要があります。

これらの関数は、特定の整数を表現するために必要なビット/バイトの最小数を測定することを理解する必要があります。int( )として宣言された変数はSystem.Int324 バイトのメモリを必要としますが、整数 7 を表現するには 1 バイト (または 3 ビット) しか必要ありません。これは、BN_num_bytes と BN_num_bits が計算するものです - 具体的な数値に必要な最小ストレージ サイズです。

関数の元の実装のソース コードは、公式の OpenSSL リポジトリにあります。

于 2013-03-09T19:58:48.790 に答える
-2

コメントの WhozCraig が言ったことを、BN_num_bits を説明するこのリンクと組み合わせます。

http://www.openssl.org/docs/crypto/BN_num_bytes.html

そして、あなたは次のようなものになり、有効なバイト数を教えてくれるはずです:

public static int NumberOfBytes(BigInteger bigInt)
{
    if (bigInt == 0)
    {
        return 0; //you need to check what BN_num_bits actually does here as not clear from docs, probably returns 0
    }

    return (int)Math.Ceiling(BigInteger.Log(bigInt + 1, 2) + 7) / 8;
}
于 2013-03-09T19:30:42.140 に答える