📄 lbcipher.pas
字号:
II(D, A, B, C, InA [ 7], S42, $432AFF97); { 50 }
II(C, D, A, B, InA [14], S43, $AB9423A7); { 51 }
II(B, C, D, A, InA [ 5], S44, $FC93A039); { 52 }
II(A, B, C, D, InA [12], S41, $655B59C3); { 53 }
II(D, A, B, C, InA [ 3], S42, $8F0CCC92); { 54 }
II(C, D, A, B, InA [10], S43, $FFEFF47D); { 55 }
II(B, C, D, A, InA [ 1], S44, $85845DD1); { 56 }
II(A, B, C, D, InA [ 8], S41, $6FA87E4F); { 57 }
II(D, A, B, C, InA [15], S42, $FE2CE6E0); { 58 }
II(C, D, A, B, InA [ 6], S43, $A3014314); { 59 }
II(B, C, D, A, InA [13], S44, $4E0811A1); { 60 }
II(A, B, C, D, InA [ 4], S41, $F7537E82); { 61 }
II(D, A, B, C, InA [11], S42, $BD3AF235); { 62 }
II(C, D, A, B, InA [ 2], S43, $2AD7D2BB); { 63 }
II(B, C, D, A, InA [ 9], S44, $EB86D391); { 64 }
Inc(Buf [0], A);
Inc(Buf [1], B);
Inc(Buf [2], C);
Inc(Buf [3], D);
Move(Buf, Buffer, SizeOf(Buffer)); {!!.01}
end;
{ -------------------------------------------------------------------------- }
procedure InitMD5(var Context : TMD5Context);
var
MD5 : TMD5ContextEx; {!!.01}
begin
Move(Context, MD5, SizeOf(MD5)); {!!.01}
MD5.Count[0] := 0;
MD5.Count[1] := 0;
{load magic initialization constants}
MD5.State[0] := $67452301;
MD5.State[1] := $EFCDAB89;
MD5.State[2] := $98BADCFE;
MD5.State[3] := $10325476;
Move(MD5, Context, SizeOf(Context)); {!!.01}
end;
{ -------------------------------------------------------------------------- }
procedure UpdateMD5(var Context : TMD5Context; const Buf; BufSize : LongInt);
var
MD5 : TMD5ContextEx;
InBuf : array [0..15] of DWord;
BufOfs : LongInt;
MDI : Word;
I : Word;
II : Word;
begin
Move(Context, MD5, SizeOf(MD5)); {!!.01}
{compute number of bytes mod 64}
MDI := (MD5.Count[0] shr 3) and $3F;
{update number of bits}
if ((MD5.Count[0] + (DWord(BufSize) shl 3)) < MD5.Count[0]) then
Inc(MD5.Count[1]);
Inc(MD5.Count[0], BufSize shl 3);
Inc(MD5.Count[1], BufSize shr 29);
{add new byte acters to buffer}
BufOfs := 0;
while (BufSize > 0) do begin
Dec(BufSize);
MD5.Buf[MDI] := TByteArray(Buf)[BufOfs]; {!!.01}
Inc(MDI);
Inc(BufOfs);
if (MDI = $40) then begin
II := 0;
for I := 0 to 15 do begin
InBuf[I] := LongInt(MD5.Buf[II + 3]) shl 24 or
LongInt(MD5.Buf[II + 2]) shl 16 or
LongInt(MD5.Buf[II + 1]) shl 8 or
LongInt(MD5.Buf[II]);
Inc(II, 4);
end;
Transform(MD5.State, InBuf);
Transform(TMD5ContextEx( Context ).State, InBuf);
MDI := 0;
end;
end;
Move(MD5, Context, SizeOf(Context)); {!!.01}
end;
{ -------------------------------------------------------------------------- }
procedure FinalizeMD5(var Context : TMD5Context; var Digest : TMD5Digest);
const
Padding: array [0..63] of Byte = (
$80, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
$00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00);
var
MD5 : TMD5ContextEx;
InBuf : array [0..15] of DWord;
MDI : LongInt;
I : Word;
II : Word;
PadLen : Word;
begin
Move(Context, MD5, SizeOf(MD5)); {!!.01}
{save number of bits}
InBuf[14] := MD5.Count[0];
InBuf[15] := MD5.Count[1];
{compute number of bytes mod 64}
MDI := (MD5.Count[0] shr 3) and $3F;
{pad out to 56 mod 64}
if (MDI < 56) then
PadLen := 56 - MDI
else
PadLen := 120 - MDI;
UpdateMD5(Context, Padding, PadLen);
Move(Context, MD5, SizeOf(MD5)); {!!.01}
{append length in bits and transform}
II := 0;
for I := 0 to 13 do begin
InBuf[I] :=
( LongInt( MD5.Buf[ II + 3 ]) shl 24 ) or
( LongInt( MD5.Buf[ II + 2 ]) shl 16 ) or
( LongInt( MD5.Buf[ II + 1 ]) shl 8 ) or
LongInt( MD5.Buf[ II ]);
Inc(II, 4);
end;
Transform(MD5.State, InBuf);
{store buffer in digest}
II := 0;
for I := 0 to 3 do begin
Digest[II] := Byte(MD5.State[I] and $FF);
Digest[II + 1] := Byte((MD5.State[I] shr 8) and $FF);
Digest[II + 2] := Byte((MD5.State[I] shr 16) and $FF);
Digest[II + 3] := Byte((MD5.State[I] shr 24) and $FF);
Inc(II, 4);
end;
Move(MD5, Context, SizeOf(Context)); {!!.01}
end;
{ -------------------------------------------------------------------------- }
procedure HashMD5(var Digest : TMD5Digest; const Buf; BufSize : LongInt);
var
Context : TMD5Context;
begin
fillchar( context, SizeOf( context ), $00 );
InitMD5(Context);
UpdateMD5(Context, Buf, BufSize);
FinalizeMD5(Context, Digest);
end;
{ -------------------------------------------------------------------------- }
procedure InitLMD(var Context : TLMDContext);
var
ContextEx : TLMDContextEx;
begin
Move(Context, ContextEx, SizeOf(ContextEx)); {!!.01}
ContextEx.DigestIndex := 0;
TBlock2048(ContextEx.Digest) := TBlock2048(Pi2048);
ContextEx.KeyIndex := 0;
ContextEx.KeyInts[0] := $55555555;
ContextEx.KeyInts[1] := $55555555;
ContextEx.KeyInts[2] := $55555555;
ContextEx.KeyInts[3] := $55555555;
Move(ContextEx, Context, SizeOf(Context)); {!!.01}
end;
{ -------------------------------------------------------------------------- }
procedure UpdateLMD(var Context : TLMDContext; const Buf; BufSize : LongInt);
var
ContextEx : TLMDContextEx; {!!.01}
AA, BB : LongInt;
CC, DD : LongInt;
I, R : LongInt;
begin
Move(Context, ContextEx, SizeOf(ContextEx)); {!!.01}
for I := 0 to BufSize - 1 do
with ContextEx do begin
{update Digest}
Digest[DigestIndex] := Digest[DigestIndex] xor
TByteArray(Buf)[I]; {!!.01}
DigestIndex := DigestIndex + 1;
if (DigestIndex = SizeOf(Digest)) then
DigestIndex := 0;
{update BlockKey}
Key[KeyIndex] := Key[KeyIndex] xor TByteArray(Buf)[I]; {!!.01}
KeyIndex := KeyIndex + 1;
if (KeyIndex = SizeOf(Key) div 2) then begin
AA := KeyInts[3];
BB := KeyInts[2];
CC := KeyInts[1];
DD := KeyInts[0];
{mix all the bits around for 4 rounds}
{achieves avalanche and eliminates funnels}
for R := 0 to 3 do begin
AA := AA + DD; DD := DD + AA; AA := AA xor (AA shr 7);
BB := BB + AA; AA := AA + BB; BB := BB xor (BB shl 13);
CC := CC + BB; BB := BB + CC; CC := CC xor (CC shr 17);
DD := DD + CC; CC := CC + DD; DD := DD xor (DD shl 9);
AA := AA + DD; DD := DD + AA; AA := AA xor (AA shr 3);
BB := BB + AA; AA := AA + BB; BB := BB xor (BB shl 7);
CC := CC + BB; BB := BB + CC; CC := CC xor (DD shr 15);
DD := DD + CC; CC := CC + DD; DD := DD xor (DD shl 11);
end;
KeyInts[0] := AA;
KeyInts[1] := BB;
KeyInts[2] := CC;
KeyInts[3] := DD;
KeyIndex := 0;
end;
end;
Move(ContextEx, Context, SizeOf(Context)); {!!.01}
end;
{ -------------------------------------------------------------------------- }
procedure FinalizeLMD(var Context : TLMDContext; var Digest; DigestSize : LongInt);
const
Padding : array [0..7] of Byte = (1, 0, 0, 0, 0, 0, 0, 0);
var
ContextEx : TLMDContextEx; {!!.01}
BCContext : TLBCContext;
I : Integer;
begin
{pad with "1", followed by as many "0"s as needed to fill the block}
Move(Context, ContextEx, SizeOf(ContextEx)); {!!.01}
UpdateLMD(Context, Padding, SizeOf(Padding) - ContextEx.KeyIndex);
Move(Context, ContextEx, SizeOf(ContextEx)); {!!.01}
{mix context using block cipher}
InitEncryptLBC(ContextEx.Key, BCContext, 8, True);
for I := 0 to (SizeOf(ContextEx.Digest) div SizeOf(TLBCBlock)) - 1 do
EncryptLBC(BCContext, PLBCBlock(@ContextEx.Digest[I * SizeOf(TLBCBlock)])^);
{return Digest of requested DigestSize}
{max digest is 2048-bit, although it could be greater if Pi2048 was larger}
Move(ContextEx.Digest, Digest, Min(SizeOf(ContextEx.Digest), DigestSize));
end;
{ -------------------------------------------------------------------------- }
procedure HashLMD(var Digest; DigestSize : LongInt; const Buf; BufSize : LongInt);
var
Context : TLMDContext;
begin
InitLMD(Context);
UpdateLMD(Context, Buf, BufSize);
FinalizeLMD(Context, Digest, DigestSize);
end;
{ -------------------------------------------------------------------------- }
procedure HashMix128(var Digest : LongInt; const Buf; BufSize : LongInt);
type
T128BitArray = array[0..0] of T128Bit;
var
Temp : T128Bit;
PTemp : PByteArray;
I, L : LongInt;
begin
Temp[0] := $243F6A88; {first 16 bytes of Pi in binary}
Temp[1] := $93F40317;
Temp[2] := $0C110496;
Temp[3] := $C709C289;
L := BufSize div SizeOf(T128Bit);
for I := 0 to L - 1 do begin
Temp[0] := Temp[0] + T128BitArray(Buf)[I][0]; {!!.01}
Temp[1] := Temp[1] + T128BitArray(Buf)[I][1]; {!!.01}
Temp[2] := Temp[2] + T128BitArray(Buf)[I][2]; {!!.01}
Temp[3] := Temp[3] + T128BitArray(Buf)[I][3]; {!!.01}
Mix128(Temp);
end;
PTemp := @Temp;
if (BufSize > L * SizeOf(T128Bit)) then begin
for I := 0 to (BufSize - L * SizeOf(T128Bit)) - 1 do
PTemp^[I] := PTemp^[I] + TByteArray(Buf)[(L * SizeOf(T128Bit)) + I]; {!!.01}
Mix128(Temp);
end;
Digest := Temp[3];
end;
{ -------------------------------------------------------------------------- }
procedure StringHashMix128(var Digest : LongInt; const Str : string);
begin
HashMix128(Digest, Str[1], Length(Str));
end;
{ -------------------------------------------------------------------------- }
procedure StringHashMD5(var Digest : TMD5Digest; const Str : string);
begin
HashMD5(Digest, Str[1], Length(Str));
end;
{ -------------------------------------------------------------------------- }
procedure StringHashLMD(var Digest; DigestSize : LongInt; const Str : string);
begin
HashLMD(Digest, DigestSize, Str[1], Length(Str));
end;
{ -------------------------------------------------------------------------- }
procedure XorMemPrim(var Mem1; const Mem2; Count : Cardinal); register;
asm
push esi
push edi
mov esi, eax //esi = Mem1
mov edi, edx //edi = Mem2
push ecx //save byte count
shr ecx, 2 //convert to dwords
jz @Continue
cld
@Loop1: //xor dwords at a time
mov eax, [edi]
xor [esi], eax
add esi, 4
add edi, 4
dec ecx
jnz @Loop1
@Continue: //handle remaining bytes (3 or less)
pop ecx
and ecx, 3
jz @Done
@Loop2: //xor remaining bytes
mov al, [edi]
xor [esi], al
inc esi
inc edi
dec ecx
jnz @Loop2
@Done:
pop edi
pop esi
end;
{ -------------------------------------------------------------------------- }
procedure XorMem(var Mem1; const Mem2; Count : Cardinal);
begin
XorMemPrim(Mem1, Mem2, Count);
end;
{ == SHA-1 hashing routines ================================================ }
procedure SHA1Clear( var Context : TSHA1Context );
begin
fillchar( Context, SizeOf( Context ), $00 );
end;
{ -------------------------------------------------------------------------- }
function SHA1SwapByteOrder( n : DWORD ) : DWORD;
begin
n := ( n shr 24 ) or (( n shr 8 ) and LBMASK_LO )
or (( n shl 8 ) and LBMASK_HI ) or ( n shl 24 );
Result := n;
end;
{ -------------------------------------------------------------------------- }
procedure HashSHA1( var Digest : TSHA1Digest; const Buf; BufSize : Longint );
var
Context : TSHA1Context;
begin
InitSHA1( Context );
UpdateSHA1( Context, Buf, BufSize );
FinalizeSHA1( Context, Digest );
end;
{ -------------------------------------------------------------------------- }
procedur
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -