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 >
Wrap
Pascal/Delphi Source File
|
2002-07-08
|
13KB
|
444 lines
{******************************************************************************}
{* DCPcrypt v2.0 written by David Barton (crypto@cityinthesky.co.uk) **********}
{******************************************************************************}
{* A binary compatible implementation of Ice and it's variants ****************}
{******************************************************************************}
{* 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 DCPice;
interface
uses
Classes, Sysutils, DCPcrypt2, DCPconst, DCPblockciphers;
type
TDCP_customice= class(TDCP_blockcipher64)
protected
rounds: dword;
ik_keysched: array[0..31,0..2] of dword;
function f(p, sk: dword): dword;
procedure key_sched_build(kb: pwordarray; n: dword; keyrot: pdwordarray);
procedure InitIce(const Key; Size: longword; n: dword);
public
procedure Burn; override;
procedure EncryptECB(const InData; var OutData); override;
procedure DecryptECB(const InData; var OutData); override;
constructor Create(AOwner: TComponent); override;
end;
TDCP_ice= class(TDCP_customice)
protected
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;
end;
TDCP_thinice= class(TDCP_customice)
protected
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;
end;
TDCP_ice2= class(TDCP_customice)
protected
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;
end;
{******************************************************************************}
{******************************************************************************}
implementation
{$R-}{$Q-}
var
ice_sbox: array[0..3,0..1023] of dword;
ice_sboxdone: boolean;
const
ice_smod: array[0..3,0..3] of dword= (
(333, 313, 505, 369),
(379, 375, 319, 391),
(361, 445, 451, 397),
(397, 425, 395, 505));
ice_sxor: array[0..3,0..3] of dword= (
($83, $85, $9b, $cd),
($cc, $a7, $ad, $41),
($4b, $2e, $d4, $33),
($ea, $cb, $2e, $04));
ice_keyrot: array[0..15] of dword= (
0, 1, 2, 3, 2, 1, 3, 0,
1, 3, 2, 0, 3, 1, 0, 2);
ice_pbox: array[0..31] of dword= (
$00000001, $00000080, $00000400, $00002000,
$00080000, $00200000, $01000000, $40000000,
$00000008, $00000020, $00000100, $00004000,
$00010000, $00800000, $04000000, $20000000,
$00000004, $00000010, $00000200, $00008000,
$00020000, $00400000, $08000000, $10000000,
$00000002, $00000040, $00000800, $00001000,
$00040000, $00100000, $02000000, $80000000);
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;
{******************************************************************************}
function gf_mult(a, b, m: dword): dword;
var
res: dword;
begin
res:= 0;
while b<> 0 do
begin
if (b and 1)<> 0 then
res:= res xor a;
a:= a shl 1;
b:= b shr 1;
if a>= 256 then
a:= a xor m;
end;
Result:= res;
end;
function gf_exp7(b, m: dword): dword;
var
x: dword;
begin
if b= 0 then
Result:= 0
else
begin
x:= gf_mult(b,b,m);
x:= gf_mult(b,x,m);
x:= gf_mult(x,x,m);
Result:= gf_mult(b,x,m);
end;
end;
function ice_perm32(x: dword): dword;
var
res: dword;
pbox: pdword;
begin
res:= 0;
pbox:= @ice_pbox;
while x<> 0 do
begin
if (x and 1)<> 0 then
res:= res or pbox^;
Inc(pbox);
x:= x shr 1;
end;
Result:= res;
end;
procedure ice_sboxes_init;
var
i, col, row: dword;
x: dword;
begin
for i:= 0 to 1023 do
begin
col:= (i shr 1) and $FF;
row:= (i and 1) or ((i and $200) shr 8);
x:= gf_exp7(col xor ice_sxor[0,row],ice_smod[0,row]) shl 24;
ice_sbox[0,i]:= ice_perm32(x);
x:= gf_exp7(col xor ice_sxor[1,row],ice_smod[1,row]) shl 16;
ice_sbox[1,i]:= ice_perm32(x);
x:= gf_exp7(col xor ice_sxor[2,row],ice_smod[2,row]) shl 8;
ice_sbox[2,i]:= ice_perm32(x);
x:= gf_exp7(col xor ice_sxor[3,row],ice_smod[3,row]);
ice_sbox[3,i]:= ice_perm32(x);
end;
end;
function TDCP_customice.f(p, sk: dword): dword;
var
tl, tr, al, ar: dword;
begin
tl:= ((p shr 16) and $3ff) or (((p shr 14) or (p shl 18)) and $ffc00);
tr:= (p and $3ff) or ((p shl 2) and $ffc00);
al:= ik_keysched[sk,2] and (tl xor tr);
ar:= al xor tr;
al:= al xor tl;
al:= al xor ik_keysched[sk,0];
ar:= ar xor ik_keysched[sk,1];
Result:= ice_sbox[0,al shr 10] or ice_sbox[1,al and $3ff] or
ice_sbox[2,ar shr 10] or ice_sbox[3,ar and $3ff];
end;
procedure TDCP_customice.key_sched_build(kb: pwordarray; n: dword; keyrot: pdwordarray);
var
i, j, k, kr: dword;
keys: pdwordarray;
currentsk: pdword;
currentkb: pword;
bit: dword;
begin
for i:= 0 to 7 do
begin
kr:= keyrot^[i];
keys:= @ik_keysched[n+i];
for j:= 0 to 2 do
keys^[j]:= 0;
for j:= 0 to 14 do
begin
currentsk:= @keys^[j mod 3];
for k:= 0 to 3 do
begin
currentkb:= @kb^[(kr + k) and 3];
bit:= currentkb^ and 1;
currentsk^:= (currentsk^ shl 1) or bit;
currentkb^:= (currentkb^ shr 1) or ((bit xor 1) shl 15);
end;
end;
end;
end;
procedure TDCP_customice.InitIce(const Key; Size: longword; n: dword);
var
i, j: dword;
kb: array[0..3] of word;
keyb: array[0..15] of byte;
begin
FillChar(keyb,Sizeof(keyb),0);
Move(key,keyb,Size div 8);
if n> 0 then
rounds:= 16 * n
else
rounds:= 8;
if rounds= 8 then
begin
for i:= 0 to 4 do
kb[3 - i]:= (keyb[i*2] shl 8) or keyb[i*2 + 1];
key_sched_build(@kb,0,@ice_keyrot);
end
else
begin
for i:= 0 to (n-1) do
begin
for j:= 0 to 3 do
kb[3-j]:= (keyb[i*8 + j*2] shl 8) or keyb[i*8 + j*2 + 1];
key_sched_build(@kb,i*8,@ice_keyrot);
key_sched_build(@kb,rounds - 8 - i*8,@ice_keyrot[8]);
end;
end;
end;
procedure TDCP_customice.Burn;
begin
FillChar(ik_keysched,Sizeof(ik_keysched),0);
Rounds:= 0;
inherited Burn;
end;
procedure TDCP_customice.EncryptECB(const InData; var OutData);
var
i, l, r: dword;
begin
if not fInitialized then
raise EDCP_blockcipher.Create('Cipher not initialized');
l:= SwapDWord(Pdword(@InData)^);
r:= SwapDWord(Pdword(longword(@InData)+4)^);
i:= 0;
while i< rounds do
begin
l:= l xor f(r,i);
r:= r xor f(l,i+1);
Inc(i,2);
end;
Pdword(@OutData)^:= SwapDWord(r);
Pdword(longword(@OutData)+4)^:= SwapDWord(l);
end;
procedure TDCP_customice.DecryptECB(const InData; var OutData);
var
l, r: dword;
i: integer;
begin
if not fInitialized then
raise EDCP_blockcipher.Create('Cipher not initialized');
l:= SwapDWord(Pdword(@InData)^);
r:= SwapDWord(Pdword(longword(@InData)+4)^);
i:= rounds-1;
while i> 0 do
begin
l:= l xor f(r,i);
r:= r xor f(l,i-1);
Dec(i,2);
end;
Pdword(@OutData)^:= SwapDWord(r);
Pdword(longword(@OutData)+4)^:= SwapDWord(l);
end;
constructor TDCP_customice.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
if not ice_sboxdone then
begin
ice_sboxes_init;
ice_sboxdone:= true;
end;
end;
{******************************************************************************}
class function TDCP_ice.GetMaxKeySize: integer;
begin
Result:= 64;
end;
class function TDCP_ice.GetID: integer;
begin
Result:= DCP_ice;
end;
class function TDCP_ice.GetAlgorithm: string;
begin
Result:= 'Ice';
end;
class function TDCP_ice.SelfTest: boolean;
const
Key1: array[0..7] of byte= ($de,$ad,$be,$ef,$01,$23,$45,$67);
InData1: array[0..7] of byte= ($fe,$dc,$ba,$98,$76,$54,$32,$10);
OutData1: array[0..7] of byte= ($7d,$6e,$f1,$ef,$30,$d4,$7a,$96);
var
Cipher: TDCP_ice;
Data: array[0..7] of byte;
begin
Cipher:= TDCP_ice.Create(nil);
Cipher.Init(Key1,Sizeof(Key1)*8,nil);
Cipher.EncryptECB(InData1,Data);
Result:= boolean(CompareMem(@Data,@OutData1,Sizeof(Data)));
Cipher.Reset;
Cipher.DecryptECB(Data,Data);
Result:= boolean(CompareMem(@Data,@InData1,Sizeof(Data))) and Result;
Cipher.Burn;
Cipher.Free;
end;
procedure TDCP_ice.InitKey(const Key; Size: longword);
begin
InitIce(Key,Size,1);
end;
{******************************************************************************}
class function TDCP_thinice.GetMaxKeySize: integer;
begin
Result:= 64;
end;
class function TDCP_thinice.GetID: integer;
begin
Result:= DCP_thinice;
end;
class function TDCP_thinice.GetAlgorithm: string;
begin
Result:= 'Thin Ice';
end;
class function TDCP_thinice.SelfTest: boolean;
const
Key1: array[0..7] of byte= ($de,$ad,$be,$ef,$01,$23,$45,$67);
InData1: array[0..7] of byte= ($fe,$dc,$ba,$98,$76,$54,$32,$10);
OutData1: array[0..7] of byte= ($de,$24,$0d,$83,$a0,$0a,$9c,$c0);
var
Cipher: TDCP_thinice;
Data: array[0..7] of byte;
begin
Cipher:= TDCP_thinice.Create(nil);
Cipher.Init(Key1,Sizeof(Key1)*8,nil);
Cipher.EncryptECB(InData1,Data);
Result:= boolean(CompareMem(@Data,@OutData1,Sizeof(Data)));
Cipher.Reset;
Cipher.DecryptECB(Data,Data);
Result:= boolean(CompareMem(@Data,@InData1,Sizeof(Data))) and Result;
Cipher.Burn;
Cipher.Free;
end;
procedure TDCP_thinice.InitKey(const Key; Size: longword);
begin
InitIce(Key,Size,0);
end;
{******************************************************************************}
class function TDCP_ice2.GetMaxKeySize: integer;
begin
Result:= 128;
end;
class function TDCP_ice2.GetID: integer;
begin
Result:= DCP_ice2;
end;
class function TDCP_ice2.GetAlgorithm: string;
begin
Result:= 'Ice2';
end;
class function TDCP_ice2.SelfTest: boolean;
const
Key1: array[0..15] of byte=
($00,$11,$22,$33,$44,$55,$66,$77,$88,$99,$aa,$bb,$cc,$dd,$ee,$ff);
InData1: array[0..7] of byte= ($fe,$dc,$ba,$98,$76,$54,$32,$10);
OutData1: array[0..7] of byte= ($f9,$48,$40,$d8,$69,$72,$f2,$1c);
var
Cipher: TDCP_ice2;
Data: array[0..7] of byte;
begin
Cipher:= TDCP_ice2.Create(nil);
Cipher.Init(Key1,Sizeof(Key1)*8,nil);
Cipher.EncryptECB(InData1,Data);
Result:= boolean(CompareMem(@Data,@OutData1,Sizeof(Data)));
Cipher.Reset;
Cipher.DecryptECB(Data,Data);
Result:= boolean(CompareMem(@Data,@InData1,Sizeof(Data))) and Result;
Cipher.Burn;
Cipher.Free;
end;
procedure TDCP_ice2.InitKey(const Key; Size: longword);
begin
InitIce(Key,Size,2);
end;
initialization
ice_sboxdone:= false;
end.