
АгеевМА_КМЗИ
.pdf{****************************************************************
**************}
implementation
{$I Cast128.inc}
{$R-}
function Cast128SelfTest; const
Key: array[0..15] of byte= ($01,$23,$45,$67,$12,$34,$56,$78,$23,$45,$67,$89,$34,$56,$78,$9A);
InBlock: array[0..7] of byte= ($01,$23,$45,$67,$89,$AB,$CD,$EF); OutBlock: array[0..7] of byte= ($23,$8B,$4F,$E5,$84,$7E,$44,$B2);
var
Block: array[0..7] of byte; Data: TCast128Data;
begin Cast128Init(Data,@Key,Sizeof(Key),nil);
Cast128EncryptECB(Data,@InBlock,@Block);
Result:= CompareMem(@Block,@OutBlock,Sizeof(Block)); Cast128DecryptECB(Data,@Block,@Block);
Result:= Result and CompareMem(@Block,@InBlock,Sizeof(Block)); Cast128Burn(Data);
end;
procedure Cast128Init; var
x, t, z: array[0..3] of DWord; i: integer;
begin
if (Len<= 0) or (Len> 16) then
raise Exception.Create('Cast128: Key must be between 1 and 16 bytes long'); with Data do
begin
if IV= nil then begin
FillChar(InitBlock,8,0);
FillChar(LastBlock,8,0); end
else begin
Move(IV^,InitBlock,8);
Move(IV^,LastBlock,8);
end;
if Len<= 10 then Rounds:= 12
else
Rounds:= 16; FillChar(x,Sizeof(x),0); Move(Key^,x,Len);
x[0]:= (x[0] shr 24) or ((x[0] shr 8) and $FF00) or ((x[0] shl 8) and $FF0000) or (x[0] shl 24);
x[1]:= (x[1] shr 24) or ((x[1] shr 8) and $FF00) or ((x[1] shl 8) and $FF0000) or (x[1] shl 24);
x[2]:= (x[2] shr 24) or ((x[2] shr 8) and $FF00) or ((x[2] shl 8) and $FF0000) or (x[2] shl 24);
x[3]:= (x[3] shr 24) or ((x[3] shr 8) and $FF00) or ((x[3] shl 8) and $FF0000) or (x[3] shl 24);
i:= 0;
while i< 32 do
begin
case (i and 4) of 0:
begin
z[0]:= x[0] xor cast_sbox5[(x[3] shr 16) and $FF] xor cast_sbox6[x[3] and $FF] xor cast_sbox7[x[3] shr 24] xor cast_sbox8[(x[3] shr 8) and $FF] xor cast_sbox7[x[2] shr 24]; t[0]:= z[0];
z[1]:= x[2] xor cast_sbox5[z[0] shr 24] xor
cast_sbox6[(z[0] shr 8) and $FF] xor cast_sbox7[(z[0] shr 16) and $FF]
xor
cast_sbox8[z[0] and $FF] xor cast_sbox8[(x[2] shr 8) and $FF]; t[1]:= z[1];
z[2]:= x[3] xor cast_sbox5[z[1] and $FF] xor
cast_sbox6[(z[1] shr 8) and $FF] xor cast_sbox7[(z[1] shr 16) and $FF]
xor
cast_sbox8[z[1] shr 24] xor cast_sbox5[(x[2] shr 16) and $FF]; t[2]:= z[2];
z[3]:= x[1] xor cast_sbox5[(z[2] shr 8) and $FF] xor cast_sbox6[(z[2] shr 16) and $FF] xor cast_sbox7[z[2] and $FF] xor cast_sbox8[z[2] shr 24] xor cast_sbox6[x[2] and $FF];
t[3]:= z[3]; end;
4: begin
x[0]:= z[2] xor cast_sbox5[(z[1] shr 16) and $FF] xor cast_sbox6[z[1] and $FF] xor cast_sbox7[z[1] shr 24] xor cast_sbox8[(z[1] shr 8) and $FF] xor cast_sbox7[z[0] shr 24]; t[0]:= x[0];
x[1]:= z[0] xor cast_sbox5[x[0] shr 24] xor
cast_sbox6[(x[0] shr 8) and $FF] xor cast_sbox7[(x[0] shr 16) and $FF]
xor
cast_sbox8[x[0] and $FF] xor cast_sbox8[(z[0] shr 8) and $FF]; t[1]:= x[1];
x[2]:= z[1] xor cast_sbox5[x[1] and $FF] xor
cast_sbox6[(x[1] shr 8) and $FF] xor cast_sbox7[(x[1] shr 16) and $FF]
xor
cast_sbox8[x[1] shr 24] xor cast_sbox5[(z[0] shr 16) and $FF]; t[2]:= x[2];
x[3]:= z[3] xor cast_sbox5[(x[2] shr 8) and $FF] xor cast_sbox6[(x[2] shr 16) and $FF] xor cast_sbox7[x[2] and $FF] xor cast_sbox8[x[2] shr 24] xor cast_sbox6[z[0] and $FF];
t[3]:= x[3]; end;
end;
case (i and 12) of 0,12:
begin
xKey[i+0]:= cast_sbox5[t[2] shr 24] xor cast_sbox6[(t[2] shr 16) and $FF]
xor
cast_sbox7[t[1] and $FF] xor cast_sbox8[(t[1] shr 8) and $FF]; xKey[i+1]:= cast_sbox5[(t[2] shr 8) and $FF] xor cast_sbox6[t[2] and $FF]
xor
cast_sbox7[(t[1] shr 16) and $FF] xor cast_sbox8[t[1] shr 24]; xKey[i+2]:= cast_sbox5[t[3] shr 24] xor cast_sbox6[(t[3] shr 16) and $FF]
xor
cast_sbox7[t[0] and $FF] xor cast_sbox8[(t[0] shr 8) and $FF]; xKey[i+3]:= cast_sbox5[(t[3] shr 8) and $FF] xor cast_sbox6[t[3] and $FF]
xor
cast_sbox7[(t[0] shr 16) and $FF] xor cast_sbox8[t[0] shr 24];
end;
4,8: begin
xKey[i+0]:= cast_sbox5[t[0] and $FF] xor cast_sbox6[(t[0] shr 8) and $FF]
xor
cast_sbox7[t[3] shr 24] xor cast_sbox8[(t[3] shr 16) and $FF]; xKey[i+1]:= cast_sbox5[(t[0] shr 16) and $FF] xor cast_sbox6[t[0] shr 24]
xor
cast_sbox7[(t[3] shr 8) and $FF] xor cast_sbox8[t[3] and $FF]; xKey[i+2]:= cast_sbox5[t[1] and $FF] xor cast_sbox6[(t[1] shr 8) and $FF]
xor
cast_sbox7[t[2] shr 24] xor cast_sbox8[(t[2] shr 16) and $FF]; xKey[i+3]:= cast_sbox5[(t[1] shr 16) and $FF] xor cast_sbox6[t[1] shr 24]
xor
cast_sbox7[(t[2] shr 8) and $FF] xor cast_sbox8[t[2] and $FF]; end;
end;
case (i and 12) of 0:
begin
xKey[i+0]:= xKey[i+0] xor cast_sbox5[(z[0] shr 8) and $FF]; xKey[i+1]:= xKey[i+1] xor cast_sbox6[(z[1] shr 8) and $FF]; xKey[i+2]:= xKey[i+2] xor cast_sbox7[(z[2] shr 16) and $FF]; xKey[i+3]:= xKey[i+3] xor cast_sbox8[z[3] shr 24];
end;
4: begin
xKey[i+0]:= xKey[i+0] xor cast_sbox5[x[2] shr 24]; xKey[i+1]:= xKey[i+1] xor cast_sbox6[(x[3] shr 16) and $FF]; xKey[i+2]:= xKey[i+2] xor cast_sbox7[x[0] and $FF];
xKey[i+3]:= xKey[i+3] xor cast_sbox8[x[1] and $FF]; end;
8: begin
xKey[i+0]:= xKey[i+0] xor cast_sbox5[(z[2] shr 16) and $FF]; xKey[i+1]:= xKey[i+1] xor cast_sbox6[z[3] shr 24]; xKey[i+2]:= xKey[i+2] xor cast_sbox7[(z[0] shr 8) and $FF]; xKey[i+3]:= xKey[i+3] xor cast_sbox8[(z[1] shr 8) and $FF];
end;
12: begin
xKey[i+0]:= xKey[i+0] xor cast_sbox5[x[0] and $FF]; xKey[i+1]:= xKey[i+1] xor cast_sbox6[x[1] and $FF]; xKey[i+2]:= xKey[i+2] xor cast_sbox7[x[2] shr 24]; xKey[i+3]:= xKey[i+3] xor cast_sbox8[(x[3] shr 16) and $FF];
end;
end;
if (i >= 16) then begin
xKey[i+0]:= xKey[i+0] and 31; xKey[i+1]:= xKey[i+1] and 31; xKey[i+2]:= xKey[i+2] and 31; xKey[i+3]:= xKey[i+3] and 31;
end;
Inc(i,4);
end;
end;
end;
procedure Cast128Burn;
begin FillChar(Data,Sizeof(Data),0);
end;
procedure Cast128EncryptECB; var
t, l, r: DWord; begin
Move(InData^,l,Sizeof(l));
Move(pointer(integer(InData)+4)^,r,Sizeof(r));
l:= (l shr 24) or ((l shr 8) and $FF00) or ((l shl 8) and $FF0000) or (l shl 24); r:= (r shr 24) or ((r shr 8) and $FF00) or ((r shl 8) and $FF0000) or (r shl 24); t:= LRot32(Data.xKey[0]+r, Data.xKey[0+16]);
l:= l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) - cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[1] xor l, Data.xKey[1+16]);
r:= r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) + cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[2]-r, Data.xKey[2+16]);
l:= l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[3]+l, Data.xKey[3+16]);
r:= r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) - cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[4] xor r, Data.xKey[4+16]);
l:= l xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) + cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[5]-l, Data.xKey[5+16]);
r:= r xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[6]+r, Data.xKey[6+16]);
l:= l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) - cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[7] xor l, Data.xKey[7+16]);
r:= r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) + cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[8]-r, Data.xKey[8+16]);
l:= l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[9]+l, Data.xKey[9+16]);
r:= r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) - cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[10] xor r, Data.xKey[10+16]);
l:= l xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) + cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[11]-l, Data.xKey[11+16]);
r:= r xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
if Data.Rounds> 12 then begin
t:= LRot32(Data.xKey[12]+r, Data.xKey[12+16]);
l:= l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) - cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[13] xor l, Data.xKey[13+16]);
r:= r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) + cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[14]-r, Data.xKey[14+16]);
l:= l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[15]+l, Data.xKey[15+16]);
r:= r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) - cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
end;
l:= (l shr 24) or ((l shr 8) and $FF00) or ((l shl 8) and $FF0000) or (l shl 24); r:= (r shr 24) or ((r shr 8) and $FF00) or ((r shl 8) and $FF0000) or (r shl 24); Move(r,OutData^,Sizeof(r));
Move(l,pointer(integer(OutData)+4)^,Sizeof(l));
end;
procedure Cast128DecryptECB; var
t, l, r: DWord; begin
Move(InData^,r,Sizeof(l));
Move(pointer(integer(InData)+4)^,l,Sizeof(l));
l:= (l shr 24) or ((l shr 8) and $FF00) or ((l shl 8) and $FF0000) or (l shl 24); r:= (r shr 24) or ((r shr 8) and $FF00) or ((r shl 8) and $FF0000) or (r shl 24); if Data.Rounds> 12 then
begin
t:= LRot32(Data.xKey[15]+l, Data.xKey[15+16]);
r:= r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) - cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[14]-r, Data.xKey[14+16]);
l:= l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[13] xor l, Data.xKey[13+16]);
r:= r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) + cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[12]+r, Data.xKey[12+16]);
l:= l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]); end;
t:= LRot32(Data.xKey[11]-l, Data.xKey[11+16]);
r:= r xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[10] xor r, Data.xKey[10+16]);
l:= l xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) + cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[9]+l, Data.xKey[9+16]);
r:= r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) - cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[8]-r, Data.xKey[8+16]);
l:= l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[7] xor l, Data.xKey[7+16]);
r:= r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) + cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[6]+r, Data.xKey[6+16]);
l:= l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) - cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[5]-l, Data.xKey[5+16]);
r:= r xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[4] xor r, Data.xKey[4+16]);
l:= l xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) + cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[3]+l, Data.xKey[3+16]);
r:= r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) - cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t:= LRot32(Data.xKey[2]-r, Data.xKey[2+16]);