[要約] RFC 3174は、SHA1と呼ばれる米国の安全なハッシュアルゴリズムに関する規格です。このRFCの目的は、データの整合性を確保するために、SHA1を使用する方法を提供することです。

Network Working Group                                   D. Eastlake, 3rd
Request for Comments: 3174                                      Motorola
Category: Informational                                         P. Jones
                                                           Cisco Systems
                                                          September 2001
        

US Secure Hash Algorithm 1 (SHA1)

米国の安全なハッシュアルゴリズム1(SHA1)

Status of this Memo

本文書の位置付け

This memo provides information for the Internet community. It does not specify an Internet standard of any kind. Distribution of this memo is unlimited.

このメモは、インターネットコミュニティに情報を提供します。いかなる種類のインターネット標準を指定しません。このメモの配布は無制限です。

Copyright Notice

著作権表示

Copyright (C) The Internet Society (2001). All Rights Reserved.

Copyright(c)The Internet Society(2001)。全著作権所有。

Abstract

概要

The purpose of this document is to make the SHA-1 (Secure Hash Algorithm 1) hash algorithm conveniently available to the Internet community. The United States of America has adopted the SHA-1 hash algorithm described herein as a Federal Information Processing Standard. Most of the text herein was taken by the authors from FIPS 180-1. Only the C code implementation is "original".

このドキュメントの目的は、SHA-1(Secure Hash Algorithm 1)Hashアルゴリズムをインターネットコミュニティが便利に利用できるようにすることです。アメリカ合衆国は、本明細書では連邦情報処理基準として説明されているSHA-1ハッシュアルゴリズムを採用しています。ここでのテキストのほとんどは、FIPS 180-1から著者によって撮影されました。Cコードの実装のみが「オリジナル」です。

Acknowledgements

謝辞

Most of the text herein was taken from [FIPS 180-1]. Only the C code implementation is "original" but its style is similar to the previously published MD4 and MD5 RFCs [RFCs 1320, 1321].

ここでのテキストのほとんどは、[FIPS 180-1]から取得されました。Cコードの実装のみが「オリジナル」ですが、そのスタイルは以前に公開されたMD4およびMD5 RFCS [RFCS 1320、1321]に似ています。

The SHA-1 is based on principles similar to those used by Professor Ronald L. Rivest of MIT when designing the MD4 message digest algorithm [MD4] and is modeled after that algorithm [RFC 1320].

SHA-1は、MD4メッセージダイジェストアルゴリズム[MD4]を設計する際にMITのRonald L. Rivest教授が使用した原則と同様の原則に基づいており、そのアルゴリズム[RFC 1320]をモデルにしています。

Useful comments from the following, which have been incorporated herein, are gratefully acknowledged:

本明細書に組み込まれている以下からの有用なコメントは、感謝されていることに感謝されています。

Tony Hansen Garrett Wollman

トニー・ハンセン・ギャレット・ウォルマン

Table of Contents

目次

   1. Overview of Contents...........................................  2
   2. Definitions of Bit Strings and Integers........................  3
   3. Operations on Words............................................  3
   4. Message Padding................................................  4
   5. Functions and Constants Used...................................  6
   6. Computing the Message Digest...................................  6
   6.1 Method 1......................................................  6
   6.2 Method 2......................................................  7
   7. C Code.........................................................  8
   7.1 .h file.......................................................  8
   7.2 .c file....................................................... 10
   7.3 Test Driver................................................... 18
   8. Security Considerations........................................ 20
   References........................................................ 21
   Authors' Addresses................................................ 21
   Full Copyright Statement.......................................... 22
        
1. Overview of Contents
1. 内容の概要

NOTE: The text below is mostly taken from [FIPS 180-1] and assertions therein of the security of SHA-1 are made by the US Government, the author of [FIPS 180-1], and not by the authors of this document.

注:以下のテキストは主に[FIPS 180-1]から取得されており、SHA-1のセキュリティに関する主張は、この文書の著者ではなく、[FIPS 180-1]の著者である米国政府によって行われます。。

This document specifies a Secure Hash Algorithm, SHA-1, for computing a condensed representation of a message or a data file. When a message of any length < 2^64 bits is input, the SHA-1 produces a 160-bit output called a message digest. The message digest can then, for example, be input to a signature algorithm which generates or verifies the signature for the message. Signing the message digest rather than the message often improves the efficiency of the process because the message digest is usually much smaller in size than the message. The same hash algorithm must be used by the verifier of a digital signature as was used by the creator of the digital signature. Any change to the message in transit will, with very high probability, result in a different message digest, and the signature will fail to verify.

このドキュメントは、メッセージまたはデータファイルの凝縮された表現を計算するために、安全なハッシュアルゴリズムSha-1を指定します。任意の長さ<2^64ビットのメッセージが入力されると、SHA-1はメッセージダイジェストと呼ばれる160ビット出力を生成します。たとえば、Message Digestは、メッセージの署名を生成または検証する署名アルゴリズムに入力することができます。メッセージではなく、メッセージのダイジェストに署名すると、メッセージがメッセージよりもはるかに小さくなるため、プロセスの効率が改善されることがよくあります。デジタル署名の作成者が使用したのと同じハッシュアルゴリズムをデジタル署名の検証者によって使用する必要があります。輸送中のメッセージへの変更は、非常に高い確率で異なるメッセージダイジェストをもたらし、署名は検証に失敗します。

