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

  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
  3. {******************************************************************************}
  4. {* A binary compatible implementation of Misty1 *******************************}
  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 DCPmisty1;
  26.  
  27. interface
  28. uses
  29.   Classes, Sysutils, DCPcrypt2, DCPconst, DCPblockciphers;
  30.  
  31. const
  32.   NUMROUNDS= 8;
  33.  
  34. type
  35.   TDCP_misty1= class(TDCP_blockcipher64)
  36.   protected
  37.     KeyData: array[0..31] of DWord;
  38.     function FI(const FI_IN, FI_KEY: DWord): DWord;
  39.     function FO(const FO_IN: DWord; const k: longword): DWord;
  40.     function FL(const FL_IN: DWord; const k: longword): DWord;
  41.     function FLINV(const FL_IN: DWord; const k: longword): DWord;
  42.     procedure InitKey(const Key; Size: longword); override;
  43.   public
  44.     class function GetID: integer; override;
  45.     class function GetAlgorithm: string; override;
  46.     class function GetMaxKeySize: integer; override;
  47.     class function SelfTest: boolean; override;
  48.     procedure Burn; override;
  49.     procedure EncryptECB(const InData; var OutData); override;
  50.     procedure DecryptECB(const InData; var OutData); override;
  51.   end;
  52.  
  53.  
  54. {******************************************************************************}
  55. {******************************************************************************}
  56. implementation
  57. {$R-}{$Q-}
  58.  
  59. {$I DCPmisty1.inc}
  60.  
  61. function SwapDword(a: dword): dword;
  62. begin
  63.   Result:= ((a and $FF) shl 24) or ((a and $FF00) shl 8) or ((a and $FF0000) shr 8) or ((a and $FF000000) shr 24);
  64. end;
  65.  
  66. class function TDCP_misty1.GetID: integer;
  67. begin
  68.   Result:= DCP_misty1;
  69. end;
  70.  
  71. class function TDCP_misty1.GetAlgorithm: string;
  72. begin
  73.   Result:= 'Misty1';
  74. end;
  75.  
  76. class function TDCP_misty1.GetMaxKeySize: integer;
  77. begin
  78.   Result:= 128;
  79. end;
  80.  
  81. class function TDCP_misty1.SelfTest: boolean;
  82. const
  83.   Key: array[0..15] of byte=
  84.     ($00,$11,$22,$33,$44,$55,$66,$77,$88,$99,$aa,$bb,$cc,$dd,$ee,$ff);
  85.   Plain1: array[0..7] of byte= ($01,$23,$45,$67,$89,$ab,$cd,$ef);
  86.   Plain2: array[0..7] of byte= ($fe,$dc,$ba,$98,$76,$54,$32,$10);
  87.   Cipher1: array[0..7] of byte= ($8b,$1d,$a5,$f5,$6a,$b3,$d0,$7c);
  88.   Cipher2: array[0..7] of byte= ($04,$b6,$82,$40,$b1,$3b,$e9,$5d);
  89. var
  90.   Cipher: TDCP_misty1;
  91.   Block: array[0..7] of byte;
  92. begin
  93.   Cipher:= TDCP_misty1.Create(nil);
  94.   Cipher.Init(Key,Sizeof(Key)*8,nil);
  95.   Cipher.EncryptECB(Plain1,Block);
  96.   Result:= CompareMem(@Cipher1,@Block,Sizeof(Block));
  97.   Cipher.DecryptECB(Block,Block);
  98.   Result:= Result and CompareMem(@Plain1,@Block,Sizeof(Block));
  99.   Cipher.EncryptECB(Plain2,Block);
  100.   Result:= Result and CompareMem(@Cipher2,@Block,Sizeof(Block));
  101.   Cipher.DecryptECB(Block,Block);
  102.   Result:= Result and CompareMem(@Plain2,@Block,Sizeof(Block));
  103.   Cipher.Burn;
  104.   Cipher.Free;
  105. end;
  106.  
  107. function TDCP_misty1.FI(const FI_IN, FI_KEY: DWord): DWord;
  108. var
  109.   d7, d9: DWord;
  110. begin
  111.   d9:= (FI_IN shr 7) and $1ff;
  112.   d7:= FI_IN and $7f;
  113.   d9:= S9Table[d9] xor d7;
  114.   d7:= (S7Table[d7] xor d9) and $7f;
  115.   d7:= d7 xor ((FI_KEY shr 9) and $7f);
  116.   d9:= d9 xor (FI_KEY and $1ff);
  117.   d9:= S9Table[d9] xor d7;
  118.   Result:= (d7 shl 9) or d9;
  119. end;
  120.  
  121. function TDCP_misty1.FO(const FO_IN: DWord; const k: longword): DWord;
  122. var
  123.   t0, t1: DWord;
  124. begin
  125.   t0:= FO_IN shr 16;
  126.   t1:= FO_IN and $FFFF;
  127.   t0:= t0 xor KeyData[k];
  128.   t0:= FI(t0,KeyData[((k+5) mod 8) + 8]);
  129.   t0:= t0 xor t1;
  130.   t1:= t1 xor KeyData[(k+2) mod 8];
  131.   t1:= FI(t1,KeyData[((k+1) mod 8) + 8]);
  132.   t1:= t1 xor t0;
  133.   t0:= t0 xor KeyData[(k+7) mod 8];
  134.   t0:= FI(t0,KeyData[((k+3) mod 8) + 8]);
  135.   t0:= t0 xor t1;
  136.   t1:= t1 xor KeyData[(k+4) mod 8];
  137.   Result:= (t1 shl 16) or t0;
  138. end;
  139.  
  140. function TDCP_misty1.FL(const FL_IN: DWord; const k: longword): DWord;
  141. var
  142.   d0, d1: DWord;
  143.   t: byte;
  144. begin
  145.   d0:= FL_IN shr 16;
  146.   d1:= FL_IN and $FFFF;
  147.   if (k mod 2)<> 0 then
  148.   begin
  149.     t:= (k-1) div 2;
  150.     d1:= d1 xor (d0 and KeyData[((t + 2) mod 8) + 8]);
  151.     d0:= d0 xor (d1 or KeyData[(t + 4) mod 8]);
  152.   end
  153.   else
  154.   begin
  155.     t:= k div 2;
  156.     d1:= d1 xor (d0 and KeyData[t]);
  157.     d0:= d0 xor (d1 or KeyData[((t+6) mod 8) + 8]);
  158.   end;
  159.   Result:= (d0 shl 16) or d1;
  160. end;
  161.  
  162. function TDCP_misty1.FLINV(const FL_IN: DWord; const k: longword): DWord;
  163. var
  164.   d0, d1: DWord;
  165.   t: byte;
  166. begin
  167.   d0:= FL_IN shr 16;
  168.   d1:= FL_IN and $FFFF;
  169.   if (k mod 2)<> 0 then
  170.   begin
  171.     t:= (k-1) div 2;
  172.     d0:= d0 xor (d1 or KeyData[(t+4) mod 8]);
  173.     d1:= d1 xor (d0 and KeyData[((t+2) mod 8) + 8]);
  174.   end
  175.   else
  176.   begin
  177.     t:= k div 2;
  178.     d0:= d0 xor (d1 or KeyData[((t+6) mod 8) + 8]);
  179.     d1:= d1 xor (d0 and KeyData[t]);
  180.   end;
  181.   Result:= (d0 shl 16) or d1;
  182. end;
  183.  
  184. procedure TDCP_misty1.InitKey(const Key; Size: longword);
  185. var
  186.   KeyB: array[0..15] of byte;
  187.   i: longword;
  188. begin
  189.   FillChar(KeyB,Sizeof(KeyB),0);
  190.   Move(Key,KeyB,Size div 8);
  191.   for i:= 0 to 7 do
  192.     KeyData[i]:= (KeyB[i*2] * 256) + KeyB[i*2+1];
  193.   for i:= 0 to 7 do
  194.   begin
  195.     KeyData[i+8]:= FI(KeyData[i],KeyData[(i+1) mod 8]);
  196.     KeyData[i+16]:= KeyData[i+8] and $1FF;
  197.     KeyData[i+24]:= KeyData[i+8] shr 9;
  198.   end;
  199. end;
  200.  
  201. procedure TDCP_misty1.Burn;
  202. begin
  203.   FillChar(KeyData,Sizeof(KeyData),0);
  204.   inherited Burn;
  205. end;
  206.  
  207. procedure TDCP_misty1.EncryptECB(const InData; var OutData);
  208. var
  209.   d0, d1: DWord;
  210.   i: longword;
  211. begin
  212.   if not fInitialized then
  213.     raise EDCP_blockcipher.Create('Cipher not initialized');
  214.   d0:= SwapDWord(PDWord(@InData)^);
  215.   d1:= SwapDWord(PDWord(longword(@InData)+4)^);
  216.   for i:= 0 to NUMROUNDS-1 do
  217.   begin
  218.     if (i mod 2)= 0 then
  219.     begin
  220.       d0:= FL(D0,i);
  221.       d1:= FL(D1,i+1);
  222.       d1:= d1 xor FO(d0,i);
  223.     end
  224.     else
  225.       d0:= d0 xor FO(d1,i);
  226.   end;
  227.   d0:= FL(d0,NUMROUNDS);
  228.   d1:= FL(d1,NUMROUNDS+1);
  229.   PDWord(@OutData)^:= SwapDWord(d1);
  230.   PDWord(longword(@OutData)+4)^:= SwapDWord(d0);
  231. end;
  232.  
  233. procedure TDCP_misty1.DecryptECB(const InData; var OutData);
  234. var
  235.   d0, d1: DWord;
  236.   i: longword;
  237. begin
  238.   if not fInitialized then
  239.     raise EDCP_blockcipher.Create('Cipher not initialized');
  240.   d1:= SwapDWord(PDWord(@InData)^);
  241.   d0:= SwapDWord(PDWord(longword(@InData)+4)^);
  242.   d1:= FLINV(d1,NUMROUNDS+1);
  243.   d0:= FLINV(d0,NUMROUNDS);
  244.   for i:= NUMROUNDS-1 downto 0 do
  245.   begin
  246.     if (i mod 2)= 0 then
  247.     begin
  248.       d1:= d1 xor FO(d0,i);
  249.       d0:= FLINV(D0,i);
  250.       d1:= FLINV(D1,i+1);
  251.     end
  252.     else
  253.       d0:= d0 xor FO(d1,i);
  254.   end;
  255.   PDWord(@OutData)^:= SwapDWord(d0);
  256.   PDWord(longword(@OutData)+4)^:= SwapDWord(d1);
  257. end;
  258.  
  259. end.
  260.