Witam,
Mam problem z implementacją algorytmu DES. Stworzełem małą klasę na podstawie opisu z tej strony:
http://db.tigra-system.pl/art.php?id=6
Poniżej przedstawiam kod źródłowy. Bardzo bym prosił żeby ktoś wskazał mi co robie źle.
{ Definicje typów }
TBit = 0..1;
TKey = String[8];
TDesKey = array[0..7] of Byte;
TDesSubKey = array[1..48] of TBit;
TBinArray = array of Char;
TDataBlock = array[0..7] of Byte;
TBitsArray = array[1..32] of TBit;
{ kodowanie jednego bloku 64-bitowego }
procedure TDesCrypto.CipherBlock(var Block: TDataBlock; Encrypt: Boolean);
var
L, R, XorResult: TBitsArray;
i, n: Integer;
CurrentBit: Byte;
begin
// 'zeruje' bufory poniewaz po permtuacji zostaje
// pare bitów (elementow tablicy) nieustawionych
// czyli np. 115 itp
FillChar(L, Length(L), 0);
FillChar(R, Length(R), 0);
FillChar(XorResult, Length(XorResult), 0);
// odczytuje poszczegolne bity z bloku danych
// i poddaje odrazu permtuacji IP
// oraz wkladam do odpowiedniej tablicy (L lub R)
for n := 0 to 7 do
begin
for i := 0 to 7 do
begin
CurrentBit := GetBit(Block[((n*8)+i) div 8], i+1);
if IP[(n*8)+i] > 31 then
R[IP[(n*8)+i] - 32] := CurrentBit
else
L[IP[(n*8)+i]] := CurrentBit;
end;
end;
// 16 rund transformacji
for n := 1 to 16 do
begin
// jezeli ma byc szyfrowanie to funkcja F przyjmuje klucze od 1 do 16
// a jezeli deszyfrowanie to zaczynam od ostatniego klucza i ide w dół (16 do 1)
if Encrypt then
F(R, FSubKeys[n])
else
F(R, FSubKeys[16-(n-1)]);
// xorowanie ciągu L i wyniku funckji R
for i := 1 to 32 do
XorResult[i] := L[i] xor R[i];
// przypisanie do L ciągu R, do R wyniku xorowania
L := R;
R := XorResult;
end;
// permutacja IP-1 (odwrotna)
// odrazu złączam obydwa ciagi w jeden
for i := 1 to 64 do
begin
// kazdy nowy bajt w bloku wynikowym
// ustawiam na 128 by byly wszystkie 8 bitow
if (i-1) mod 8 = 0 then
Block[i div 8] := 128;
if InvertedIP[i-1] <= 32 then
n := L[InvertedIP[i-1]]
else
n := R[InvertedIP[i-1] - 32];
// zapis do bloku wyjsciowego
SetBit(Block[i div 8], i mod 8, n);
end;
end;
{ funkcja F }
procedure TDesCrypto.F(var Block: TBitsArray; Key: TDesSubKey);
var
TmpBlock: array[1..48] of Byte;
RowByte, ColByte, NewNo: Byte;
i, n: Integer;
begin
// czyszcze bufor
FillChar(TmpBlock, Length(TmpBlock), 0);
// Przekształcenie bloku 32-bitowego przez macierz E
// oraz xorowanie z kluczem K[i]
for i := 1 to 48 do
begin
TmpBlock[i] := Block[E[i]];
TmpBlock[i] := TmpBlock[i] xor Key[i];
end;
// dzielenie danych na skrzynki 6-bitowe
for i := 0 to 7 do
begin
RowByte := 2;
// wyciagniecie 1 i 6 bitu
SetBit(RowByte, 7, TmpBlock[(i*6)+1]);
SetBit(RowByte, 8, TmpBlock[(i*6)+6]);
ColByte := 8;
// wyciagniecie bitow 2-5
SetBit(ColByte, 5, TmpBlock[(i*6)+2]);
SetBit(ColByte, 6, TmpBlock[(i*6)+3]);
SetBit(ColByte, 7, TmpBlock[(i*6)+4]);
SetBit(ColByte, 8, TmpBlock[(i*6)+5]);
// odczytanie wartosci z tabeli skrzynki i
NewNo := SBoxes[i][RowByte][ColByte];
// zapis do buforu wynikowego nowych bitow
for n := 1 to 4 do
TmpBlock[((i)*4)+n+(i*1)] := GetBit(NewNo, n+4);
end;
// permutacja przez macierz P
for i := 1 to 32 do
Block[i] := TmpBlock[P[i]];
end;
{ Generowanie kluczy }
procedure TDesCrypto.GenerateKeys;
var
C, D: array[1..28] of TBit;
ClearKey: array[1..56] of TBit;
CurrentBit: Byte;
i, n: Integer;
begin
// czyszcze bufory
FillChar(C, Length(C), 0);
FillChar(D, Length(D), 0);
// odrzucam co 8 bit z klucza wejsciowego (głównego)
for i := 1 to 64 do
begin
if i mod 8 = 0 then
Continue;
CurrentBit := GetBit(FKey[i div 8], i mod 8);
ClearKey[i - (i div 8)] := CurrentBit;
end;
// permutacja PC_1
// oraz dzielenie na 2 ciągi
for i := 1 to 56 do
begin
if PC_1[i] > 28 then
D[PC_1[i] - 28] := ClearKey[i]
else
C[PC_1[i]] := ClearKey[i];
end;
// 16 rund transformacji
for n := 1 to 16 do
begin
// w zaleznosci od liczby przesuniec przypadajacych na dana runde
// o tyle przesuwam ciagi C i D
for i := 1 to ShiftTable[n] do
begin
ShiftLeft(C, n);
ShiftLeft(D, n);
end;
// permutacja PC_2
// oraz zapis do klucza wyjsciowego
for i := 1 to 48 do
begin
if PC_2[i] > 28 then
FSubKeys[n][i] := D[PC_2[i shr 1]]
else
FSubKeys[n][i] := C[PC_2[i]];
end;
end;
end;
{ Inne procedury pomocnicze }
procedure TDesCrypto.ShiftLeft(var aSubKey; const Round: Byte);
var
i, Tmp: Byte;
KeyPart: TDesSubKey absolute aSubKey;
begin
Tmp := KeyPart[1];
for i := 1 to 27 do
KeyPart[i] := KeyPart[i+1];
KeyPart[28] := Tmp;
end;
function TDesCrypto.GetKey: TKey;
var
i: Byte;
begin
for i := 0 to 7 do
Result[i+1] := Char(FKey[i]);
end;
procedure TDesCrypto.SetKey(Value: TKey);
var
i: Byte;
begin
for i := 0 to 7 do
FKey[i] := Byte(Value[i+1]);
end;
Byłbym wdzięczny jeżeli ktoś pomógłby mi.
/////////////////////////////////////////////
edit
/////////////////////////////////////////////
ok, wszystko bylo zle :) zle zrozumialem ten opis, posluzylem sie tym i zrobilem wszystko od nowa:
http://www.aci.net/kalliste/des.htm