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

  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
  3. {******************************************************************************}
  4. {* A binary compatible implementation of Rijndael *****************************}
  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 DCPrijndael;
  26.  
  27. interface
  28. uses
  29.   Classes, Sysutils, DCPcrypt2, DCPconst, DCPblockciphers;
  30.  
  31. const
  32.   BC= 4;
  33.   MAXROUNDS= 14;
  34.  
  35. type
  36.   TDCP_rijndael= class(TDCP_blockcipher128)
  37.   protected
  38.     numrounds: longword;
  39.     rk, drk: array[0..MAXROUNDS,0..7] of DWord;
  40.     procedure InitKey(const Key; Size: longword); override;
  41.   public
  42.     class function GetID: integer; override;
  43.     class function GetAlgorithm: string; override;
  44.     class function GetMaxKeySize: integer; override;
  45.     class function SelfTest: boolean; override;
  46.     procedure Burn; override;
  47.     procedure EncryptECB(const InData; var OutData); override;
  48.     procedure DecryptECB(const InData; var OutData); override;
  49.   end;
  50.  
  51.  
  52. {******************************************************************************}
  53. {******************************************************************************}
  54. implementation
  55. {$R-}{$Q-}
  56. {$I DCPrijndael.inc}
  57.  
  58. class function TDCP_rijndael.GetMaxKeySize: integer;
  59. begin
  60.   Result:= 256;
  61. end;
  62.  
  63. class function TDCP_rijndael.GetID: integer;
  64. begin
  65.   Result:= DCP_rijndael;
  66. end;
  67.  
  68. class function TDCP_rijndael.GetAlgorithm: string;
  69. begin
  70.   Result:= 'Rijndael';
  71. end;
  72.  
  73. class function TDCP_rijndael.SelfTest: boolean;
  74. const
  75.   Key1: array[0..15] of byte=
  76.     ($00,$01,$02,$03,$05,$06,$07,$08,$0A,$0B,$0C,$0D,$0F,$10,$11,$12);
  77.   InData1: array[0..15] of byte=
  78.     ($50,$68,$12,$A4,$5F,$08,$C8,$89,$B9,$7F,$59,$80,$03,$8B,$83,$59);
  79.   OutData1: array[0..15] of byte=
  80.     ($D8,$F5,$32,$53,$82,$89,$EF,$7D,$06,$B5,$06,$A4,$FD,$5B,$E9,$C9);
  81.   Key2: array[0..23] of byte=
  82.     ($A0,$A1,$A2,$A3,$A5,$A6,$A7,$A8,$AA,$AB,$AC,$AD,$AF,$B0,$B1,$B2,
  83.      $B4,$B5,$B6,$B7,$B9,$BA,$BB,$BC);
  84.   InData2: array[0..15] of byte=
  85.     ($4F,$1C,$76,$9D,$1E,$5B,$05,$52,$C7,$EC,$A8,$4D,$EA,$26,$A5,$49);
  86.   OutData2: array[0..15] of byte=
  87.     ($F3,$84,$72,$10,$D5,$39,$1E,$23,$60,$60,$8E,$5A,$CB,$56,$05,$81);
  88.   Key3: array[0..31] of byte=
  89.     ($00,$01,$02,$03,$05,$06,$07,$08,$0A,$0B,$0C,$0D,$0F,$10,$11,$12,
  90.      $14,$15,$16,$17,$19,$1A,$1B,$1C,$1E,$1F,$20,$21,$23,$24,$25,$26);
  91.   InData3: array[0..15] of byte=
  92.     ($5E,$25,$CA,$78,$F0,$DE,$55,$80,$25,$24,$D3,$8D,$A3,$FE,$44,$56);
  93.   OutData3: array[0..15] of byte=
  94.     ($E8,$B7,$2B,$4E,$8B,$E2,$43,$43,$8C,$9F,$FF,$1F,$0E,$20,$58,$72);
  95. var
  96.   Block: array[0..15] of byte;
  97.   Cipher: TDCP_rijndael;
  98. begin
  99.   Cipher:= TDCP_rijndael.Create(nil);
  100.   Cipher.Init(Key1,Sizeof(Key1)*8,nil);
  101.   Cipher.EncryptECB(InData1,Block);
  102.   Result:= boolean(CompareMem(@Block,@OutData1,16));
  103.   Cipher.DecryptECB(Block,Block);
  104.   Cipher.Burn;
  105.   Result:= Result and boolean(CompareMem(@Block,@InData1,16));
  106.   Cipher.Init(Key2,Sizeof(Key2)*8,nil);
  107.   Cipher.EncryptECB(InData2,Block);
  108.   Result:= Result and boolean(CompareMem(@Block,@OutData2,16));
  109.   Cipher.DecryptECB(Block,Block);
  110.   Cipher.Burn;
  111.   Result:= Result and boolean(CompareMem(@Block,@InData2,16));
  112.   Cipher.Init(Key3,Sizeof(Key3)*8,nil);
  113.   Cipher.EncryptECB(InData3,Block);
  114.   Result:= Result and boolean(CompareMem(@Block,@OutData3,16));
  115.   Cipher.DecryptECB(Block,Block);
  116.   Cipher.Burn;
  117.   Result:= Result and boolean(CompareMem(@Block,@InData3,16));
  118.   Cipher.Free;
  119. end;
  120.  
  121. procedure InvMixColumn(a: PByteArray; BC: byte);
  122. var
  123.   j: longword;
  124. begin
  125.   for j:= 0 to (BC-1) do
  126.     PDWord(@(a^[j*4]))^:= PDWord(@U1[a^[j*4+0]])^ xor
  127.                        PDWord(@U2[a^[j*4+1]])^ xor
  128.                        PDWord(@U3[a^[j*4+2]])^ xor
  129.                        PDWord(@U4[a^[j*4+3]])^;
  130. end;
  131.  
  132. procedure TDCP_rijndael.InitKey(const Key; Size: longword);
  133. var
  134.   KC, ROUNDS, j, r, t, rconpointer: longword;
  135.   tk: array[0..MAXKC-1,0..3] of byte;
  136. begin
  137.   Size:= Size div 8;
  138.  
  139.   FillChar(tk,Sizeof(tk),0);
  140.   Move(Key,tk,Size);
  141.   if Size<= 16 then
  142.   begin
  143.     KC:= 4;
  144.     Rounds:= 10;
  145.   end
  146.   else if Size<= 24 then
  147.   begin
  148.     KC:= 6;
  149.     Rounds:= 12;
  150.   end
  151.   else
  152.   begin
  153.     KC:= 8;
  154.     Rounds:= 14;
  155.   end;
  156.   numrounds:= rounds;
  157.   r:= 0;
  158.   t:= 0;
  159.   j:= 0;
  160.   while (j< KC) and (r< (rounds+1)) do
  161.   begin
  162.     while (j< KC) and (t< BC) do
  163.     begin
  164.       rk[r,t]:= PDWord(@tk[j])^;
  165.       Inc(j);
  166.       Inc(t);
  167.     end;
  168.     if t= BC then
  169.     begin
  170.       t:= 0;
  171.       Inc(r);
  172.     end;
  173.   end;
  174.   rconpointer:= 0;
  175.   while (r< (rounds+1)) do
  176.   begin
  177.     tk[0,0]:= tk[0,0] xor S[tk[KC-1,1]];
  178.     tk[0,1]:= tk[0,1] xor S[tk[KC-1,2]];
  179.     tk[0,2]:= tk[0,2] xor S[tk[KC-1,3]];
  180.     tk[0,3]:= tk[0,3] xor S[tk[KC-1,0]];
  181.     tk[0,0]:= tk[0,0] xor rcon[rconpointer];
  182.     Inc(rconpointer);
  183.     if KC<> 8 then
  184.     begin
  185.       for j:= 1 to (KC-1) do
  186.         PDWord(@tk[j])^:= PDWord(@tk[j])^ xor PDWord(@tk[j-1])^;
  187.     end
  188.     else
  189.     begin
  190.       for j:= 1 to ((KC div 2)-1) do
  191.         PDWord(@tk[j])^:= PDWord(@tk[j])^ xor PDWord(@tk[j-1])^;
  192.       tk[KC div 2,0]:= tk[KC div 2,0] xor S[tk[KC div 2 - 1,0]];
  193.       tk[KC div 2,1]:= tk[KC div 2,1] xor S[tk[KC div 2 - 1,1]];
  194.       tk[KC div 2,2]:= tk[KC div 2,2] xor S[tk[KC div 2 - 1,2]];
  195.       tk[KC div 2,3]:= tk[KC div 2,3] xor S[tk[KC div 2 - 1,3]];
  196.       for j:= ((KC div 2) + 1) to (KC-1) do
  197.         PDWord(@tk[j])^:= PDWord(@tk[j])^ xor PDWord(@tk[j-1])^;
  198.     end;
  199.     j:= 0;
  200.     while (j< KC) and (r< (rounds+1)) do
  201.     begin
  202.       while (j< KC) and (t< BC) do
  203.       begin
  204.         rk[r,t]:= PDWord(@tk[j])^;
  205.         Inc(j);
  206.         Inc(t);
  207.       end;
  208.       if t= BC then
  209.       begin
  210.         Inc(r);
  211.         t:= 0;
  212.       end;
  213.     end;
  214.   end;
  215.   Move(rk,drk,Sizeof(rk));
  216.   for r:= 1 to (numrounds-1) do
  217.     InvMixColumn(@drk[r],BC);
  218. end;
  219.  
  220. procedure TDCP_rijndael.Burn;
  221. begin
  222.   numrounds:= 0;
  223.   FillChar(rk,Sizeof(rk),0);
  224.   FillChar(drk,Sizeof(drk),0);
  225.   inherited Burn;
  226. end;
  227.  
  228. procedure TDCP_rijndael.EncryptECB(const InData; var OutData);
  229. var
  230.   r: longword;
  231.   tempb: array[0..MAXBC-1,0..3] of byte;
  232.   a: array[0..MAXBC,0..3] of byte;
  233. begin
  234.   if not fInitialized then
  235.     raise EDCP_blockcipher.Create('Cipher not initialized');
  236.   PDword(@a[0,0])^:= PDword(@InData)^;
  237.   PDword(@a[1,0])^:= PDword(dword(@InData)+4)^;
  238.   PDword(@a[2,0])^:= PDword(dword(@InData)+8)^;
  239.   PDword(@a[3,0])^:= PDword(dword(@InData)+12)^;
  240.   for r:= 0 to (numrounds-2) do
  241.   begin
  242.     PDWord(@tempb[0])^:= PDWord(@a[0])^ xor rk[r,0];
  243.     PDWord(@tempb[1])^:= PDWord(@a[1])^ xor rk[r,1];
  244.     PDWord(@tempb[2])^:= PDWord(@a[2])^ xor rk[r,2];
  245.     PDWord(@tempb[3])^:= PDWord(@a[3])^ xor rk[r,3];
  246.     PDWord(@a[0])^:= PDWord(@T1[tempb[0,0]])^ xor
  247.                      PDWord(@T2[tempb[1,1]])^ xor
  248.                      PDWord(@T3[tempb[2,2]])^ xor
  249.                      PDWord(@T4[tempb[3,3]])^;
  250.     PDWord(@a[1])^:= PDWord(@T1[tempb[1,0]])^ xor
  251.                      PDWord(@T2[tempb[2,1]])^ xor
  252.                      PDWord(@T3[tempb[3,2]])^ xor
  253.                      PDWord(@T4[tempb[0,3]])^;
  254.     PDWord(@a[2])^:= PDWord(@T1[tempb[2,0]])^ xor
  255.                      PDWord(@T2[tempb[3,1]])^ xor
  256.                      PDWord(@T3[tempb[0,2]])^ xor
  257.                      PDWord(@T4[tempb[1,3]])^;
  258.     PDWord(@a[3])^:= PDWord(@T1[tempb[3,0]])^ xor
  259.                      PDWord(@T2[tempb[0,1]])^ xor
  260.                      PDWord(@T3[tempb[1,2]])^ xor
  261.                      PDWord(@T4[tempb[2,3]])^;
  262.   end;
  263.   PDWord(@tempb[0])^:= PDWord(@a[0])^ xor rk[numrounds-1,0];
  264.   PDWord(@tempb[1])^:= PDWord(@a[1])^ xor rk[numrounds-1,1];
  265.   PDWord(@tempb[2])^:= PDWord(@a[2])^ xor rk[numrounds-1,2];
  266.   PDWord(@tempb[3])^:= PDWord(@a[3])^ xor rk[numrounds-1,3];
  267.   a[0,0]:= T1[tempb[0,0],1];
  268.   a[0,1]:= T1[tempb[1,1],1];
  269.   a[0,2]:= T1[tempb[2,2],1];
  270.   a[0,3]:= T1[tempb[3,3],1];
  271.   a[1,0]:= T1[tempb[1,0],1];
  272.   a[1,1]:= T1[tempb[2,1],1];
  273.   a[1,2]:= T1[tempb[3,2],1];
  274.   a[1,3]:= T1[tempb[0,3],1];
  275.   a[2,0]:= T1[tempb[2,0],1];
  276.   a[2,1]:= T1[tempb[3,1],1];
  277.   a[2,2]:= T1[tempb[0,2],1];
  278.   a[2,3]:= T1[tempb[1,3],1];
  279.   a[3,0]:= T1[tempb[3,0],1];
  280.   a[3,1]:= T1[tempb[0,1],1];
  281.   a[3,2]:= T1[tempb[1,2],1];
  282.   a[3,3]:= T1[tempb[2,3],1];
  283.   PDWord(@a[0])^:= PDWord(@a[0])^ xor rk[numrounds,0];
  284.   PDWord(@a[1])^:= PDWord(@a[1])^ xor rk[numrounds,1];
  285.   PDWord(@a[2])^:= PDWord(@a[2])^ xor rk[numrounds,2];
  286.   PDWord(@a[3])^:= PDWord(@a[3])^ xor rk[numrounds,3];
  287.  
  288.   PDword(@OutData)^:= PDword(@a[0,0])^;
  289.   PDword(dword(@OutData)+4)^:= PDword(@a[1,0])^;
  290.   PDword(dword(@OutData)+8)^:= PDword(@a[2,0])^;
  291.   PDword(dword(@OutData)+12)^:= PDword(@a[3,0])^;
  292. end;
  293.  
  294. procedure TDCP_rijndael.DecryptECB(const InData; var OutData);
  295. var
  296.   r: longword;
  297.   tempb: array[0..MAXBC-1,0..3] of byte;
  298.   a: array[0..MAXBC,0..3] of byte;
  299. begin
  300.   if not fInitialized then
  301.     raise EDCP_blockcipher.Create('Cipher not initialized');
  302.   PDword(@a[0,0])^:= PDword(@InData)^;
  303.   PDword(@a[1,0])^:= PDword(dword(@InData)+4)^;
  304.   PDword(@a[2,0])^:= PDword(dword(@InData)+8)^;
  305.   PDword(@a[3,0])^:= PDword(dword(@InData)+12)^;
  306.   for r:= NumRounds downto 2 do
  307.   begin
  308.     PDWord(@tempb[0])^:= PDWord(@a[0])^ xor drk[r,0];
  309.     PDWord(@tempb[1])^:= PDWord(@a[1])^ xor drk[r,1];
  310.     PDWord(@tempb[2])^:= PDWord(@a[2])^ xor drk[r,2];
  311.     PDWord(@tempb[3])^:= PDWord(@a[3])^ xor drk[r,3];
  312.     PDWord(@a[0])^:= PDWord(@T5[tempb[0,0]])^ xor
  313.                      PDWord(@T6[tempb[3,1]])^ xor
  314.                      PDWord(@T7[tempb[2,2]])^ xor
  315.                      PDWord(@T8[tempb[1,3]])^;
  316.     PDWord(@a[1])^:= PDWord(@T5[tempb[1,0]])^ xor
  317.                      PDWord(@T6[tempb[0,1]])^ xor
  318.                      PDWord(@T7[tempb[3,2]])^ xor
  319.                      PDWord(@T8[tempb[2,3]])^;
  320.     PDWord(@a[2])^:= PDWord(@T5[tempb[2,0]])^ xor
  321.                      PDWord(@T6[tempb[1,1]])^ xor
  322.                      PDWord(@T7[tempb[0,2]])^ xor
  323.                      PDWord(@T8[tempb[3,3]])^;
  324.     PDWord(@a[3])^:= PDWord(@T5[tempb[3,0]])^ xor
  325.                      PDWord(@T6[tempb[2,1]])^ xor
  326.                      PDWord(@T7[tempb[1,2]])^ xor
  327.                      PDWord(@T8[tempb[0,3]])^;
  328.   end;
  329.   PDWord(@tempb[0])^:= PDWord(@a[0])^ xor drk[1,0];
  330.   PDWord(@tempb[1])^:= PDWord(@a[1])^ xor drk[1,1];
  331.   PDWord(@tempb[2])^:= PDWord(@a[2])^ xor drk[1,2];
  332.   PDWord(@tempb[3])^:= PDWord(@a[3])^ xor drk[1,3];
  333.   a[0,0]:= S5[tempb[0,0]];
  334.   a[0,1]:= S5[tempb[3,1]];
  335.   a[0,2]:= S5[tempb[2,2]];
  336.   a[0,3]:= S5[tempb[1,3]];
  337.   a[1,0]:= S5[tempb[1,0]];
  338.   a[1,1]:= S5[tempb[0,1]];
  339.   a[1,2]:= S5[tempb[3,2]];
  340.   a[1,3]:= S5[tempb[2,3]];
  341.   a[2,0]:= S5[tempb[2,0]];
  342.   a[2,1]:= S5[tempb[1,1]];
  343.   a[2,2]:= S5[tempb[0,2]];
  344.   a[2,3]:= S5[tempb[3,3]];
  345.   a[3,0]:= S5[tempb[3,0]];
  346.   a[3,1]:= S5[tempb[2,1]];
  347.   a[3,2]:= S5[tempb[1,2]];
  348.   a[3,3]:= S5[tempb[0,3]];
  349.   PDWord(@a[0])^:= PDWord(@a[0])^ xor drk[0,0];
  350.   PDWord(@a[1])^:= PDWord(@a[1])^ xor drk[0,1];
  351.   PDWord(@a[2])^:= PDWord(@a[2])^ xor drk[0,2];
  352.   PDWord(@a[3])^:= PDWord(@a[3])^ xor drk[0,3];
  353.   PDword(@OutData)^:= PDword(@a[0,0])^;
  354.   PDword(dword(@OutData)+4)^:= PDword(@a[1,0])^;
  355.   PDword(dword(@OutData)+8)^:= PDword(@a[2,0])^;
  356.   PDword(dword(@OutData)+12)^:= PDword(@a[3,0])^;
  357. end;
  358.  
  359.  
  360. end.
  361.