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

  1. {******************************************************************************}
  2. {* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
  3. {******************************************************************************}
  4. {* A binary compatible implementation of IDEA *********************************}
  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 DCPidea;
  26.  
  27. interface
  28. uses
  29.   Classes, Sysutils, DCPcrypt2, DCPconst, DCPblockciphers;
  30.  
  31. type
  32.   TDCP_idea= class(TDCP_blockcipher64)
  33.   protected
  34.     EK, DK: array[0..51] of word;
  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.  
  52. class function TDCP_idea.GetMaxKeySize: integer;
  53. begin
  54.   Result:= 128;
  55. end;
  56.  
  57. class function TDCP_idea.GetID: integer;
  58. begin
  59.   Result:= DCP_idea;
  60. end;
  61.  
  62. class function TDCP_idea.GetAlgorithm: string;
  63. begin
  64.   Result:= 'IDEA';
  65. end;
  66.  
  67. class function TDCP_idea.SelfTest: boolean;
  68. const
  69.   Key1: array[0..15] of byte=
  70.     ($3A,$98,$4E,$20,$00,$19,$5D,$B3,$2E,$E5,$01,$C8,$C4,$7C,$EA,$60);
  71.   InData1: array[0..7] of byte=
  72.     ($01,$02,$03,$04,$05,$06,$07,$08);
  73.   OutData1: array[0..7] of byte=
  74.     ($97,$BC,$D8,$20,$07,$80,$DA,$86);
  75.   Key2: array[0..15] of byte=
  76.     ($00,$64,$00,$C8,$01,$2C,$01,$90,$01,$F4,$02,$58,$02,$BC,$03,$20);
  77.   InData2: array[0..7] of byte=
  78.     ($05,$32,$0A,$64,$14,$C8,$19,$FA);
  79.   OutData2: array[0..7] of byte=
  80.     ($65,$BE,$87,$E7,$A2,$53,$8A,$ED);
  81. var
  82.   Cipher: TDCP_idea;
  83.   Data: array[0..7] of byte;
  84. begin
  85.   Cipher:= TDCP_idea.Create(nil);
  86.   Cipher.Init(Key1,Sizeof(Key1)*8,nil);
  87.   Cipher.EncryptECB(InData1,Data);
  88.   Result:= boolean(CompareMem(@Data,@OutData1,Sizeof(Data)));
  89.   Cipher.DecryptECB(Data,Data);
  90.   Result:= Result and boolean(CompareMem(@Data,@InData1,Sizeof(Data)));
  91.   Cipher.Burn;
  92.   Cipher.Init(Key2,Sizeof(Key2)*8,nil);
  93.   Cipher.EncryptECB(InData2,Data);
  94.   Result:= Result and boolean(CompareMem(@Data,@OutData2,Sizeof(Data)));
  95.   Cipher.DecryptECB(Data,Data);
  96.   Result:= Result and boolean(CompareMem(@Data,@InData2,Sizeof(Data)));
  97.   Cipher.Burn;
  98.   Cipher.Free;
  99. end;
  100.  
  101. function MulInv(x: word): word;
  102. var
  103.   t0, t1, q, y: word;
  104. begin
  105.   if x<= 1 then
  106.   begin
  107.     Result:= x;
  108.     Exit;
  109.   end;
  110.   t1:= DWord($10001) div x;
  111.   y:= DWord($10001) mod x;
  112.   if y= 1 then
  113.   begin
  114.     Result:= (1 - t1) and $FFFF;
  115.     Exit;
  116.   end;
  117.   t0:= 1;
  118.   repeat
  119.     q:= x div y;
  120.     x:= x mod y;
  121.     t0:= t0 + (q*t1);
  122.     if x= 1 then
  123.     begin
  124.       Result:= t0;
  125.       Exit;
  126.     end;
  127.     q:= y div x;
  128.     y:= y mod x;
  129.     t1:= t1 + (q*t0);
  130.   until y= 1;
  131.   Result:= (1-t1) and $FFFF;
  132. end;
  133.  
  134. procedure TDCP_idea.InitKey(const Key; Size: longword);
  135. var
  136.   i: integer;
  137. begin
  138.   Size:= Size div 8;
  139.  
  140.   FillChar(EK,Sizeof(EK),0);
  141.   Move(Key,EK,Size);
  142.   for i:= 0 to 7 do
  143.     EK[i]:= (EK[i] shl 8) or (EK[i] shr 8);
  144.   for i:= 1 to 5 do
  145.   begin
  146.     EK[(i*8)+0]:= (EK[((i-1)*8)+1] shl 9) or (EK[((i-1)*8)+2] shr 7);
  147.     EK[(i*8)+1]:= (EK[((i-1)*8)+2] shl 9) or (EK[((i-1)*8)+3] shr 7);
  148.     EK[(i*8)+2]:= (EK[((i-1)*8)+3] shl 9) or (EK[((i-1)*8)+4] shr 7);
  149.     EK[(i*8)+3]:= (EK[((i-1)*8)+4] shl 9) or (EK[((i-1)*8)+5] shr 7);
  150.     EK[(i*8)+4]:= (EK[((i-1)*8)+5] shl 9) or (EK[((i-1)*8)+6] shr 7);
  151.     EK[(i*8)+5]:= (EK[((i-1)*8)+6] shl 9) or (EK[((i-1)*8)+7] shr 7);
  152.     EK[(i*8)+6]:= (EK[((i-1)*8)+7] shl 9) or (EK[((i-1)*8)+0] shr 7);
  153.     EK[(i*8)+7]:= (EK[((i-1)*8)+0] shl 9) or (EK[((i-1)*8)+1] shr 7);
  154.   end;
  155.   EK[48]:= (EK[41] shl 9) or (EK[42] shr 7);
  156.   EK[49]:= (EK[42] shl 9) or (EK[43] shr 7);
  157.   EK[50]:= (EK[43] shl 9) or (EK[44] shr 7);
  158.   EK[51]:= (EK[44] shl 9) or (EK[45] shr 7);
  159.  
  160.   DK[51]:= MulInv(EK[3]);
  161.   DK[50]:= -EK[2];
  162.   DK[49]:= -EK[1];
  163.   DK[48]:= MulInv(EK[0]);
  164.   for i:= 0 to 6 do
  165.   begin
  166.     DK[47-i*6]:= EK[i*6+5];
  167.     DK[46-i*6]:= EK[i*6+4];
  168.     DK[45-i*6]:= MulInv(EK[i*6+9]);
  169.     DK[44-i*6]:= -EK[i*6+7];
  170.     DK[43-i*6]:= -EK[i*6+8];
  171.     DK[42-i*6]:= MulInv(EK[i*6+6]);
  172.   end;
  173.   DK[5]:= EK[47];
  174.   DK[4]:= EK[46];
  175.   DK[3]:= MulInv(EK[51]);
  176.   DK[2]:= -EK[50];
  177.   DK[1]:= -EK[49];
  178.   DK[0]:= MulInv(EK[48]);
  179. end;
  180.  
  181. procedure TDCP_idea.Burn;
  182. begin
  183.   FillChar(EK,Sizeof(EK),0);
  184.   FillChar(DK,Sizeof(DK),0);
  185.   inherited Burn;
  186. end;
  187.  
  188. procedure Mul(var x: word; const y: word);
  189. var
  190.   p: DWord;
  191.   t16: word;
  192. begin
  193.   p:= DWord(x)*y;
  194.   if p= 0 then
  195.     x:= 1 - x - y
  196.   else
  197.   begin
  198.     x:= p shr 16;
  199.     t16:= p and $FFFF;
  200.     x:= t16 - x;
  201.     if (t16 < x) then
  202.       Inc(x);
  203.   end;
  204. end;
  205.  
  206. procedure TDCP_idea.EncryptECB(const InData; var OutData);
  207. var
  208.   x: array[1..4] of word;
  209.   s3, s2: word;
  210.   i: longword;
  211. begin
  212.   if not fInitialized then
  213.     raise EDCP_blockcipher.Create('Cipher not initialized');
  214.   PDword(@X[1])^:= PDword(@InData)^;
  215.   PDword(@X[3])^:= PDword(dword(@InData)+4)^;
  216.   for i:= 1 to 4 do
  217.     x[i]:= (x[i] shl 8) or (x[i] shr 8);
  218.   for i:= 0 to 7 do
  219.   begin
  220.     Mul(x[1],EK[(i*6)+0]);
  221.     Inc(x[2],EK[(i*6)+1]);
  222.     Inc(x[3],EK[(i*6)+2]);
  223.     Mul(x[4],EK[(i*6)+3]);
  224.     s3:= x[3];
  225.     x[3]:= x[3] xor x[1];
  226.     Mul(x[3],EK[(i*6)+4]);
  227.     s2:= x[2];
  228.     x[2]:= x[2] xor x[4];
  229.     Inc(x[2],x[3]);
  230.     Mul(x[2],EK[(i*6)+5]);
  231.     Inc(x[3],x[2]);
  232.     x[1]:= x[1] xor x[2];
  233.     x[4]:= x[4] xor x[3];
  234.     x[2]:= x[2] xor s3;
  235.     x[3]:= x[3] xor s2;
  236.   end;
  237.   Mul(x[1],EK[48]);
  238.   Inc(x[3],EK[49]);
  239.   Inc(x[2],EK[50]);
  240.   Mul(x[4],EK[51]);
  241.   x[1]:= (x[1] shl 8) or (x[1] shr 8);
  242.   s2:= (x[3] shl 8) or (x[3] shr 8);
  243.   x[3]:= (x[2] shl 8) or (x[2] shr 8);
  244.   x[4]:= (x[4] shl 8) or (x[4] shr 8);
  245.   x[2]:= s2;
  246.   PDword(@OutData)^:= PDword(@x[1])^;
  247.   PDword(dword(@OutData)+4)^:= PDword(@x[3])^;
  248. end;
  249.  
  250. procedure TDCP_idea.DecryptECB(const InData; var OutData);
  251. var
  252.   x: array[1..4] of word;
  253.   s3, s2: word;
  254.   i: longword;
  255. begin
  256.   if not fInitialized then
  257.     raise EDCP_blockcipher.Create('Cipher not initialized');
  258.   PDword(@X[1])^:= PDword(@InData)^;
  259.   PDword(@X[3])^:= PDword(dword(@InData)+4)^;
  260.   for i:= 1 to 4 do
  261.     x[i]:= (x[i] shl 8) or (x[i] shr 8);
  262.   for i:= 0 to 7 do
  263.   begin
  264.     Mul(x[1],DK[(i*6)+0]);
  265.     Inc(x[2],DK[(i*6)+1]);
  266.     Inc(x[3],DK[(i*6)+2]);
  267.     Mul(x[4],DK[(i*6)+3]);
  268.     s3:= x[3];
  269.     x[3]:= x[3] xor x[1];
  270.     Mul(x[3],DK[(i*6)+4]);
  271.     s2:= x[2];
  272.     x[2]:= x[2] xor x[4];
  273.     Inc(x[2],x[3]);
  274.     Mul(x[2],DK[(i*6)+5]);
  275.     Inc(x[3],x[2]);
  276.     x[1]:= x[1] xor x[2];
  277.     x[4]:= x[4] xor x[3];
  278.     x[2]:= x[2] xor s3;
  279.     x[3]:= x[3] xor s2;
  280.   end;
  281.   Mul(x[1],DK[48]);
  282.   Inc(x[3],DK[49]);
  283.   Inc(x[2],DK[50]);
  284.   Mul(x[4],DK[51]);
  285.   x[1]:= (x[1] shl 8) or (x[1] shr 8);
  286.   s2:= (x[3] shl 8) or (x[3] shr 8);
  287.   x[3]:= (x[2] shl 8) or (x[2] shr 8);
  288.   x[4]:= (x[4] shl 8) or (x[4] shr 8);
  289.   x[2]:= s2;
  290.   PDword(@OutData)^:= PDword(@x[1])^;
  291.   PDword(dword(@OutData)+4)^:= PDword(@x[3])^;
  292. end;
  293.  
  294.  
  295. end.
  296.