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

  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
  3. {******************************************************************************}
  4. {* A binary compatible implementation of Ice and it's variants ****************}
  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 DCPice;
  26.  
  27. interface
  28. uses
  29.   Classes, Sysutils, DCPcrypt2, DCPconst, DCPblockciphers;
  30.  
  31. type
  32.   TDCP_customice= class(TDCP_blockcipher64)
  33.   protected
  34.     rounds: dword;
  35.     ik_keysched: array[0..31,0..2] of dword;
  36.     function f(p, sk: dword): dword;
  37.     procedure key_sched_build(kb: pwordarray; n: dword; keyrot: pdwordarray);
  38.     procedure InitIce(const Key; Size: longword; n: dword);
  39.   public
  40.     procedure Burn; override;
  41.     procedure EncryptECB(const InData; var OutData); override;
  42.     procedure DecryptECB(const InData; var OutData); override;
  43.     constructor Create(AOwner: TComponent); override;
  44.   end;
  45.  
  46.   TDCP_ice= class(TDCP_customice)
  47.   protected
  48.     procedure InitKey(const Key; Size: longword); override;
  49.   public
  50.     class function GetID: integer; override;
  51.     class function GetAlgorithm: string; override;
  52.     class function GetMaxKeySize: integer; override;
  53.     class function SelfTest: boolean; override;
  54.   end;
  55.  
  56.   TDCP_thinice= class(TDCP_customice)
  57.   protected
  58.     procedure InitKey(const Key; Size: longword); override;
  59.   public
  60.     class function GetID: integer; override;
  61.     class function GetAlgorithm: string; override;
  62.     class function GetMaxKeySize: integer; override;
  63.     class function SelfTest: boolean; override;
  64.   end;
  65.  
  66.   TDCP_ice2= class(TDCP_customice)
  67.   protected
  68.     procedure InitKey(const Key; Size: longword); override;
  69.   public
  70.     class function GetID: integer; override;
  71.     class function GetAlgorithm: string; override;
  72.     class function GetMaxKeySize: integer; override;
  73.     class function SelfTest: boolean; override;
  74.   end;
  75.  
  76. {******************************************************************************}
  77. {******************************************************************************}
  78. implementation
  79. {$R-}{$Q-}
  80.  
  81. var
  82.   ice_sbox: array[0..3,0..1023] of dword;
  83.   ice_sboxdone: boolean;
  84.  
  85. const
  86.   ice_smod: array[0..3,0..3] of dword= (
  87.     (333, 313, 505, 369),
  88.     (379, 375, 319, 391),
  89.     (361, 445, 451, 397),
  90.     (397, 425, 395, 505));
  91.   ice_sxor: array[0..3,0..3] of dword= (
  92.     ($83, $85, $9b, $cd),
  93.     ($cc, $a7, $ad, $41),
  94.     ($4b, $2e, $d4, $33),
  95.     ($ea, $cb, $2e, $04));
  96.   ice_keyrot: array[0..15] of dword= (
  97.      0, 1, 2, 3, 2, 1, 3, 0,
  98.      1, 3, 2, 0, 3, 1, 0, 2);
  99.   ice_pbox: array[0..31] of dword= (
  100.      $00000001,  $00000080,  $00000400,  $00002000,
  101.      $00080000,  $00200000,  $01000000,  $40000000,
  102.      $00000008,  $00000020,  $00000100,  $00004000,
  103.      $00010000,  $00800000,  $04000000,  $20000000,
  104.      $00000004,  $00000010,  $00000200,  $00008000,
  105.      $00020000,  $00400000,  $08000000,  $10000000,
  106.      $00000002,  $00000040,  $00000800,  $00001000,
  107.      $00040000,  $00100000,  $02000000,  $80000000);
  108.  
  109. function SwapDword(a: dword): dword;
  110. begin
  111.   Result:= ((a and $FF) shl 24) or ((a and $FF00) shl 8) or ((a and $FF0000) shr 8) or ((a and $FF000000) shr 24);
  112. end;
  113.  
  114. {******************************************************************************}
  115. function gf_mult(a, b, m: dword): dword;
  116. var
  117.   res: dword;
  118. begin
  119.   res:= 0;
  120.   while b<> 0 do
  121.   begin
  122.     if (b and 1)<> 0 then
  123.       res:= res xor a;
  124.     a:= a shl 1;
  125.     b:= b shr 1;
  126.     if a>= 256 then
  127.       a:= a xor m;
  128.   end;
  129.   Result:= res;
  130. end;
  131.  
  132. function gf_exp7(b, m: dword): dword;
  133. var
  134.   x: dword;
  135. begin
  136.   if b= 0 then
  137.     Result:= 0
  138.   else
  139.   begin
  140.     x:= gf_mult(b,b,m);
  141.     x:= gf_mult(b,x,m);
  142.     x:= gf_mult(x,x,m);
  143.     Result:= gf_mult(b,x,m);
  144.   end;
  145. end;
  146.  
  147. function ice_perm32(x: dword): dword;
  148. var
  149.   res: dword;
  150.   pbox: pdword;
  151. begin
  152.   res:= 0;
  153.   pbox:= @ice_pbox;
  154.   while x<> 0 do
  155.   begin
  156.     if (x and 1)<> 0 then
  157.       res:= res or pbox^;
  158.     Inc(pbox);
  159.     x:= x shr 1;
  160.   end;
  161.   Result:= res;
  162. end;
  163.  
  164. procedure ice_sboxes_init;
  165. var
  166.   i, col, row: dword;
  167.   x: dword;
  168. begin
  169.   for i:= 0 to 1023 do
  170.   begin
  171.     col:= (i shr 1) and $FF;
  172.     row:= (i and 1) or ((i and $200) shr 8);
  173.     x:= gf_exp7(col xor ice_sxor[0,row],ice_smod[0,row]) shl 24;
  174.     ice_sbox[0,i]:= ice_perm32(x);
  175.     x:= gf_exp7(col xor ice_sxor[1,row],ice_smod[1,row]) shl 16;
  176.     ice_sbox[1,i]:= ice_perm32(x);
  177.     x:= gf_exp7(col xor ice_sxor[2,row],ice_smod[2,row]) shl  8;
  178.     ice_sbox[2,i]:= ice_perm32(x);
  179.     x:= gf_exp7(col xor ice_sxor[3,row],ice_smod[3,row]);
  180.     ice_sbox[3,i]:= ice_perm32(x);
  181.   end;
  182. end;
  183.  
  184. function TDCP_customice.f(p, sk: dword): dword;
  185. var
  186.   tl, tr, al, ar: dword;
  187. begin
  188.   tl:= ((p shr 16) and $3ff) or (((p shr 14) or (p shl 18)) and $ffc00);
  189.   tr:= (p and $3ff) or ((p shl 2) and $ffc00);
  190.   al:= ik_keysched[sk,2] and (tl xor tr);
  191.   ar:= al xor tr;
  192.   al:= al xor tl;
  193.   al:= al xor ik_keysched[sk,0];
  194.   ar:= ar xor ik_keysched[sk,1];
  195.   Result:= ice_sbox[0,al shr 10] or ice_sbox[1,al and $3ff] or
  196.            ice_sbox[2,ar shr 10] or ice_sbox[3,ar and $3ff];
  197. end;
  198.  
  199.  
  200. procedure TDCP_customice.key_sched_build(kb: pwordarray; n: dword; keyrot: pdwordarray);
  201. var
  202.   i, j, k, kr: dword;
  203.   keys: pdwordarray;
  204.   currentsk: pdword;
  205.   currentkb: pword;
  206.   bit: dword;
  207. begin
  208.   for i:= 0 to 7 do
  209.   begin
  210.     kr:= keyrot^[i];
  211.     keys:= @ik_keysched[n+i];
  212.     for j:= 0 to 2 do
  213.       keys^[j]:= 0;
  214.     for j:= 0 to 14 do
  215.     begin
  216.       currentsk:= @keys^[j mod 3];
  217.       for k:= 0 to 3 do
  218.       begin
  219.         currentkb:= @kb^[(kr + k) and 3];
  220.         bit:= currentkb^ and 1;
  221.         currentsk^:= (currentsk^ shl 1) or bit;
  222.         currentkb^:= (currentkb^ shr 1) or ((bit xor 1) shl 15);
  223.       end;
  224.     end;
  225.   end;
  226. end;
  227.  
  228. procedure TDCP_customice.InitIce(const Key; Size: longword; n: dword);
  229. var
  230.   i, j: dword;
  231.   kb: array[0..3] of word;
  232.   keyb: array[0..15] of byte;
  233. begin
  234.   FillChar(keyb,Sizeof(keyb),0);
  235.   Move(key,keyb,Size div 8);
  236.   if n> 0 then
  237.     rounds:= 16 * n
  238.   else
  239.     rounds:= 8;
  240.  
  241.   if rounds= 8 then
  242.   begin
  243.     for i:= 0 to 4 do
  244.       kb[3 - i]:= (keyb[i*2] shl 8) or keyb[i*2 + 1];
  245.     key_sched_build(@kb,0,@ice_keyrot);
  246.   end
  247.   else
  248.   begin
  249.     for i:= 0 to (n-1) do
  250.     begin
  251.       for j:= 0 to 3 do
  252.         kb[3-j]:= (keyb[i*8 + j*2] shl 8) or keyb[i*8 + j*2 + 1];
  253.       key_sched_build(@kb,i*8,@ice_keyrot);
  254.       key_sched_build(@kb,rounds - 8 - i*8,@ice_keyrot[8]);
  255.     end;
  256.   end;
  257. end;
  258.  
  259. procedure TDCP_customice.Burn;
  260. begin
  261.   FillChar(ik_keysched,Sizeof(ik_keysched),0);
  262.   Rounds:= 0;
  263.   inherited Burn;
  264. end;
  265.  
  266. procedure TDCP_customice.EncryptECB(const InData; var OutData);
  267. var
  268.   i, l, r: dword;
  269. begin
  270.   if not fInitialized then
  271.     raise EDCP_blockcipher.Create('Cipher not initialized');
  272.   l:= SwapDWord(Pdword(@InData)^);
  273.   r:= SwapDWord(Pdword(longword(@InData)+4)^);
  274.   i:= 0;
  275.   while i< rounds do
  276.   begin
  277.     l:= l xor f(r,i);
  278.     r:= r xor f(l,i+1);
  279.     Inc(i,2);
  280.   end;
  281.   Pdword(@OutData)^:= SwapDWord(r);
  282.   Pdword(longword(@OutData)+4)^:= SwapDWord(l);
  283. end;
  284.  
  285. procedure TDCP_customice.DecryptECB(const InData; var OutData);
  286. var
  287.   l, r: dword;
  288.   i: integer;
  289. begin
  290.   if not fInitialized then
  291.     raise EDCP_blockcipher.Create('Cipher not initialized');
  292.   l:= SwapDWord(Pdword(@InData)^);
  293.   r:= SwapDWord(Pdword(longword(@InData)+4)^);
  294.   i:= rounds-1;
  295.   while i> 0 do
  296.   begin
  297.     l:= l xor f(r,i);
  298.     r:= r xor f(l,i-1);
  299.     Dec(i,2);
  300.   end;
  301.   Pdword(@OutData)^:= SwapDWord(r);
  302.   Pdword(longword(@OutData)+4)^:= SwapDWord(l);
  303. end;
  304.  
  305. constructor TDCP_customice.Create(AOwner: TComponent);
  306. begin
  307.   inherited Create(AOwner);
  308.   if not ice_sboxdone then
  309.   begin
  310.     ice_sboxes_init;
  311.     ice_sboxdone:= true;
  312.   end;
  313. end;
  314.  
  315. {******************************************************************************}
  316. class function TDCP_ice.GetMaxKeySize: integer;
  317. begin
  318.   Result:= 64;
  319. end;
  320.  
  321. class function TDCP_ice.GetID: integer;
  322. begin
  323.   Result:= DCP_ice;
  324. end;
  325.  
  326. class function TDCP_ice.GetAlgorithm: string;
  327. begin
  328.   Result:= 'Ice';
  329. end;
  330.  
  331. class function TDCP_ice.SelfTest: boolean;
  332. const
  333.   Key1: array[0..7] of byte= ($de,$ad,$be,$ef,$01,$23,$45,$67);
  334.   InData1: array[0..7] of byte= ($fe,$dc,$ba,$98,$76,$54,$32,$10);
  335.   OutData1: array[0..7] of byte= ($7d,$6e,$f1,$ef,$30,$d4,$7a,$96);
  336. var
  337.   Cipher: TDCP_ice;
  338.   Data: array[0..7] of byte;
  339. begin
  340.   Cipher:= TDCP_ice.Create(nil);
  341.   Cipher.Init(Key1,Sizeof(Key1)*8,nil);
  342.   Cipher.EncryptECB(InData1,Data);
  343.   Result:= boolean(CompareMem(@Data,@OutData1,Sizeof(Data)));
  344.   Cipher.Reset;
  345.   Cipher.DecryptECB(Data,Data);
  346.   Result:= boolean(CompareMem(@Data,@InData1,Sizeof(Data))) and Result;
  347.   Cipher.Burn;
  348.   Cipher.Free;
  349. end;
  350.  
  351. procedure TDCP_ice.InitKey(const Key; Size: longword);
  352. begin
  353.   InitIce(Key,Size,1);
  354. end;
  355.  
  356. {******************************************************************************}
  357. class function TDCP_thinice.GetMaxKeySize: integer;
  358. begin
  359.   Result:= 64;
  360. end;
  361.  
  362. class function TDCP_thinice.GetID: integer;
  363. begin
  364.   Result:= DCP_thinice;
  365. end;
  366.  
  367. class function TDCP_thinice.GetAlgorithm: string;
  368. begin
  369.   Result:= 'Thin Ice';
  370. end;
  371.  
  372. class function TDCP_thinice.SelfTest: boolean;
  373. const
  374.   Key1: array[0..7] of byte= ($de,$ad,$be,$ef,$01,$23,$45,$67);
  375.   InData1: array[0..7] of byte= ($fe,$dc,$ba,$98,$76,$54,$32,$10);
  376.   OutData1: array[0..7] of byte= ($de,$24,$0d,$83,$a0,$0a,$9c,$c0);
  377. var
  378.   Cipher: TDCP_thinice;
  379.   Data: array[0..7] of byte;
  380. begin
  381.   Cipher:= TDCP_thinice.Create(nil);
  382.   Cipher.Init(Key1,Sizeof(Key1)*8,nil);
  383.   Cipher.EncryptECB(InData1,Data);
  384.   Result:= boolean(CompareMem(@Data,@OutData1,Sizeof(Data)));
  385.   Cipher.Reset;
  386.   Cipher.DecryptECB(Data,Data);
  387.   Result:= boolean(CompareMem(@Data,@InData1,Sizeof(Data))) and Result;
  388.   Cipher.Burn;
  389.   Cipher.Free;
  390. end;
  391.  
  392. procedure TDCP_thinice.InitKey(const Key; Size: longword);
  393. begin
  394.   InitIce(Key,Size,0);
  395. end;
  396.  
  397. {******************************************************************************}
  398. class function TDCP_ice2.GetMaxKeySize: integer;
  399. begin
  400.   Result:= 128;
  401. end;
  402.  
  403. class function TDCP_ice2.GetID: integer;
  404. begin
  405.   Result:= DCP_ice2;
  406. end;
  407.  
  408. class function TDCP_ice2.GetAlgorithm: string;
  409. begin
  410.   Result:= 'Ice2';
  411. end;
  412.  
  413. class function TDCP_ice2.SelfTest: boolean;
  414. const
  415.   Key1: array[0..15] of byte=
  416.     ($00,$11,$22,$33,$44,$55,$66,$77,$88,$99,$aa,$bb,$cc,$dd,$ee,$ff);
  417.   InData1: array[0..7] of byte= ($fe,$dc,$ba,$98,$76,$54,$32,$10);
  418.   OutData1: array[0..7] of byte= ($f9,$48,$40,$d8,$69,$72,$f2,$1c);
  419. var
  420.   Cipher: TDCP_ice2;
  421.   Data: array[0..7] of byte;
  422. begin
  423.   Cipher:= TDCP_ice2.Create(nil);
  424.   Cipher.Init(Key1,Sizeof(Key1)*8,nil);
  425.   Cipher.EncryptECB(InData1,Data);
  426.   Result:= boolean(CompareMem(@Data,@OutData1,Sizeof(Data)));
  427.   Cipher.Reset;
  428.   Cipher.DecryptECB(Data,Data);
  429.   Result:= boolean(CompareMem(@Data,@InData1,Sizeof(Data))) and Result;
  430.   Cipher.Burn;
  431.   Cipher.Free;
  432. end;
  433.  
  434. procedure TDCP_ice2.InitKey(const Key; Size: longword);
  435. begin
  436.   InitIce(Key,Size,2);
  437. end;
  438.  
  439.  
  440. initialization
  441.   ice_sboxdone:= false;
  442.  
  443. end.
  444.