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

  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
  3. {******************************************************************************}
  4. {* A binary compatible implementation of Blowfish *****************************}
  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 DCPblowfish;
  26.  
  27. interface
  28. uses
  29.   Classes, Sysutils, DCPcrypt2, DCPconst, DCPblockciphers;
  30.  
  31. type
  32.   TDCP_blowfish= class(TDCP_blockcipher64)
  33.   protected
  34.     SBox: array[0..3,0..255] of DWord;
  35.     PBox: array[0..17] of DWord;
  36.     procedure InitKey(const Key; Size: longword); override;
  37.   public
  38.     class function GetId: integer; override;
  39.     class function GetAlgorithm: string; override;
  40.     class function GetMaxKeySize: integer; override;
  41.     class function SelfTest: boolean; override;
  42.     procedure Burn; override;
  43.     procedure EncryptECB(const InData; var OutData); override;
  44.     procedure DecryptECB(const InData; var OutData); override;
  45.   end;
  46.  
  47.  
  48. {******************************************************************************}
  49. {******************************************************************************}
  50. implementation
  51. {$R-}{$Q-}
  52. {$I DCPblowfish.inc}
  53.  
  54. class function TDCP_blowfish.GetID: integer;
  55. begin
  56.   Result:= DCP_blowfish;
  57. end;
  58.  
  59. class function TDCP_blowfish.GetAlgorithm: string;
  60. begin
  61.   Result:= 'Blowfish';
  62. end;
  63.  
  64. class function TDCP_blowfish.GetMaxKeySize: integer;
  65. begin
  66.   Result:= 448;
  67. end;
  68.  
  69. class function TDCP_blowfish.SelfTest: boolean;
  70. const
  71.   Key1: array[0..7] of byte= ($00,$00,$00,$00,$00,$00,$00,$00);
  72.   Key2: array[0..7] of byte= ($7C,$A1,$10,$45,$4A,$1A,$6E,$57);
  73.   InData1: array[0..7] of byte= ($00,$00,$00,$00,$00,$00,$00,$00);
  74.   InData2: array[0..7] of byte= ($01,$A1,$D6,$D0,$39,$77,$67,$42);
  75.   OutData1: array[0..7] of byte= ($4E,$F9,$97,$45,$61,$98,$DD,$78);
  76.   OutData2: array[0..7] of byte= ($59,$C6,$82,$45,$EB,$05,$28,$2B);
  77. var
  78.   Cipher: TDCP_blowfish;
  79.   Data: array[0..7] of byte;
  80. begin
  81.   Cipher:= TDCP_blowfish.Create(nil);
  82.   Cipher.Init(Key1,Sizeof(Key1)*8,nil);
  83.   Cipher.EncryptECB(InData1,Data);
  84.   Result:= boolean(CompareMem(@Data,@OutData1,Sizeof(Data)));
  85.   Cipher.Reset;
  86.   Cipher.DecryptECB(Data,Data);
  87.   Result:= boolean(CompareMem(@Data,@InData1,Sizeof(Data))) and Result;
  88.   Cipher.Burn;
  89.   Cipher.Init(Key2,Sizeof(Key2)*8,nil);
  90.   Cipher.EncryptECB(InData2,Data);
  91.   Result:= boolean(CompareMem(@Data,@OutData2,Sizeof(Data))) and Result;
  92.   Cipher.Reset;
  93.   Cipher.DecryptECB(Data,Data);
  94.   Result:= boolean(CompareMem(@Data,@InData2,Sizeof(Data))) and Result;
  95.   Cipher.Burn;
  96.   Cipher.Free;
  97. end;
  98.  
  99. procedure TDCP_blowfish.InitKey(const Key; Size: longword);
  100. var
  101.   i, k: longword;
  102.   A: DWord;
  103.   KeyB: PByteArray;
  104.   Block: array[0..7] of byte;
  105. begin
  106.   Size:= Size div 8;
  107.   KeyB:= @Key;
  108.   Move(SBoxOrg,SBox,Sizeof(SBox));
  109.   Move(PBoxOrg,PBox,Sizeof(PBox));
  110.   k:= 0;
  111.   for i:= 0 to 17 do
  112.   begin
  113.     A:= dword(KeyB^[(k+3) mod Size]);
  114.     A:= A + (dword(KeyB^[(k+2) mod Size]) shl 8);
  115.     A:= A + (dword(KeyB^[(k+1) mod Size]) shl 16);
  116.     A:= A + (dword(KeyB^[k]) shl 24);
  117.     PBox[i]:= PBox[i] xor A;
  118.     k:= (k+4) mod Size;
  119.   end;
  120.   FillChar(Block,Sizeof(Block),0);
  121.   for i:= 0 to 8 do
  122.   begin
  123.     EncryptECB(Block,Block);
  124.     PBox[i*2]:= dword(Block[3]) + (dword(Block[2]) shl 8) + (dword(Block[1]) shl 16) + (dword(Block[0]) shl 24);
  125.     PBox[i*2+1]:= dword(Block[7]) + (dword(Block[6]) shl 8) + (dword(Block[5]) shl 16) + (dword(Block[4]) shl 24);
  126.   end;
  127.   for k:= 0 to 3 do
  128.   begin
  129.     for i:= 0 to 127 do
  130.     begin
  131.       EncryptECB(Block,Block);
  132.       SBox[k,i*2]:= dword(Block[3]) + (dword(Block[2]) shl 8) + (dword(Block[1]) shl 16) + (dword(Block[0]) shl 24);
  133.       SBox[k,i*2+1]:= dword(Block[7]) + (dword(Block[6]) shl 8) + (dword(Block[5]) shl 16) + (dword(Block[4]) shl 24);
  134.     end;
  135.   end;
  136. end;
  137.  
  138. procedure TDCP_blowfish.Burn;
  139. begin
  140.   FillChar(SBox,Sizeof(SBox),$FF);
  141.   FillChar(PBox,Sizeof(PBox),$FF);
  142.   inherited Burn;
  143. end;
  144.  
  145. procedure TDCP_blowfish.EncryptECB(const InData; var OutData);
  146. var
  147.   xL, xR: DWord;
  148. begin
  149.   if not fInitialized then
  150.     raise EDCP_blockcipher.Create('Cipher not initialized');
  151.   xL:= Pdword(@InData)^;
  152.   xR:= Pdword(longword(@InData)+4)^;
  153.   xL:= ((xL and $FF) shl 24) or ((xL and $FF00) shl 8) or ((xL and $FF0000) shr 8) or ((xL and $FF000000) shr 24);
  154.   xR:= ((xR and $FF) shl 24) or ((xR and $FF00) shl 8) or ((xR and $FF0000) shr 8) or ((xR and $FF000000) shr 24);
  155.   xL:= xL xor PBox[0];
  156.   xR:= xR xor (((SBox[0,(xL shr 24) and $FF] + SBox[1,(xL shr 16) and $FF]) xor
  157.     SBox[2,(xL shr 8) and $FF]) + SBox[3,xL and $FF]) xor PBox[1];
  158.   xL:= xL xor (((SBox[0,(xR shr 24) and $FF] + SBox[1,(xR shr 16) and $FF]) xor
  159.     SBox[2,(xR shr 8) and $FF]) + SBox[3,xR and $FF]) xor PBox[2];
  160.   xR:= xR xor (((SBox[0,(xL shr 24) and $FF] + SBox[1,(xL shr 16) and $FF]) xor
  161.     SBox[2,(xL shr 8) and $FF]) + SBox[3,xL and $FF]) xor PBox[3];
  162.   xL:= xL xor (((SBox[0,(xR shr 24) and $FF] + SBox[1,(xR shr 16) and $FF]) xor
  163.     SBox[2,(xR shr 8) and $FF]) + SBox[3,xR and $FF]) xor PBox[4];
  164.   xR:= xR xor (((SBox[0,(xL shr 24) and $FF] + SBox[1,(xL shr 16) and $FF]) xor
  165.     SBox[2,(xL shr 8) and $FF]) + SBox[3,xL and $FF]) xor PBox[5];
  166.   xL:= xL xor (((SBox[0,(xR shr 24) and $FF] + SBox[1,(xR shr 16) and $FF]) xor
  167.     SBox[2,(xR shr 8) and $FF]) + SBox[3,xR and $FF]) xor PBox[6];
  168.   xR:= xR xor (((SBox[0,(xL shr 24) and $FF] + SBox[1,(xL shr 16) and $FF]) xor
  169.     SBox[2,(xL shr 8) and $FF]) + SBox[3,xL and $FF]) xor PBox[7];
  170.   xL:= xL xor (((SBox[0,(xR shr 24) and $FF] + SBox[1,(xR shr 16) and $FF]) xor
  171.     SBox[2,(xR shr 8) and $FF]) + SBox[3,xR and $FF]) xor PBox[8];
  172.   xR:= xR xor (((SBox[0,(xL shr 24) and $FF] + SBox[1,(xL shr 16) and $FF]) xor
  173.     SBox[2,(xL shr 8) and $FF]) + SBox[3,xL and $FF]) xor PBox[9];
  174.   xL:= xL xor (((SBox[0,(xR shr 24) and $FF] + SBox[1,(xR shr 16) and $FF]) xor
  175.     SBox[2,(xR shr 8) and $FF]) + SBox[3,xR and $FF]) xor PBox[10];
  176.   xR:= xR xor (((SBox[0,(xL shr 24) and $FF] + SBox[1,(xL shr 16) and $FF]) xor
  177.     SBox[2,(xL shr 8) and $FF]) + SBox[3,xL and $FF]) xor PBox[11];
  178.   xL:= xL xor (((SBox[0,(xR shr 24) and $FF] + SBox[1,(xR shr 16) and $FF]) xor
  179.     SBox[2,(xR shr 8) and $FF]) + SBox[3,xR and $FF]) xor PBox[12];
  180.   xR:= xR xor (((SBox[0,(xL shr 24) and $FF] + SBox[1,(xL shr 16) and $FF]) xor
  181.     SBox[2,(xL shr 8) and $FF]) + SBox[3,xL and $FF]) xor PBox[13];
  182.   xL:= xL xor (((SBox[0,(xR shr 24) and $FF] + SBox[1,(xR shr 16) and $FF]) xor
  183.     SBox[2,(xR shr 8) and $FF]) + SBox[3,xR and $FF]) xor PBox[14];
  184.   xR:= xR xor (((SBox[0,(xL shr 24) and $FF] + SBox[1,(xL shr 16) and $FF]) xor
  185.     SBox[2,(xL shr 8) and $FF]) + SBox[3,xL and $FF]) xor PBox[15];
  186.   xL:= xL xor (((SBox[0,(xR shr 24) and $FF] + SBox[1,(xR shr 16) and $FF]) xor
  187.     SBox[2,(xR shr 8) and $FF]) + SBox[3,xR and $FF]) xor PBox[16];
  188.   xR:= xR xor PBox[17];
  189.   xL:= ((xL and $FF) shl 24) or ((xL and $FF00) shl 8) or ((xL and $FF0000) shr 8) or ((xL and $FF000000) shr 24);
  190.   xR:= ((xR and $FF) shl 24) or ((xR and $FF00) shl 8) or ((xR and $FF0000) shr 8) or ((xR and $FF000000) shr 24);
  191.   Pdword(@OutData)^:= xR;
  192.   Pdword(longword(@OutData)+4)^:= xL;
  193. end;
  194.  
  195. procedure TDCP_blowfish.DecryptECB(const InData; var OutData);
  196. var
  197.   xL, xR: DWord;
  198. begin
  199.   if not fInitialized then
  200.     raise EDCP_blockcipher.Create('Cipher not initialized');
  201.   xL:= Pdword(@InData)^;
  202.   xR:= Pdword(longword(@InData)+4)^;
  203.   xL:= (xL shr 24) or ((xL shr 8) and $FF00) or ((xL shl 8) and $FF0000) or (xL shl 24);
  204.   xR:= (xR shr 24) or ((xR shr 8) and $FF00) or ((xR shl 8) and $FF0000) or (xR shl 24);
  205.   xL:= xL xor PBox[17];
  206.   xR:= xR xor (((SBox[0,(xL shr 24) and $FF] + SBox[1,(xL shr 16) and $FF]) xor
  207.     SBox[2,(xL shr 8) and $FF]) + SBox[3,xL and $FF]) xor PBox[16];
  208.   xL:= xL xor (((SBox[0,(xR shr 24) and $FF] + SBox[1,(xR shr 16) and $FF]) xor
  209.     SBox[2,(xR shr 8) and $FF]) + SBox[3,xR and $FF]) xor PBox[15];
  210.   xR:= xR xor (((SBox[0,(xL shr 24) and $FF] + SBox[1,(xL shr 16) and $FF]) xor
  211.     SBox[2,(xL shr 8) and $FF]) + SBox[3,xL and $FF]) xor PBox[14];
  212.   xL:= xL xor (((SBox[0,(xR shr 24) and $FF] + SBox[1,(xR shr 16) and $FF]) xor
  213.     SBox[2,(xR shr 8) and $FF]) + SBox[3,xR and $FF]) xor PBox[13];
  214.   xR:= xR xor (((SBox[0,(xL shr 24) and $FF] + SBox[1,(xL shr 16) and $FF]) xor
  215.     SBox[2,(xL shr 8) and $FF]) + SBox[3,xL and $FF]) xor PBox[12];
  216.   xL:= xL xor (((SBox[0,(xR shr 24) and $FF] + SBox[1,(xR shr 16) and $FF]) xor
  217.     SBox[2,(xR shr 8) and $FF]) + SBox[3,xR and $FF]) xor PBox[11];
  218.   xR:= xR xor (((SBox[0,(xL shr 24) and $FF] + SBox[1,(xL shr 16) and $FF]) xor
  219.     SBox[2,(xL shr 8) and $FF]) + SBox[3,xL and $FF]) xor PBox[10];
  220.   xL:= xL xor (((SBox[0,(xR shr 24) and $FF] + SBox[1,(xR shr 16) and $FF]) xor
  221.     SBox[2,(xR shr 8) and $FF]) + SBox[3,xR and $FF]) xor PBox[9];
  222.   xR:= xR xor (((SBox[0,(xL shr 24) and $FF] + SBox[1,(xL shr 16) and $FF]) xor
  223.     SBox[2,(xL shr 8) and $FF]) + SBox[3,xL and $FF]) xor PBox[8];
  224.   xL:= xL xor (((SBox[0,(xR shr 24) and $FF] + SBox[1,(xR shr 16) and $FF]) xor
  225.     SBox[2,(xR shr 8) and $FF]) + SBox[3,xR and $FF]) xor PBox[7];
  226.   xR:= xR xor (((SBox[0,(xL shr 24) and $FF] + SBox[1,(xL shr 16) and $FF]) xor
  227.     SBox[2,(xL shr 8) and $FF]) + SBox[3,xL and $FF]) xor PBox[6];
  228.   xL:= xL xor (((SBox[0,(xR shr 24) and $FF] + SBox[1,(xR shr 16) and $FF]) xor
  229.     SBox[2,(xR shr 8) and $FF]) + SBox[3,xR and $FF]) xor PBox[5];
  230.   xR:= xR xor (((SBox[0,(xL shr 24) and $FF] + SBox[1,(xL shr 16) and $FF]) xor
  231.     SBox[2,(xL shr 8) and $FF]) + SBox[3,xL and $FF]) xor PBox[4];
  232.   xL:= xL xor (((SBox[0,(xR shr 24) and $FF] + SBox[1,(xR shr 16) and $FF]) xor
  233.     SBox[2,(xR shr 8) and $FF]) + SBox[3,xR and $FF]) xor PBox[3];
  234.   xR:= xR xor (((SBox[0,(xL shr 24) and $FF] + SBox[1,(xL shr 16) and $FF]) xor
  235.     SBox[2,(xL shr 8) and $FF]) + SBox[3,xL and $FF]) xor PBox[2];
  236.   xL:= xL xor (((SBox[0,(xR shr 24) and $FF] + SBox[1,(xR shr 16) and $FF]) xor
  237.     SBox[2,(xR shr 8) and $FF]) + SBox[3,xR and $FF]) xor PBox[1];
  238.   xR:= xR xor PBox[0];
  239.   xL:= (xL shr 24) or ((xL shr 8) and $FF00) or ((xL shl 8) and $FF0000) or (xL shl 24);
  240.   xR:= (xR shr 24) or ((xR shr 8) and $FF00) or ((xR shl 8) and $FF0000) or (xR shl 24);
  241.   Pdword(@OutData)^:= xR;
  242.   Pdword(longword(@OutData)+4)^:= xL;
  243. end;
  244.  
  245. end.
  246.