The SHA-1 is called secure because it is computationally infeasible to find a message which corresponds to a given message digest, or to find two different messages which produce the same message digest. Any change to a message in transit will, with very high probability, result in a different message digest, and the signature will fail to verify.

SHA-1は、特定のメッセージダイジェストに対応するメッセージを見つけるか、同じメッセージダイジェストを生成する2つの異なるメッセージを見つけることが計算的に実行不可能であるため、Secureと呼ばれます。輸送中のメッセージへの変更は、非常に高い確率で異なるメッセージダイジェストをもたらし、署名は検証に失敗します。

Section 2 below defines the terminology and functions used as building blocks to form SHA-1.

以下のセクション2は、SHA-1を形成するためにビルディングブロックとして使用される用語と関数を定義しています。

2. Definitions of Bit Strings and Integers
2. ビット文字列と整数の定義

The following terminology related to bit strings and integers will be used:

ビット文字列と整数に関連する次の用語が使用されます。

a. A hex digit is an element of the set {0, 1, ... , 9, A, ... , F}. A hex digit is the representation of a 4-bit string. Examples: 7 = 0111, A = 1010.

a. 16進数は、セット{0、1、...、9、a、...、f}の要素です。16進数は、4ビット文字列の表現です。例:7 = 0111、a = 1010。

b. A word equals a 32-bit string which may be represented as a sequence of 8 hex digits. To convert a word to 8 hex digits each 4-bit string is converted to its hex equivalent as described in (a) above. Example:

b. 単語は、8ヘクス桁のシーケンスとして表される可能性のある32ビット文字列に等しくなります。単語を8ヘクスの桁に変換するには、上記の(a)に記載されているように、各4ビット文字列がその16進量に変換されます。例:

1010 0001 0000 0011 1111 1110 0010 0011 = A103FE23.

1010 0001 0000 0011 1111 1110 0010 0011 = A103FE23。

c. An integer between 0 and 2^32 - 1 inclusive may be represented as a word. The least significant four bits of the integer are represented by the right-most hex digit of the word representation. Example: the integer 291 = 2^8+2^5+2^1+2^0 = 256+32+2+1 is represented by the hex word, 00000123.

c. 0〜2^32-1の整数は、単語として表される場合があります。整数の最も重要な4ビットは、表現という単語の右桁の数字で表されます。例:整数291 = 2^8 2^5 2^1 2^0 = 256 32 2 1は、hex単語00000123で表されます。

      If z is an integer, 0 <= z < 2^64, then z = (2^32)x + y where 0 <=
      x < 2^32 and 0 <= y < 2^32.  Since x and y can be represented as
      words X and Y, respectively, z can be represented as the pair of
      words (X,Y).
        

d. block = 512-bit string. A block (e.g., B) may be represented as a sequence of 16 words.

d. ブロック= 512ビット文字列。ブロック(例:b)は、16語のシーケンスとして表される場合があります。

3. Operations on Words
3. 言葉の操作

The following logical operators will be applied to words:

次の論理演算子は言葉に適用されます。

a. Bitwise logical word operations

a. ビットごとの論理ワード操作

X AND Y = bitwise logical "and" of X and Y.

xおよびy = xとyのbitwise論理 "および"

X OR Y = bitwise logical "inclusive-or" of X and Y.

xまたはy = xおよびyのビットワイズ論理「包括的」。

X XOR Y = bitwise logical "exclusive-or" of X and Y.

x xor y = xとyのビットワイズ論理「排他的または」

NOT X = bitwise logical "complement" of X.

x =ビットワイズの論理的な「補体」ではありません。

Example:

例:

               01101100101110011101001001111011
         XOR   01100101110000010110100110110111
               --------------------------------
           =   00001001011110001011101111001100
        
   b. The operation X + Y is defined as follows:  words X and Y
      represent integers x and y, where 0 <= x < 2^32 and 0 <= y < 2^32.
      For positive integers n and m, let n mod m be the remainder upon
      dividing n by m.  Compute
        
         z  =  (x + y) mod 2^32.
        

Then 0 <= z < 2^32. Convert z to a word, Z, and define Z = X + Y.

次に0 <= z <2^32。zをワード、zに変換し、z = x yを定義します。

   c. The circular left shift operation S^n(X), where X is a word and n
      is an integer with 0 <= n < 32, is defined by
        
         S^n(X)  =  (X << n) OR (X >> 32-n).
        

In the above, X << n is obtained as follows: discard the left-most n bits of X and then pad the result with n zeroes on the right (the result will still be 32 bits). X >> n is obtained by discarding the right-most n bits of X and then padding the result with n zeroes on the left. Thus S^n(X) is equivalent to a circular shift of X by n positions to the left.

上記では、x << nは次のように取得されます。Xの左Nビットを捨ててから、結果を右側のゼロでパッドします(結果は32ビットです)。x >> nは、Xの右Nビットを破棄し、左側のnゼロで結果をパディングすることにより得られます。したがって、s^n(x)は、左へのn位置によるxの円形シフトに相当します。

4. Message Padding
4. メッセージパディング

