home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 December / Chip_2002-12_cd1.bin / ctenari / Hytha / MultiHSH.exe / SR.RAR / SR / DCPCrypt / Ciphers / DCPrc5.pas < prev    next >
Pascal/Delphi Source File  |  2002-07-08  |  7KB  |  201 lines

  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
  3. {******************************************************************************}
  4. {* A binary compatible implementation of RC5 **********************************}
  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 DCPrc5;
  26.  
  27. interface
  28. uses
  29.   Classes, Sysutils, DCPcrypt2, DCPconst, DCPblockciphers;
  30.  
  31. const
  32.   NUMROUNDS= 12;    { number of rounds must be between 12-16 }
  33.  
  34. type
  35.   TDCP_rc5= class(TDCP_blockcipher64)
  36.   protected
  37.     KeyData: array[0..((NUMROUNDS*2)+1)] of DWord;
  38.     procedure InitKey(const Key; Size: longword); override;
  39.   public
  40.     class function GetId: integer; override;
  41.     class function GetAlgorithm: string; override;
  42.     class function GetMaxKeySize: integer; override;
  43.     class function SelfTest: boolean; override;
  44.     procedure Burn; override;
  45.     procedure EncryptECB(const InData; var OutData); override;
  46.     procedure DecryptECB(const InData; var OutData); override;
  47.   end;
  48.  
  49.  
  50. {******************************************************************************}
  51. {******************************************************************************}
  52. implementation
  53. {$R-}{$Q-}
  54.  
  55. const
  56.    sBox: array[0..33] of dword= (
  57.     $B7E15163,$5618CB1C,$F45044D5,$9287BE8E,$30BF3847,$CEF6B200,
  58.     $6D2E2BB9,$0B65A572,$A99D1F2B,$47D498E4,$E60C129D,$84438C56,
  59.     $227B060F,$C0B27FC8,$5EE9F981,$FD21733A,$9B58ECF3,$399066AC,
  60.     $D7C7E065,$75FF5A1E,$1436D3D7,$B26E4D90,$50A5C749,$EEDD4102,
  61.     $8D14BABB,$2B4C3474,$C983AE2D,$67BB27E6,$05F2A19F,$A42A1B58,
  62.     $42619511,$E0990ECA,$7ED08883,$1D08023C);
  63.  
  64. function LRot32(a, b: longword): longword;
  65. begin
  66.   Result:= (a shl b) or (a shr (32-b));
  67. end;
  68.  
  69. function RRot32(a, b: longword): longword;
  70. begin
  71.   Result:= (a shr b) or (a shl (32-b));
  72. end;
  73.  
  74. class function TDCP_rc5.GetID: integer;
  75. begin
  76.   Result:= DCP_rc5;
  77. end;
  78.  
  79. class function TDCP_rc5.GetAlgorithm: string;
  80. begin
  81.   Result:= 'RC5';
  82. end;
  83.  
  84. class function TDCP_rc5.GetMaxKeySize: integer;
  85. begin
  86.   Result:= 2048;
  87. end;
  88.  
  89. class function TDCP_rc5.SelfTest: boolean;
  90. const
  91.   Key1: array[0..15] of byte=
  92.     ($DC,$49,$DB,$13,$75,$A5,$58,$4F,$64,$85,$B4,$13,$B5,$F1,$2B,$AF);
  93.   Plain1: array[0..1] of dword=
  94.     ($B7B3422F,$92FC6903);
  95.   Cipher1: array[0..1] of dword=
  96.     ($B278C165,$CC97D184);
  97.   Key2: array[0..15] of byte=
  98.     ($52,$69,$F1,$49,$D4,$1B,$A0,$15,$24,$97,$57,$4D,$7F,$15,$31,$25);
  99.   Plain2: array[0..1] of dword=
  100.     ($B278C165,$CC97D184);
  101.   Cipher2: array[0..1] of dword=
  102.     ($15E444EB,$249831DA);
  103. var
  104.   Cipher: TDCP_rc5;
  105.   Data: array[0..1] of dword;
  106. begin
  107.   Cipher:= TDCP_rc5.Create(nil);
  108.   Cipher.Init(Key1,Sizeof(Key1)*8,nil);
  109.   Cipher.EncryptECB(Plain1,Data);
  110.   Result:= boolean(CompareMem(@Data,@Cipher1,Sizeof(Data)));
  111.   Cipher.DecryptECB(Data,Data);
  112.   Result:= Result and boolean(CompareMem(@Data,@Plain1,Sizeof(Data)));
  113.   Cipher.Burn;
  114.   Cipher.Init(Key2,Sizeof(Key2)*8,nil);
  115.   Cipher.EncryptECB(Plain2,Data);
  116.   Result:= Result and boolean(CompareMem(@Data,@Cipher2,Sizeof(Data)));
  117.   Cipher.DecryptECB(Data,Data);
  118.   Result:= Result and boolean(CompareMem(@Data,@Plain2,Sizeof(Data)));
  119.   Cipher.Burn;
  120.   Cipher.Free;
  121. end;
  122.  
  123. procedure TDCP_rc5.InitKey(const Key; Size: longword);
  124. var
  125.   xKeyD: array[0..63] of DWord;
  126.   i, j, k, xKeyLen: longword;
  127.   A, B: DWord;
  128. begin
  129.   FillChar(xKeyD,Sizeof(xKeyD),0);
  130.   Size:= Size div 8;
  131.   Move(Key,xKeyD,Size);
  132.   xKeyLen:= Size div 4;
  133.   if (Size mod 4)<> 0 then
  134.     Inc(xKeyLen);
  135.   Move(sBox,KeyData,(NUMROUNDS+1)*8);
  136.   i:= 0; j:= 0;
  137.   A:= 0; B:= 0;
  138.   if xKeyLen> ((NUMROUNDS+1)*2) then
  139.     k:= xKeyLen*3
  140.   else
  141.     k:= (NUMROUNDS+1)*6;
  142.   for k:= k downto 1 do
  143.   begin
  144.     A:= LRot32(KeyData[i]+A+B,3);
  145.     KeyData[i]:= A;
  146.     B:= LRot32(xKeyD[j]+A+B,A+B);
  147.     xKeyD[j]:= B;
  148.     i:= (i+1) mod ((NUMROUNDS+1)*2);
  149.     j:= (j+1) mod xKeyLen;
  150.   end;
  151.   FillChar(xKeyD,Sizeof(xKeyD),0);
  152. end;
  153.  
  154. procedure TDCP_rc5.Burn;
  155. begin
  156.   FillChar(KeyData,Sizeof(KeyData),$FF);
  157.   inherited Burn;
  158. end;
  159.  
  160. procedure TDCP_rc5.EncryptECB(const InData; var OutData);
  161. var
  162.   A, B: DWord;
  163.   i: longword;
  164. begin
  165.   if not fInitialized then
  166.     raise EDCP_blockcipher.Create('Cipher not initialized');
  167.   A:= PDword(@InData)^ + KeyData[0];
  168.   B:= PDword(longword(@InData)+4)^ + KeyData[1];
  169.   for i:= 1 to NUMROUNDS do
  170.   begin
  171.     A:= A xor B;
  172.     A:= LRot32(A,B)+KeyData[2*i];
  173.     B:= B xor A;
  174.     B:= LRot32(B,A)+KeyData[(2*i)+1];
  175.   end;
  176.   PDword(@OutData)^:= A;
  177.   PDword(longword(@OutData)+4)^:= B;
  178. end;
  179.  
  180. procedure TDCP_rc5.DecryptECB(const InData; var OutData);
  181. var
  182.   A, B: DWord;
  183.   i: longword;
  184. begin
  185.   if not fInitialized then
  186.     raise EDCP_blockcipher.Create('Cipher not initialized');
  187.   A:= PDword(@InData)^;
  188.   B:= PDword(longword(@InData)+4)^;
  189.   for i:= NUMROUNDS downto 1 do
  190.   begin
  191.     B:= RRot32(B-KeyData[(2*i)+1],A);
  192.     B:= B xor A;
  193.     A:= RRot32(A-KeyData[2*i],B);
  194.     A:= A xor B;
  195.   end;
  196.   PDword(@OutData)^:= A - KeyData[0];
  197.   PDword(longword(@OutData)+4)^:= B - KeyData[1];
  198. end;
  199.  
  200. end.
  201.