Ìîäóëü äëÿ RC6 øèôðîâàíèÿ
Àâòîð: Ìàòâååâ Èãîðü
Ïåðåêâàëèôèöèðîâàëñÿ õàêåð â ñâÿùåííèêà è îäíàæäû ïðèõîäèò íà ïðîïîâåäü ïîñëå áîëüøîãî ïåðåïîÿ. Çàïëåòàþùèìñÿ ÿçûêîì: - È äà ïîìîæåò òåáå F1, è ñîõðàíèò òåáÿ F2! Âî èìÿ Controla, Alta è ñâÿòîãî Dela, äà áóäåò òàê - Reset! |
Äàííàÿ ñòàòüÿ ÿâëÿåòñÿ ëîãè÷åñêèì çàâåðøåíèåì òåìû øèôðîâàíèÿ äàííûõ, êîòîðîé ÿ ïîñâÿòèë òðè ñòàòüè (Ìîäóëü äëÿ IDEA øèôðîâàíèÿ, Ìîäóëü äëÿ RC5 øèôðîâàíèÿ è äàííàÿ). Äàííàÿ ñòàòüÿ ïîñâÿùåíà àëãîðèòìó øèôðîâàíèÿ RC6.
Êàê ÿ óæå ãîâîðèë, RC6 Î÷åíü ïîõîæ íà RC5, âî âñÿêîì ñëó÷àå ðàñ÷åò ïîäêëþ÷à ïðîèçâîäèòñÿ òåì æå ñïîñîáîì, ÷òî è â RC5. RC6 ó÷àñòâîâàë â êîíêóðñå íà çâàíèå AES è, ïî íåêîòîðûì äàííûì, íå âûèãðàë òîëüêî èç-çà ìåäëåííîé ðàáîòû àïïàðàòíûõ ðåàëèçàöèé. Ïðîãðàììíûå æå ðåàëèçàöèè RC6, ïîæàëóé, ÿâëÿþòñÿ ñàìûìè áûñòðûìè ñðåäè àëãîðèòìîâ øèôðîâàíèÿ, ïðè îáåñïå÷åíèè äîñòàòî÷íîé ñòîéêîñòè øèôðà.
Íèæåïðåäñòàâëåííûé ìîäóëü ïîñòðîåí ïî òîìó æå ïðèíöèïó, ÷òî è ïðåäûäóùèå - èìåíà ôóíêöèé ñîâïàäàþò è åñëè âû õîòèòå çàìåíèòü â ñâîåé ïðîãðàììå øèôðîâàíèå ñ IDEA èëè RC5 íà RC6 - ïðîñòî äîáàâüòå ìîäóëü RC6, à IDEA èëè RC5 - óäàëèòå èç ñïèñêà uses.
Øèôð RC6, â îòëè÷èè îò RC5, îïåðèðóåò áëîêàìè ïî 16 áàéò, à ìîäóëü ïîñòðîåí òàê, ÷òî åñëè ïðè øèôðàöèè ìåòîäàìè: EncryptCopy, DecryptCopy, EncryptStream, DecryptStream ðàçìåð äàííûõ íå áóäåò êðàòåí 16 - ïîñëåäíèé áëîê äëèííîé 1..15 áàéò íå øèôðóåòñÿ è â "÷èñòîì" âèäå äîáàâëÿåòñÿ ê çàøèôðîâàííûì. Òàêæå è ïðè äåøèôðîâàíèè - åñëè ïîñëåäíèé áëîê ðàçìåðîì 1..15 áàéò îí íå äåøèôðóåòñÿ à äîáàâëÿåòñÿ ê ðàñøèôðîâàííûì äàííûì. Òàêîé ïîäõîä îáåñïå÷èâàåò â ïîëíîé ìåðå "ñèììåòðè÷íîå" øèôðîâàíèå òàê êàê ðàçìåðû âõîäíûõ è âûõîäíûõ äàííûõ ïîëíîñòüþ ñîâïàäàþò. Îäíàêî òàêîé ïîäõîä ïðèâîäèò ê íåêîòîðûì ñëîæíîñòÿì, åñëè ïîñëåäíèé áëîê òàêæå íóæäàåòñÿ â øèôðîâàíèè. Íà ìîé âçãëÿä ëó÷øèé âûõîä - äîáàâèòü ïðè øèôðîâàíèè ê èñõîäíûì äàííûì ñòðîêó îïðåäåëåííîé äëèííû è ïîñëå äåøèôðîâàíèÿ îòñå÷ü ñ êîíöà ñòðîêó òîé æå äëèííû.
Òàêæå â çàêëþ÷åíèè öûêëà ñòàòåé, ïîñâÿùåííûõ øèôðîâàíèþ ÿ ïîäãîòîâèë ïðèìåðû ïî âñåì ïðåäñòàâëåííûì àëãîðèòìàì (IDEA, RC5, RC6).
À âîò ïîñëåäíèé ìîäóëü:
{ *********************************************************************** } { } { Delphi Åncryption Library } { Åncryption / Decryption stream - RC6 } { } { Copyright (c) 2004 by Matveev Igor Vladimirovich } { With offers and wishes write: [email protected] } { } { *********************************************************************** } unit RC6; interface uses SysUtils, Classes; const Rounds = 20; KeyLength = 2 * (Rounds + 2); BlockSize = 16; KeySize = 16 * 4; P32 = $b7e15163; Q32 = $9e3779b9; lgw = 5; type TRC6Block = array[1..4] of LongWord; var S : array[0..KeyLength-1] of LongWord; Key : string; KeyPtr : PChar; //////////////////////////////////////////////////////////////////////////////// // Äîïîëíèòåëüíûå ôóíêöèè procedure Initialize(AKey: string); // Èíèöèàëèçàöèÿ procedure CalculateSubKeys; // Ïîäãîòîâêà ïîäêëþ÷åé function EncipherBlock(var Block): Boolean; // Øèôðàöèÿ áëîêà (16 áàéò) function DecipherBlock(var Block): Boolean; // Äåøèôðàöèÿ áëîêà //////////////////////////////////////////////////////////////////////////////// // Ãëàâíûå ôóíêöèè function EncryptCopy(DestStream, SourseStream : TStream; Count: Int64; Key : string): Boolean; // Çàøèôðîâàòü äàííûå èç îäíîãî ïîòîêà â äðóãîé function DecryptCopy(DestStream, SourseStream : TStream; Count: Int64; Key : string): Boolean; // Ðàñøèôðîâàòü äàííûå èç îäíîãî ïîòîêà â äðóãîé function EncryptStream(DataStream: TStream; Count: Int64; Key: string): Boolean; // Çàøèôðîâàòü ñîäåðæèìîå ïîòîêà function DecryptStream(DataStream: TStream; Count: Int64; Key: string): Boolean; // Ðàñøèôðîâàòü ñîäåðæèìîå ïîòîêà implementation //////////////////////////////////////////////////////////////////////////////// function ROL(a, s: LongWord): LongWord; asm mov ecx, s rol eax, cl end; //////////////////////////////////////////////////////////////////////////////// function ROR(a, s: LongWord): LongWord; asm mov ecx, s ror eax, cl end; //////////////////////////////////////////////////////////////////////////////// procedure InvolveKey; var TempKey : string; i, j : Integer; K1, K2 : LongWord; begin // Ðàçâîðà÷èâàíèå êëþ÷à äî äëèííû KeySize = 64 TempKey := Key; i := 1; while ((Length(TempKey) mod KeySize) <> 0) do begin TempKey := TempKey + TempKey[i]; Inc(i); end; i := 1; j := 0; while (i < Length(TempKey)) do begin Move((KeyPtr+j)^, K1, 4); Move(TempKey[i], K2, 4); K1 := ROL(K1, K2) xor K2; Move(K1, (KeyPtr+j)^, 4); j := (j + 4) mod KeySize; Inc(i, 4); end; end; //////////////////////////////////////////////////////////////////////////////// procedure CalculateSubKeys; var i, j, k : Integer; L : array[0..15] of LongWord; A, B : LongWord; begin // Êîïèðîâàíèå êëþ÷à â L Move(KeyPtr^, L, KeySize); // Èíèöèàëèçàöèÿ ïîäêëþ÷à S S[0] := P32; for i := 1 to KeyLength-1 do S[i] := S[i-1] + Q32; // Ñìåøèâàíèå S ñ êëþ÷îì i := 0; j := 0; A := 0; B := 0; for k := 1 to 3*KeyLength do begin A := ROL((S[i] + A + B), 3); S[i] := A; B := ROL((L[j] + A + B), (A + B)); L[j] := B; i := (i + 1) mod KeyLength; j := (j + 1) mod 16; end; end; //////////////////////////////////////////////////////////////////////////////// procedure Initialize(AKey: string); begin GetMem(KeyPtr, KeySize); FillChar(KeyPtr^, KeySize, #0); Key := AKey; InvolveKey; end; //////////////////////////////////////////////////////////////////////////////// function EncipherBlock(var Block): Boolean; var RC6Block : TRC6Block absolute Block; i : Integer; t, u : LongWord; Temp : LongWord; begin // Èíèöèàëèçàöèÿ áëîêà Inc(RC6Block[2], S[0]); Inc(RC6Block[4], S[1]); for i := 1 to Rounds do begin t := ROL((RC6Block[2] * (2*RC6Block[2] + 1)), lgw); u := ROL((RC6Block[4] * (2*RC6Block[4] + 1)), lgw); RC6Block[1] := ROL((RC6Block[1] xor t), u) + S[2*i]; RC6Block[3] := ROL((RC6Block[3] xor u), t) + S[2*i+1]; Temp := RC6Block[1]; RC6Block[1] := RC6Block[2]; RC6Block[2] := RC6Block[3]; RC6Block[3] := RC6Block[4]; RC6Block[4] := Temp; end; RC6Block[1] := RC6Block[1] + S[2*Rounds+2]; RC6Block[3] := RC6Block[3] + S[2*Rounds+3]; Result := TRUE; end; //////////////////////////////////////////////////////////////////////////////// function DecipherBlock(var Block): Boolean; var RC6Block : TRC6Block absolute Block; i : Integer; t, u : LongWord; Temp : LongWord; begin // Èíèöèàëèçàöèÿ áëîêà RC6Block[3] := RC6Block[3] - S[2*Rounds+3]; RC6Block[1] := RC6Block[1] - S[2*Rounds+2]; for i := Rounds downto 1 do begin Temp := RC6Block[4]; RC6Block[4] := RC6Block[3]; RC6Block[3] := RC6Block[2]; RC6Block[2] := RC6Block[1]; RC6Block[1] := Temp; u := ROL((RC6Block[4] * (2*RC6Block[4] + 1)),lgw); t := ROL((RC6Block[2] * (2*RC6Block[2] + 1)),lgw); RC6Block[3] := ROR((RC6Block[3]-S[2*i+1]), t) xor u; RC6Block[1] := ROR((RC6Block[1]-S[2*i]), u) xor t; end; Dec(RC6Block[4], S[1]); Dec(RC6Block[2], S[0]); Result := TRUE; end; //////////////////////////////////////////////////////////////////////////////// // Ðåàëèçàöèÿ ãëàâíûõ ôóíêöèé function EncryptCopy(DestStream, SourseStream : TStream; Count: Int64; Key : string): Boolean; var Buffer : TRC6Block; PrCount : Int64; AddCount : Byte; begin Result := True; try if Key = '' then begin DestStream.CopyFrom(SourseStream, Count); Exit; end; Initialize(Key); CalculateSubKeys; PrCount := 0; while Count - PrCount >= BlockSize do begin SourseStream.Read(Buffer, BlockSize); EncipherBlock(Buffer); DestStream.Write(Buffer, BlockSize); Inc(PrCount, BlockSize); end; AddCount := Count - PrCount; if Count - PrCount <> 0 then begin SourseStream.Read(Buffer, AddCount); DestStream.Write(Buffer, AddCount); end; except Result := False; end; end; //////////////////////////////////////////////////////////////////////////////// function DecryptCopy(DestStream, SourseStream : TStream; Count: Int64; Key : string): Boolean; var Buffer : TRC6Block; PrCount : Int64; AddCount : Byte; begin Result := True; try if Key = '' then begin DestStream.CopyFrom(SourseStream, Count); Exit; end; Initialize(Key); CalculateSubKeys; PrCount := 0; while Count - PrCount >= BlockSize do begin SourseStream.Read(Buffer, BlockSize); DecipherBlock(Buffer); DestStream.Write(Buffer, BlockSize); Inc(PrCount, BlockSize); end; AddCount := Count - PrCount; if Count - PrCount <> 0 then begin SourseStream.Read(Buffer, AddCount); DestStream.Write(Buffer, AddCount); end; except Result := False; end; end; //////////////////////////////////////////////////////////////////////////////// function EncryptStream(DataStream: TStream; Count: Int64; Key: string): Boolean; var Buffer : TRC6Block; PrCount : Int64; begin Result := True; try if Key = '' then begin DataStream.Seek(Count, soFromCurrent); Exit; end; Initialize(Key); CalculateSubKeys; PrCount := 0; while Count - PrCount >= BlockSize do begin DataStream.Read(Buffer, BlockSize); EncipherBlock(Buffer); DataStream.Seek(-BlockSize, soFromCurrent); DataStream.Write(Buffer, BlockSize); Inc(PrCount, BlockSize); end; except Result := False; end; end; //////////////////////////////////////////////////////////////////////////////// function DecryptStream(DataStream: TStream; Count: Int64; Key: string): Boolean; var Buffer : TRC6Block; PrCount : Int64; begin Result := True; try if Key = '' then begin DataStream.Seek(Count, soFromCurrent); Exit; end; Initialize(Key); CalculateSubKeys; PrCount := 0; while Count - PrCount >= BlockSize do begin DataStream.Read(Buffer, BlockSize); DecipherBlock(Buffer); DataStream.Seek(-BlockSize, soFromCurrent); DataStream.Write(Buffer, BlockSize); Inc(PrCount, BlockSize); end; except Result := False; end; end; // Çàâåðøåíèå ãëàâíûõ ôóíêöèé ... //////////////////////////////////////////////////////////////////////////////// end.
Äàëåå: Ìîäóëü äëÿ ïîäñ÷åòà CRC64 »»