home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 December / Chip_2002-12_cd1.bin / ctenari / Hytha / MultiHSH.exe / SR.RAR / SR / DCPCrypt / Hashes / DCPhaval.pas next >
Pascal/Delphi Source File  |  2002-07-11  |  16KB  |  500 lines

  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
  3. {******************************************************************************}
  4. {* A binary compatible implementation of Haval ********************************}
  5. {******************************************************************************}
  6. {* Copyright (c) 1999-2002 David Barton                                       *}
  7. {* Permission is hereby granted, free of charge, to any person obtaining a    *}
  8. {* copy of this software and associated documentation files (the "Software"), *}
  9. {* to deal in the Software without restriction, including without limitation  *}
  10. {* the rights to use, copy, modify, merge, publish, distribute, sublicense,   *}
  11. {* and/or sell copies of the Software, and to permit persons to whom the      *}
  12. {* Software is furnished to do so, subject to the following conditions:       *}
  13. {*                                                                            *}
  14. {* The above copyright notice and this permission notice shall be included in *}
  15. {* all copies or substantial portions of the Software.                        *}
  16. {*                                                                            *}
  17. {* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *}
  18. {* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *}
  19. {* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *}
  20. {* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *}
  21. {* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    *}
  22. {* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        *}
  23. {* DEALINGS IN THE SOFTWARE.                                                  *}
  24. {******************************************************************************}
  25. unit DCPhaval;
  26.  
  27. interface
  28. uses
  29.   Classes, Sysutils, DCPcrypt2, DCPconst;
  30.  
  31. type
  32.   TDCP_haval= class(TDCP_hash)
  33.   protected
  34.     LenHi, LenLo: longword;
  35.     Index: DWord;
  36.     CurrentHash: array[0..7] of DWord;
  37.     HashBuffer: array[0..127] of byte;
  38.     procedure Compress;
  39.   public
  40.     class function GetId: integer; override;
  41.     class function GetAlgorithm: string; override;
  42.     class function GetHashSize: integer; override;
  43.     class function SelfTest: boolean; override;
  44.     procedure Init; override;
  45.     procedure Burn; override;
  46.     procedure Update(const Buffer; Size: longword); override;
  47.     procedure Final(var Digest); override;
  48.   end;
  49.  
  50. { Choose how many passes (previous versions of DCPcrypt uses 5 passes) }
  51. { ONLY UNCOMMENT ONE! }
  52. //{$DEFINE PASS3}
  53. //{$DEFINE PASS4}
  54. {$DEFINE PASS5}
  55.  
  56. { Choose digest length (previous versions of DCPcrypt uses 256bits) }
  57. { ONLY UNCOMMENT ONE! }
  58. //{$DEFINE DIGEST128}
  59. //{$DEFINE DIGEST160}
  60. //{$DEFINE DIGEST192}
  61. //{$DEFINE DIGEST224}
  62. {$DEFINE DIGEST256}
  63.  
  64.  
  65. {******************************************************************************}
  66. {******************************************************************************}
  67. implementation
  68. {$R-}{$Q-}
  69.  
  70. procedure TDCP_haval.Compress;
  71. var
  72.   t7, t6, t5, t4, t3, t2, t1, t0: DWord;
  73.   W: array[0..31] of DWord;
  74.   Temp: dword;
  75. begin
  76.   t0:= CurrentHash[0];
  77.   t1:= CurrentHash[1];
  78.   t2:= CurrentHash[2];
  79.   t3:= CurrentHash[3];
  80.   t4:= CurrentHash[4];
  81.   t5:= CurrentHash[5];
  82.   t6:= CurrentHash[6];
  83.   t7:= CurrentHash[7];
  84.   Move(HashBuffer,W,Sizeof(W));
  85.  
  86. {$IFDEF PASS3}
  87.   {$INCLUDE DCPhaval3.inc}
  88. {$ELSE}
  89.   {$IFDEF PASS4}
  90.     {$INCLUDE DCPhaval4.inc}
  91.   {$ELSE}
  92.     {$INCLUDE DCPhaval5.inc}
  93.   {$ENDIF}
  94. {$ENDIF}
  95.  
  96.   Inc(CurrentHash[0],t0);
  97.   Inc(CurrentHash[1],t1);
  98.   Inc(CurrentHash[2],t2);
  99.   Inc(CurrentHash[3],t3);
  100.   Inc(CurrentHash[4],t4);
  101.   Inc(CurrentHash[5],t5);
  102.   Inc(CurrentHash[6],t6);
  103.   Inc(CurrentHash[7],t7);
  104.   FillChar(W,Sizeof(W),0);
  105.   Index:= 0;
  106.   FillChar(HashBuffer,Sizeof(HashBuffer),0);
  107. end;
  108.  
  109. class function TDCP_haval.GetHashSize: integer;
  110. begin
  111. {$IFDEF DIGEST128}
  112.   Result:= 128;
  113. {$ELSE}
  114.   {$IFDEF DIGEST160}
  115.     Result:= 160;
  116.   {$ELSE}
  117.     {$IFDEF DIGEST192}
  118.       Result:= 192;
  119.     {$ELSE}
  120.       {$IFDEF DIGEST224}
  121.         Result:= 224;
  122.       {$ELSE}
  123.         Result:= 256;
  124.       {$ENDIF}
  125.     {$ENDIF}
  126.   {$ENDIF}
  127. {$ENDIF}
  128. end;
  129.  
  130. class function TDCP_haval.GetId: integer;
  131. begin
  132.   Result:= DCP_haval;
  133. end;
  134.  
  135. class function TDCP_haval.GetAlgorithm: string;
  136. begin
  137.   Result:= 'Haval (';
  138. {$IFDEF DIGEST128}
  139.   Result:= Result+'128bit, ';
  140. {$ELSE}
  141.   {$IFDEF DIGEST160}
  142.     Result:= Result+'160bit, ';
  143.   {$ELSE}
  144.     {$IFDEF DIGEST192}
  145.       Result:= Result+'192bit, ';
  146.     {$ELSE}
  147.       {$IFDEF DIGEST224}
  148.         Result:= Result+'224bit, ';
  149.       {$ELSE}
  150.         Result:= Result+'256bit, ';
  151.       {$ENDIF}
  152.     {$ENDIF}
  153.   {$ENDIF}
  154. {$ENDIF}
  155. {$IFDEF PASS3}
  156.   Result:= Result+'3 passes)';
  157. {$ELSE}
  158.   {$IFDEF PASS4}
  159.     Result:= Result+'4 passes)';
  160.   {$ELSE}
  161.     Result:= Result+'5 passes)';
  162.   {$ENDIF}
  163. {$ENDIF}
  164. end;
  165.  
  166. class function TDCP_haval.SelfTest: boolean;
  167. {$IFDEF PASS3}
  168.   {$IFDEF DIGEST128}
  169.     const
  170.       Test1Out: array[0..15] of byte=
  171.         ($1B,$DC,$55,$6B,$29,$AD,$02,$EC,$09,$AF,$8C,$66,$47,$7F,$2A,$87);
  172.     var
  173.       TestHash: TDCP_haval;
  174.       TestOut: array[0..15] of byte;
  175.     begin
  176.       TestHash:= TDCP_haval.Create(nil);
  177.       TestHash.Init;
  178.       TestHash.UpdateStr('');
  179.       TestHash.Final(TestOut);
  180.       Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out));
  181.       TestHash.Free;
  182.   {$ELSE}
  183.     {$IFDEF DIGEST160}
  184.       const
  185.         Test1Out: array[0..19] of byte=
  186.           ($5E,$16,$10,$FC,$ED,$1D,$3A,$DB,$0B,$B1,
  187.            $8E,$92,$AC,$2B,$11,$F0,$BD,$99,$D8,$ED);
  188.       var
  189.         TestHash: TDCP_haval;
  190.         TestOut: array[0..19] of byte;
  191.       begin
  192.         TestHash:= TDCP_haval.Create(nil);
  193.         TestHash.Init;
  194.         TestHash.UpdateStr('a');
  195.         TestHash.Final(TestOut);
  196.         Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out));
  197.         TestHash.Free;
  198.     {$ELSE}
  199.       begin
  200.         Result:= true;
  201.     {$ENDIF}
  202.   {$ENDIF}
  203. {$ELSE}
  204.   {$IFDEF PASS4}
  205.     {$IFDEF DIGEST192}
  206.       const
  207.         Test1Out: array[0..23] of byte=
  208.           ($74,$AA,$31,$18,$2F,$F0,$9B,$CC,$E4,$53,$A7,$F7,
  209.            $1B,$5A,$7C,$5E,$80,$87,$2F,$A9,$0C,$D9,$3A,$E4);
  210.       var
  211.         TestHash: TDCP_haval;
  212.         TestOut: array[0..23] of byte;
  213.       begin
  214.         TestHash:= TDCP_haval.Create(nil);
  215.         TestHash.Init;
  216.         TestHash.UpdateStr('HAVAL');
  217.         TestHash.Final(TestOut);
  218.         Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out));
  219.         TestHash.Free;
  220.     {$ELSE}
  221.       {$IFDEF DIGEST224}
  222.         const
  223.           Test1Out: array[0..27] of byte=
  224.             ($14,$4C,$B2,$DE,$11,$F0,$5D,$F7,$C3,$56,$28,$2A,$3B,$48,
  225.              $57,$96,$DA,$65,$3F,$6B,$70,$28,$68,$C7,$DC,$F4,$AE,$76);
  226.         var
  227.           TestHash: TDCP_haval;
  228.           TestOut: array[0..27] of byte;
  229.         begin
  230.           TestHash:= TDCP_haval.Create(nil);
  231.           TestHash.Init;
  232.           TestHash.UpdateStr('0123456789');
  233.           TestHash.Final(TestOut);
  234.           Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out));
  235.           TestHash.Free;
  236.       {$ELSE}
  237.         begin
  238.           Result:= true;
  239.       {$ENDIF}
  240.     {$ENDIF}
  241.   {$ELSE}
  242.     {$IFDEF DIGEST256}
  243.       const
  244.         Test1Out: array[0..31] of byte=
  245.           ($1A,$1D,$C8,$09,$9B,$DA,$A7,$F3,$5B,$4D,$A4,$E8,$05,$F1,$A2,$8F,
  246.            $EE,$90,$9D,$8D,$EE,$92,$01,$98,$18,$5C,$BC,$AE,$D8,$A1,$0A,$8D);
  247.         Test2Out: array[0..31] of byte=
  248.           ($C5,$64,$7F,$C6,$C1,$87,$7F,$FF,$96,$74,$2F,$27,$E9,$26,$6B,$68,
  249.            $74,$89,$4F,$41,$A0,$8F,$59,$13,$03,$3D,$9D,$53,$2A,$ED,$DB,$39);
  250.       var
  251.         TestHash: TDCP_haval;
  252.         TestOut: array[0..31] of byte;
  253.       begin
  254.         TestHash:= TDCP_haval.Create(nil);
  255.         TestHash.Init;
  256.         TestHash.UpdateStr('abcdefghijklmnopqrstuvwxyz');
  257.         TestHash.Final(TestOut);
  258.         Result:= CompareMem(@TestOut,@Test1Out,Sizeof(Test1Out));
  259.         TestHash.Init;
  260.         TestHash.UpdateStr('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789');
  261.         TestHash.Final(TestOut);
  262.         Result:= CompareMem(@TestOut,@Test2Out,Sizeof(Test2Out)) and Result;
  263.         TestHash.Free;
  264.     {$ELSE}
  265.       begin
  266.         Result:= true;
  267.     {$ENDIF}
  268.   {$ENDIF}
  269. {$ENDIF}
  270. end;
  271.  
  272. procedure TDCP_haval.Init;
  273. begin
  274.   Burn;
  275.   CurrentHash[0]:= $243F6A88;
  276.   CurrentHash[1]:= $85A308D3;
  277.   CurrentHash[2]:= $13198A2E;
  278.   CurrentHash[3]:= $03707344;
  279.   CurrentHash[4]:= $A4093822;
  280.   CurrentHash[5]:= $299F31D0;
  281.   CurrentHash[6]:= $082EFA98;
  282.   CurrentHash[7]:= $EC4E6C89;
  283.   fInitialized:= true;
  284. end;
  285.  
  286. procedure TDCP_haval.Burn;
  287. begin
  288.   LenHi:= 0; LenLo:= 0;
  289.   Index:= 0;
  290.   FillChar(HashBuffer,Sizeof(HashBuffer),0);
  291.   FillChar(CurrentHash,Sizeof(CurrentHash),0);
  292.   fInitialized:= false;
  293. end;
  294.  
  295. procedure TDCP_haval.Update(const Buffer; Size: longword);
  296. var
  297.   PBuf: ^byte;
  298. begin
  299.   if not fInitialized then
  300.     raise EDCP_hash.Create('Hash not initialized');
  301.  
  302.   Inc(LenHi,Size shr 29);
  303.   Inc(LenLo,Size*8);
  304.   if LenLo< (Size*8) then
  305.     Inc(LenHi);
  306.  
  307.   PBuf:= @Buffer;
  308.   while Size> 0 do
  309.   begin
  310.     if (Sizeof(HashBuffer)-Index)<= DWord(Size) then
  311.     begin
  312.       Move(PBuf^,HashBuffer[Index],Sizeof(HashBuffer)-Index);
  313.       Dec(Size,Sizeof(HashBuffer)-Index);
  314.       Inc(PBuf,Sizeof(HashBuffer)-Index);
  315.       Compress;
  316.     end
  317.     else
  318.     begin
  319.       Move(PBuf^,HashBuffer[Index],Size);
  320.       Inc(Index,Size);
  321.       Size:= 0;
  322.     end;
  323.   end;
  324. end;
  325.  
  326. procedure TDCP_haval.Final(var Digest);
  327. {$IFNDEF DIGEST256}
  328.   {$IFNDEF DIGEST224}
  329.     var
  330.       temp: dword;
  331.   {$ENDIF}
  332. {$ENDIF}
  333. begin
  334.   if not fInitialized then
  335.     raise EDCP_hash.Create('Hash not initialized');
  336.   HashBuffer[Index]:= $80;
  337.   if Index>= 118 then
  338.     Compress;
  339. {$IFDEF PASS3}
  340.   {$IFDEF DIGEST128}
  341.     HashBuffer[118]:= ((128 and 3) shl 6) or (3 shl 3) or 1;
  342.     HashBuffer[119]:= (128 shr 2) and $FF;
  343.   {$ELSE}
  344.     {$IFDEF DIGEST160}
  345.       HashBuffer[118]:= ((160 and 3) shl 6) or (3 shl 3) or 1;
  346.       HashBuffer[119]:= (160 shr 2) and $FF;
  347.     {$ELSE}
  348.       {$IFDEF DIGEST192}
  349.         HashBuffer[118]:= ((192 and 3) shl 6) or (3 shl 3) or 1;
  350.         HashBuffer[119]:= (192 shr 2) and $FF;
  351.       {$ELSE}
  352.         {$IFDEF DIGEST224}
  353.           HashBuffer[118]:= ((224 and 3) shl 6) or (3 shl 3) or 1;
  354.           HashBuffer[119]:= (224 shr 2) and $FF;
  355.         {$ELSE}
  356.           HashBuffer[118]:= ((256 and 3) shl 6) or (3 shl 3) or 1;
  357.           HashBuffer[119]:= (256 shr 2) and $FF;
  358.         {$ENDIF}
  359.       {$ENDIF}
  360.     {$ENDIF}
  361.   {$ENDIF}
  362. {$ELSE}
  363.   {$IFDEF PASS4}
  364.     {$IFDEF DIGEST128}
  365.       HashBuffer[118]:= ((128 and 3) shl 6) or (4 shl 3) or 1;
  366.       HashBuffer[119]:= (128 shr 2) and $FF;
  367.     {$ELSE}
  368.       {$IFDEF DIGEST160}
  369.         HashBuffer[118]:= ((160 and 3) shl 6) or (4 shl 3) or 1;
  370.         HashBuffer[119]:= (160 shr 2) and $FF;
  371.       {$ELSE}
  372.         {$IFDEF DIGEST192}
  373.           HashBuffer[118]:= ((192 and 3) shl 6) or (4 shl 3) or 1;
  374.           HashBuffer[119]:= (192 shr 2) and $FF;
  375.         {$ELSE}
  376.           {$IFDEF DIGEST224}
  377.             HashBuffer[118]:= ((224 and 3) shl 6) or (4 shl 3) or 1;
  378.             HashBuffer[119]:= (224 shr 2) and $FF;
  379.           {$ELSE}
  380.             HashBuffer[118]:= ((256 and 3) shl 6) or (4 shl 3) or 1;
  381.             HashBuffer[119]:= (256 shr 2) and $FF;
  382.           {$ENDIF}
  383.         {$ENDIF}
  384.       {$ENDIF}
  385.     {$ENDIF}
  386.   {$ELSE}
  387.     {$IFDEF DIGEST128}
  388.       HashBuffer[118]:= ((128 and 3) shl 6) or (5 shl 3) or 1;
  389.       HashBuffer[119]:= (2128 shr 2) and $FF;
  390.     {$ELSE}
  391.       {$IFDEF DIGEST160}
  392.         HashBuffer[118]:= ((160 and 3) shl 6) or (5 shl 3) or 1;
  393.         HashBuffer[119]:= (160 shr 2) and $FF;
  394.       {$ELSE}
  395.         {$IFDEF DIGEST192}
  396.           HashBuffer[118]:= ((192 and 3) shl 6) or (5 shl 3) or 1;
  397.           HashBuffer[119]:= (192 shr 2) and $FF;
  398.         {$ELSE}
  399.           {$IFDEF DIGEST224}
  400.             HashBuffer[118]:= ((224 and 3) shl 6) or (5 shl 3) or 1;
  401.             HashBuffer[119]:= (224 shr 2) and $FF;
  402.           {$ELSE}
  403.             HashBuffer[118]:= ((256 and 3) shl 6) or (5 shl 3) or 1;
  404.             HashBuffer[119]:= (256 shr 2) and $FF;
  405.           {$ENDIF}
  406.         {$ENDIF}
  407.       {$ENDIF}
  408.     {$ENDIF}
  409.   {$ENDIF}
  410. {$ENDIF}
  411.   PDWord(@HashBuffer[120])^:= LenLo;
  412.   PDWord(@HashBuffer[124])^:= LenHi;
  413.   Compress;
  414. {$IFDEF DIGEST128}
  415.   temp:= (CurrentHash[7] and $000000FF) or
  416.          (CurrentHash[6] and $FF000000) or
  417.          (CurrentHash[5] and $00FF0000) or
  418.          (CurrentHash[4] and $0000FF00);
  419.   Inc(CurrentHash[0],(temp shr 8) or (temp shl 24));
  420.   temp:= (CurrentHash[7] and $0000FF00) or
  421.          (CurrentHash[6] and $000000FF) or
  422.          (CurrentHash[5] and $FF000000) or
  423.          (CurrentHash[4] and $00FF0000);
  424.   Inc(CurrentHash[1],(temp shr 16) or (temp shl 16));
  425.   temp:= (CurrentHash[7] and $00FF0000) or
  426.          (CurrentHash[6] and $0000FF00) or
  427.          (CurrentHash[5] and $000000FF) or
  428.          (CurrentHash[4] and $FF000000);
  429.   Inc(CurrentHash[2],(temp shr 24) or (temp shl 8));
  430.   temp:= (CurrentHash[7] and $FF000000) or
  431.          (CurrentHash[6] and $00FF0000) or
  432.          (CurrentHash[5] and $0000FF00) or
  433.          (CurrentHash[4] and $000000FF);
  434.   Inc(CurrentHash[3],temp);
  435.   Move(CurrentHash,Digest,128 div 8);
  436. {$ELSE}
  437.   {$IFDEF DIGEST160}
  438.     temp:= (CurrentHash[7] and $3F) or
  439.            (CurrentHash[6] and ($7F shl 25)) or
  440.            (CurrentHash[5] and ($3F shl 19));
  441.     Inc(CurrentHash[0],(temp shr 19) or (temp shl 13));
  442.     temp:= (CurrentHash[7] and ($3F shl 6)) or
  443.            (CurrentHash[6] and $3F) or
  444.            (CurrentHash[5] and ($7F shl 25));
  445.     Inc(CurrentHash[1],(temp shr 25) or (temp shl 7));
  446.     temp:= (CurrentHash[7] and ($7F shl 12)) or
  447.            (CurrentHash[6] and ($3F shl 6)) or
  448.            (CurrentHash[5] and $3F);
  449.     Inc(CurrentHash[2],temp);
  450.     temp:= (CurrentHash[7] and ($3F shl 19)) or
  451.            (CurrentHash[6] and ($7F shl 12)) or
  452.            (CurrentHash[5] and ($3F shl 6));
  453.     Inc(CurrentHash[3],temp shr 6);
  454.     temp:= (CurrentHash[7] and ($7F shl 25)) or
  455.            (CurrentHash[6] and ($3F shl 19)) or
  456.            (CurrentHash[5] and ($7F shl 12));
  457.     Inc(CurrentHash[4],temp shr 12);
  458.     Move(CurrentHash,Digest,160 div 8);
  459.   {$ELSE}
  460.     {$IFDEF DIGEST192}
  461.       temp:= (CurrentHash[7] and $1F) or
  462.              (CurrentHash[6] and ($3F shl 26));
  463.       Inc(CurrentHash[0],(temp shr 26) or (temp shl 6));
  464.       temp:= (CurrentHash[7] and ($1F shl 5)) or
  465.              (CurrentHash[6] and $1F);
  466.       Inc(CurrentHash[1],temp);
  467.       temp:= (CurrentHash[7] and ($3F shl 10)) or
  468.              (CurrentHash[6] and ($1F shl 5));
  469.       Inc(CurrentHash[2],temp shr 5);
  470.       temp:= (CurrentHash[7] and ($1F shl 16)) or
  471.              (CurrentHash[6] and ($3F shl 10));
  472.       Inc(CurrentHash[3],temp shr 10);
  473.       temp:= (CurrentHash[7] and ($1F shl 21)) or
  474.              (CurrentHash[6] and ($1F shl 16));
  475.       Inc(CurrentHash[4],temp shr 16);
  476.       temp:= (CurrentHash[7] and ($3F shl 26)) or
  477.              (CurrentHash[6] and ($1F shl 21));
  478.       Inc(CurrentHash[5],temp shr 21);
  479.       Move(CurrentHash,Digest,192 div 8);
  480.     {$ELSE}
  481.       {$IFDEF DIGEST224}
  482.         Inc(CurrentHash[0],(CurrentHash[7] shr 27) and $1F);
  483.         Inc(CurrentHash[1],(CurrentHash[7] shr 22) and $1F);
  484.         Inc(CurrentHash[2],(CurrentHash[7] shr 18) and $F);
  485.         Inc(CurrentHash[3],(CurrentHash[7] shr 13) and $1F);
  486.         Inc(CurrentHash[4],(CurrentHash[7] shr 9) and $F);
  487.         Inc(CurrentHash[5],(CurrentHash[7] shr 4) and $1F);
  488.         Inc(CurrentHash[6],CurrentHash[7] and $F);
  489.         Move(CurrentHash,Digest,224 div 8);
  490.       {$ELSE}
  491.         Move(CurrentHash,Digest,256 div 8);
  492.       {$ENDIF}
  493.     {$ENDIF}
  494.   {$ENDIF}
  495. {$ENDIF}
  496.   Burn;
  497. end;
  498.  
  499. end.
  500.