mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
DEL: Unused unit
This commit is contained in:
parent
fb6f09b551
commit
970f0ecf59
1 changed files with 0 additions and 982 deletions
|
|
@ -1,982 +0,0 @@
|
|||
unit blake2b;
|
||||
|
||||
{Blake2B - max 512 bit hash/MAC function}
|
||||
|
||||
interface
|
||||
|
||||
(*************************************************************************
|
||||
|
||||
DESCRIPTION : Blake2B - max 512 bit hash/MAC function
|
||||
|
||||
REQUIREMENTS : TP6/7, D1-D7/D9-D10/D12/D17-D18/D25S, FPC, VP
|
||||
|
||||
EXTERNAL DATA : ---
|
||||
|
||||
MEMORY USAGE : ---
|
||||
|
||||
DISPLAY MODE : ---
|
||||
|
||||
REFERENCES : - Saarinen et al: The BLAKE2 Cryptographic Hash and Message
|
||||
Authentication Code (MAC); https://tools.ietf.org/html/rfc7693
|
||||
- Aumasson et al: BLAKE2: simpler, smaller, fast as MD5;
|
||||
https://blake2.net/blake2.pdf
|
||||
- Official reference code: https://github.com/BLAKE2/BLAKE2
|
||||
|
||||
|
||||
Version Date Author Modification
|
||||
------- -------- ------- ------------------------------------------
|
||||
0.10 06.10.17 W.Ehrhardt Initial D6 implementation (from Blake2s / RFC code)
|
||||
0.11 06.10.17 we removed updatelen, max input < 2^64
|
||||
0.12 06.10.17 we FPC fix
|
||||
0.13 06.10.17 we blake2b_selftest
|
||||
0.14 06.10.17 we used int64 instead of u64
|
||||
0.15 07.10.17 we unroll compress loop for Delphi
|
||||
0.16 07.10.17 we adjust/assert context size
|
||||
0.17 03.11.17 we Use THashContext and internal blake2b_ctx
|
||||
0.18 04.11.17 we Dummy functions for TP5-7, D1-D3, IV with longints
|
||||
0.19 05.11.17 we Some commpn code for 64 and 16/32 bit
|
||||
0.20 05.11.17 we 32-Bit BASM
|
||||
0.21 05.11.17 we 16-Bit BASM
|
||||
0.22 21.11.14 eh Faster blake2b_compress routines from EddyHawk
|
||||
0.23 23.11.14 we Replace RotR(,16) with word moves for non-int64
|
||||
0.24 24.11.14 we RotR63 with BASM
|
||||
0.25 24.11.14 we RotR24 with byte move
|
||||
0.26 24.11.14 we RotR63, Add64 for VER5X
|
||||
|
||||
**************************************************************************)
|
||||
|
||||
(*-------------------------------------------------------------------------
|
||||
(C) Copyright 2017 Wolfgang Ehrhardt
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from
|
||||
the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software in
|
||||
a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
----------------------------------------------------------------------------*)
|
||||
|
||||
|
||||
{$i STD.INC}
|
||||
|
||||
uses
|
||||
BTypes, Hash;
|
||||
|
||||
const
|
||||
BLAKE2B_BlockLen = 128;
|
||||
BLAKE2B_MaxDigLen = 64;
|
||||
BLAKE2B_MaxKeyLen = 64;
|
||||
|
||||
type
|
||||
TBlake2BDigest = packed array[0..BLAKE2B_MaxDigLen-1] of byte; {max. blake2b digest}
|
||||
TBlake2BBlock = packed array[0..BLAKE2B_BlockLen-1] of byte;
|
||||
|
||||
|
||||
function blake2b_Init(var ctx: THashContext; key: pointer; keylen, diglen: word): integer;
|
||||
{-Initialize context for a digest of diglen bytes; keylen=0: no key}
|
||||
|
||||
procedure blake2b_update(var ctx: THashContext; msg: pointer; mlen: longint);
|
||||
{-Add "mlen" bytes from "msg" into the hash}
|
||||
|
||||
procedure blake2b_Final(var ctx: THashContext; var Digest: TBlake2BDigest);
|
||||
{-Finalize calculation, generate message digest, clear context}
|
||||
|
||||
function blake2b_full(var dig: TBlake2BDigest; diglen: word;
|
||||
key: pointer; keylen: word;
|
||||
msg: pointer; mlen: longint): integer;
|
||||
{-Calculate hash digest of Msg with init/update/final}
|
||||
|
||||
function blake2b_selftest: boolean;
|
||||
{-Return true, if self test is OK}
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
|
||||
{The next comment is copy from blake2b-ref.c}
|
||||
|
||||
(*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
|
||||
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
|
||||
your option. The terms of these licenses can be found at:
|
||||
|
||||
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
- OpenSSL license : https://www.openssl.org/source/license.html
|
||||
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
More information about the BLAKE2 hash function can be found at
|
||||
https://blake2.net.
|
||||
*)
|
||||
|
||||
{Initialization Vector, longints for compatibility}
|
||||
const
|
||||
blake2b_ivl: array[0..15] of longint = (
|
||||
longint($F3BCC908), longint($6A09E667),
|
||||
longint($84CAA73B), longint($BB67AE85),
|
||||
longint($FE94F82B), longint($3C6EF372),
|
||||
longint($5F1D36F1), longint($A54FF53A),
|
||||
longint($ADE682D1), longint($510E527F),
|
||||
longint($2B3E6C1F), longint($9B05688C),
|
||||
longint($FB41BD6B), longint($1F83D9AB),
|
||||
longint($137E2179), longint($5BE0CD19));
|
||||
|
||||
const
|
||||
sigma: array[0..11,0..15] of byte = (
|
||||
( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ),
|
||||
( 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ),
|
||||
( 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 ),
|
||||
( 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 ),
|
||||
( 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 ),
|
||||
( 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 ),
|
||||
( 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 ),
|
||||
( 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 ),
|
||||
( 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 ),
|
||||
( 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 ),
|
||||
( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ),
|
||||
( 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 )
|
||||
);
|
||||
|
||||
|
||||
{$ifdef HAS_INT64}
|
||||
|
||||
type
|
||||
blake2b_ctx = packed record
|
||||
h: packed array[0..7] of int64;
|
||||
t: packed array[0..1] of int64;
|
||||
b: TBlake2BBlock;
|
||||
c: longint;
|
||||
outlen: longint;
|
||||
fill4: packed array[217..HASHCTXSIZE] of byte;
|
||||
end;
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
procedure blake2b_compress(var ctx: blake2b_ctx; last: boolean);
|
||||
{- Compression function, "last" indicates last block}
|
||||
var
|
||||
v,m: array[0..15] of int64;
|
||||
tem: int64;
|
||||
round,k: integer;
|
||||
begin
|
||||
with ctx do begin
|
||||
{init work variables}
|
||||
move(h, v, sizeof(h));
|
||||
move(blake2b_ivl, v[8], sizeof(h));
|
||||
v[12] := v[12] xor t[0]; {low 64 bits of offset}
|
||||
v[13] := v[13] xor t[1]; {high 64 bits}
|
||||
if last then v[14] := not v[14]; {last block flag set}
|
||||
|
||||
{get little-endian words}
|
||||
move(b, m, sizeof(m));
|
||||
|
||||
{do 12 rounds}
|
||||
for round:=0 to 11 do begin
|
||||
{** EddyHawk speed-ups **}
|
||||
{use same rearrangements as blake2s' 32/64 bit code}
|
||||
v[ 0] := (v[ 0] + v[ 4]) + m[sigma[round][ 0]];
|
||||
v[ 1] := (v[ 1] + v[ 5]) + m[sigma[round][ 2]];
|
||||
v[ 2] := (v[ 2] + v[ 6]) + m[sigma[round][ 4]];
|
||||
v[ 3] := (v[ 3] + v[ 7]) + m[sigma[round][ 6]];
|
||||
|
||||
tem := v[12] xor v[ 0];
|
||||
v[12] := (tem shr 32) or (tem shl (64-32));
|
||||
tem := v[13] xor v[ 1];
|
||||
v[13] := (tem shr 32) or (tem shl (64-32));
|
||||
tem := v[14] xor v[ 2];
|
||||
v[14] := (tem shr 32) or (tem shl (64-32));
|
||||
tem := v[15] xor v[ 3];
|
||||
v[15] := (tem shr 32) or (tem shl (64-32));
|
||||
|
||||
v[ 8] := v[ 8] + v[12];
|
||||
v[ 9] := v[ 9] + v[13];
|
||||
v[10] := v[10] + v[14];
|
||||
v[11] := v[11] + v[15];
|
||||
|
||||
tem := v[ 4] xor v[ 8];
|
||||
v[ 4] := (tem shr 24) or (tem shl (64-24));
|
||||
tem := v[ 5] xor v[ 9];
|
||||
v[ 5] := (tem shr 24) or (tem shl (64-24));
|
||||
tem := v[ 6] xor v[10];
|
||||
v[ 6] := (tem shr 24) or (tem shl (64-24));
|
||||
tem := v[ 7] xor v[11];
|
||||
v[ 7] := (tem shr 24) or (tem shl (64-24));
|
||||
|
||||
{---}
|
||||
|
||||
v[ 0] := (v[ 0] + v[ 4]) + m[sigma[round][ 1]];
|
||||
v[ 1] := (v[ 1] + v[ 5]) + m[sigma[round][ 3]];
|
||||
v[ 2] := (v[ 2] + v[ 6]) + m[sigma[round][ 5]];
|
||||
v[ 3] := (v[ 3] + v[ 7]) + m[sigma[round][ 7]];
|
||||
|
||||
tem := v[12] xor v[ 0];
|
||||
v[12] := (tem shr 16) or (tem shl (64-16));
|
||||
tem := v[13] xor v[ 1];
|
||||
v[13] := (tem shr 16) or (tem shl (64-16));
|
||||
tem := v[14] xor v[ 2];
|
||||
v[14] := (tem shr 16) or (tem shl (64-16));
|
||||
tem := v[15] xor v[ 3];
|
||||
v[15] := (tem shr 16) or (tem shl (64-16));
|
||||
|
||||
v[ 8] := v[ 8] + v[12];
|
||||
v[ 9] := v[ 9] + v[13];
|
||||
v[10] := v[10] + v[14];
|
||||
v[11] := v[11] + v[15];
|
||||
|
||||
tem := v[ 4] xor v[ 8];
|
||||
v[ 4] := (tem shr 63) or (tem shl (64-63));
|
||||
tem := v[ 5] xor v[ 9];
|
||||
v[ 5] := (tem shr 63) or (tem shl (64-63));
|
||||
tem := v[ 6] xor v[10];
|
||||
v[ 6] := (tem shr 63) or (tem shl (64-63));
|
||||
tem := v[ 7] xor v[11];
|
||||
v[ 7] := (tem shr 63) or (tem shl (64-63));
|
||||
|
||||
{---}
|
||||
|
||||
v[ 0] := (v[ 0] + v[ 5]) + m[sigma[round][ 8]];
|
||||
v[ 1] := (v[ 1] + v[ 6]) + m[sigma[round][10]];
|
||||
v[ 2] := (v[ 2] + v[ 7]) + m[sigma[round][12]];
|
||||
v[ 3] := (v[ 3] + v[ 4]) + m[sigma[round][14]];
|
||||
|
||||
tem := v[15] xor v[ 0];
|
||||
v[15] := (tem shr 32) or (tem shl (64-32));
|
||||
tem := v[12] xor v[ 1];
|
||||
v[12] := (tem shr 32) or (tem shl (64-32));
|
||||
tem := v[13] xor v[ 2];
|
||||
v[13] := (tem shr 32) or (tem shl (64-32));
|
||||
tem := v[14] xor v[ 3];
|
||||
v[14] := (tem shr 32) or (tem shl (64-32));
|
||||
|
||||
v[10] := v[10] + v[15];
|
||||
v[11] := v[11] + v[12];
|
||||
v[ 8] := v[ 8] + v[13];
|
||||
v[ 9] := v[ 9] + v[14];
|
||||
|
||||
tem := v[ 5] xor v[10];
|
||||
v[ 5] := (tem shr 24) or (tem shl (64-24));
|
||||
tem := v[ 6] xor v[11];
|
||||
v[ 6] := (tem shr 24) or (tem shl (64-24));
|
||||
tem := v[ 7] xor v[ 8];
|
||||
v[ 7] := (tem shr 24) or (tem shl (64-24));
|
||||
tem := v[ 4] xor v[ 9];
|
||||
v[ 4] := (tem shr 24) or (tem shl (64-24));
|
||||
|
||||
{---}
|
||||
|
||||
v[ 0] := (v[ 0] + v[ 5]) + m[sigma[round][ 9]];
|
||||
v[ 1] := (v[ 1] + v[ 6]) + m[sigma[round][11]];
|
||||
v[ 2] := (v[ 2] + v[ 7]) + m[sigma[round][13]];
|
||||
v[ 3] := (v[ 3] + v[ 4]) + m[sigma[round][15]];
|
||||
|
||||
tem := v[15] xor v[ 0];
|
||||
v[15] := (tem shr 16) or (tem shl (64-16));
|
||||
tem := v[12] xor v[ 1];
|
||||
v[12] := (tem shr 16) or (tem shl (64-16));
|
||||
tem := v[13] xor v[ 2];
|
||||
v[13] := (tem shr 16) or (tem shl (64-16));
|
||||
tem := v[14] xor v[ 3];
|
||||
v[14] := (tem shr 16) or (tem shl (64-16));
|
||||
|
||||
v[10] := v[10] + v[15];
|
||||
v[11] := v[11] + v[12];
|
||||
v[ 8] := v[ 8] + v[13];
|
||||
v[ 9] := v[ 9] + v[14];
|
||||
|
||||
tem := v[ 5] xor v[10];
|
||||
v[ 5] := (tem shr 63) or (tem shl (64-63));
|
||||
tem := v[ 6] xor v[11];
|
||||
v[ 6] := (tem shr 63) or (tem shl (64-63));
|
||||
tem := v[ 7] xor v[ 8];
|
||||
v[ 7] := (tem shr 63) or (tem shl (64-63));
|
||||
tem := v[ 4] xor v[ 9];
|
||||
v[ 4] := (tem shr 63) or (tem shl (64-63));
|
||||
end;
|
||||
|
||||
{finalization}
|
||||
for k:=0 to 7 do begin
|
||||
h[k] := h[k] xor v[k] xor v[k+8];
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
procedure blake2b_update(var ctx: THashContext; msg: pointer; mlen: longint);
|
||||
{-Add "mlen" bytes from "msg" into the hash}
|
||||
var
|
||||
left,fill: integer;
|
||||
begin
|
||||
with blake2b_ctx(ctx) do begin
|
||||
if mlen > 0 then begin
|
||||
left := c;
|
||||
fill := BLAKE2B_BlockLen - left;
|
||||
if mlen > fill then begin
|
||||
c := 0;
|
||||
if fill>0 then move(msg^, b[left], fill);
|
||||
t[0] := t[0] + BLAKE2B_BlockLen;
|
||||
blake2b_compress(blake2b_ctx(ctx), false);
|
||||
inc(Ptr2Inc(Msg),fill);
|
||||
dec(mlen,fill);
|
||||
while mlen > BLAKE2B_BlockLen do begin
|
||||
move(msg^,b,BLAKE2B_BlockLen);
|
||||
t[0] := t[0] + BLAKE2B_BlockLen;
|
||||
blake2b_compress(blake2b_ctx(ctx), false); {compress (not last)}
|
||||
inc(Ptr2Inc(Msg),BLAKE2B_BlockLen);
|
||||
dec(mlen,BLAKE2B_BlockLen);
|
||||
end;
|
||||
end;
|
||||
if mlen > 0 then begin
|
||||
move(msg^, b[c], mlen);
|
||||
c := c + mlen;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
procedure blake2b_Final(var ctx: THashContext; var Digest: TBlake2BDigest);
|
||||
{-Finalize calculation, generate message digest, clear context}
|
||||
var
|
||||
i: integer;
|
||||
begin
|
||||
with blake2b_ctx(ctx) do begin
|
||||
t[0] := t[0] + c;
|
||||
while c < BLAKE2B_BlockLen do begin {fill up with zeros}
|
||||
b[c] := 0;
|
||||
inc(c);
|
||||
end;
|
||||
blake2b_compress(blake2b_ctx(ctx), true); {final block}
|
||||
{little endian convert and store}
|
||||
fillchar(Digest, sizeof(Digest),0);
|
||||
for i:=0 to outlen-1 do begin
|
||||
Digest[i] := (h[i shr 3] shr (8*(i and 7))) and $FF;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{$else}
|
||||
|
||||
type
|
||||
blake2b_ctx = packed record
|
||||
h: packed array[0..15] of longint;
|
||||
t: packed array[0..3] of longint;
|
||||
b: TBlake2BBlock;
|
||||
c: longint;
|
||||
outlen: longint;
|
||||
fill4: packed array[217..HASHCTXSIZE] of byte;
|
||||
end;
|
||||
|
||||
type
|
||||
TW64 = packed record
|
||||
L,H: longint;
|
||||
end;
|
||||
TW16 = packed record
|
||||
w0,w1,w2,w3: word
|
||||
end;
|
||||
|
||||
{$ifdef BIT16}
|
||||
{$ifdef BASM}
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
procedure Add64(var z: TW64; {$ifdef CONST} const {$else} var {$endif} x: TW64); assembler;
|
||||
{-Inc a 64 bit integer}
|
||||
asm
|
||||
les bx,[x]
|
||||
db $66; mov ax,es:[bx]
|
||||
db $66; mov dx,es:[bx+4]
|
||||
les bx,[z]
|
||||
db $66; add es:[bx],ax
|
||||
db $66; adc es:[bx+4],dx
|
||||
end;
|
||||
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
procedure RotR63(var x: tw64);
|
||||
{-Rotate right 63 bits = rotate left 1}
|
||||
begin
|
||||
asm
|
||||
les bx,[x]
|
||||
db $66; mov ax,es:[bx]
|
||||
db $66; mov dx,es:[bx+4]
|
||||
db $66; shl ax,1
|
||||
db $66; rcl dx,1
|
||||
adc ax,0
|
||||
db $66; mov es:[bx],ax
|
||||
db $66; mov es:[bx+4],dx
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{$else}
|
||||
|
||||
{16-bit compilers without BASM}
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
procedure Add64(var Z: TW64; var X: TW64);
|
||||
{-Inc a 64 bit integer}
|
||||
inline(
|
||||
$8C/$DF/ {mov di,ds }
|
||||
$5E/ {pop si }
|
||||
$1F/ {pop ds }
|
||||
$8B/$04/ {mov ax,[si] }
|
||||
$8B/$5C/$02/ {mov bx,[si+02]}
|
||||
$8B/$4C/$04/ {mov cx,[si+04]}
|
||||
$8B/$54/$06/ {mov dx,[si+06]}
|
||||
$5E/ {pop si }
|
||||
$1F/ {pop ds }
|
||||
$01/$04/ {add [si],ax }
|
||||
$11/$5C/$02/ {adc [si+02],bx}
|
||||
$11/$4C/$04/ {adc [si+04],cx}
|
||||
$11/$54/$06/ {adc [si+06],dx}
|
||||
$8E/$DF); {mov ds,di }
|
||||
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
procedure RotR63(var x: tw64);
|
||||
{-Rotate right 63 bits = rotate left 1}
|
||||
inline(
|
||||
$8C/$D9/ {mov cx,ds }
|
||||
$5B/ {pop bx }
|
||||
$1F/ {pop ds }
|
||||
$8B/$47/$06/ {mov ax,[bx+06]}
|
||||
$D1/$E0/ {shl ax,1 }
|
||||
$8B/$07/ {mov ax,[bx] }
|
||||
$D1/$D0/ {rcl ax,1 }
|
||||
$89/$07/ {mov [bx],ax }
|
||||
$8B/$47/$02/ {mov ax,[bx+02]}
|
||||
$D1/$D0/ {rcl ax,1 }
|
||||
$89/$47/$02/ {mov [bx+02],ax}
|
||||
$8B/$47/$04/ {mov ax,[bx+04]}
|
||||
$D1/$D0/ {rcl ax,1 }
|
||||
$89/$47/$04/ {mov [bx+04],ax}
|
||||
$8B/$47/$06/ {mov ax,[bx+06]}
|
||||
$D1/$D0/ {rcl ax,1 }
|
||||
$89/$47/$06/ {mov [bx+06],ax}
|
||||
$8E/$D9); {mov ds,cx }
|
||||
{$endif}
|
||||
|
||||
{$else}
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
procedure Add64(var z: TW64; const x: TW64); assembler;
|
||||
{-Inc a 64 bit integer z := z + x}
|
||||
asm
|
||||
{$ifdef LoadArgs}
|
||||
mov eax,[z]
|
||||
mov edx,[x]
|
||||
{$endif}
|
||||
mov ecx,[edx]
|
||||
add [eax],ecx
|
||||
mov ecx,[edx+4]
|
||||
adc [eax+4],ecx
|
||||
end;
|
||||
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
procedure RotR63(var x: tw64); assembler;
|
||||
{-Rotate right 63 bits}
|
||||
asm
|
||||
{$ifdef LoadArgs}
|
||||
mov eax,[x]
|
||||
{$endif}
|
||||
mov ecx,[eax]
|
||||
mov edx,[eax+4]
|
||||
shl ecx,1
|
||||
rcl edx,1
|
||||
adc ecx,0
|
||||
mov [eax],ecx
|
||||
mov [eax+4],edx
|
||||
end;
|
||||
|
||||
{$endif}
|
||||
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
procedure RotR24(var x: tw64);
|
||||
{-Rotate right 24 bits}
|
||||
var
|
||||
a: packed array[0..7] of byte absolute x;
|
||||
b0,b1,b2: byte;
|
||||
begin
|
||||
b0 := a[0];
|
||||
b1 := a[1];
|
||||
b2 := a[2];
|
||||
a[0] := a[3];
|
||||
a[1] := a[4];
|
||||
a[2] := a[5];
|
||||
a[3] := a[6];
|
||||
a[4] := a[7];
|
||||
a[5] := b0;
|
||||
a[6] := b1;
|
||||
a[7] := b2;
|
||||
end;
|
||||
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
procedure inct01(var ctx: THashContext; cnt: longint);
|
||||
{-Increment byte counter in ctx}
|
||||
begin
|
||||
with blake2b_ctx(ctx) do begin
|
||||
if t[0] < 0 then begin
|
||||
{Overflow if t[0]+cnt changes sign}
|
||||
inc(t[0], cnt);
|
||||
if t[0] >= 0 then inc(t[1]);
|
||||
end
|
||||
else inc(t[0], cnt);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
procedure blake2b_compress(var ctx: blake2b_ctx; last: boolean);
|
||||
{-Compression function, "last" indicates last block}
|
||||
var
|
||||
v,m: array[0..15] of tw64;
|
||||
tem: longint;
|
||||
round,k: integer;
|
||||
tw: word;
|
||||
begin
|
||||
{get message}
|
||||
with ctx do begin
|
||||
{init work variables}
|
||||
move(h, v, sizeof(h));
|
||||
move(blake2b_ivl, v[8], sizeof(h));
|
||||
|
||||
v[12].l := v[12].l xor t[0]; {low 64 bits of offset}
|
||||
v[12].h := v[12].h xor t[1];
|
||||
v[13].l := v[13].l xor t[2]; {high 64 bits}
|
||||
v[13].h := v[13].h xor t[3];
|
||||
if last then begin
|
||||
v[14].l := not v[14].l; {last block flag set}
|
||||
v[14].h := not v[14].h;
|
||||
end;
|
||||
|
||||
{get little-endian words}
|
||||
move(b, m, sizeof(m));
|
||||
|
||||
{do 12 rounds}
|
||||
for round:=0 to 11 do begin
|
||||
{** EddyHawk speed-ups **}
|
||||
{replaces G64 with partial unroll}
|
||||
{replaces rotr64 by 32 with swap & temp var}
|
||||
{ integrates xor-ing into that swapping}
|
||||
{splits 1 BLAKE2b round into quarter-rounds}
|
||||
{ regroups them}
|
||||
{further splitting/regroupings, seems a bit better}
|
||||
{moves message addition to the front, seems a bit better}
|
||||
|
||||
add64(v[0],m[sigma[round][2*0]]);
|
||||
add64(v[1],m[sigma[round][2*1]]);
|
||||
add64(v[2],m[sigma[round][2*2]]);
|
||||
add64(v[3],m[sigma[round][2*3]]);
|
||||
add64(v[0],v[4]);
|
||||
add64(v[1],v[5]);
|
||||
add64(v[2],v[6]);
|
||||
add64(v[3],v[7]);
|
||||
|
||||
tem := v[12].L xor v[0].L;
|
||||
v[12].L := v[12].H xor v[0].H;
|
||||
v[12].H := tem;
|
||||
tem := v[13].L xor v[1].L;
|
||||
v[13].L := v[13].H xor v[1].H;
|
||||
v[13].H := tem;
|
||||
tem := v[14].L xor v[2].L;
|
||||
v[14].L := v[14].H xor v[2].H;
|
||||
v[14].H := tem;
|
||||
tem := v[15].L xor v[3].L;
|
||||
v[15].L := v[15].H xor v[3].H;
|
||||
v[15].H := tem;
|
||||
|
||||
add64(v[ 8],v[12]);
|
||||
add64(v[ 9],v[13]);
|
||||
add64(v[10],v[14]);
|
||||
add64(v[11],v[15]);
|
||||
|
||||
v[4].L := v[4].L xor v[ 8].L;
|
||||
v[5].L := v[5].L xor v[ 9].L;
|
||||
v[6].L := v[6].L xor v[10].L;
|
||||
v[7].L := v[7].L xor v[11].L;
|
||||
v[4].H := v[4].H xor v[ 8].H;
|
||||
v[5].H := v[5].H xor v[ 9].H;
|
||||
v[6].H := v[6].H xor v[10].H;
|
||||
v[7].H := v[7].H xor v[11].H;
|
||||
|
||||
RotR24(v[4]);
|
||||
RotR24(v[5]);
|
||||
RotR24(v[6]);
|
||||
RotR24(v[7]);
|
||||
|
||||
{---}
|
||||
|
||||
add64(v[0],m[sigma[round][2*0+1]]);
|
||||
add64(v[1],m[sigma[round][2*1+1]]);
|
||||
add64(v[2],m[sigma[round][2*2+1]]);
|
||||
add64(v[3],m[sigma[round][2*3+1]]);
|
||||
add64(v[0],v[4]);
|
||||
add64(v[1],v[5]);
|
||||
add64(v[2],v[6]);
|
||||
add64(v[3],v[7]);
|
||||
|
||||
v[12].L := v[12].L xor v[ 0].L;
|
||||
v[13].L := v[13].L xor v[ 1].L;
|
||||
v[14].L := v[14].L xor v[ 2].L;
|
||||
v[15].L := v[15].L xor v[ 3].L;
|
||||
v[12].H := v[12].H xor v[ 0].H;
|
||||
v[13].H := v[13].H xor v[ 1].H;
|
||||
v[14].H := v[14].H xor v[ 2].H;
|
||||
v[15].H := v[15].H xor v[ 3].H;
|
||||
|
||||
{WE V0.23: Replace RotR(,16) with word moves}
|
||||
{RotR(v[12],16);}
|
||||
with TW16(v[12]) do begin
|
||||
tw := w0;
|
||||
w0 := w1;
|
||||
w1 := w2;
|
||||
w2 := w3;
|
||||
w3 := tw;
|
||||
end;
|
||||
{RotR(v[13],16);}
|
||||
with TW16(v[13]) do begin
|
||||
tw := w0;
|
||||
w0 := w1;
|
||||
w1 := w2;
|
||||
w2 := w3;
|
||||
w3 := tw;
|
||||
end;
|
||||
{RotR(v[14],16);}
|
||||
with TW16(v[14]) do begin
|
||||
tw := w0;
|
||||
w0 := w1;
|
||||
w1 := w2;
|
||||
w2 := w3;
|
||||
w3 := tw;
|
||||
end;
|
||||
{RotR(v[15],16);}
|
||||
with TW16(v[15]) do begin
|
||||
tw := w0;
|
||||
w0 := w1;
|
||||
w1 := w2;
|
||||
w2 := w3;
|
||||
w3 := tw;
|
||||
end;
|
||||
|
||||
add64(v[ 8],v[12]);
|
||||
add64(v[ 9],v[13]);
|
||||
add64(v[10],v[14]);
|
||||
add64(v[11],v[15]);
|
||||
|
||||
v[4].L := v[4].L xor v[ 8].L;
|
||||
v[5].L := v[5].L xor v[ 9].L;
|
||||
v[6].L := v[6].L xor v[10].L;
|
||||
v[7].L := v[7].L xor v[11].L;
|
||||
v[4].H := v[4].H xor v[ 8].H;
|
||||
v[5].H := v[5].H xor v[ 9].H;
|
||||
v[6].H := v[6].H xor v[10].H;
|
||||
v[7].H := v[7].H xor v[11].H;
|
||||
|
||||
RotR63(v[4]);
|
||||
RotR63(v[5]);
|
||||
RotR63(v[6]);
|
||||
RotR63(v[7]);
|
||||
{---}
|
||||
|
||||
add64(v[0],m[sigma[round][2*4]]);
|
||||
add64(v[1],m[sigma[round][2*5]]);
|
||||
add64(v[2],m[sigma[round][2*6]]);
|
||||
add64(v[3],m[sigma[round][2*7]]);
|
||||
add64(v[0],v[5]);
|
||||
add64(v[1],v[6]);
|
||||
add64(v[2],v[7]);
|
||||
add64(v[3],v[4]);
|
||||
|
||||
tem := v[15].L xor v[0].L;
|
||||
v[15].L := v[15].H xor v[0].H;
|
||||
v[15].H := tem;
|
||||
tem := v[12].L xor v[1].L;
|
||||
v[12].L := v[12].H xor v[1].H;
|
||||
v[12].H := tem;
|
||||
tem := v[13].L xor v[2].L;
|
||||
v[13].L := v[13].H xor v[2].H;
|
||||
v[13].H := tem;
|
||||
tem := v[14].L xor v[3].L;
|
||||
v[14].L := v[14].H xor v[3].H;
|
||||
v[14].H := tem;
|
||||
|
||||
add64(v[10],v[15]);
|
||||
add64(v[11],v[12]);
|
||||
add64(v[ 8],v[13]);
|
||||
add64(v[ 9],v[14]);
|
||||
|
||||
v[5].L := v[5].L xor v[10].L;
|
||||
v[6].L := v[6].L xor v[11].L;
|
||||
v[7].L := v[7].L xor v[ 8].L;
|
||||
v[4].L := v[4].L xor v[ 9].L;
|
||||
v[5].H := v[5].H xor v[10].H;
|
||||
v[6].H := v[6].H xor v[11].H;
|
||||
v[7].H := v[7].H xor v[ 8].H;
|
||||
v[4].H := v[4].H xor v[ 9].H;
|
||||
|
||||
RotR24(v[5]);
|
||||
RotR24(v[6]);
|
||||
RotR24(v[7]);
|
||||
RotR24(v[4]);
|
||||
|
||||
|
||||
add64(v[0],m[sigma[round][2*4+1]]);
|
||||
add64(v[1],m[sigma[round][2*5+1]]);
|
||||
add64(v[2],m[sigma[round][2*6+1]]);
|
||||
add64(v[3],m[sigma[round][2*7+1]]);
|
||||
add64(v[0],v[5]);
|
||||
add64(v[1],v[6]);
|
||||
add64(v[2],v[7]);
|
||||
add64(v[3],v[4]);
|
||||
|
||||
v[15].L := v[15].L xor v[ 0].L;
|
||||
v[12].L := v[12].L xor v[ 1].L;
|
||||
v[13].L := v[13].L xor v[ 2].L;
|
||||
v[14].L := v[14].L xor v[ 3].L;
|
||||
v[15].H := v[15].H xor v[ 0].H;
|
||||
v[12].H := v[12].H xor v[ 1].H;
|
||||
v[13].H := v[13].H xor v[ 2].H;
|
||||
v[14].H := v[14].H xor v[ 3].H;
|
||||
|
||||
{WE V0.23: Replace RotR(,16) with word moves}
|
||||
{RotR(v[15],16);}
|
||||
with TW16(v[15]) do begin
|
||||
tw := w0;
|
||||
w0 := w1;
|
||||
w1 := w2;
|
||||
w2 := w3;
|
||||
w3 := tw;
|
||||
end;
|
||||
{RotR(v[12],16);}
|
||||
with TW16(v[12]) do begin
|
||||
tw := w0;
|
||||
w0 := w1;
|
||||
w1 := w2;
|
||||
w2 := w3;
|
||||
w3 := tw;
|
||||
end;
|
||||
{RotR(v[13],16);}
|
||||
with TW16(v[13]) do begin
|
||||
tw := w0;
|
||||
w0 := w1;
|
||||
w1 := w2;
|
||||
w2 := w3;
|
||||
w3 := tw;
|
||||
end;
|
||||
{RotR(v[14],16);}
|
||||
with TW16(v[14]) do begin
|
||||
tw := w0;
|
||||
w0 := w1;
|
||||
w1 := w2;
|
||||
w2 := w3;
|
||||
w3 := tw;
|
||||
end;
|
||||
|
||||
add64(v[10],v[15]);
|
||||
add64(v[11],v[12]);
|
||||
add64(v[ 8],v[13]);
|
||||
add64(v[ 9],v[14]);
|
||||
|
||||
v[5].L := v[5].L xor v[10].L;
|
||||
v[6].L := v[6].L xor v[11].L;
|
||||
v[7].L := v[7].L xor v[ 8].L;
|
||||
v[4].L := v[4].L xor v[ 9].L;
|
||||
v[5].H := v[5].H xor v[10].H;
|
||||
v[6].H := v[6].H xor v[11].H;
|
||||
v[7].H := v[7].H xor v[ 8].H;
|
||||
v[4].H := v[4].H xor v[ 9].H;
|
||||
|
||||
RotR63(v[5]);
|
||||
RotR63(v[6]);
|
||||
RotR63(v[7]);
|
||||
RotR63(v[4]);
|
||||
end;
|
||||
|
||||
{finalization}
|
||||
for k:=0 to 7 do begin
|
||||
h[2*k] := h[2*k] xor v[k].l xor v[k+8].l;
|
||||
h[2*k+1] := h[2*k+1] xor v[k].h xor v[k+8].h;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
procedure blake2b_update(var ctx: THashContext; msg: pointer; mlen: longint);
|
||||
{-Add "mlen" bytes from "msg" into the hash}
|
||||
var
|
||||
left,fill: integer;
|
||||
begin
|
||||
with blake2b_ctx(ctx) do begin
|
||||
if mlen > 0 then begin
|
||||
left := c;
|
||||
fill := BLAKE2B_BlockLen - left;
|
||||
if mlen > fill then begin
|
||||
c := 0;
|
||||
if fill>0 then move(msg^, b[left], fill);
|
||||
inct01(ctx, BLAKE2B_BlockLen);
|
||||
blake2b_compress(blake2b_ctx(ctx), false);
|
||||
inc(Ptr2Inc(Msg),fill);
|
||||
dec(mlen,fill);
|
||||
while mlen > BLAKE2B_BlockLen do begin
|
||||
move(msg^,b,BLAKE2B_BlockLen);
|
||||
inct01(ctx, BLAKE2B_BlockLen);
|
||||
blake2b_compress(blake2b_ctx(ctx), false); {compress (not last)}
|
||||
inc(Ptr2Inc(Msg),BLAKE2B_BlockLen);
|
||||
dec(mlen,BLAKE2B_BlockLen);
|
||||
end;
|
||||
end;
|
||||
if mlen > 0 then begin
|
||||
move(msg^, b[c], mlen);
|
||||
c := c + mlen;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
procedure blake2b_Final(var ctx: THashContext; var Digest: TBlake2BDigest);
|
||||
{-Finalize calculation, generate message digest, clear context}
|
||||
begin
|
||||
with blake2b_ctx(ctx) do begin
|
||||
inct01(ctx, c);
|
||||
while c < BLAKE2B_BlockLen do begin {fill up with zeros}
|
||||
b[c] := 0;
|
||||
inc(c);
|
||||
end;
|
||||
blake2b_compress(blake2b_ctx(ctx), true); {final block}
|
||||
{little endian convert and store}
|
||||
fillchar(Digest, sizeof(Digest),0);
|
||||
move(h, Digest, outlen);
|
||||
end;
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
function blake2b_Init(var ctx: THashContext; key: pointer; keylen, diglen: word): integer;
|
||||
{-Initialize context for a digest of diglen bytes; keylen=0: no key}
|
||||
var
|
||||
tb: TBlake2BBlock;
|
||||
begin
|
||||
if (diglen=0) or (diglen > BLAKE2B_MaxDigLen) or (keylen > BLAKE2B_MaxKeyLen) then begin
|
||||
blake2b_Init := -1; {illegal parameters}
|
||||
exit;
|
||||
end;
|
||||
blake2b_Init := 0;
|
||||
fillchar(ctx, sizeof(ctx), 0);
|
||||
with blake2b_ctx(ctx) do begin
|
||||
move(blake2b_ivl, h, sizeof(h));
|
||||
outlen := diglen;
|
||||
{Fill the lowest 32 bit of h, same for 16/32/64 bit}
|
||||
h[0] := h[0] xor (($01010000) xor (keylen shl 8) xor outlen);
|
||||
if keylen > 0 then begin
|
||||
fillchar(tb, sizeof(tb),0);
|
||||
move(key^, tb, keylen);
|
||||
blake2b_update(ctx, @tb, BLAKE2B_BlockLen);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
function blake2b_full(var dig: TBlake2BDigest; diglen: word;
|
||||
key: pointer; keylen: word;
|
||||
msg: pointer; mlen: longint): integer;
|
||||
{-Calculate hash digest of Msg with init/update/final}
|
||||
var
|
||||
ctx: THashContext;
|
||||
begin
|
||||
if blake2b_init(ctx, key, keylen, diglen) <> 0 then begin
|
||||
blake2b_full := -1;
|
||||
end
|
||||
else begin
|
||||
blake2b_update(ctx, msg, mlen);
|
||||
blake2b_final(ctx, dig);
|
||||
blake2b_full := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{---------------------------------------------------------------------------}
|
||||
function blake2b_selftest: boolean;
|
||||
{-Return true, if self test is OK}
|
||||
procedure selftest_seq(outp: pbyte; len, seed: integer);
|
||||
var
|
||||
t,a,b: longint;
|
||||
i: integer;
|
||||
begin
|
||||
a := longint($DEAD4BAD) * seed;
|
||||
b := 1;
|
||||
for i:=1 to len do begin
|
||||
t := a+b;
|
||||
a := b;
|
||||
b := t;
|
||||
outp^ := (t shr 24) and $FF;
|
||||
inc(Ptr2Inc(outp));
|
||||
end;
|
||||
end;
|
||||
const
|
||||
{Grand hash of hash results}
|
||||
blake2b_res: array[0..31] of byte = (
|
||||
$C2, $3A, $78, $00, $D9, $81, $23, $BD,
|
||||
$10, $F5, $06, $C6, $1E, $29, $DA, $56,
|
||||
$03, $D7, $63, $B8, $BB, $AD, $2E, $73,
|
||||
$7F, $5E, $76, $5A, $7B, $CC, $D4, $75
|
||||
);
|
||||
{Parameter sets}
|
||||
b2s_md_len: array[0..3] of integer = (20, 32, 48, 64);
|
||||
b2s_in_len: array[0..5] of integer = (0, 3, 128, 129, 255, 1024);
|
||||
var
|
||||
i,j, outlen, inlen: integer;
|
||||
md, key: TBlake2BDigest;
|
||||
ctx: THashContext;
|
||||
inb: array[0..1023] of byte;
|
||||
begin
|
||||
blake2b_selftest := false;
|
||||
{256-bit hash for testing}
|
||||
if blake2b_init(ctx, nil, 0, 32) <> 0 then exit;
|
||||
for i:=0 to 3 do begin
|
||||
outlen := b2s_md_len[i];
|
||||
for j:=0 to 5 do begin
|
||||
inlen := b2s_in_len[j];
|
||||
selftest_seq(pbyte(@inb), inlen, inlen); {unkeyed hash}
|
||||
if blake2b_full(md, outlen, nil, 0, @inb, inlen) <> 0 then exit;
|
||||
blake2b_update(ctx, @md, outlen); {hash the hash}
|
||||
selftest_seq(pbyte(@key), outlen, outlen); {keyed hash}
|
||||
if blake2b_full(md, outlen, @key, outlen, @inb, inlen) <> 0 then exit;
|
||||
blake2b_update(ctx, @md, outlen); {hash the hash}
|
||||
end;
|
||||
end;
|
||||
{Compute and compare the hash of hashes.}
|
||||
blake2b_final(ctx, md);
|
||||
for i:=0 to 31 do begin
|
||||
if md[i] <> blake2b_res[i] then exit;
|
||||
end;
|
||||
blake2b_selftest := true;
|
||||
end;
|
||||
|
||||
|
||||
begin
|
||||
{$ifdef HAS_ASSERT}
|
||||
assert(sizeof(blake2b_ctx)=HASHCTXSIZE , '** Invalid sizeof(blake2b_ctx)');
|
||||
{$endif}
|
||||
end.
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue