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 >
Wrap
Pascal/Delphi Source File
|
2002-07-08
|
8KB
|
260 lines
{******************************************************************************}
{* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
{******************************************************************************}
{* A binary compatible implementation of Misty1 *******************************}
{******************************************************************************}
{* Copyright (c) 1999-2002 David Barton *}
{* Permission is hereby granted, free of charge, to any person obtaining a *}
{* copy of this software and associated documentation files (the "Software"), *}
{* to deal in the Software without restriction, including without limitation *}
{* the rights to use, copy, modify, merge, publish, distribute, sublicense, *}
{* and/or sell copies of the Software, and to permit persons to whom the *}
{* Software is furnished to do so, subject to the following conditions: *}
{* *}
{* The above copyright notice and this permission notice shall be included in *}
{* all copies or substantial portions of the Software. *}
{* *}
{* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *}
{* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *}
{* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *}
{* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *}
{* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *}
{* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *}
{* DEALINGS IN THE SOFTWARE. *}
{******************************************************************************}
unit DCPmisty1;
interface
uses
Classes, Sysutils, DCPcrypt2, DCPconst, DCPblockciphers;
const
NUMROUNDS= 8;
type
TDCP_misty1= class(TDCP_blockcipher64)
protected
KeyData: array[0..31] of DWord;
function FI(const FI_IN, FI_KEY: DWord): DWord;
function FO(const FO_IN: DWord; const k: longword): DWord;
function FL(const FL_IN: DWord; const k: longword): DWord;
function FLINV(const FL_IN: DWord; const k: longword): DWord;
procedure InitKey(const Key; Size: longword); override;
public
class function GetID: integer; override;
class function GetAlgorithm: string; override;
class function GetMaxKeySize: integer; override;
class function SelfTest: boolean; override;
procedure Burn; override;
procedure EncryptECB(const InData; var OutData); override;
procedure DecryptECB(const InData; var OutData); override;
end;
{******************************************************************************}
{******************************************************************************}
implementation
{$R-}{$Q-}
{$I DCPmisty1.inc}
function SwapDword(a: dword): dword;
begin
Result:= ((a and $FF) shl 24) or ((a and $FF00) shl 8) or ((a and $FF0000) shr 8) or ((a and $FF000000) shr 24);
end;
class function TDCP_misty1.GetID: integer;
begin
Result:= DCP_misty1;
end;
class function TDCP_misty1.GetAlgorithm: string;
begin
Result:= 'Misty1';
end;
class function TDCP_misty1.GetMaxKeySize: integer;
begin
Result:= 128;
end;
class function TDCP_misty1.SelfTest: boolean;
const
Key: array[0..15] of byte=
($00,$11,$22,$33,$44,$55,$66,$77,$88,$99,$aa,$bb,$cc,$dd,$ee,$ff);
Plain1: array[0..7] of byte= ($01,$23,$45,$67,$89,$ab,$cd,$ef);
Plain2: array[0..7] of byte= ($fe,$dc,$ba,$98,$76,$54,$32,$10);
Cipher1: array[0..7] of byte= ($8b,$1d,$a5,$f5,$6a,$b3,$d0,$7c);
Cipher2: array[0..7] of byte= ($04,$b6,$82,$40,$b1,$3b,$e9,$5d);
var
Cipher: TDCP_misty1;
Block: array[0..7] of byte;
begin
Cipher:= TDCP_misty1.Create(nil);
Cipher.Init(Key,Sizeof(Key)*8,nil);
Cipher.EncryptECB(Plain1,Block);
Result:= CompareMem(@Cipher1,@Block,Sizeof(Block));
Cipher.DecryptECB(Block,Block);
Result:= Result and CompareMem(@Plain1,@Block,Sizeof(Block));
Cipher.EncryptECB(Plain2,Block);
Result:= Result and CompareMem(@Cipher2,@Block,Sizeof(Block));
Cipher.DecryptECB(Block,Block);
Result:= Result and CompareMem(@Plain2,@Block,Sizeof(Block));
Cipher.Burn;
Cipher.Free;
end;
function TDCP_misty1.FI(const FI_IN, FI_KEY: DWord): DWord;
var
d7, d9: DWord;
begin
d9:= (FI_IN shr 7) and $1ff;
d7:= FI_IN and $7f;
d9:= S9Table[d9] xor d7;
d7:= (S7Table[d7] xor d9) and $7f;
d7:= d7 xor ((FI_KEY shr 9) and $7f);
d9:= d9 xor (FI_KEY and $1ff);
d9:= S9Table[d9] xor d7;
Result:= (d7 shl 9) or d9;
end;
function TDCP_misty1.FO(const FO_IN: DWord; const k: longword): DWord;
var
t0, t1: DWord;
begin
t0:= FO_IN shr 16;
t1:= FO_IN and $FFFF;
t0:= t0 xor KeyData[k];
t0:= FI(t0,KeyData[((k+5) mod 8) + 8]);
t0:= t0 xor t1;
t1:= t1 xor KeyData[(k+2) mod 8];
t1:= FI(t1,KeyData[((k+1) mod 8) + 8]);
t1:= t1 xor t0;
t0:= t0 xor KeyData[(k+7) mod 8];
t0:= FI(t0,KeyData[((k+3) mod 8) + 8]);
t0:= t0 xor t1;
t1:= t1 xor KeyData[(k+4) mod 8];
Result:= (t1 shl 16) or t0;
end;
function TDCP_misty1.FL(const FL_IN: DWord; const k: longword): DWord;
var
d0, d1: DWord;
t: byte;
begin
d0:= FL_IN shr 16;
d1:= FL_IN and $FFFF;
if (k mod 2)<> 0 then
begin
t:= (k-1) div 2;
d1:= d1 xor (d0 and KeyData[((t + 2) mod 8) + 8]);
d0:= d0 xor (d1 or KeyData[(t + 4) mod 8]);
end
else
begin
t:= k div 2;
d1:= d1 xor (d0 and KeyData[t]);
d0:= d0 xor (d1 or KeyData[((t+6) mod 8) + 8]);
end;
Result:= (d0 shl 16) or d1;
end;
function TDCP_misty1.FLINV(const FL_IN: DWord; const k: longword): DWord;
var
d0, d1: DWord;
t: byte;
begin
d0:= FL_IN shr 16;
d1:= FL_IN and $FFFF;
if (k mod 2)<> 0 then
begin
t:= (k-1) div 2;
d0:= d0 xor (d1 or KeyData[(t+4) mod 8]);
d1:= d1 xor (d0 and KeyData[((t+2) mod 8) + 8]);
end
else
begin
t:= k div 2;
d0:= d0 xor (d1 or KeyData[((t+6) mod 8) + 8]);
d1:= d1 xor (d0 and KeyData[t]);
end;
Result:= (d0 shl 16) or d1;
end;
procedure TDCP_misty1.InitKey(const Key; Size: longword);
var
KeyB: array[0..15] of byte;
i: longword;
begin
FillChar(KeyB,Sizeof(KeyB),0);
Move(Key,KeyB,Size div 8);
for i:= 0 to 7 do
KeyData[i]:= (KeyB[i*2] * 256) + KeyB[i*2+1];
for i:= 0 to 7 do
begin
KeyData[i+8]:= FI(KeyData[i],KeyData[(i+1) mod 8]);
KeyData[i+16]:= KeyData[i+8] and $1FF;
KeyData[i+24]:= KeyData[i+8] shr 9;
end;
end;
procedure TDCP_misty1.Burn;
begin
FillChar(KeyData,Sizeof(KeyData),0);
inherited Burn;
end;
procedure TDCP_misty1.EncryptECB(const InData; var OutData);
var
d0, d1: DWord;
i: longword;
begin
if not fInitialized then
raise EDCP_blockcipher.Create('Cipher not initialized');
d0:= SwapDWord(PDWord(@InData)^);
d1:= SwapDWord(PDWord(longword(@InData)+4)^);
for i:= 0 to NUMROUNDS-1 do
begin
if (i mod 2)= 0 then
begin
d0:= FL(D0,i);
d1:= FL(D1,i+1);
d1:= d1 xor FO(d0,i);
end
else
d0:= d0 xor FO(d1,i);
end;
d0:= FL(d0,NUMROUNDS);
d1:= FL(d1,NUMROUNDS+1);
PDWord(@OutData)^:= SwapDWord(d1);
PDWord(longword(@OutData)+4)^:= SwapDWord(d0);
end;
procedure TDCP_misty1.DecryptECB(const InData; var OutData);
var
d0, d1: DWord;
i: longword;
begin
if not fInitialized then
raise EDCP_blockcipher.Create('Cipher not initialized');
d1:= SwapDWord(PDWord(@InData)^);
d0:= SwapDWord(PDWord(longword(@InData)+4)^);
d1:= FLINV(d1,NUMROUNDS+1);
d0:= FLINV(d0,NUMROUNDS);
for i:= NUMROUNDS-1 downto 0 do
begin
if (i mod 2)= 0 then
begin
d1:= d1 xor FO(d0,i);
d0:= FLINV(D0,i);
d1:= FLINV(D1,i+1);
end
else
d0:= d0 xor FO(d1,i);
end;
PDWord(@OutData)^:= SwapDWord(d0);
PDWord(longword(@OutData)+4)^:= SwapDWord(d1);
end;
end.