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

  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
  3. {******************************************************************************}
  4. {* A binary compatible implementation of RC6 **********************************}
  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 DCPrc6;
  26.  
  27. interface
  28. uses
  29.   Classes, Sysutils, DCPcrypt2, DCPconst, DCPblockciphers;
  30.  
  31. const
  32.   NUMROUNDS= 20; { number of rounds must be between 16-24 }
  33.  
  34. type
  35.   TDCP_rc6= class(TDCP_blockcipher128)
  36.   protected
  37.     KeyData: array[0..((NUMROUNDS*2)+3)] 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..51] 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,$BB3F7BF5,$5976F5AE,
  63.     $F7AE6F67,$95E5E920,$341D62D9,$D254DC92,$708C564B,$0EC3D004,
  64.     $ACFB49BD,$4B32C376,$E96A3D2F,$87A1B6E8,$25D930A1,$C410AA5A,
  65.     $62482413,$007F9DCC,$9EB71785,$3CEE913E);
  66.  
  67.  
  68. function LRot32(X: DWord; c: longword): DWord;
  69. begin
  70.   LRot32:= (X shl c) or (X shr (32 - c));
  71. end;
  72.  
  73. function RRot32(X: DWord; c: longword): DWord;
  74. begin
  75.   RRot32:= (X shr c) or (X shl (32 - c));
  76. end;
  77.  
  78. class function TDCP_rc6.GetID: integer;
  79. begin
  80.   Result:= DCP_rc6;
  81. end;
  82.  
  83. class function TDCP_rc6.GetAlgorithm: string;
  84. begin
  85.   Result:= 'RC6';
  86. end;
  87.  
  88. class function TDCP_rc6.GetMaxKeySize: integer;
  89. begin
  90.   Result:= 2048;
  91. end;
  92.  
  93. class function TDCP_rc6.SelfTest: boolean;
  94. const
  95.   Key1: array[0..15] of byte=
  96.     ($01,$23,$45,$67,$89,$ab,$cd,$ef,$01,$12,$23,$34,$45,$56,$67,$78);
  97.   Plain1: array[0..15] of byte=
  98.     ($02,$13,$24,$35,$46,$57,$68,$79,$8a,$9b,$ac,$bd,$ce,$df,$e0,$f1);
  99.   Cipher1: array[0..15] of byte=
  100.     ($52,$4e,$19,$2f,$47,$15,$c6,$23,$1f,$51,$f6,$36,$7e,$a4,$3f,$18);
  101.   Key2: array[0..31] of byte=
  102.     ($01,$23,$45,$67,$89,$ab,$cd,$ef,$01,$12,$23,$34,$45,$56,$67,$78,
  103.      $89,$9a,$ab,$bc,$cd,$de,$ef,$f0,$10,$32,$54,$76,$98,$ba,$dc,$fe);
  104.   Plain2: array[0..15] of byte=
  105.     ($02,$13,$24,$35,$46,$57,$68,$79,$8a,$9b,$ac,$bd,$ce,$df,$e0,$f1);
  106.   Cipher2: array[0..15] of byte=
  107.     ($c8,$24,$18,$16,$f0,$d7,$e4,$89,$20,$ad,$16,$a1,$67,$4e,$5d,$48);
  108. var
  109.   Cipher: TDCP_rc6;
  110.   Data: array[0..15] of byte;
  111. begin
  112.   Cipher:= TDCP_rc6.Create(nil);
  113.   Cipher.Init(Key1,Sizeof(Key1)*8,nil);
  114.   Cipher.EncryptECB(Plain1,Data);
  115.   Result:= boolean(CompareMem(@Data,@Cipher1,Sizeof(Data)));
  116.   Cipher.DecryptECB(Data,Data);
  117.   Result:= Result and boolean(CompareMem(@Data,@Plain1,Sizeof(Data)));
  118.   Cipher.Burn;
  119.   Cipher.Init(Key2,Sizeof(Key2)*8,nil);
  120.   Cipher.EncryptECB(Plain2,Data);
  121.   Result:= Result and boolean(CompareMem(@Data,@Cipher2,Sizeof(Data)));
  122.   Cipher.DecryptECB(Data,Data);
  123.   Result:= Result and boolean(CompareMem(@Data,@Plain2,Sizeof(Data)));
  124.   Cipher.Burn;
  125.   Cipher.Free;
  126. end;
  127.  
  128. procedure TDCP_rc6.InitKey(const Key; Size: longword);
  129. var
  130.   xKeyD: array[0..63] of DWord;
  131.   i, j, k, xKeyLen: longword;
  132.   A, B: DWord;
  133. begin
  134.   Size:= Size div 8;
  135.   FillChar(xKeyD,Sizeof(xKeyD),0);
  136.   Move(Key,xKeyD,Size);
  137.   xKeyLen:= Size div 4;
  138.   if (Size mod 4)<> 0 then
  139.     Inc(xKeyLen);
  140.   Move(sBox,KeyData,((NUMROUNDS*2)+4)*4);
  141.   i:= 0; j:= 0;
  142.   A:= 0; B:= 0;
  143.   if xKeyLen> ((NUMROUNDS*2)+4) then
  144.     k:= xKeyLen*3
  145.   else
  146.     k:= ((NUMROUNDS*2)+4)*3;
  147.   for k:= 1 to k do
  148.   begin
  149.     A:= LRot32(KeyData[i]+A+B,3);
  150.     KeyData[i]:= A;
  151.     B:= LRot32(xKeyD[j]+A+B,A+B);
  152.     xKeyD[j]:= B;
  153.     i:= (i+1) mod ((NUMROUNDS*2)+4);
  154.     j:= (j+1) mod xKeyLen;
  155.   end;
  156.   FillChar(xKeyD,Sizeof(xKeyD),0);
  157. end;
  158.  
  159. procedure TDCP_rc6.Burn;
  160. begin
  161.   FillChar(KeyData,Sizeof(KeyData),$FF);
  162.   inherited Burn;
  163. end;
  164.  
  165. procedure TDCP_rc6.EncryptECB(const InData; var OutData);
  166. var
  167.   x0, x1, x2, x3: DWord;
  168.   u, t: DWord;
  169.   i: longword;
  170. begin
  171.   if not fInitialized then
  172.     raise EDCP_blockcipher.Create('Cipher not initialized');
  173.   x0:= PDword(@InData)^;
  174.   x1:= PDword(longword(@InData)+4)^;
  175.   x2:= PDword(longword(@InData)+8)^;
  176.   x3:= PDword(longword(@InData)+12)^;
  177.   x1:= x1 + KeyData[0];
  178.   x3:= x3 + KeyData[1];
  179.   for i:= 1 to NUMROUNDS do
  180.   begin
  181.     t:= Lrot32(x1 * (2*x1 + 1),5);
  182.     u:= Lrot32(x3 * (2*x3 + 1),5);
  183.     x0:= Lrot32(x0 xor t,u) + KeyData[2*i];
  184.     x2:= Lrot32(x2 xor u,t) + KeyData[2*i+1];
  185.     t:= x0; x0:= x1; x1:= x2; x2:= x3; x3:= t;
  186.   end;
  187.   x0:= x0 + KeyData[(2*NUMROUNDS)+2];
  188.   x2:= x2 + KeyData[(2*NUMROUNDS)+3];
  189.   PDword(@OutData)^:= x0;
  190.   PDword(longword(@OutData)+4)^:= x1;
  191.   PDword(longword(@OutData)+8)^:= x2;
  192.   PDword(longword(@OutData)+12)^:= x3;
  193. end;
  194.  
  195. procedure TDCP_rc6.DecryptECB(const InData; var OutData);
  196. var
  197.   x0, x1, x2, x3: DWord;
  198.   u, t: DWord;
  199.   i: longword;
  200. begin
  201.   if not fInitialized then
  202.     raise EDCP_blockcipher.Create('Cipher not initialized');
  203.   x0:= PDword(@InData)^;
  204.   x1:= PDword(longword(@InData)+4)^;
  205.   x2:= PDword(longword(@InData)+8)^;
  206.   x3:= PDword(longword(@InData)+12)^;
  207.   x2:= x2 - KeyData[(2*NUMROUNDS)+3];
  208.   x0:= x0 - KeyData[(2*NUMROUNDS)+2];
  209.   for i:= NUMROUNDS downto 1 do
  210.   begin
  211.     t:= x0; x0:= x3; x3:= x2; x2:= x1; x1:= t;
  212.     u:= Lrot32(x3 * (2*x3 + 1),5);
  213.     t:= Lrot32(x1 * (2*x1 + 1),5);
  214.     x2:= Rrot32(x2 - KeyData[2*i+1],t) xor u;
  215.     x0:= Rrot32(x0 - KeyData[2*i],u) xor t;
  216.   end;
  217.   x3:= x3 - KeyData[1];
  218.   x1:= x1 - KeyData[0];
  219.   PDword(@OutData)^:= x0;
  220.   PDword(longword(@OutData)+4)^:= x1;
  221.   PDword(longword(@OutData)+8)^:= x2;
  222.   PDword(longword(@OutData)+12)^:= x3;
  223. end;
  224.  
  225. end.
  226.