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

  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
  3. {******************************************************************************}
  4. {* A binary compatible implementation of Cast256 ******************************}
  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 DCPcast256;
  26.  
  27. interface
  28. uses
  29.   Classes, Sysutils, DCPcrypt2, DCPconst, DCPblockciphers;
  30.  
  31. type
  32.   TDCP_cast256= class(TDCP_blockcipher128)
  33.   protected
  34.     Kr, Km: array[0..11,0..3] of DWord;
  35.     procedure InitKey(const Key; Size: longword); override;
  36.   public
  37.     class function GetId: integer; override;
  38.     class function GetAlgorithm: string; override;
  39.     class function GetMaxKeySize: integer; override;
  40.     class function SelfTest: boolean; override;
  41.     procedure Burn; override;
  42.     procedure EncryptECB(const InData; var OutData); override;
  43.     procedure DecryptECB(const InData; var OutData); override;
  44.   end;
  45.  
  46.  
  47. {******************************************************************************}
  48. {******************************************************************************}
  49. implementation
  50. {$R-}{$Q-}
  51. {$I DCPcast256.inc}
  52.  
  53. function LRot32(a, n: dword): dword;
  54. begin
  55.   Result:= (a shl n) or (a shr (32-n));
  56. end;
  57.  
  58. function SwapDword(a: dword): dword;
  59. begin
  60.   Result:= ((a and $FF) shl 24) or ((a and $FF00) shl 8) or ((a and $FF0000) shr 8) or ((a and $FF000000) shr 24);
  61. end;
  62.  
  63. function F1(a,rk,mk: DWord): DWord;
  64. var
  65.   t: DWord;
  66. begin
  67.   t:= LRot32(mk + a,rk);
  68.   Result:= ((S1[t shr 24] xor S2[(t shr 16) and $FF]) - S3[(t shr 8) and $FF]) + S4[t and $FF];
  69. end;
  70. function F2(a,rk,mk: DWord): DWord;
  71. var
  72.   t: DWord;
  73. begin
  74.   t:= LRot32(mk xor a,rk);
  75.   Result:= ((S1[t shr 24] - S2[(t shr 16) and $FF]) + S3[(t shr 8) and $FF]) xor S4[t and $FF];
  76. end;
  77. function F3(a,rk,mk: DWord): DWord;
  78. var
  79.   t: DWord;
  80. begin
  81.   t:= LRot32(mk - a,rk);
  82.   Result:= ((S1[t shr 24] + S2[(t shr 16) and $FF]) xor S3[(t shr 8) and $FF]) - S4[t and $FF];
  83. end;
  84.  
  85. class function TDCP_cast256.GetMaxKeySize: integer;
  86. begin
  87.   Result:= 256;
  88. end;
  89.  
  90. class function TDCP_cast256.GetId: integer;
  91. begin
  92.   Result:= DCP_cast256;
  93. end;
  94.  
  95. class function TDCP_cast256.GetAlgorithm: string;
  96. begin
  97.   Result:= 'Cast256';
  98. end;
  99.  
  100. class function TDCP_cast256.SelfTest: boolean;
  101. const
  102.   Key1: array[0..15] of byte=
  103.     ($23,$42,$bb,$9e,$fa,$38,$54,$2c,$0a,$f7,$56,$47,$f2,$9f,$61,$5d);
  104.   InBlock1: array[0..15] of byte=
  105.     ($00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$0c,$9b,$28,$07);
  106.   OutBlock1: array[0..15] of byte=
  107.     ($96,$3a,$8a,$50,$ce,$b5,$4d,$08,$e0,$de,$e0,$f1,$d0,$41,$3d,$cf);
  108.   Key2: array[0..23] of byte=
  109.     ($23,$42,$bb,$9e,$fa,$38,$54,$2c,$be,$d0,$ac,$83,$94,$0a,$c2,$98,$ba,$c7,$7a,$77,$17,$94,$28,$63);
  110.   InBlock2: array[0..15] of byte=
  111.     ($00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$de,$25,$5a,$ff);
  112.   OutBlock2: array[0..15] of byte=
  113.     ($2b,$c1,$92,$9f,$30,$13,$47,$a9,$9d,$3f,$3e,$45,$ad,$34,$01,$e8);
  114.   Key3: array[0..31] of byte=
  115.     ($23,$42,$bb,$9e,$fa,$38,$54,$2c,$be,$d0,$ac,$83,$94,$0a,$c2,$98,$8d,$7c,$47,$ce,$26,$49,$08,$46,$1c,$c1,$b5,$13,$7a,$e6,$b6,$04);
  116.   InBlock3: array[0..15] of byte=
  117.     ($00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$c5,$fc,$eb,$19);
  118.   OutBlock3: array[0..15] of byte=
  119.     ($1e,$2e,$bc,$6c,$9f,$2e,$43,$8e,$1d,$90,$d9,$b9,$c6,$85,$32,$86);
  120. var
  121.   Block: array[0..15] of byte;
  122.   Cipher: TDCP_cast256;
  123. begin
  124.   Cipher:= TDCP_cast256.Create(nil);
  125.   Cipher.Init(Key1,Sizeof(Key1)*8,nil);
  126.   Cipher.EncryptECB(InBlock1,Block);
  127.   Result:= boolean(CompareMem(@Block,@OutBlock1,8));
  128.   Cipher.DecryptECB(Block,Block);
  129.   Result:= Result and boolean(CompareMem(@Block,@InBlock1,16));
  130.   Cipher.Burn;
  131.   Cipher.Init(Key2,Sizeof(Key2)*8,nil);
  132.   Cipher.EncryptECB(InBlock2,Block);
  133.   Result:= Result and boolean(CompareMem(@Block,@OutBlock2,8));
  134.   Cipher.DecryptECB(Block,Block);
  135.   Result:= Result and boolean(CompareMem(@Block,@InBlock2,16));
  136.   Cipher.Burn;
  137.   Cipher.Init(Key3,Sizeof(Key3)*8,nil);
  138.   Cipher.EncryptECB(InBlock3,Block);
  139.   Result:= Result and boolean(CompareMem(@Block,@OutBlock3,8));
  140.   Cipher.DecryptECB(Block,Block);
  141.   Result:= Result and boolean(CompareMem(@Block,@InBlock3,16));
  142.   Cipher.Burn;
  143.   Cipher.Free;
  144. end;
  145.  
  146. procedure TDCP_cast256.InitKey(const Key; Size: longword);
  147. var
  148.   x: array[0..7] of DWord;
  149.   cm, cr: DWord;
  150.   i, j: longword;
  151.   tr, tm: array[0..7] of DWord;
  152. begin
  153.   Size:= Size div 8;
  154.  
  155.   FillChar(x,Sizeof(x),0);
  156.   Move(Key,x,Size);
  157.  
  158.   cm:= $5a827999;
  159.   cr:= 19;
  160.   for i:= 0 to 7 do
  161.     x[i]:= (x[i] shl 24) or ((x[i] shl 8) and $FF0000) or ((x[i] shr 8) and $FF00) or (x[i] shr 24);
  162.   for i:= 0 to 11 do
  163.   begin
  164.     for j:= 0 to 7 do
  165.     begin
  166.       tm[j]:= cm;
  167.       Inc(cm,$6ed9eba1);
  168.       tr[j]:= cr;
  169.       Inc(cr,17);
  170.     end;
  171.     x[6]:= x[6] xor f1(x[7],tr[0],tm[0]);
  172.     x[5]:= x[5] xor f2(x[6],tr[1],tm[1]);
  173.     x[4]:= x[4] xor f3(x[5],tr[2],tm[2]);
  174.     x[3]:= x[3] xor f1(x[4],tr[3],tm[3]);
  175.     x[2]:= x[2] xor f2(x[3],tr[4],tm[4]);
  176.     x[1]:= x[1] xor f3(x[2],tr[5],tm[5]);
  177.     x[0]:= x[0] xor f1(x[1],tr[6],tm[6]);
  178.     x[7]:= x[7] xor f2(x[0],tr[7],tm[7]);
  179.  
  180.     for j:= 0 to 7 do
  181.     begin
  182.       tm[j]:= cm;
  183.       Inc(cm,$6ed9eba1);
  184.       tr[j]:= cr;
  185.       Inc(cr,17);
  186.     end;
  187.     x[6]:= x[6] xor f1(x[7],tr[0],tm[0]);
  188.     x[5]:= x[5] xor f2(x[6],tr[1],tm[1]);
  189.     x[4]:= x[4] xor f3(x[5],tr[2],tm[2]);
  190.     x[3]:= x[3] xor f1(x[4],tr[3],tm[3]);
  191.     x[2]:= x[2] xor f2(x[3],tr[4],tm[4]);
  192.     x[1]:= x[1] xor f3(x[2],tr[5],tm[5]);
  193.     x[0]:= x[0] xor f1(x[1],tr[6],tm[6]);
  194.     x[7]:= x[7] xor f2(x[0],tr[7],tm[7]);
  195.  
  196.     Kr[i,0]:= x[0] and 31;
  197.     Kr[i,1]:= x[2] and 31;
  198.     Kr[i,2]:= x[4] and 31;
  199.     Kr[i,3]:= x[6] and 31;
  200.     Km[i,0]:= x[7];
  201.     Km[i,1]:= x[5];
  202.     Km[i,2]:= x[3];
  203.     Km[i,3]:= x[1];
  204.   end;
  205.   FillChar(x,Sizeof(x),$FF);
  206. end;
  207.  
  208. procedure TDCP_cast256.Burn;
  209. begin
  210.   FillChar(Kr,Sizeof(Kr),$FF);
  211.   FillChar(Km,Sizeof(Km),$FF);
  212.   inherited Burn;
  213. end;
  214.  
  215. procedure TDCP_cast256.EncryptECB(const InData; var OutData);
  216. var
  217.   A: array[0..3] of DWord;
  218. begin
  219.   if not fInitialized then
  220.     raise EDCP_blockcipher.Create('Cipher not initialized');
  221.   A[0]:= PDWord(@InData)^;
  222.   A[1]:= PDWord(longword(@InData)+4)^;
  223.   A[2]:= PDWord(longword(@InData)+8)^;
  224.   A[3]:= PDWord(longword(@InData)+12)^;
  225.  
  226.   A[0]:= SwapDWord(A[0]);
  227.   A[1]:= SwapDWord(A[1]);
  228.   A[2]:= SwapDWord(A[2]);
  229.   A[3]:= SwapDWord(A[3]);
  230.   A[2]:= A[2] xor f1(A[3],kr[0,0],km[0,0]);
  231.   A[1]:= A[1] xor f2(A[2],kr[0,1],km[0,1]);
  232.   A[0]:= A[0] xor f3(A[1],kr[0,2],km[0,2]);
  233.   A[3]:= A[3] xor f1(A[0],kr[0,3],km[0,3]);
  234.   A[2]:= A[2] xor f1(A[3],kr[1,0],km[1,0]);
  235.   A[1]:= A[1] xor f2(A[2],kr[1,1],km[1,1]);
  236.   A[0]:= A[0] xor f3(A[1],kr[1,2],km[1,2]);
  237.   A[3]:= A[3] xor f1(A[0],kr[1,3],km[1,3]);
  238.   A[2]:= A[2] xor f1(A[3],kr[2,0],km[2,0]);
  239.   A[1]:= A[1] xor f2(A[2],kr[2,1],km[2,1]);
  240.   A[0]:= A[0] xor f3(A[1],kr[2,2],km[2,2]);
  241.   A[3]:= A[3] xor f1(A[0],kr[2,3],km[2,3]);
  242.   A[2]:= A[2] xor f1(A[3],kr[3,0],km[3,0]);
  243.   A[1]:= A[1] xor f2(A[2],kr[3,1],km[3,1]);
  244.   A[0]:= A[0] xor f3(A[1],kr[3,2],km[3,2]);
  245.   A[3]:= A[3] xor f1(A[0],kr[3,3],km[3,3]);
  246.   A[2]:= A[2] xor f1(A[3],kr[4,0],km[4,0]);
  247.   A[1]:= A[1] xor f2(A[2],kr[4,1],km[4,1]);
  248.   A[0]:= A[0] xor f3(A[1],kr[4,2],km[4,2]);
  249.   A[3]:= A[3] xor f1(A[0],kr[4,3],km[4,3]);
  250.   A[2]:= A[2] xor f1(A[3],kr[5,0],km[5,0]);
  251.   A[1]:= A[1] xor f2(A[2],kr[5,1],km[5,1]);
  252.   A[0]:= A[0] xor f3(A[1],kr[5,2],km[5,2]);
  253.   A[3]:= A[3] xor f1(A[0],kr[5,3],km[5,3]);
  254.  
  255.   A[3]:= A[3] xor f1(A[0],kr[6,3],km[6,3]);
  256.   A[0]:= A[0] xor f3(A[1],kr[6,2],km[6,2]);
  257.   A[1]:= A[1] xor f2(A[2],kr[6,1],km[6,1]);
  258.   A[2]:= A[2] xor f1(A[3],kr[6,0],km[6,0]);
  259.   A[3]:= A[3] xor f1(A[0],kr[7,3],km[7,3]);
  260.   A[0]:= A[0] xor f3(A[1],kr[7,2],km[7,2]);
  261.   A[1]:= A[1] xor f2(A[2],kr[7,1],km[7,1]);
  262.   A[2]:= A[2] xor f1(A[3],kr[7,0],km[7,0]);
  263.   A[3]:= A[3] xor f1(A[0],kr[8,3],km[8,3]);
  264.   A[0]:= A[0] xor f3(A[1],kr[8,2],km[8,2]);
  265.   A[1]:= A[1] xor f2(A[2],kr[8,1],km[8,1]);
  266.   A[2]:= A[2] xor f1(A[3],kr[8,0],km[8,0]);
  267.   A[3]:= A[3] xor f1(A[0],kr[9,3],km[9,3]);
  268.   A[0]:= A[0] xor f3(A[1],kr[9,2],km[9,2]);
  269.   A[1]:= A[1] xor f2(A[2],kr[9,1],km[9,1]);
  270.   A[2]:= A[2] xor f1(A[3],kr[9,0],km[9,0]);
  271.   A[3]:= A[3] xor f1(A[0],kr[10,3],km[10,3]);
  272.   A[0]:= A[0] xor f3(A[1],kr[10,2],km[10,2]);
  273.   A[1]:= A[1] xor f2(A[2],kr[10,1],km[10,1]);
  274.   A[2]:= A[2] xor f1(A[3],kr[10,0],km[10,0]);
  275.   A[3]:= A[3] xor f1(A[0],kr[11,3],km[11,3]);
  276.   A[0]:= A[0] xor f3(A[1],kr[11,2],km[11,2]);
  277.   A[1]:= A[1] xor f2(A[2],kr[11,1],km[11,1]);
  278.   A[2]:= A[2] xor f1(A[3],kr[11,0],km[11,0]);
  279.   A[0]:= SwapDWord(A[0]);
  280.   A[1]:= SwapDWord(A[1]);
  281.   A[2]:= SwapDWord(A[2]);
  282.   A[3]:= SwapDWord(A[3]);
  283.  
  284.   PDWord(@OutData)^:= A[0];
  285.   PDWord(longword(@OutData)+4)^:= A[1];
  286.   PDWord(longword(@OutData)+8)^:= A[2];
  287.   PDWord(longword(@OutData)+12)^:= A[3];
  288. end;
  289.  
  290. procedure TDCP_cast256.DecryptECB(const InData; var OutData);
  291. var
  292.   A: array[0..3] of DWord;
  293. begin
  294.   if not fInitialized then
  295.     raise EDCP_blockcipher.Create('Cipher not initialized');
  296.   A[0]:= PDWord(@InData)^;
  297.   A[1]:= PDWord(longword(@InData)+4)^;
  298.   A[2]:= PDWord(longword(@InData)+8)^;
  299.   A[3]:= PDWord(longword(@InData)+12)^;
  300.  
  301.   A[0]:= SwapDWord(A[0]);
  302.   A[1]:= SwapDWord(A[1]);
  303.   A[2]:= SwapDWord(A[2]);
  304.   A[3]:= SwapDWord(A[3]);
  305.   A[2]:= A[2] xor f1(A[3],kr[11,0],km[11,0]);
  306.   A[1]:= A[1] xor f2(A[2],kr[11,1],km[11,1]);
  307.   A[0]:= A[0] xor f3(A[1],kr[11,2],km[11,2]);
  308.   A[3]:= A[3] xor f1(A[0],kr[11,3],km[11,3]);
  309.   A[2]:= A[2] xor f1(A[3],kr[10,0],km[10,0]);
  310.   A[1]:= A[1] xor f2(A[2],kr[10,1],km[10,1]);
  311.   A[0]:= A[0] xor f3(A[1],kr[10,2],km[10,2]);
  312.   A[3]:= A[3] xor f1(A[0],kr[10,3],km[10,3]);
  313.   A[2]:= A[2] xor f1(A[3],kr[9,0],km[9,0]);
  314.   A[1]:= A[1] xor f2(A[2],kr[9,1],km[9,1]);
  315.   A[0]:= A[0] xor f3(A[1],kr[9,2],km[9,2]);
  316.   A[3]:= A[3] xor f1(A[0],kr[9,3],km[9,3]);
  317.   A[2]:= A[2] xor f1(A[3],kr[8,0],km[8,0]);
  318.   A[1]:= A[1] xor f2(A[2],kr[8,1],km[8,1]);
  319.   A[0]:= A[0] xor f3(A[1],kr[8,2],km[8,2]);
  320.   A[3]:= A[3] xor f1(A[0],kr[8,3],km[8,3]);
  321.   A[2]:= A[2] xor f1(A[3],kr[7,0],km[7,0]);
  322.   A[1]:= A[1] xor f2(A[2],kr[7,1],km[7,1]);
  323.   A[0]:= A[0] xor f3(A[1],kr[7,2],km[7,2]);
  324.   A[3]:= A[3] xor f1(A[0],kr[7,3],km[7,3]);
  325.   A[2]:= A[2] xor f1(A[3],kr[6,0],km[6,0]);
  326.   A[1]:= A[1] xor f2(A[2],kr[6,1],km[6,1]);
  327.   A[0]:= A[0] xor f3(A[1],kr[6,2],km[6,2]);
  328.   A[3]:= A[3] xor f1(A[0],kr[6,3],km[6,3]);
  329.  
  330.   A[3]:= A[3] xor f1(A[0],kr[5,3],km[5,3]);
  331.   A[0]:= A[0] xor f3(A[1],kr[5,2],km[5,2]);
  332.   A[1]:= A[1] xor f2(A[2],kr[5,1],km[5,1]);
  333.   A[2]:= A[2] xor f1(A[3],kr[5,0],km[5,0]);
  334.   A[3]:= A[3] xor f1(A[0],kr[4,3],km[4,3]);
  335.   A[0]:= A[0] xor f3(A[1],kr[4,2],km[4,2]);
  336.   A[1]:= A[1] xor f2(A[2],kr[4,1],km[4,1]);
  337.   A[2]:= A[2] xor f1(A[3],kr[4,0],km[4,0]);
  338.   A[3]:= A[3] xor f1(A[0],kr[3,3],km[3,3]);
  339.   A[0]:= A[0] xor f3(A[1],kr[3,2],km[3,2]);
  340.   A[1]:= A[1] xor f2(A[2],kr[3,1],km[3,1]);
  341.   A[2]:= A[2] xor f1(A[3],kr[3,0],km[3,0]);
  342.   A[3]:= A[3] xor f1(A[0],kr[2,3],km[2,3]);
  343.   A[0]:= A[0] xor f3(A[1],kr[2,2],km[2,2]);
  344.   A[1]:= A[1] xor f2(A[2],kr[2,1],km[2,1]);
  345.   A[2]:= A[2] xor f1(A[3],kr[2,0],km[2,0]);
  346.   A[3]:= A[3] xor f1(A[0],kr[1,3],km[1,3]);
  347.   A[0]:= A[0] xor f3(A[1],kr[1,2],km[1,2]);
  348.   A[1]:= A[1] xor f2(A[2],kr[1,1],km[1,1]);
  349.   A[2]:= A[2] xor f1(A[3],kr[1,0],km[1,0]);
  350.   A[3]:= A[3] xor f1(A[0],kr[0,3],km[0,3]);
  351.   A[0]:= A[0] xor f3(A[1],kr[0,2],km[0,2]);
  352.   A[1]:= A[1] xor f2(A[2],kr[0,1],km[0,1]);
  353.   A[2]:= A[2] xor f1(A[3],kr[0,0],km[0,0]);
  354.   A[0]:= SwapDWord(A[0]);
  355.   A[1]:= SwapDWord(A[1]);
  356.   A[2]:= SwapDWord(A[2]);
  357.   A[3]:= SwapDWord(A[3]);
  358.  
  359.   PDWord(@OutData)^:= A[0];
  360.   PDWord(longword(@OutData)+4)^:= A[1];
  361.   PDWord(longword(@OutData)+8)^:= A[2];
  362.   PDWord(longword(@OutData)+12)^:= A[3];
  363. end;
  364.  
  365.  
  366. end.
  367.