SHA-1 is used to compute a message digest for a message or data file that is provided as input. The message or data file should be considered to be a bit string. The length of the message is the number of bits in the message (the empty message has length 0). If the number of bits in a message is a multiple of 8, for compactness we can represent the message in hex. The purpose of message padding is to make the total length of a padded message a multiple of 512. SHA-1 sequentially processes blocks of 512 bits when computing the message digest. The following specifies how this padding shall be performed. As a summary, a "1" followed by m "0"s followed by a 64- bit integer are appended to the end of the message to produce a padded message of length 512 * n. The 64-bit integer is the length of the original message. The padded message is then processed by the SHA-1 as n 512-bit blocks.

SHA-1は、入力として提供されるメッセージまたはデータファイルのメッセージダイジェストを計算するために使用されます。メッセージまたはデータファイルは、少し文字列と見なされる必要があります。メッセージの長さは、メッセージ内のビット数です(空のメッセージには長さ0)。メッセージ内のビット数が8の倍数である場合、コンパクトさのためにヘックスでメッセージを表すことができます。メッセージパディングの目的は、パッド付きメッセージの全長を512の倍数にすることです。SHA-1は、メッセージダイジェストを計算するときに512ビットのブロックを順次処理します。以下は、このパディングの実行方法を指定します。概要として、「1」と続いて64ビット整数が続く「1」に続いて、メッセージの最後に追加されて、長さ512 * nのパッド入りメッセージが作成されます。64ビット整数は、元のメッセージの長さです。パッド付きメッセージは、SHA-1によってN 512ビットブロックとして処理されます。

Suppose a message has length l < 2^64. Before it is input to the SHA-1, the message is padded on the right as follows:

メッセージに長さl <2^64があるとします。SHA-1に入力される前に、メッセージは次のように右側にパッドにされています。

a. "1" is appended. Example: if the original message is "01010000", this is padded to "010100001".

a. 「1」が追加されます。例:元のメッセージが「01010000」の場合、これは「010100001」にパッドにされています。

b. "0"s are appended. The number of "0"s will depend on the original length of the message. The last 64 bits of the last 512-bit block are reserved

b. 「0」は追加されています。「0」の数は、メッセージの元の長さによって異なります。最後の512ビットブロックの最後の64ビットは予約されています

for the length l of the original message.

元のメッセージの長さlの場合。

Example: Suppose the original message is the bit string

例:元のメッセージがビット文字列であるとします

01100001 01100010 01100011 01100100 01100101.

01100001 0110001001100011 01100100 01100101。

After step (a) this gives

ステップ(a)の後にこれが与えます

01100001 01100010 01100011 01100100 01100101 1.

01100001 0110001001100011 01100100 01100101 1。

Since l = 40, the number of bits in the above is 41 and 407 "0"s are appended, making the total now 448. This gives (in hex)

L = 40であるため、上記のビット数は41および407 "0" sが追加されているため、合計は448になります。

61626364 65800000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000.

61626364 65800000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

c. Obtain the 2-word representation of l, the number of bits in the original message. If l < 2^32 then the first word is all zeroes. Append these two words to the padded message.

c. 元のメッセージのビット数であるLの2ワード表現を取得します。l <2^32の場合、最初の単語はすべてゼロです。これら2つの単語をパッド入りのメッセージに追加します。

Example: Suppose the original message is as in (b). Then l = 40 (note that l is computed before any padding). The two-word representation of 40 is hex 00000000 00000028. Hence the final padded message is hex

例:元のメッセージが(b)のようにあるとします。次に、L = 40(パディングの前にLが計算されることに注意してください)。40の2ワード表現はhex 0000000000000028です。したがって、最終的なパッド入りメッセージはhexです

61626364 65800000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000028.

61626364 65800000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028。

The padded message will contain 16 * n words for some n > 0. The padded message is regarded as a sequence of n blocks M(1) , M(2), first characters (or bits) of the message.

パッド入りのメッセージには、n> 0の16 * nワードが含まれます。パッド付きメッセージは、メッセージのnブロックm(1)、m(2)、最初の文字(またはビット)のシーケンスと見なされます。

5. Functions and Constants Used
5. 使用される関数と定数

A sequence of logical functions f(0), f(1),..., f(79) is used in SHA-1. Each f(t), 0 <= t <= 79, operates on three 32-bit words B, C, D and produces a 32-bit word as output. f(t;B,C,D) is defined as follows: for words B, C, D,

一連の論理関数f(0)、f(1)、...、f(79)はSHA-1で使用されます。各f(t)、0 <= t <= 79は、3つの32ビットワードb、c、dで動作し、出力として32ビット単語を生成します。f(t; b、c、d)は次のように定義されています:単語B、C、D、

      f(t;B,C,D) = (B AND C) OR ((NOT B) AND D)         ( 0 <= t <= 19)
        
      f(t;B,C,D) = B XOR C XOR D                        (20 <= t <= 39)
        
      f(t;B,C,D) = (B AND C) OR (B AND D) OR (C AND D)  (40 <= t <= 59)
        

f(t;B,C,D) = B XOR C XOR D (60 <= t <= 79).

f(t; b、c、d)= b xor c xor d(60 <= t <= 79)。

A sequence of constant words K(0), K(1), ... , K(79) is used in the SHA-1. In hex these are given by

一定の単語k(0)、k(1)、...、k(79)のシーケンスは、SHA-1で使用されます。ヘックスでは、これらはによって与えられます

      K(t) = 5A827999         ( 0 <= t <= 19)
        
      K(t) = 6ED9EBA1         (20 <= t <= 39)
        
      K(t) = 8F1BBCDC         (40 <= t <= 59)
        

K(t) = CA62C1D6 (60 <= t <= 79).

k(t)= ca62c1d6(60 <= t <= 79)。

6. Computing the Message Digest
6. メッセージダイジェストを計算します

The methods given in 6.1 and 6.2 below yield the same message digest. Although using method 2 saves sixty-four 32-bit words of storage, it is likely to lengthen execution time due to the increased complexity of the address computations for the { W[t] } in step (c). There are other computation methods which give identical results.

以下の6.1および6.2で与えられた方法は、同じメッセージダイジェストを生成します。方法2を使用すると、64ビットのストレージの単語が保存されますが、ステップ(c)の{w [t]}のアドレス計算の複雑さが増加するため、実行時間が長くなる可能性があります。同一の結果を与える他の計算方法があります。

6.1 Method 1
6.1 方法1

The message digest is computed using the message padded as described in section 4. The computation is described using two buffers, each consisting of five 32-bit words, and a sequence of eighty 32-bit words. The words of the first 5-word buffer are labeled A,B,C,D,E. The words of the second 5-word buffer are labeled H0, H1, H2, H3, H4. The words of the 80-word sequence are labeled W(0), W(1),..., W(79). A single word buffer TEMP is also employed.

メッセージダイジェストは、セクション4で説明されているようにパッド入りのメッセージを使用して計算されます。計算は、それぞれ5つの32ビット単語と80の32ビット単語のシーケンスで構成される2つのバッファーを使用して説明されています。最初の5ワードバッファーの単語には、a、b、c、d、eとラベル付けされています。2番目の5ワードバッファーの言葉は、H0、H1、H2、H3、H4とラベル付けされています。80ワードのシーケンスの単語には、W(0)、W(1)、...、W(79)というラベルが付いています。一語のバッファ温度も採用されています。

To generate the message digest, the 16-word blocks M(1), M(2),..., M(n) defined in section 4 are processed in order. The processing of each M(i) involves 80 steps.

メッセージダイジェストを生成するには、セクション4で定義された16ワードブロックm(1)、m(2)、...、m(n)が順番に処理されます。各M(i)の処理には80ステップが含まれます。

Before processing any blocks, the H's are initialized as follows: in hex,

ブロックを処理する前に、Hは次のように初期化されます。

      H0 = 67452301
        
      H1 = EFCDAB89
        
      H2 = 98BADCFE
        
      H3 = 10325476
        

H4 = C3D2E1F0.

H4 = C3D2E1F0。

Now M(1), M(2), ... , M(n) are processed. To process M(i), we proceed as follows:

現在、m(1)、m(2)、...、m(n)が処理されます。m(i)を処理するには、次のように進めます。

a. Divide M(i) into 16 words W(0), W(1), ... , W(15), where W(0) is the left-most word.

a. m(i)を16ワードw(0)、w(1)、...、w(15)に分割します。ここで、w(0)は左の単語です。

b. For t = 16 to 79 let

b. t = 16〜79の場合

W(t) = S^1(W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16)).

w(t)= s^1(w(t-3)xor w(t-8)xor w(t-14)xor w(t-16))。

c. Let A = H0, B = H1, C = H2, D = H3, E = H4.

c. a = h0、b = h1、c = h2、d = h3、e = h4とします。

d. For t = 0 to 79 do

d. t = 0から79の場合

         TEMP = S^5(A) + f(t;B,C,D) + E + W(t) + K(t);
        
         E = D;  D = C;  C = S^30(B);  B = A; A = TEMP;
        

e. Let H0 = H0 + A, H1 = H1 + B, H2 = H2 + C, H3 = H3 + D, H4 = H4 + E.

e. H0 = H0 A、H1 = H1 B、H2 = H2 C、H3 = H3 D、H4 = H4 E.

After processing M(n), the message digest is the 160-bit string represented by the 5 words

m(n)を処理した後、メッセージダイジェストは5語で表される160ビット文字列です

H0 H1 H2 H3 H4.

H0 H1 H2 H3 H4。

6.2 Method 2
6.2 方法2

The method above assumes that the sequence W(0), ... , W(79) is implemented as an array of eighty 32-bit words. This is efficient from the standpoint of minimization of execution time, since the addresses of W(t-3), ... ,W(t-16) in step (b) are easily computed. If space is at a premium, an alternative is to regard { W(t) } as a circular queue, which may be implemented using an array of sixteen 32-bit words W[0], ... W[15]. In this case, in hex let

上記の方法は、シーケンスw(0)、...、w(79)が80の32ビット単語の配列として実装されていることを前提としています。これは、ステップ(b)のW(T-3)、...、W(T-16)のアドレスが簡単に計算されるため、実行時間の最小化の観点から効率的です。スペースがプレミアムである場合、代替手段は、{w(t)}を円形のキューと見なすことです。これは、16の32ビット単語w [0]、... w [15]の配列を使用して実装できます。この場合、ヘックスで

MASK = 0000000F. Then processing of M(i) is as follows:

mask = 0000000f。次に、m(i)の処理は次のとおりです。

a. Divide M(i) into 16 words W[0], ... , W[15], where W[0] is the left-most word.

a. m(i)を16ワードw [0]、...、w [15]に分割します。ここで、w [0]は左の単語です。

b. Let A = H0, B = H1, C = H2, D = H3, E = H4.

b. a = h0、b = h1、c = h2、d = h3、e = h4とします。

c. For t = 0 to 79 do

c. t = 0から79の場合

s = t AND MASK;

s = tおよびマスク。

         if (t >= 16) W[s] = S^1(W[(s + 13) AND MASK] XOR W[(s + 8) AND
         MASK] XOR W[(s + 2) AND MASK] XOR W[s]);
        
         TEMP = S^5(A) + f(t;B,C,D) + E + W[s] + K(t);
        
         E = D; D = C; C = S^30(B); B = A; A = TEMP;
        

d. Let H0 = H0 + A, H1 = H1 + B, H2 = H2 + C, H3 = H3 + D, H4 = H4 + E.

d. H0 = H0 A、H1 = H1 B、H2 = H2 C、H3 = H3 D、H4 = H4 E.

7. C Code
7. Cコード

Below is a demonstration implementation of SHA-1 in C. Section 7.1 contains the header file, 7.2 the C code, and 7.3 a test driver.

以下は、CのSHA-1のデモンストレーション実装です。セクション7.1には、ヘッダーファイル、7.2 Cコード、7.3テストドライバーが含まれています。

7.1 .h file
7.1 .hファイル
/*
 *  sha1.h
 *
 *  Description:
 *      This is the header file for code which implements the Secure
 *      Hashing Algorithm 1 as defined in FIPS PUB 180-1 published
 *      April 17, 1995.
 *
 *      Many of the variable names in this code, especially the
 *      single character names, were used because those were the names
 *      used in the publication.
 *
 *      Please read the file sha1.c for more information.
 *
 */
        

#ifndef _SHA1_H_ #define _SHA1_H_

#ifndef _sha1_h_ #define _sha1_h_

#include <stdint.h>
/*
 * If you do not have the ISO standard stdint.h header file, then you
 * must typdef the following:
 *    name              meaning
 *  uint32_t         unsigned 32 bit integer
 *  uint8_t          unsigned 8 bit integer (i.e., unsigned char)
 *  int_least16_t    integer of >= 16 bits
 *
 */
        
#ifndef _SHA_enum_
#define _SHA_enum_
enum
{
    shaSuccess = 0,
    shaNull,            /* Null pointer parameter */
    shaInputTooLong,    /* input data too long */
    shaStateError       /* called Input after Result */
};
#endif
#define SHA1HashSize 20
        
/*
 *  This structure will hold context information for the SHA-1
 *  hashing operation
 */
typedef struct SHA1Context
{
    uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest  */
        
    uint32_t Length_Low;            /* Message length in bits      */
    uint32_t Length_High;           /* Message length in bits      */
        
                               /* Index into message block array   */
    int_least16_t Message_Block_Index;
    uint8_t Message_Block[64];      /* 512-bit message blocks      */
        
    int Computed;               /* Is the digest computed?         */
    int Corrupted;             /* Is the message digest corrupted? */
} SHA1Context;
        
/*
 *  Function Prototypes
 */
        
int SHA1Reset(  SHA1Context *);
int SHA1Input(  SHA1Context *,
                const uint8_t *,
                unsigned int);
int SHA1Result( SHA1Context *,
                uint8_t Message_Digest[SHA1HashSize]);
        

#endif

#endif

7.2 .c file
7.2 .cファイル
/*
 *  sha1.c
 *
 *  Description:
 *      This file implements the Secure Hashing Algorithm 1 as
 *      defined in FIPS PUB 180-1 published April 17, 1995.
 *
 *      The SHA-1, produces a 160-bit message digest for a given
 *      data stream.  It should take about 2**n steps to find a
 *      message with the same digest as a given message and
 *      2**(n/2) to find any two messages with the same digest,
 *      when n is the digest size in bits.  Therefore, this
 *      algorithm can serve as a means of providing a
 *      "fingerprint" for a message.
 *
 *  Portability Issues:
 *      SHA-1 is defined in terms of 32-bit "words".  This code
 *      uses <stdint.h> (included via "sha1.h" to define 32 and 8
 *      bit unsigned integer types.  If your C compiler does not
 *      support 32 bit unsigned integers, this code is not
 *      appropriate.
 *
 *  Caveats:
 *      SHA-1 is designed to work with messages less than 2^64 bits
 *      long.  Although SHA-1 allows a message digest to be generated
 *      for messages of any number of bits less than 2^64, this
 *      implementation only works with messages with a length that is
 *      a multiple of the size of an 8-bit character.
 *
 */
        

#include "sha1.h"

#include "sha1.h"

/*
 *  Define the SHA1 circular left shift macro
 */
#define SHA1CircularShift(bits,word) \
                (((word) << (bits)) | ((word) >> (32-(bits))))
        
/* Local Function Prototyptes */
void SHA1PadMessage(SHA1Context *);
void SHA1ProcessMessageBlock(SHA1Context *);
        
/*
 *  SHA1Reset
 *
 *  Description:
 *      This function will initialize the SHA1Context in preparation
 *      for computing a new SHA1 message digest.
 *
 *  Parameters:
 *      context: [in/out]
 *          The context to reset.
 *
 *  Returns:
 *      sha Error Code.
 *
 */
