OSDN Git Service

This commit was manufactured by cvs2svn to create branch 'Bb62'.
[gikonavigoeson/gikonavi.git] / SHA1Unit.pas
1 unit SHA1Unit;
2
3 interface
4
5 uses
6         Windows, SysUtils;
7
8 const
9     SHA1_A = DWORD( $67452301 );
10     SHA1_B = DWORD( $EFCDAB89 );
11     SHA1_C = DWORD( $98BADCFE );
12     SHA1_D = DWORD( $10325476 );
13     SHA1_E = DWORD( $C3D2E1F0 );
14     SHA1_K1 = DWORD( $5A827999 );
15     SHA1_K2 = DWORD( $6ED9EBA1 );
16     SHA1_K3 = DWORD( $8F1BBCDC );
17     SHA1_K4 = DWORD( $CA62C1D6 );
18     LBMASK_HI = DWORD( $FF0000 );
19     LBMASK_LO = DWORD( $FF00 );
20
21 type
22     TSHA1Digest = array [0..19] of Byte;
23     TSHA1Context = record
24         sdHi    : DWord;
25         sdLo    : DWord;
26         sdIndex : DWord;
27         sdHash  : array [0..4] of DWord;
28         sdBuf   : array [0..63] of Byte;
29     end;
30
31     function SHA1SwapByteOrder( n : DWORD ) : DWORD;
32     procedure HashSHA1( var Digest : TSHA1Digest; const Buf; BufSize : Longint );
33     procedure StringHashSHA1(var Digest : TSHA1Digest; const Str : string);
34     procedure SHA1Hash( var Context : TSHA1Context );
35
36 implementation
37 //! \95\8e\9a\97ñ\97pSHA1\83n\83b\83V\83\85\8eæ\93¾
38 procedure StringHashSHA1(var Digest : TSHA1Digest; const Str : string);
39 begin
40     HashSHA1(Digest, Str[1], Length(Str));
41 end;
42 //! SHA1\83n\83b\83V\83\85\8eæ\93¾
43 procedure HashSHA1( var Digest : TSHA1Digest; const Buf; BufSize : Longint );
44 var
45     Context : TSHA1Context;
46     PBuf: ^Byte;
47     procedure UpdateLen( var Context : TSHA1Context; Len : DWord );
48     begin
49         Inc( Context.sdLo,( Len shl 3 ));
50         if Context.sdLo < ( Len shl 3 ) then
51             Inc( Context.sdHi );
52         Inc( Context.sdHi, Len shr 29 );
53     end;
54 begin
55     //0\96\84\82ß
56     fillchar( Context, SizeOf( Context ), 0 );
57     // \83}\83W\83b\83N\83i\83\93\83o\81[\82Å\8f\89\8aú\89»\82·\82é
58     Context.sdHash[ 0 ] := SHA1_A;
59     Context.sdHash[ 1 ] := SHA1_B;
60     Context.sdHash[ 2 ] := SHA1_C;
61     Context.sdHash[ 3 ] := SHA1_D;
62     Context.sdHash[ 4 ] := SHA1_E;
63
64     UpdateLen( Context, BufSize );
65     PBuf := @Buf;
66     while BufSize > 0 do begin
67         if ( Sizeof( Context.sdBuf ) - Context.sdIndex ) <= DWord( BufSize ) then begin
68             Move( PBuf^, Context.sdBuf[ Context.sdIndex ], Sizeof( Context.sdBuf ) - Context.sdIndex );
69             Dec( BufSize, Sizeof( Context.sdBuf ) - Context.sdIndex );
70             Inc( PBuf, Sizeof( Context.sdBuf ) - Context.sdIndex );
71             SHA1Hash( Context );
72         end else begin
73             Move( PBuf^, Context.sdBuf[ Context.sdIndex ], BufSize );
74             Inc( Context.sdIndex, BufSize );
75             BufSize := 0;
76         end;
77     end;
78
79     Context.sdBuf[ Context.sdIndex ] := $80;
80
81     if Context.sdIndex >= 56 then
82         SHA1Hash( Context );
83
84     PDWord( @Context.sdBuf[ 56 ])^ := SHA1SwapByteOrder( Context.sdHi );
85     PDWord( @Context.sdBuf[ 60 ])^ := SHA1SwapByteOrder( Context.sdLo );
86
87     SHA1Hash( Context );
88
89     Context.sdHash[ 0 ] := SHA1SwapByteOrder( Context.sdHash[ 0 ]);
90     Context.sdHash[ 1 ] := SHA1SwapByteOrder( Context.sdHash[ 1 ]);
91     Context.sdHash[ 2 ] := SHA1SwapByteOrder( Context.sdHash[ 2 ]);
92     Context.sdHash[ 3 ] := SHA1SwapByteOrder( Context.sdHash[ 3 ]);
93     Context.sdHash[ 4 ] := SHA1SwapByteOrder( Context.sdHash[ 4 ]);
94
95     Move( Context.sdHash, Digest, Sizeof( Digest ));
96 end;
97 //! \83n\83b\83V\83\85\8f\88\97\9d
98 procedure SHA1Hash( var Context : TSHA1Context );
99 var
100     A : DWord;
101     B : DWord;
102     C : DWord;
103     D : DWord;
104     E : DWord;
105
106     temp : DWord;
107     W : array[ 0..79 ] of DWord;
108
109     i : Longint;
110     function SHA1CircularShift(I, C : DWord) : DWord; register;
111     asm
112         mov  ecx, edx
113         rol  eax, cl
114     end;
115 begin
116     with Context do begin
117         sdIndex:= 0;
118         Move( sdBuf, W, Sizeof( W ));
119
120         // Initialize the first 16 words in the array W
121         for i := 0 to 15 do begin
122             W[ i ]:= SHA1SwapByteOrder( W[ i ] );
123         end;
124
125         // Transform Message block from 16 32 bit words to 80 32 bit words
126         // Wt, = ( Wt-3 xor Wt-8 xor Wt-13 xor Wt-16 ) rolL 1 : Wt is W sub t
127         for i:= 16 to 79 do begin
128             W[i]:= SHA1CircularShift( W[ i - 3 ] xor W[ i - 8 ] xor W[ i - 14 ] xor W[ i - 16 ], 1 );
129         end;
130
131         A := sdHash[ 0 ];
132         B := sdHash[ 1 ];
133         C := sdHash[ 2 ];
134         D := sdHash[ 3 ];
135         E := sdHash[ 4 ];
136
137         // the four rounds
138         for i:= 0 to 19 do begin
139             temp    := SHA1CircularShift( A, 5 ) + ( D xor ( B and ( C xor D ))) + E + W[ i ] + SHA1_K1;
140             E       := D;
141             D       := C;
142             C       := SHA1CircularShift( B, 30 );
143             B       := A;
144             A       := temp;
145         end;
146
147         for i:= 20 to 39 do begin
148             temp    := SHA1CircularShift( A, 5 ) + ( B xor C xor D ) + E + W[ i ] + SHA1_K2;
149             E       := D;
150             D       := C;
151             C       := SHA1CircularShift( B, 30 );
152             B       := A;
153             A       := temp;
154         end;
155
156         for i:= 40 to 59 do begin
157             temp    := SHA1CircularShift( A, 5 ) + (( B and C ) or ( D and ( B or C ))) + E + W[ i ] + SHA1_K3;
158             E       := D;
159             D       := C;
160             C       := SHA1CircularShift( B, 30 );
161             B       := A;
162             A       := temp;
163         end;
164
165         for i:= 60 to 79 do
166         begin
167             temp    := SHA1CircularShift( A, 5 ) + ( B xor C xor D ) + E + W[ i ] + SHA1_K4;
168             E       := D;
169             D       := C;
170             C       := SHA1CircularShift( B, 30 );
171             B       := A;
172             A       := temp;
173         end;
174
175         sdHash[ 0 ]:= sdHash[ 0 ] + A;
176         sdHash[ 1 ]:= sdHash[ 1 ] + B;
177         sdHash[ 2 ]:= sdHash[ 2 ] + C;
178         sdHash[ 3 ]:= sdHash[ 3 ] + D;
179         sdHash[ 4 ]:= sdHash[ 4 ] + E;
180
181         FillChar( W, Sizeof( W ), 0 );
182         FillChar( sdBuf, Sizeof( sdBuf ), 0 );
183     end;
184 end;
185
186 //! \8fã\88Ê\83o\83C\83g\82Æ\89º\88Ê\83o\83C\83g\82Ì\93ü\82ê\91Ö\82¦
187 function SHA1SwapByteOrder( n : DWORD ) : DWORD;
188 begin
189     n := ( n shr 24 ) or (( n shr 8 ) and LBMASK_LO )
190        or (( n shl 8 ) and LBMASK_HI ) or ( n shl 24 );
191     Result := n;
192 end;
193
194 end.