home *** CD-ROM | disk | FTP | other *** search
/ Chip 1999 January / Chip_1999-01_cd.bin / zkuste / delphi / QDB / QDB.ZIP / qdbu.pas < prev    next >
Pascal/Delphi Source File  |  1998-06-27  |  8KB  |  275 lines

  1.  
  2. {*****************************************************************************}
  3. {                                                                             }
  4. {          QDBU supplies the password and secure hashing for QDB              }
  5. {            QDB v2.10 Visual Components for Delphi 1, 2, & 3                 }
  6. {                                                                             }
  7. {       Copyright (c) 1995, 1996, 1997, 1998 Robert R. Marsh, S.J.            }
  8. {             & the British Province of the Society of Jesus                  }
  9. {                                                                             }
  10. {              This source code may *not* be redistributed                    }
  11. {              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                    }
  12. {                                                                             }
  13. {       If you like QDB and find yourself using it please consider            }
  14. {       making a donation to your favorite charity. I would also be           }
  15. {       pleased if you would acknowledge QDB in any projects that             }
  16. {       make use of it.                                                       }
  17. {                                                                             }
  18. {       QDB is supplied as is. The author disclaims all warranties,           }
  19. {       expressed or implied, including, without limitation, the              }
  20. {       warranties of merchantability and of fitness for any purpose.         }
  21. {       The author assumes no liability for damages, direct or                }
  22. {       consequential, which may result from the use of QDB.                  }
  23. {                                                                             }
  24. {                           rrm@sprynet.com                                   }
  25. {                  http://home.sprynet.com/sprynet/rrm                        }
  26. {                                                                             }
  27. {*****************************************************************************}
  28.  
  29. (*
  30.   This code is based on the work of Koos Lodewijkx (J.P.Lodewijkx@inter.nl.net).
  31. *)
  32.  
  33.  
  34. {$R-,A-,Q-}
  35. unit QDBU;
  36.  
  37. interface
  38.  
  39. type
  40.   THash = array[0..19] of Char;
  41.  
  42. function Hash(const s: string): THash;
  43.  
  44. procedure Shroud(var buffer; buflen: longint; Hash: THash);
  45.  
  46. procedure UnShroud(var buffer; buflen: longint; Hash: THash);
  47.  
  48. implementation
  49.  
  50. type
  51.   TSHAContext = record
  52.     State: array[0..4] of LongInt;
  53.     Count: array[0..1] of LongInt;
  54.     case Integer of
  55.       0: (BufChar: array[0..63] of Byte);
  56.       1: (BufLong: array[0..15] of LongInt)
  57.   end;
  58.  
  59. procedure ReverseBytes(var Buf; ByteCnt: Word);
  60. var
  61.   BufLong: array[0..0] of LongInt absolute Buf;
  62.   Tmp: LongInt;
  63.   i: Word;
  64. begin
  65.   ByteCnt := ByteCnt div 4;
  66.   for i := 0 to ByteCnt - 1 do begin
  67.     Tmp := (BufLong[i] shl 16) or (BufLong[i] shr 16);
  68.     BufLong[i] := ((Tmp and $00FF00FF) shl 8) or ((Tmp and $FF00FF00) shr 8)
  69.   end
  70. end;
  71.  
  72. procedure SHAInit(var SHAContext: TSHAContext);
  73. {  Start SHA accumulation.  Set bit count to 0 and State to mysterious  }
  74. {  initialization constants.                                            }
  75. begin
  76.   FillChar(SHAContext, SizeOf(TSHAContext), #0);
  77.   with SHAContext do begin
  78.     State[0] := $67452301;
  79.     State[1] := $EFCDAB89;
  80.     State[2] := $98BADCFE;
  81.     State[3] := $10325476;
  82.     State[4] := $C3D2E1F0
  83.   end
  84. end;
  85.  
  86. procedure SHATransform(var Buf: array of LongInt; const Data: array of LongInt); forward;
  87.  
  88. procedure SHAUpdate(var SHAContext: TSHAContext; const Data; Len: Word);
  89. {  Update context to reflect the concatenation of another buffer full  }
  90. {  of bytes.                                                           }
  91. type
  92.   TByteArray = array[0..0] of Byte;
  93. var
  94.   Index: Word;
  95.   t: LongInt;
  96. begin
  97.   { Update bitcount }
  98.   with SHAContext do begin
  99.     t := Count[0];
  100.     Inc(Count[0], LongInt(Len) shl 3);
  101.     if Count[0] < t then
  102.       Inc(Count[1]);
  103.     Inc(Count[1], Len shr 29); { Makes no sense for Len of type Word, will be 0 }
  104.     t := (t shr 3) and $3F;
  105.  
  106.     Index := 0;
  107.     { Handle any leading odd-sized chunks }
  108.     if t <> 0 then begin
  109.       Index := t;
  110.       t := 64 - t;
  111.       if Len < t then begin
  112.         Move(Data, BufChar[Index], Len);
  113.         Exit
  114.       end;
  115.       Move(Data, BufChar[Index], t);
  116.       SHATransform(State, BufLong);
  117.       Dec(Len, t)
  118.     end;
  119.  
  120.     { Process data in 64-byte chunks }
  121.     while Len >= 64 do begin
  122.       Move(TByteArray(Data)[Index], BufChar, 64);
  123.       SHATransform(State, BufLong);
  124.       Inc(Index, 64);
  125.       Dec(Len, 64)
  126.     end;
  127.  
  128.     { Handle any remaining bytes of data. }
  129.     Move(TByteArray(Data)[Index], BufChar, Len)
  130.   end
  131. end;
  132.  
  133. function SHAFinal(var SHAContext: TSHAContext): THash;
  134. var
  135.   Cnt: Word;
  136.   p: Byte;
  137.   tmpres: THash;
  138. begin
  139.   with SHAContext do begin
  140.     { Compute number of bytes mod 64 }
  141.     Cnt := (Count[0] shr 3) and $3F;
  142.  
  143.     { Set the first char of padding to $80 }
  144.     p := Cnt;
  145.     BufChar[p] := $80;
  146.     Inc(p);
  147.  
  148.     { Bytes of padding needed to make 64 bytes }
  149.     Cnt := 64 - 1 - Cnt;
  150.  
  151.     { Pad out to 56 mod 64 }
  152.     if Cnt < 8 then begin
  153.       { Two lots of padding:  Pad the first block to 64 bytes }
  154.       FillChar(BufChar[p], Cnt, #0);
  155.       SHATransform(State, BufLong);
  156.  
  157.       { Now fill the next block with 56 bytes }
  158.       FillChar(BufChar, 56, #0)
  159.     end else
  160.       { Pad block to 56 bytes }
  161.       FillChar(BufChar[p], Cnt - 8, #0);
  162.  
  163.     { Append length in bits and transform }
  164.     BufLong[14] := Count[1];
  165.     BufLong[15] := Count[0];
  166.     ReverseBytes(BufLong[14], 8);
  167.     SHATransform(State, BufLong);
  168.  
  169.     { Resulting Hash equals current State }
  170.     Move(State, tmpres, SizeOf(THash));
  171.     ReverseBytes(tmpres, SizeOf(THash));
  172.     Result := tmpres;
  173.   end;
  174.  
  175.   FillChar(SHAContext, SizeOf(TSHAContext), #0)
  176. end;
  177.  
  178. function rol(x: LongInt; cnt: Byte): LongInt;
  179. { Rotate left }
  180. begin
  181.   Result := (x shl cnt) or (x shr (32 - cnt))
  182. end;
  183.  
  184. procedure SHATransform(var Buf: array of LongInt; const Data: array of LongInt);
  185. var
  186.   a, b, c, d, e: LongInt;
  187.   Tmp: LongInt;
  188.   w: array[0..15] of LongInt;
  189.   i: Word;
  190. begin
  191.   a := Buf[0];
  192.   b := Buf[1];
  193.   c := Buf[2];
  194.   d := Buf[3];
  195.   e := Buf[4];
  196.  
  197.   Move(Data, w, 64);
  198.   ReverseBytes(w, 64);
  199.  
  200.   for i := 0 to 79 do begin
  201.     if i > 15 then
  202.       w[i and 15] := rol(w[i and 15] xor w[(i - 14) and 15] xor
  203.         w[(i - 8) and 15] xor w[(i - 3) and 15], 1);
  204.     if i <= 19 then
  205.       Tmp := rol(a, 5) + e + w[i and 15] + $5A827999 + ((b and c) or ((not b) and d))
  206.     else if i <= 39 then
  207.       Tmp := rol(a, 5) + e + w[i and 15] + $6ED9EBA1 + (b xor c xor d)
  208.     else if i <= 59 then
  209.       Tmp := rol(a, 5) + e + w[i and 15] + $8F1BBCDC + ((b and c) or (b and d) or (c and d))
  210.     else
  211.       Tmp := rol(a, 5) + e + w[i and 15] + $CA62C1D6 + (b xor c xor d);
  212.     e := d;
  213.     d := c;
  214.     c := rol(b, 30);
  215.     b := a;
  216.     a := Tmp
  217.   end;
  218.  
  219.   Inc(Buf[0], a);
  220.   Inc(Buf[1], b);
  221.   Inc(Buf[2], c);
  222.   Inc(Buf[3], d);
  223.   Inc(Buf[4], e)
  224. end;
  225.  
  226. function Hash(const s: string): THash;
  227. var
  228.   SHAContext: TSHAContext;
  229. begin
  230.   SHAInit(SHAContext);
  231.   SHAUpdate(SHAContext, s[1], length(s));
  232.   Result := SHAFinal(SHAContext);
  233. end;
  234.  
  235. procedure Crypt(var buffer; buflen: longint; Hash: THash);
  236. const
  237.   a = 1664525;
  238.   b = 1013904223;
  239. var
  240.   n: longint;
  241.   r: longint;
  242.   ByteBuff: array[0..0] of byte absolute buffer;
  243.   LongBuff: array[0..0] of longint absolute buffer;
  244.   LongHash: array[0..0] of longint absolute Hash;
  245. begin
  246.   r := LongHash[0];
  247.   for n := 1 to 4 do
  248.   begin
  249.     r := r xor LongHash[n];
  250.   end;
  251.   for n := 1 to (buflen div SizeOf(longint)) do
  252.   begin
  253.     r := a * r + b;
  254.     LongBuff[n - 1] := LongBuff[n - 1] xor r;
  255.   end;
  256.   for n := SizeOf(longint) * (buflen div SizeOf(longint)) + 1 to buflen do
  257.   begin
  258.     r := a * r + b;
  259.     ByteBuff[n - 1] := ByteBuff[n - 1] xor r;
  260.   end;
  261. end;
  262.  
  263. procedure Shroud(var buffer; buflen: longint; Hash: THash);
  264. begin
  265.   Crypt(buffer, buflen, Hash);
  266. end;
  267.  
  268. procedure UnShroud(var buffer; buflen: longint; Hash: THash);
  269. begin
  270.   Crypt(buffer, buflen, Hash);
  271. end;
  272.  
  273. end.
  274.  
  275.