int SHA1Reset(SHA1Context *context)
{
    if (!context)
    {
        return shaNull;
    }
        
    context->Length_Low             = 0;
    context->Length_High            = 0;
    context->Message_Block_Index    = 0;
        
    context->Intermediate_Hash[0]   = 0x67452301;
    context->Intermediate_Hash[1]   = 0xEFCDAB89;
    context->Intermediate_Hash[2]   = 0x98BADCFE;
    context->Intermediate_Hash[3]   = 0x10325476;
    context->Intermediate_Hash[4]   = 0xC3D2E1F0;
        
    context->Computed   = 0;
    context->Corrupted  = 0;
        

return shaSuccess; }

Shasuccessを返します。}

/*
 *  SHA1Result
 *
 *  Description:
 *      This function will return the 160-bit message digest into the
 *      Message_Digest array  provided by the caller.
 *      NOTE: The first octet of hash is stored in the 0th element,
 *            the last octet of hash in the 19th element.
 *
 *  Parameters:
 *      context: [in/out]
 *          The context to use to calculate the SHA-1 hash.
 *      Message_Digest: [out]
 *          Where the digest is returned.
 *
 *  Returns:
 *      sha Error Code.
 *
 */
int SHA1Result( SHA1Context *context,
                uint8_t Message_Digest[SHA1HashSize])
{
    int i;
        
    if (!context || !Message_Digest)
    {
        return shaNull;
    }
        
    if (context->Corrupted)
    {
        return context->Corrupted;
    }
        
    if (!context->Computed)
    {
        SHA1PadMessage(context);
        for(i=0; i<64; ++i)
        {
            /* message may be sensitive, clear it out */
            context->Message_Block[i] = 0;
        }
        context->Length_Low = 0;    /* and clear length */
        context->Length_High = 0;
        context->Computed = 1;
        

}

}

    for(i = 0; i < SHA1HashSize; ++i)
    {
        Message_Digest[i] = context->Intermediate_Hash[i>>2]
                            >> 8 * ( 3 - ( i & 0x03 ) );
    }
        

return shaSuccess; }

Shasuccessを返します。}

/*
 *  SHA1Input
 *
 *  Description:
 *      This function accepts an array of octets as the next portion
 *      of the message.
 *
 *  Parameters:
 *      context: [in/out]
 *          The SHA context to update
 *      message_array: [in]
 *          An array of characters representing the next portion of
 *          the message.
 *      length: [in]
 *          The length of the message in message_array
 *
 *  Returns:
 *      sha Error Code.
 *
 */
int SHA1Input(    SHA1Context    *context,
                  const uint8_t  *message_array,
                  unsigned       length)
{
    if (!length)
    {
        return shaSuccess;
    }
        
    if (!context || !message_array)
    {
        return shaNull;
    }
        
    if (context->Computed)
    {
        context->Corrupted = shaStateError;
        

return shaStateError; }

ShastateErrorを返します。}

    if (context->Corrupted)
    {
         return context->Corrupted;
    }
    while(length-- && !context->Corrupted)
    {
    context->Message_Block[context->Message_Block_Index++] =
                    (*message_array & 0xFF);
        
    context->Length_Low += 8;
    if (context->Length_Low == 0)
    {
        context->Length_High++;
        if (context->Length_High == 0)
        {
            /* Message is too long */
            context->Corrupted = 1;
        }
    }
        
    if (context->Message_Block_Index == 64)
    {
        SHA1ProcessMessageBlock(context);
    }
        
    message_array++;
    }
        

return shaSuccess; }

Shasuccessを返します。}

/*
 *  SHA1ProcessMessageBlock
 *
 *  Description:
 *      This function will process the next 512 bits of the message
 *      stored in the Message_Block array.
 *
 *  Parameters:
 *      None.
 *
 *  Returns:
 *      Nothing.
 *
 *  Comments:
        
 *      Many of the variable names in this code, especially the
 *      single character names, were used because those were the
 *      names used in the publication.
 *
 *
 */
void SHA1ProcessMessageBlock(SHA1Context *context)
{
    const uint32_t K[] =    {       /* Constants defined in SHA-1   */
                            0x5A827999,
                            0x6ED9EBA1,
                            0x8F1BBCDC,
                            0xCA62C1D6
                            };
    int           t;                 /* Loop counter                */
    uint32_t      temp;              /* Temporary word value        */
    uint32_t      W[80];             /* Word sequence               */
    uint32_t      A, B, C, D, E;     /* Word buffers                */
        
    /*
     *  Initialize the first 16 words in the array W
     */
    for(t = 0; t < 16; t++)
    {
        W[t] = context->Message_Block[t * 4] << 24;
        W[t] |= context->Message_Block[t * 4 + 1] << 16;
        W[t] |= context->Message_Block[t * 4 + 2] << 8;
        W[t] |= context->Message_Block[t * 4 + 3];
    }
        
    for(t = 16; t < 80; t++)
    {
       W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
    }
        
    A = context->Intermediate_Hash[0];
    B = context->Intermediate_Hash[1];
    C = context->Intermediate_Hash[2];
    D = context->Intermediate_Hash[3];
    E = context->Intermediate_Hash[4];
        
    for(t = 0; t < 20; t++)
    {
        temp =  SHA1CircularShift(5,A) +
                ((B & C) | ((~B) & D)) + E + W[t] + K[0];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        
        B = A;
        A = temp;
    }
        
    for(t = 20; t < 40; t++)
    {
        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = temp;
    }
        
    for(t = 40; t < 60; t++)
    {
        temp = SHA1CircularShift(5,A) +
               ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = temp;
    }
        
    for(t = 60; t < 80; t++)
    {
        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = temp;
    }
        
    context->Intermediate_Hash[0] += A;
    context->Intermediate_Hash[1] += B;
    context->Intermediate_Hash[2] += C;
    context->Intermediate_Hash[3] += D;
    context->Intermediate_Hash[4] += E;
        
    context->Message_Block_Index = 0;
}
        
