📄 gost.pas
字号:
t: LongWord;
begin
t := k1 + r;
l := l xor (gost_sbox_1[t and $ff] xor gost_sbox_2[(t shr 8) and $ff] xor
gost_sbox_3[(t shr 16) and $ff] xor gost_sbox_4[t shr 24]);
t := k2 + l;
r := r xor (gost_sbox_1[t and $ff] xor gost_sbox_2[(t shr 8) and $ff] xor
gost_sbox_3[(t shr 16) and $ff] xor gost_sbox_4[t shr 24]);
end;
{$ENDIF}
procedure GOST_ENCRYPT(var l, r: LongWord; key: array of LongWord);
var
t: LongWord;
begin
GOST_ENCRYPT_ROUND(l, r, key[0], key[1]);
GOST_ENCRYPT_ROUND(l, r, key[2], key[3]);
GOST_ENCRYPT_ROUND(l, r, key[4], key[5]);
GOST_ENCRYPT_ROUND(l, r, key[6], key[7]);
GOST_ENCRYPT_ROUND(l, r, key[0], key[1]);
GOST_ENCRYPT_ROUND(l, r, key[2], key[3]);
GOST_ENCRYPT_ROUND(l, r, key[4], key[5]);
GOST_ENCRYPT_ROUND(l, r, key[6], key[7]);
GOST_ENCRYPT_ROUND(l, r, key[0], key[1]);
GOST_ENCRYPT_ROUND(l, r, key[2], key[3]);
GOST_ENCRYPT_ROUND(l, r, key[4], key[5]);
GOST_ENCRYPT_ROUND(l, r, key[6], key[7]);
GOST_ENCRYPT_ROUND(l, r, key[7], key[6]);
GOST_ENCRYPT_ROUND(l, r, key[5], key[4]);
GOST_ENCRYPT_ROUND(l, r, key[3], key[2]);
GOST_ENCRYPT_ROUND(l, r, key[1], key[0]);
t := r; r := l; l := t;
end;
procedure gosthash_compress(var h, m: array of LongWord);
var
i, l, r: LongWord;
key, u, v, w, s: array[0..7] of LongWord;
begin
Move(h, u, SizeOf(u));
Move(m, v, SizeOf(v));
i := 0;
while i < 8 do
begin
w[0] := u[0] xor v[0];
w[1] := u[1] xor v[1];
w[2] := u[2] xor v[2];
w[3] := u[3] xor v[3];
w[4] := u[4] xor v[4];
w[5] := u[5] xor v[5];
w[6] := u[6] xor v[6];
w[7] := u[7] xor v[7];
{P-Transformation}
key[0] := (w[0] and $000000ff) or ((w[2] and $000000ff) shl 8) or ((w[4] and $000000ff) shl 16) or ((w[6] and $000000ff) shl 24);
key[1] := ((w[0] and $0000ff00) shr 8) or (w[2] and $0000ff00) or ((w[4] and $0000ff00) shl 8) or ((w[6] and $0000ff00) shl 16);
key[2] := ((w[0] and $00ff0000) shr 16) or ((w[2] and $00ff0000) shr 8) or (w[4] and $00ff0000)
or ((w[6] and $00ff0000) shl 8);
key[3] := ((w[0] and $ff000000) shr 24) or ((w[2] and $ff000000) shr 16) or ((w[4] and $ff000000) shr 8) or (w[6] and $ff000000);
key[4] := (w[1] and $000000ff) or ((w[3] and $000000ff) shl 8) or ((w[5] and $000000ff) shl 16) or ((w[7] and $000000ff) shl 24);
key[5] := ((w[1] and $0000ff00) shr 8) or (w[3] and $0000ff00) or ((w[5] and $0000ff00) shl 8) or ((w[7] and $0000ff00) shl 16);
key[6] := ((w[1] and $00ff0000) shr 16) or ((w[3] and $00ff0000) shr 8) or (w[5] and $00ff0000)
or ((w[7] and $00ff0000) shl 8);
key[7] := ((w[1] and $ff000000) shr 24) or ((w[3] and $ff000000) shr 16) or ((w[5] and $ff000000) shr 8) or (w[7] and $ff000000);
r := h[i];
l := h[i + 1];
GOST_ENCRYPT(l, r, key);
s[i] := r;
s[i + 1] := l;
if (i = 6) then Break;
l := u[0] xor u[2];
r := u[1] xor u[3];
u[0] := u[2];
u[1] := u[3];
u[2] := u[4];
u[3] := u[5];
u[4] := u[6];
u[5] := u[7];
u[6] := l;
u[7] := r;
if i = 2 then
begin
asm
xor dword [u ], $ff00ff00
xor dword [u + 4], $ff00ff00
xor dword [u + 8], $00ff00ff
xor dword [u + 12], $00ff00ff
xor dword [u + 16], $00ffff00
xor dword [u + 20], $ff0000ff
xor dword [u + 24], $000000ff
xor dword [u + 28], $ff00ffff
end;
end;
l := v[0];
r := v[2];
v[0] := v[4];
v[2] := v[6];
v[4] := l xor r;
v[6] := v[0] xor r;
l := v[1];
r := v[3];
v[1] := v[5];
v[3] := v[7];
v[5] := l xor r;
v[7] := v[1] xor r;
Inc(i, 2);
end;
{12 rounds of the LFSR (computed from a product matrix) and xor in M}
u[0] := m[0] xor s[6];
u[1] := m[1] xor s[7];
u[2] := m[2] xor (s[0] shl 16) xor (s[0] shr 16) xor (s[0] and $ffff) xor (s[1] and $ffff) xor (s[1] shr 16) xor (s[2] shl 16) xor s[6] xor (s[6] shl 16) xor (s[7] and $ffff0000) xor (s[7] shr 16);
u[3] := m[3] xor (s[0] and $ffff) xor (s[0] shl 16) xor (s[1] and $ffff) xor (s[1] shl 16)
xor (s[1] shr 16) xor (s[2] shl 16) xor (s[2] shr 16) xor (s[3] shl 16) xor s[6] xor (s[6] shl 16) xor (s[6] shr 16) xor (s[7] and $ffff) xor (s[7] shl 16) xor (s[7] shr 16);
u[4] := m[4] xor (s[0] and $ffff0000) xor (s[0] shl 16) xor (s[0] shr 16) xor
(s[1] and $ffff0000) xor (s[1] shr 16) xor (s[2] shl 16) xor (s[2] shr 16) xor (s[3] shl 16) xor (s[3] shr 16) xor (s[4] shl 16) xor (s[6] shl 16) xor (s[6] shr 16) xor (s[7] and $ffff) xor (s[7] shl 16) xor (s[7] shr 16);
u[5] := m[5] xor (s[0] shl 16) xor (s[0] shr 16) xor (s[0] and $ffff0000) xor
(s[1] and $ffff) xor s[2] xor (s[2] shr 16) xor (s[3] shl 16) xor (s[3] shr
16) xor (s[4] shl 16) xor (s[4] shr 16) xor (s[5] shl 16) xor (s[6] shl 16) xor (s[6] shr 16) xor (s[7] and $ffff0000) xor (s[7] shl 16) xor (s[7] shr 16);
u[6] := m[6] xor s[0] xor (s[1] shr 16) xor (s[2] shl 16) xor s[3] xor (s[3] shr 16)
xor (s[4] shl 16) xor (s[4] shr 16) xor (s[5] shl 16) xor (s[5] shr 16) xor s[6] xor (s[6] shl 16) xor (s[6] shr 16) xor (s[7] shl 16);
u[7] := m[7] xor (s[0] and $ffff0000) xor (s[0] shl 16) xor (s[1] and $ffff) xor
(s[1] shl 16) xor (s[2] shr 16) xor (s[3] shl 16) xor s[4] xor (s[4] shr 16) xor (s[5] shl 16) xor (s[5] shr 16) xor (s[6] shr 16) xor (s[7] and $ffff) xor (s[7] shl 16) xor (s[7] shr 16);
{16 * 1 round of the LFSR and xor in H}
v[0] := h[0] xor (u[1] shl 16) xor (u[0] shr 16);
v[1] := h[1] xor (u[2] shl 16) xor (u[1] shr 16);
v[2] := h[2] xor (u[3] shl 16) xor (u[2] shr 16);
v[3] := h[3] xor (u[4] shl 16) xor (u[3] shr 16);
v[4] := h[4] xor (u[5] shl 16) xor (u[4] shr 16);
v[5] := h[5] xor (u[6] shl 16) xor (u[5] shr 16);
v[6] := h[6] xor (u[7] shl 16) xor (u[6] shr 16);
v[7] := h[7] xor (u[0] and $ffff0000) xor (u[0] shl 16) xor (u[7] shr 16) xor (u[1] and $ffff0000) xor (u[1] shl 16) xor (u[6] shl 16) xor (u[7] and $ffff0000);
{61 rounds of LFSR, mixing up h (computed from a product matrix)}
h[0] := (v[0] and $ffff0000) xor (v[0] shl 16) xor (v[0] shr 16) xor (v[1] shr 16) xor
(v[1] and $ffff0000) xor (v[2] shl 16) xor (v[3] shr 16) xor (v[4] shl 16) xor (v[5] shr 16) xor v[5] xor (v[6] shr 16) xor (v[7] shl 16) xor (v[7] shr 16) xor (v[7] and $ffff);
h[1] := (v[0] shl 16) xor (v[0] shr 16) xor (v[0] and $ffff0000) xor (v[1] and
$ffff) xor v[2] xor (v[2] shr 16) xor (v[3] shl 16) xor (v[4] shr 16) xor (v[5] shl 16) xor (v[6] shl 16) xor v[6] xor (v[7] and $ffff0000) xor (v[7] shr 16);
h[2] := (v[0] and $ffff) xor (v[0] shl 16) xor (v[1] shl 16) xor (v[1] shr 16) xor
(v[1] and $ffff0000) xor (v[2] shl 16) xor (v[3] shr 16) xor v[3] xor (v[4] shl 16) xor (v[5] shr 16) xor v[6] xor (v[6] shr 16) xor (v[7] and $ffff) xor (v[7] shl 16) xor (v[7] shr 16);
h[3] := (v[0] shl 16) xor (v[0] shr 16) xor (v[0] and $ffff0000) xor (v[1] and $ffff0000)
xor (v[1] shr 16) xor (v[2] shl 16) xor (v[2] shr 16) xor v[2] xor (v[3] shl 16) xor (v[4] shr 16) xor v[4] xor (v[5] shl 16) xor (v[6] shl 16) xor (v[7] and $ffff) xor (v[7] shr 16);
h[4] := (v[0] shr 16) xor (v[1] shl 16) xor v[1] xor (v[2] shr 16) xor v[2] xor (v[3] shl 16) xor (v[3] shr 16) xor v[3] xor (v[4] shl 16) xor (v[5] shr 16) xor v[5]
xor (v[6] shl 16) xor (v[6] shr 16) xor (v[7] shl 16);
h[5] := (v[0] shl 16) xor (v[0] and $ffff0000) xor (v[1] shl 16) xor (v[1] shr 16) xor (v[1] and $ffff0000) xor (v[2] shl 16) xor v[2] xor (v[3] shr 16) xor v[3]
xor (v[4] shl 16) xor (v[4] shr 16) xor v[4] xor (v[5] shl 16) xor (v[6] shl 16) xor (v[6] shr 16) xor v[6] xor (v[7] shl 16) xor (v[7] shr 16) xor (v[7] and $ffff0000);
h[6] := v[0] xor v[2] xor (v[2] shr 16) xor v[3] xor (v[3] shl 16) xor v[4] xor (v[4] shr 16)
xor (v[5] shl 16) xor (v[5] shr 16) xor v[5] xor (v[6] shl 16) xor (v[6] shr 16) xor v[6] xor (v[7] shl 16) xor v[7];
h[7] := v[0] xor (v[0] shr 16) xor (v[1] shl 16) xor (v[1] shr 16) xor (v[2] shl 16) xor (v[3] shr 16) xor v[3] xor (v[4] shl 16) xor v[4] xor (v[5] shr 16) xor v[5]
xor (v[6] shl 16) xor (v[6] shr 16) xor (v[7] shl 16) xor v[7];
end;
procedure GostInit(var ctx: TGostCtx);
begin
FillChar(ctx, SizeOf(ctx), 0);
end;
procedure AddCarry(var len: TArr8LW; const Value: LongWord); assembler;
asm
xor ecx,ecx
add [eax + 0 * 4], edx
adc [eax + 1 * 4], ecx
adc [eax + 2 * 4], ecx
adc [eax + 3 * 4], ecx
adc [eax + 4 * 4], ecx
adc [eax + 5 * 4], ecx
adc [eax + 6 * 4], ecx
adc [eax + 7 * 4], ecx
end;
procedure gosthash_bytes(var ctx: TGostCtx; const buf: Pointer; bits: LongWord);
var
i, j, a, c: LongWord;
m: array[0..7] of LongWord;
begin
j := 0;
c := 0;
for i := 0 to 7 do
begin
Move(Ptr(LongWord(buf) + j)^, a, 4); //Copy a dword from buffer to a
Inc(j, 4);
m[i] := a;
c := a + c + ctx.sum[i];
if ((a = $FFFFFFFF) and (ctx.sum[i] = $FFFFFFFF)) then
begin
ctx.sum[i] := c;
c := 1;
end
else
begin
ctx.sum[i] := c;
if c < a then c := 1 else c := 0;
end;
end;
gosthash_compress(ctx.hash, m);
AddCarry(ctx.len, bits);
end;
procedure GostUpdate(var ctx: TGostCtx; const buf: Pointer; len: LongWord);
var
i, j: LongWord;
begin
i := ctx.partial_bytes;
j := 0;
while (i < 32) and (j < len) do
begin
ctx.partial[i] := PByteArray(buf)^[j];
Inc(i); Inc(j);
end;
if (i < 32) then
begin
ctx.partial_bytes := i;
Exit;
end;
gosthash_bytes(ctx, @ctx.partial, 256);
while ((j + 32) < len) do
begin
gosthash_bytes(ctx, @(PByteArray(buf)^[j]), 256);
Inc(j, 32);
end;
i := 0;
while j < len do
begin
ctx.partial[i] := PByteArray(buf)^[j];
Inc(i); Inc(j);
end;
ctx.partial_bytes := i;
end;
function GostFinal(var ctx: TGostCtx): String;
var
i, j, a: LongWord;
digest: array[0..31] of Byte;
begin
if (ctx.partial_bytes > 0) then
begin
FillChar((@ctx.partial[ctx.partial_bytes])^, 32 - ctx.partial_bytes, 0);
gosthash_bytes(ctx, @ctx.partial, ctx.partial_bytes shl 3);
end;
gosthash_compress(ctx.hash, ctx.len);
gosthash_compress(ctx.hash, ctx.sum);
j := 0;
for i := 0 to 7 do
begin
a := ctx.hash[i];
digest[j] := Byte(a);
digest[j + 1] := Byte(a shr 8);
digest[j + 2] := Byte(a shr 16);
digest[j + 3] := Byte(a shr 24);
Inc(j, 4);
end;
Result := '';
for i := 0 to 31 do
Result := Result + IntToHex(digest[i], 2);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -