6

リトルエンディアン形式のデータの sha256 ハッシュを生成する必要があります。sha 256 アルゴリズムを使用する前に、ビッグ エンディアンに変換する必要があるかどうかを知りたいです。または、アルゴリズムが「エンディアンに依存しない」場合。

編集:申し訳ありませんが、はっきりしていないと思います。私が知りたいのは次のことです: sha256 アルゴリズムでは、メッセージの最後に特定のビットを埋め込む必要があります。最初のステップは、メッセージの最後に 1 を追加することです。次に、最後までゼロで埋めます。最後に、メッセージの長さをビット単位で追加する必要があります。私が知りたいのは、このパディングがリトルエンディアンで実行できるかどうかです。たとえば、640 ビット メッセージの場合、最後のワードを 0x280 (ビッグ エンディアン) または 0x8002000 (リトル エンディアン) として書き込むことができます。このパディングはリトルエンディアンで行うことができますか?

4

3 に答える 3

7

適切なハッシュのみが必要な場合、SHA256 はエンディアンに依存しません。しかし、SHA256 を作成していて、正しい実装で同じ結果を得たい場合は、リトル エンディアンのハードウェアでゲームをプレイする必要があります。SHA256 は算術加算 (mod 2*32) とブール演算を組み合わせているため、内部的にエンディアンに依存しません。

于 2012-12-10T21:34:28.820 に答える
2

sha 256 と sha 512 について回答させてください。要するに、アルゴリズム自体はエンディアンに依存しません。エンディアンに依存する部分は、データがバイト バッファーからアルゴリズムの作業変数にインポートされるときと、ダイジェスト結果 (バイト バッファーも) にエクスポートされるときです。インポート/エクスポートにキャストが含まれる場合、エンディアンが重要になります。

キャストが発生する可能性がある場所: sha 512 には、128 バイトの作業バッファーがあります。私のコードでは、次のように定義されています。

    union
    {
        U64   w [80]; (see U64 example below)
        byte  buffer [128];
    };

入力データはこのバイト バッファにコピーされ、W で処理が行われます。これは、データが 64 ビット タイプにキャストされたことを意味します。このデータは交換する必要があります。私の場合、リトルエンディアンのマシンに交換されています。

より良い方法は、各バイトを受け取り、それを u64 型の正しい場所に配置する get マクロを準備することです。

アルゴリズムが完了すると、ダイジェストの結果が作業変数からバイト バッファーに出力されます。これが memcpy によって行われる場合は、スワップも必要になります。

sha 512 (64 ビット マシン用に設計されている) を 32 ビット マシンに実装すると、別のキャストが発生する可能性があります。私の場合、定義されている 64 ビット型があります。

    typedef struct {
        uint high;
        uint low;
    } U64;

次のように、リトルエンディアンに対しても定義するとします。

    typedef struct {
        uint low;
        uint high;
    } U64;

そして、k アルゴリズムの初期化は次のように行われます。

    static const SHA_U64 k[80] =  
    { 
        {0xD728AE22, 0x428A2F98}, {0x23EF65CD, 0x71374491}, ...
        ...
        ...
    }

しかし、どのマシンでも k[0].high の論理値が同じである必要があります。したがって、この例では、高い値と低い値が入れ替わった別の k 配列が必要になります。

データが作業パラメーターに格納された後は、ビッグ エンディアンとリトル エンディアンの両方のマシンでビット単位の操作を行っても同じ結果になります。

適切な方法は、キャストを避けることです。マクロを使用して、入力バッファーから作業パラメーターにバイトをインポートします。メモリ マッピングを考えずに論理値を操作します。出力をマクロでダイジェスト結果にエクスポートします。

バイト バッファから int32 に 32 ビットを取得するためのマクロ (BE = ビッグ エンディアン):

    #define GET_BE_BYTES_FROM32(a) 
    ((((NQ_UINT32) (a)[0]) << 24) | 
    (((NQ_UINT32) (a)[1]) << 16)  | 
    (((NQ_UINT32) (a)[2]) << 8)   | 
    ((NQ_UINT32) (a)[3])) 

    #define GET_LE_BYTES_FROM32(a) 
    ((((NQ_UINT32) (a)[3]) << 24) | 
    (((NQ_UINT32) (a)[2]) << 16)  | 
    (((NQ_UINT32) (a)[1]) << 8)   | 
    ((NQ_UINT32) (a)[0])) 
于 2016-08-24T11:04:19.687 に答える
1

SHA-256 実装自体がパディングを処理する必要があります。独自の特殊な SHA-256 コードを実装していない限り、パディングに対処する必要はありません。その場合、「前処理ステップ」で指定されたパディング ルールでは、長さが 64 ビットのビッグ エンディアン整数であることに注意してください。SHA-2を参照してください- ウィキペディア

「エンディアンにとらわれない」が何を意味するのかを理解することさえ困難ですが、ハッシュアルゴリズムのすべてのビット、バイト、およびワードの順序は非常に重要であるため、私はその用語を使用しません.

于 2011-07-08T23:06:02.617 に答える