/*
 *  SHA1PadMessage
 *
        

* Description: * According to the standard, the message must be padded to an even * 512 bits. The first padding bit must be a '1'. The last 64 * bits represent the length of the original message. All bits in * between should be 0. This function will pad the message * according to those rules by filling the Message_Block array * accordingly. It will also call the ProcessMessageBlock function * provided appropriately. When it returns, it can be assumed that * the message digest has been computed. * * Parameters: * context: [in/out] * The context to pad * ProcessMessageBlock: [in] * The appropriate SHA*ProcessMessageBlock function * Returns: * Nothing. * */

* 説明: *標準によれば、メッセージは均一な * 512ビットにパディングする必要があります。最初のパディングビットは「1」でなければなりません。最後の64 *ビットは、元のメッセージの長さを表します。*間にあるすべてのビットは0でなければなりません。この関数は、メッセージ_blockアレイ *にそれに応じて、これらのルールに従ってメッセージ *をパッドに埋めます。また、ProcessMessageBlock関数 *を適切に呼び出します。返されると、メッセージダイジェストが計算されていると想定できます。* *パラメーター: *コンテキスト:[in/out] * PADのコンテキスト * ProcessMessageBlock:[in] *適切なsha * processmessageblock関数 * returns: * Nothing。* */

void SHA1PadMessage(SHA1Context *context)
{
    /*
     *  Check to see if the current message block is too small to hold
     *  the initial padding bits and length.  If so, we will pad the
     *  block, process it, and then continue padding into a second
     *  block.
     */
    if (context->Message_Block_Index > 55)
    {
        context->Message_Block[context->Message_Block_Index++] = 0x80;
        while(context->Message_Block_Index < 64)
        {
            context->Message_Block[context->Message_Block_Index++] = 0;
        }
        

SHA1ProcessMessageBlock(context);

sha1processmessageblock(コンテキスト);

        while(context->Message_Block_Index < 56)
        {
            context->Message_Block[context->Message_Block_Index++] = 0;
        }
    }
    else
    {
        context->Message_Block[context->Message_Block_Index++] = 0x80;
        while(context->Message_Block_Index < 56)
        {
        
            context->Message_Block[context->Message_Block_Index++] = 0;
        }
    }
        
    /*
     *  Store the message length as the last 8 octets
     */
    context->Message_Block[56] = context->Length_High >> 24;
    context->Message_Block[57] = context->Length_High >> 16;
    context->Message_Block[58] = context->Length_High >> 8;
    context->Message_Block[59] = context->Length_High;
    context->Message_Block[60] = context->Length_Low >> 24;
    context->Message_Block[61] = context->Length_Low >> 16;
    context->Message_Block[62] = context->Length_Low >> 8;
    context->Message_Block[63] = context->Length_Low;
        

SHA1ProcessMessageBlock(context); }

sha1processmessageblock(コンテキスト);}

7.3 Test Driver
7.3 テストドライバー

The following code is a main program test driver to exercise the code in sha1.c.

次のコードは、sha1.cでコードを行使するメインプログラムテストドライバーです。

/*
 *  sha1test.c
 *
 *  Description:
 *      This file will exercise the SHA-1 code performing the three
 *      tests documented in FIPS PUB 180-1 plus one which calls
 *      SHA1Input with an exact multiple of 512 bits, plus a few
 *      error test checks.
 *
 *  Portability Issues:
 *      None.
 *
 */
        
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "sha1.h"
        
/*
 *  Define patterns for testing
 */
#define TEST1   "abc"
#define TEST2a  "abcdbcdecdefdefgefghfghighijhi"
        
#define TEST2b  "jkijkljklmklmnlmnomnopnopq"
#define TEST2   TEST2a TEST2b
#define TEST3   "a"
#define TEST4a  "01234567012345670123456701234567"
#define TEST4b  "01234567012345670123456701234567"
    /* an exact multiple of 512 bits */
#define TEST4   TEST4a TEST4b
char *testarray[4] =
{
    TEST1,
    TEST2,
    TEST3,
    TEST4
};
long int repeatcount[4] = { 1, 1, 1000000, 10 };
char *resultarray[4] =
{
    "A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D",
    "84 98 3E 44 1C 3B D2 6E BA AE 4A A1 F9 51 29 E5 E5 46 70 F1",
    "34 AA 97 3C D4 C4 DA A4 F6 1E EB 2B DB AD 27 31 65 34 01 6F",
    "DE A3 56 A2 CD DD 90 C7 A7 EC ED C5 EB B5 63 93 4F 46 04 52"
};
        
