📄 msgcipher1.pas
字号:
{Copyright: Hagen Reddmann mailto:HaReddmann@AOL.COM
Author: Hagen Reddmann
Remarks: freeware, but this Copyright must be included
known Problems: none
Version: 3.0, Part I from Delphi Encryption Compendium ( DEC Part I)
Delphi 2-4, designed and testet under D3 & D4
Description: Include a Selection of various Cipher's (Encryption Algo)
impl. Algo:
Cast128, Cast256, Mars, Misty 1, RC2, RC4, RC5, RC6,
FROG, Rijndael, Skipjack, Single DES, Double DES,
Triple DES, Double DES 16byte Plain, Triple DES 16,
Triple DES 24, DESX, NewDES, Diamond II,
Diamond II Lite, Sapphire II
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
}
unit MsgCipher1;
{$I MsgVer.inc}
{$I Ver.inc}
interface
uses SysUtils,
{$IFDEF DEBUG_LOG}
MsgDebug,
{$ENDIF}
MsgDECUtil, MsgCipher, MsgHash;
type
TCipher_Rijndael = class;
TCipher_1DES = class; {Single DES 8 byte Blocksize, 8 byte Keysize 56 bits relevant}
TCipher_2DES = class; {Double DES 8 byte Blocksize, 16 byte Keysize 112 bits relevant}
TCipher_3DES = class; {Triple DES 8 byte Blocksize, 24 byte Keysize 168 bits relevant}
TCipher_2DDES = class; {Double DES 16 byte Blocksize, 16 byte Keysize 112 bits relevant}
TCipher_3DDES = class; {Triple DES 16 byte Blocksize, 24 byte Keysize 168 bits relevant}
TCipher_3TDES = class; {Triple DES 24 byte Blocksize, 24 byte Keysize 168 bits relevant}
TCipher_Rijndael = class(TCipher)
private
FRounds: Integer;
protected
class procedure GetContext(var ABufSize, AKeySize, AUserSize: Integer); override;
class function TestVector: Pointer; override;
procedure Encode(Data: Pointer); override;
procedure Decode(Data: Pointer); override;
public
procedure Init(const Key; Size: Integer; IVector: Pointer); override;
end;
TCipher_1DES = class(TCipher)
protected
class procedure GetContext(var ABufSize, AKeySize, AUserSize: Integer); override;
class function TestVector: Pointer; override;
procedure Encode(Data: Pointer); override;
procedure Decode(Data: Pointer); override;
procedure MakeKey(const Data: array of Byte; Key: PInteger; Reverse: Boolean);
public
procedure Init(const Key; Size: Integer; IVector: Pointer); override;
end;
TCipher_2DES = class(TCipher_1DES)
protected
class procedure GetContext(var ABufSize, AKeySize, AUserSize: Integer); override;
class function TestVector: Pointer; override;
procedure Encode(Data: Pointer); override;
procedure Decode(Data: Pointer); override;
public
procedure Init(const Key; Size: Integer; IVector: Pointer); override;
end;
TCipher_3DES = class(TCipher_1DES)
protected
class procedure GetContext(var ABufSize, AKeySize, AUserSize: Integer); override;
class function TestVector: Pointer; override;
procedure Encode(Data: Pointer); override;
procedure Decode(Data: Pointer); override;
public
procedure Init(const Key; Size: Integer; IVector: Pointer); override;
end;
TCipher_2DDES = class(TCipher_2DES)
protected
class procedure GetContext(var ABufSize, AKeySize, AUserSize: Integer); override;
class function TestVector: Pointer; override;
procedure Encode(Data: Pointer); override;
procedure Decode(Data: Pointer); override;
end;
TCipher_3DDES = class(TCipher_3DES)
protected
class procedure GetContext(var ABufSize, AKeySize, AUserSize: Integer); override;
class function TestVector: Pointer; override;
procedure Encode(Data: Pointer); override;
procedure Decode(Data: Pointer); override;
end;
TCipher_3TDES = class(TCipher_3DES)
protected
class procedure GetContext(var ABufSize, AKeySize, AUserSize: Integer); override;
class function TestVector: Pointer; override;
procedure Encode(Data: Pointer); override;
procedure Decode(Data: Pointer); override;
end;
implementation
{$I cipher1.inc}
type
PCipherRec = ^TCipherRec;
TCipherRec = packed record
case Integer of
0: (X: array[0..7] of Byte);
1: (A, B: LongWord);
end;
const
{don't change this}
Rijndael_Blocks = 4;
Rijndael_Rounds = 14;
class procedure TCipher_Rijndael.GetContext(var ABufSize, AKeySize, AUserSize: Integer);
begin
ABufSize := Rijndael_Blocks * 4;
AKeySize := 32;
AUserSize := (Rijndael_Rounds + 1) * Rijndael_Blocks * SizeOf(Integer) * 2;
end;
class function TCipher_Rijndael.TestVector: Pointer;
asm
MOV EAX,OFFSET @Vector
RET
@Vector: DB 094h,06Dh,02Bh,05Eh,0E0h,0ADh,01Bh,05Ch
DB 0A5h,023h,0A5h,013h,095h,08Bh,03Dh,02Dh
DB 093h,087h,0F3h,037h,045h,051h,0F6h,058h
DB 09Bh,0E7h,090h,01Bh,036h,087h,0F9h,0A9h
end;
procedure TCipher_Rijndael.Encode(Data: Pointer);
var
P,K: PInteger;
I,A,B,C,D: Integer;
begin
P := User;
K := Data;
for I := 2 to FRounds do
begin
A := K^ xor P^; Inc(P); Inc(K);
B := K^ xor P^; Inc(P); Inc(K);
C := K^ xor P^; Inc(P); Inc(K);
D := K^ xor P^; Inc(P);
K^ := Rijndael_T[0, D and $FF] xor
Rijndael_T[1, A shr 8 and $FF] xor
Rijndael_T[2, B shr 16 and $FF] xor
Rijndael_T[3, C shr 24]; Dec(K);
K^ := Rijndael_T[0, C and $FF] xor
Rijndael_T[1, D shr 8 and $FF] xor
Rijndael_T[2, A shr 16 and $FF] xor
Rijndael_T[3, B shr 24]; Dec(K);
K^ := Rijndael_T[0, B and $FF] xor
Rijndael_T[1, C shr 8 and $FF] xor
Rijndael_T[2, D shr 16 and $FF] xor
Rijndael_T[3, A shr 24]; Dec(K);
K^ := Rijndael_T[0, A and $FF] xor
Rijndael_T[1, B shr 8 and $FF] xor
Rijndael_T[2, C shr 16 and $FF] xor
Rijndael_T[3, D shr 24];
end;
A := K^ xor P^; Inc(P); Inc(K);
B := K^ xor P^; Inc(P); Inc(K);
C := K^ xor P^; Inc(P); Inc(K);
D := K^ xor P^; Inc(P);
K^ := Rijndael_S[0, D and $FF] or
Rijndael_S[0, A shr 8 and $FF] shl 8 or
Rijndael_S[0, B shr 16 and $FF] shl 16 or
Rijndael_S[0, C shr 24] shl 24; Dec(K);
K^ := Rijndael_S[0, C and $FF] or
Rijndael_S[0, D shr 8 and $FF] shl 8 or
Rijndael_S[0, A shr 16 and $FF] shl 16 or
Rijndael_S[0, B shr 24] shl 24; Dec(K);
K^ := Rijndael_S[0, B and $FF] or
Rijndael_S[0, C shr 8 and $FF] shl 8 or
Rijndael_S[0, D shr 16 and $FF] shl 16 or
Rijndael_S[0, A shr 24] shl 24; Dec(K);
K^ := Rijndael_S[0, A and $FF] or
Rijndael_S[0, B shr 8 and $FF] shl 8 or
Rijndael_S[0, C shr 16 and $FF] shl 16 or
Rijndael_S[0, D shr 24] shl 24;
for I := 1 to Rijndael_Blocks do
begin
K^ := K^ xor P^;
Inc(P);
Inc(K);
end;
end;
procedure TCipher_Rijndael.Decode(Data: Pointer);
var
P,K: PInteger;
I,A,B,C,D: Integer;
begin
P := Pointer(PChar(User) + UserSize shr 1);
Inc(P, FRounds * 4 +3);
K := Pointer(PChar(Data) + 12);
for I := 2 to FRounds do
begin
D := K^ xor P^; Dec(P); Dec(K);
C := K^ xor P^; Dec(P); Dec(K);
B := K^ xor P^; Dec(P); Dec(K);
A := K^ xor P^; Dec(P);
K^ := Rijndael_T[4, A and $FF] xor
Rijndael_T[5, D shr 8 and $FF] xor
Rijndael_T[6, C shr 16 and $FF] xor
Rijndael_T[7, B shr 24]; Inc(K);
K^ := Rijndael_T[4, B and $FF] xor
Rijndael_T[5, A shr 8 and $FF] xor
Rijndael_T[6, D shr 16 and $FF] xor
Rijndael_T[7, C shr 24]; Inc(K);
K^ := Rijndael_T[4, C and $FF] xor
Rijndael_T[5, B shr 8 and $FF] xor
Rijndael_T[6, A shr 16 and $FF] xor
Rijndael_T[7, D shr 24]; Inc(K);
K^ := Rijndael_T[4, D and $FF] xor
Rijndael_T[5, C shr 8 and $FF] xor
Rijndael_T[6, B shr 16 and $FF] xor
Rijndael_T[7, A shr 24];
end;
D := K^ xor P^; Dec(P); Dec(K);
C := K^ xor P^; Dec(P); Dec(K);
B := K^ xor P^; Dec(P); Dec(K);
A := K^ xor P^; Dec(P);
K^ := Rijndael_S[1, A and $FF] or
Rijndael_S[1, D shr 8 and $FF] shl 8 or
Rijndael_S[1, C shr 16 and $FF] shl 16 or
Rijndael_S[1, B shr 24] shl 24; Inc(K);
K^ := Rijndael_S[1, B and $FF] or
Rijndael_S[1, A shr 8 and $FF] shl 8 or
Rijndael_S[1, D shr 16 and $FF] shl 16 or
Rijndael_S[1, C shr 24] shl 24; Inc(K);
K^ := Rijndael_S[1, C and $FF] or
Rijndael_S[1, B shr 8 and $FF] shl 8 or
Rijndael_S[1, A shr 16 and $FF] shl 16 or
Rijndael_S[1, D shr 24] shl 24; Inc(K);
K^ := Rijndael_S[1, D and $FF] or
Rijndael_S[1, C shr 8 and $FF] shl 8 or
Rijndael_S[1, B shr 16 and $FF] shl 16 or
Rijndael_S[1, A shr 24] shl 24;
for I := 0 to 3 do
begin
K^ := K^ xor P^;
Dec(P);
Dec(K);
end;
end;
procedure TCipher_Rijndael.Init(const Key; Size: Integer; IVector: Pointer);
var
K: array[0..7] of Integer;
procedure BuildEncodeKey;
const
RND_Data: array[0..29] of Byte = (
$01,$02,$04,$08,$10,$20,$40,$80,$1B,$36,$6C,$D8,$AB,$4D,$9A,
$2F,$5E,$BC,$63,$C6,$97,$35,$6A,$D4,$B3,$7D,$FA,$EF,$C5,$91);
var
T,R: Integer;
procedure NextRounds;
var
J: Integer;
begin
J := 0;
while (J < FRounds-6) and (R <= FRounds) do
begin
while (J < FRounds-6) and (T < Rijndael_Blocks) do
begin
PIntArray(User)[R * Rijndael_Blocks + T] := K[J];
Inc(J);
Inc(T);
end;
if T = Rijndael_Blocks then
begin
T := 0;
Inc(R);
end;
end;
end;
var
RND: PByte;
B: PByte;
I: Integer;
begin
R := 0;
T := 0;
RND := @RND_Data;
NextRounds;
while R <= FRounds do
begin
B := @K;
B^ := B^ xor Rijndael_S[0, K[FRounds -7] shr 8 and $FF] xor RND^; Inc(B);
B^ := B^ xor Rijndael_S[0, K[FRounds -7] shr 16 and $FF]; Inc(B);
B^ := B^ xor Rijndael_S[0, K[FRounds -7] shr 24]; Inc(B);
B^ := B^ xor Rijndael_S[0, K[FRounds -7] and $FF];
Inc(RND);
if FRounds = 14 then
begin
for I := 1 to 7 do K[I] := K[I] xor K[I -1];
B := @K[4];
B^ := B^ xor Rijndael_S[0, K[3] and $FF]; Inc(B);
B^ := B^ xor Rijndael_S[0, K[3] shr 8 and $FF]; Inc(B);
B^ := B^ xor Rijndael_S[0, K[3] shr 16 and $FF]; Inc(B);
B^ := B^ xor Rijndael_S[0, K[3] shr 24];
for I := 5 to 7 do K[I] := K[I] xor K[I -1];
end else
for I := 1 to FRounds -7 do K[I] := K[I] xor K[I -1];
NextRounds;
end;
end;
procedure BuildDecodeKey;
var
I: Integer;
D: PInteger;
begin
D := Pointer(PChar(User) + UserSize shr 1);
Move(User^, D^, UserSize shr 1);
Inc(D, 4);
for I := 0 to FRounds * 4 - 5 do
begin
D^ := Rijndael_Key[D^ and $FF] xor
ROL(Rijndael_Key[D^ shr 8 and $FF], 8) xor
ROL(Rijndael_Key[D^ shr 16 and $FF], 16) xor
ROL(Rijndael_Key[D^ shr 24], 24);
Inc(D);
end;
end;
begin
InitBegin(Size);
if Size <= 16 then FRounds := 10 else
if Size <= 24 then FRounds := 12 else FRounds := 14;
FillChar(K, SizeOf(K), 0);
Move(Key, K, Size);
BuildEncodeKey;
BuildDecodeKey;
FillChar(K, SizeOf(K), 0);
InitEnd(IVector);
end;
{DES}
procedure DES_Func(Data: PIntArray; Key: PInteger); register;
var
L,R,X,Y,I: LongWord;
begin
L := SwapInteger(Data[0]);
R := SwapInteger(Data[1]);
X := (L shr 4 xor R) and $0F0F0F0F; R := R xor X; L := L xor X shl 4;
X := (L shr 16 xor R) and $0000FFFF; R := R xor X; L := L xor X shl 16;
X := (R shr 2 xor L) and $33333333; L := L xor X; R := R xor X shl 2;
X := (R shr 8 xor L) and $00FF00FF; L := L xor X; R := R xor X shl 8;
R := R shl 1 or R shr 31;
X := (L xor R) and $AAAAAAAA;
R := R xor X;
L := L xor X;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -