home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 October / Chip_2001-10_cd1.bin / zkuste / delphi / nastroje / WP.ZIP / Sha1.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-09-26  |  5.0 KB  |  181 lines

  1. {
  2. ***************************************************
  3. * A binary compatible SHA1 implementation         *
  4. * written by Dave Barton (davebarton@bigfoot.com) *
  5. ***************************************************
  6. * 160bit hash size                                *
  7. ***************************************************
  8. }
  9. unit SHA1;
  10.  
  11. interface
  12. uses
  13.   Sysutils, Tools;
  14.  
  15. type
  16.   TSHA1Digest= array[0..19] of byte;
  17.   TSHA1Context= record
  18.     Hash: array[0..4] of DWord;
  19.     Hi, Lo: integer;
  20.     Buffer: array[0..63] of byte;
  21.     Index: integer;
  22.   end;
  23.  
  24. function SHA1SelfTest: boolean;
  25. procedure SHA1Init(var Context: TSHA1Context);
  26. procedure SHA1Update(var Context: TSHA1Context; Buffer: pointer; Len: integer);
  27. procedure SHA1Final(var Context: TSHA1Context; var Digest: TSHA1Digest);
  28.  
  29. //******************************************************************************
  30. implementation
  31. {$R-}
  32.  
  33. function SHA1SelfTest: boolean;
  34. const
  35.   s: string= 'abc';
  36.   OutDigest: TSHA1Digest=
  37.     ($a9,$99,$3e,$36,$47,$06,$81,$6a,$ba,$3e,$25,$71,$78,$50,$c2,$6c,$9c,$d0,$d8,$9d);
  38. var
  39.   Context: TSHA1Context;
  40.   Digest: TSHA1Digest;
  41. begin
  42.   SHA1Init(Context);
  43.   SHA1Update(Context,@s[1],length(s));
  44.   SHA1Final(Context,Digest);
  45.   if CompareMem(@Digest,@OutDigest,Sizeof(Digest)) then
  46.     Result:= true
  47.   else
  48.     Result:= false;
  49. end;
  50.  
  51. //******************************************************************************
  52. function F1(x, y, z: DWord): DWord;
  53. begin
  54.   Result:= z xor (x and (y xor z));
  55. end;
  56. function F2(x, y, z: DWord): DWord;
  57. begin
  58.   Result:= x xor y xor z;
  59. end;
  60. function F3(x, y, z: DWord): DWord;
  61. begin
  62.   Result:= (x and y) or (z and (x or y));
  63. end;
  64.  
  65. //******************************************************************************
  66. function RB(A: DWord): DWord;
  67. begin
  68.   Result:= (A shr 24) or ((A shr 8) and $FF00) or ((A shl 8) and $FF0000) or (A shl 24);
  69. end;
  70.  
  71. procedure SHA1Compress(var Data: TSHA1Context);
  72. var
  73.   A, B, C, D, E, T: DWord;
  74.   W: array[0..79] of DWord;
  75.   i: integer;
  76. begin
  77.   Move(Data.Buffer,W,Sizeof(Data.Buffer));
  78.   for i:= 0 to 15 do
  79.     W[i]:= RB(W[i]);
  80.   for i:= 16 to 79 do
  81.     W[i]:= LRot32(W[i-3] xor W[i-8] xor W[i-14] xor W[i-16],1);
  82.   A:= Data.Hash[0]; B:= Data.Hash[1]; C:= Data.Hash[2]; D:= Data.Hash[3]; E:= Data.Hash[4];
  83.   for i:= 0 to 19 do
  84.   begin
  85.     T:= LRot32(A,5) + F1(B,C,D) + E + W[i] + $5A827999;
  86.     E:= D; D:= C; C:= LRot32(B,30); B:= A; A:= T;
  87.   end;
  88.   for i:= 20 to 39 do
  89.   begin
  90.     T:= LRot32(A,5) + F2(B,C,D) + E + W[i] + $6ED9EBA1;
  91.     E:= D; D:= C; C:= LRot32(B,30); B:= A; A:= T;
  92.   end;
  93.   for i:= 40 to 59 do
  94.   begin
  95.     T:= LRot32(A,5) + F3(B,C,D) + E + W[i] + $8F1BBCDC;
  96.     E:= D; D:= C; C:= LRot32(B,30); B:= A; A:= T;
  97.   end;
  98.   for i:= 60 to 79 do
  99.   begin
  100.     T:= LRot32(A,5) + F2(B,C,D) + E + W[i] + $CA62C1D6;
  101.     E:= D; D:= C; C:= LRot32(B,30); B:= A; A:= T;
  102.   end;
  103.   Data.Hash[0]:= Data.Hash[0] + A;
  104.   Data.Hash[1]:= Data.Hash[1] + B;
  105.   Data.Hash[2]:= Data.Hash[2] + C;
  106.   Data.Hash[3]:= Data.Hash[3] + D;
  107.   Data.Hash[4]:= Data.Hash[4] + E;
  108.   FillChar(W,Sizeof(W),0);
  109.   FillChar(Data.Buffer,Sizeof(Data.Buffer),0);
  110. end;
  111.  
  112. //******************************************************************************
  113. procedure SHA1Init(var Context: TSHA1Context);
  114. begin
  115.   Context.Hi:= 0; Context.Lo:= 0;
  116.   Context.Index:= 0;
  117.   FillChar(Context.Buffer,Sizeof(Context.Buffer),0);
  118.   Context.Hash[0]:= $67452301;
  119.   Context.Hash[1]:= $EFCDAB89;
  120.   Context.Hash[2]:= $98BADCFE;
  121.   Context.Hash[3]:= $10325476;
  122.   Context.Hash[4]:= $C3D2E1F0;
  123. end;
  124.  
  125. //******************************************************************************
  126. procedure SHA1UpdateLen(var Context: TSHA1Context; Len: integer);
  127. var
  128.   i, k: integer;
  129. begin
  130.   for k:= 0 to 7 do
  131.   begin
  132.     i:= Context.Lo;
  133.     Inc(Context.Lo,Len);
  134.     if Context.Lo< i then
  135.       Inc(Context.Hi);
  136.   end;
  137. end;
  138.  
  139. //******************************************************************************
  140. procedure SHA1Update(var Context: TSHA1Context; Buffer: pointer; Len: integer);
  141. type
  142.   PByte= ^Byte;
  143. begin
  144.   SHA1UpdateLen(Context,Len);
  145.   while Len> 0 do
  146.   begin
  147.     Context.Buffer[Context.Index]:= PByte(Buffer)^;
  148.     Inc(PByte(Buffer));
  149.     Inc(Context.Index);
  150.     Dec(Len);
  151.     if Context.Index= 64 then
  152.     begin
  153.       Context.Index:= 0;
  154.       SHA1Compress(Context);
  155.     end;
  156.   end;
  157. end;
  158.  
  159. //******************************************************************************
  160. procedure SHA1Final(var Context: TSHA1Context; var Digest: TSHA1Digest);
  161. type
  162.   PDWord= ^DWord;
  163. begin
  164.   Context.Buffer[Context.Index]:= $80;
  165.   if Context.Index>= 56 then
  166.     SHA1Compress(Context);
  167.   PDWord(@Context.Buffer[56])^:= RB(Context.Hi);
  168.   PDWord(@Context.Buffer[60])^:= RB(Context.Lo);
  169.   SHA1Compress(Context);
  170.   Context.Hash[0]:= RB(Context.Hash[0]);
  171.   Context.Hash[1]:= RB(Context.Hash[1]);
  172.   Context.Hash[2]:= RB(Context.Hash[2]);
  173.   Context.Hash[3]:= RB(Context.Hash[3]);
  174.   Context.Hash[4]:= RB(Context.Hash[4]);
  175.   Move(Context.Hash,Digest,Sizeof(Digest));
  176.   FillChar(Context,Sizeof(Context),0);
  177. end;
  178.  
  179.  
  180. end.
  181.