int main()
{
    SHA1Context sha;
    int i, j, err;
    uint8_t Message_Digest[20];
        
    /*
     *  Perform SHA-1 tests
     */
    for(j = 0; j < 4; ++j)
    {
        printf( "\nTest %d: %d, '%s'\n",
                j+1,
                repeatcount[j],
                testarray[j]);
        
        err = SHA1Reset(&sha);
        if (err)
        {
            fprintf(stderr, "SHA1Reset Error %d.\n", err );
            break;    /* out of for j loop */
        }
        
        for(i = 0; i < repeatcount[j]; ++i)
        {
        
            err = SHA1Input(&sha,
                  (const unsigned char *) testarray[j],
                  strlen(testarray[j]));
            if (err)
            {
                fprintf(stderr, "SHA1Input Error %d.\n", err );
                break;    /* out of for i loop */
            }
        }
        
        err = SHA1Result(&sha, Message_Digest);
        if (err)
        {
            fprintf(stderr,
            "SHA1Result Error %d, could not compute message digest.\n",
            err );
        }
        else
        {
            printf("\t");
            for(i = 0; i < 20 ; ++i)
            {
                printf("%02X ", Message_Digest[i]);
            }
            printf("\n");
        }
        printf("Should match:\n");
        printf("\t%s\n", resultarray[j]);
    }
        
    /* Test some error returns */
    err = SHA1Input(&sha,(const unsigned char *) testarray[1], 1);
    printf ("\nError %d. Should be %d.\n", err, shaStateError );
    err = SHA1Reset(0);
    printf ("\nError %d. Should be %d.\n", err, shaNull );
    return 0;
}
        
8. Security Considerations
8. セキュリティに関する考慮事項

This document is intended to provide convenient open source access by the Internet community to the United States of America Federal Information Processing Standard Secure Hash Function SHA-1 [FIPS 180-1]. No independent assertion of the security of this hash function by the authors for any particular use is intended.

このドキュメントは、インターネットコミュニティがアメリカ合衆国連邦情報処理標準安全なハッシュ関数SHA-1 [FIPS 180-1]に便利なオープンソースアクセスを提供することを目的としています。特定の使用に関する著者によるこのハッシュ関数のセキュリティの独立した主張は意図されていません。

References

参考文献

[FIPS 180-1] "Secure Hash Standard", United States of American, National Institute of Science and Technology, Federal Information Processing Standard (FIPS) 180-1, April 1993.

[FIPS 180-1]「Secure Hash Standard」、アメリカ合衆国、国立科学技術研究所、連邦情報処理標準(FIPS)180-1、1993年4月。

[MD4] "The MD4 Message Digest Algorithm," Advances in Cryptology - CRYPTO '90 Proceedings, Springer-Verlag, 1991, pp. 303-311.

[MD4]「MD4 Message Digestアルゴリズム」、Cryptogy-Crypto '90 Proceedings、Springer-Verlag、1991、pp。303-311。

[RFC 1320] Rivest, R., "The MD4 Message-Digest Algorithm", RFC 1320, April 1992.

[RFC 1320] Rivest、R。、「The MD4 Message-Digest Algorithm」、RFC 1320、1992年4月。

[RFC 1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, April 1992.

[RFC 1321] Rivest、R。、「The MD5 Message-Digest Algorithm」、RFC 1321、1992年4月。

[RFC 1750] Eastlake, D., Crocker, S. and J. Schiller, "Randomness Requirements for Security", RFC 1750, December 1994.

[RFC 1750] Eastlake、D.、Crocker、S。and J. Schiller、「セキュリティのランダム性要件」、RFC 1750、1994年12月。

Authors' Addresses

著者のアドレス

Donald E. Eastlake, 3rd Motorola 155 Beaver Street Milford, MA 01757 USA

ドナルドE.イーストレイク、第3モトローラ155ビーバーストリートミルフォード、マサチューセッツ州01757 USA

   Phone:   +1 508-634-2066 (h)
            +1 508-261-5434 (w)
   Fax:     +1 508-261-4777
   EMail:   Donald.Eastlake@motorola.com
        

Paul E. Jones Cisco Systems, Inc. 7025 Kit Creek Road Research Triangle Park, NC 27709 USA

Paul E. Jones Cisco Systems、Inc。7025 Kit Creek Road Research Triangle Park、NC 27709 USA

   Phone:   +1 919 392 6948
   EMail:   paulej@packetizer.com
        

Full Copyright Statement

完全な著作権声明

Copyright (C) The Internet Society (2001). All Rights Reserved.

Copyright(c)The Internet Society(2001)。全著作権所有。

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.

このドキュメントと翻訳は他の人にコピーされて提供される場合があり、それについてコメントまたは説明するか、その実装を支援する派生作品は、いかなる種類の制限なしに、準備、コピー、公開、配布される場合があります。、上記の著作権通知とこの段落がそのようなすべてのコピーとデリバティブ作品に含まれている場合。ただし、このドキュメント自体は、インターネット協会や他のインターネット組織への著作権通知や参照を削除するなど、いかなる方法でも変更できない場合があります。インターネット標準のプロセスに従うか、英語以外の言語に翻訳するために必要な場合に従う必要があります。

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

上記の限られた許可は永続的であり、インターネット社会またはその後継者または譲受人によって取り消されることはありません。

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

この文書と本書に含まれる情報は、「現状」に基づいて提供されており、インターネット社会とインターネットエンジニアリングタスクフォースは、ここにある情報の使用が行われないという保証を含むがこれらに限定されないすべての保証を否認します。特定の目的に対する商品性または適合性の権利または黙示的な保証を侵害します。

Acknowledgement

謝辞

Funding for the RFC Editor function is currently provided by the Internet Society.

RFCエディター機能の資金は現在、インターネット協会によって提供されています。