Browse Source

ADD - added HashLib4Pascal to PascalCoin Libraries.

Ugochukwu Mmaduekwe 7 years ago
parent
commit
d5d3f01bfd
100 changed files with 32221 additions and 0 deletions
  1. 153 0
      src/libraries/hashlib4pascal/HashLib/src/Base/HlpHMACNotBuildInAdapter.pas
  2. 367 0
      src/libraries/hashlib4pascal/HashLib/src/Base/HlpHash.pas
  3. 183 0
      src/libraries/hashlib4pascal/HashLib/src/Base/HlpHashBuffer.pas
  4. 124 0
      src/libraries/hashlib4pascal/HashLib/src/Base/HlpHashCryptoNotBuildIn.pas
  5. 1180 0
      src/libraries/hashlib4pascal/HashLib/src/Base/HlpHashFactory.pas
  6. 274 0
      src/libraries/hashlib4pascal/HashLib/src/Base/HlpHashResult.pas
  7. 10 0
      src/libraries/hashlib4pascal/HashLib/src/Base/HlpHashRounds.pas
  8. 12 0
      src/libraries/hashlib4pascal/HashLib/src/Base/HlpHashSize.pas
  9. 43 0
      src/libraries/hashlib4pascal/HashLib/src/Base/HlpKDF.pas
  10. 95 0
      src/libraries/hashlib4pascal/HashLib/src/Base/HlpMultipleTransformNonBlock.pas
  11. 105 0
      src/libraries/hashlib4pascal/HashLib/src/Checksum/HlpAdler32.pas
  12. 1423 0
      src/libraries/hashlib4pascal/HashLib/src/Checksum/HlpCRC.pas
  13. 85 0
      src/libraries/hashlib4pascal/HashLib/src/Checksum/HlpCRC16.pas
  14. 106 0
      src/libraries/hashlib4pascal/HashLib/src/Checksum/HlpCRC32.pas
  15. 86 0
      src/libraries/hashlib4pascal/HashLib/src/Checksum/HlpCRC64.pas
  16. 102 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/Blake2BConfigurations/HlpBlake2BConfig.pas
  17. 139 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/Blake2BConfigurations/HlpBlake2BIvBuilder.pas
  18. 100 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/Blake2BConfigurations/HlpBlake2BTreeConfig.pas
  19. 102 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/Blake2SConfigurations/HlpBlake2SConfig.pas
  20. 137 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/Blake2SConfigurations/HlpBlake2SIvBuilder.pas
  21. 100 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/Blake2SConfigurations/HlpBlake2STreeConfig.pas
  22. 1756 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpBlake2B.pas
  23. 1537 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpBlake2S.pas
  24. 1669 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpGOST3411_2012.pas
  25. 460 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpGost.pas
  26. 283 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpGrindahl256.pas
  27. 404 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpGrindahl512.pas
  28. 209 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpHAS160.pas
  29. 2187 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpHaval.pas
  30. 170 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpMD2.pas
  31. 161 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpMD4.pas
  32. 195 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpMD5.pas
  33. 102 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpMDBase.pas
  34. 283 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpPanama.pas
  35. 190 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpRIPEMD.pas
  36. 332 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpRIPEMD128.pas
  37. 570 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpRIPEMD160.pas
  38. 347 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpRIPEMD256.pas
  39. 579 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpRIPEMD320.pas
  40. 213 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpRadioGatun32.pas
  41. 211 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpRadioGatun64.pas
  42. 566 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA0.pas
  43. 245 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA1.pas
  44. 61 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA2_224.pas
  45. 63 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA2_256.pas
  46. 948 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA2_256Base.pas
  47. 64 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA2_384.pas
  48. 63 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA2_512.pas
  49. 1303 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA2_512Base.pas
  50. 65 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA2_512_224.pas
  51. 64 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA2_512_256.pas
  52. 2814 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA3.pas
  53. 815 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSnefru.pas
  54. 1038 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpTiger.pas
  55. 1038 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpTiger2.pas
  56. 292 0
      src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpWhirlPool.pas
  57. 494 0
      src/libraries/hashlib4pascal/HashLib/src/Hash128/HlpMurmurHash3_x64_128.pas
  58. 561 0
      src/libraries/hashlib4pascal/HashLib/src/Hash128/HlpMurmurHash3_x86_128.pas
  59. 79 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpAP.pas
  60. 72 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpBKDR.pas
  61. 69 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpBernstein.pas
  62. 69 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpBernstein1.pas
  63. 51 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpDEK.pas
  64. 69 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpDJB.pas
  65. 75 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpELF.pas
  66. 69 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpFNV.pas
  67. 69 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpFNV1a.pas
  68. 69 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpJS.pas
  69. 395 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpJenkins3.pas
  70. 185 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpMurmur2.pas
  71. 253 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpMurmurHash3_x86_32.pas
  72. 74 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpOneAtTime.pas
  73. 79 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpPJW.pas
  74. 73 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpRS.pas
  75. 70 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpRotating.pas
  76. 69 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpSDBM.pas
  77. 68 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpShiftAndXor.pas
  78. 118 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpSuperFast.pas
  79. 244 0
      src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpXXHash32.pas
  80. 69 0
      src/libraries/hashlib4pascal/HashLib/src/Hash64/HlpFNV1a64.pas
  81. 69 0
      src/libraries/hashlib4pascal/HashLib/src/Hash64/HlpFNV64.pas
  82. 268 0
      src/libraries/hashlib4pascal/HashLib/src/Hash64/HlpMurmur2_64.pas
  83. 332 0
      src/libraries/hashlib4pascal/HashLib/src/Hash64/HlpSipHash.pas
  84. 283 0
      src/libraries/hashlib4pascal/HashLib/src/Hash64/HlpXXHash64.pas
  85. 127 0
      src/libraries/hashlib4pascal/HashLib/src/Include/HashLib.inc
  86. 16 0
      src/libraries/hashlib4pascal/HashLib/src/Include/HashLibHelper.inc
  87. 35 0
      src/libraries/hashlib4pascal/HashLib/src/Interfaces/HlpICRC.pas
  88. 61 0
      src/libraries/hashlib4pascal/HashLib/src/Interfaces/HlpIHash.pas
  89. 86 0
      src/libraries/hashlib4pascal/HashLib/src/Interfaces/HlpIHashInfo.pas
  90. 28 0
      src/libraries/hashlib4pascal/HashLib/src/Interfaces/HlpIHashResult.pas
  91. 24 0
      src/libraries/hashlib4pascal/HashLib/src/Interfaces/HlpIKDF.pas
  92. 31 0
      src/libraries/hashlib4pascal/HashLib/src/Interfaces/IBlake2BConfigurations/HlpIBlake2BConfig.pas
  93. 28 0
      src/libraries/hashlib4pascal/HashLib/src/Interfaces/IBlake2BConfigurations/HlpIBlake2BTreeConfig.pas
  94. 31 0
      src/libraries/hashlib4pascal/HashLib/src/Interfaces/IBlake2SConfigurations/HlpIBlake2SConfig.pas
  95. 28 0
      src/libraries/hashlib4pascal/HashLib/src/Interfaces/IBlake2SConfigurations/HlpIBlake2STreeConfig.pas
  96. 202 0
      src/libraries/hashlib4pascal/HashLib/src/KDF/HlpPBKDF2_HMACNotBuildInAdapter.pas
  97. 73 0
      src/libraries/hashlib4pascal/HashLib/src/NullDigest/HlpNullDigest.pas
  98. 246 0
      src/libraries/hashlib4pascal/HashLib/src/Nullable/HlpNullable.pas
  99. 138 0
      src/libraries/hashlib4pascal/HashLib/src/Packages/Delphi/HashLib4PascalPackage.dpk
  100. 449 0
      src/libraries/hashlib4pascal/HashLib/src/Packages/FPC/HashLib4PascalPackage.lpk

+ 153 - 0
src/libraries/hashlib4pascal/HashLib/src/Base/HlpHMACNotBuildInAdapter.pas

@@ -0,0 +1,153 @@
+unit HlpHMACNotBuildInAdapter;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF HAS_UNITSCOPE}
+  System.SysUtils,
+{$ELSE}
+  SysUtils,
+{$ENDIF HAS_UNITSCOPE}
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHash,
+  HlpIHashInfo,
+  HlpIHashResult,
+  HlpNullable;
+
+type
+
+  THMACNotBuildInAdapter = class sealed(THash, IHMAC, IHMACNotBuildIn, IWithKey,
+    ICrypto, ICryptoNotBuildIn)
+
+  strict private
+
+    Fm_hash: IHash;
+    Fm_opad, Fm_ipad, Fm_key: THashLibByteArray;
+    Fm_blocksize: Int32;
+
+  strict protected
+
+    function GetName: String; override;
+
+    function GetKey(): THashLibByteArray; virtual;
+    function GetKeyLength(): TNullableInteger;
+    procedure SetKey(value: THashLibByteArray); virtual;
+    procedure UpdatePads();
+
+  public
+
+    constructor Create(a_underlyingHash: IHash);
+    procedure Initialize(); override;
+    function TransformFinal(): IHashResult; override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    property Key: THashLibByteArray read GetKey write SetKey;
+    property Name: String read GetName;
+    property KeyLength: TNullableInteger read GetKeyLength;
+
+  end;
+
+implementation
+
+{ THMACNotBuildInAdapter }
+
+constructor THMACNotBuildInAdapter.Create(a_underlyingHash: IHash);
+begin
+  Inherited Create(a_underlyingHash.HashSize, a_underlyingHash.BlockSize);
+  Fm_hash := a_underlyingHash;
+  Fm_blocksize := Fm_hash.BlockSize;
+  System.SetLength(Fm_key, 0);
+  System.SetLength(Fm_ipad, Fm_blocksize);
+  System.SetLength(Fm_opad, Fm_blocksize);
+end;
+
+function THMACNotBuildInAdapter.GetKey: THashLibByteArray;
+begin
+  result := System.Copy(Fm_key);
+end;
+
+function THMACNotBuildInAdapter.GetKeyLength: TNullableInteger;
+begin
+  result := Nil;
+end;
+
+procedure THMACNotBuildInAdapter.SetKey(value: THashLibByteArray);
+begin
+  if (value = Nil) then
+  begin
+
+    System.SetLength(Fm_key, 0);
+  end
+  else
+  begin
+    Fm_key := System.Copy(value);
+  end;
+end;
+
+procedure THMACNotBuildInAdapter.UpdatePads;
+var
+  LKey: THashLibByteArray;
+  Idx, LBlockSize: Int32;
+begin
+  LBlockSize := Fm_blocksize;
+  if (System.Length(Key) > LBlockSize) then
+  begin
+    LKey := Fm_hash.ComputeBytes(Key).GetBytes();
+  end
+  else
+  begin
+    LKey := Key;
+  end;
+
+  System.FillChar(Fm_ipad[0], LBlockSize * System.SizeOf(Byte), $36);
+  System.FillChar(Fm_opad[0], LBlockSize * System.SizeOf(Byte), $5C);
+
+  Idx := 0;
+  while (Idx < System.Length(LKey)) and (Idx < LBlockSize) do
+  begin
+    Fm_ipad[Idx] := Fm_ipad[Idx] xor LKey[Idx];
+    Fm_opad[Idx] := Fm_opad[Idx] xor LKey[Idx];
+    System.Inc(Idx);
+  end;
+
+end;
+
+procedure THMACNotBuildInAdapter.Initialize;
+begin
+  Fm_hash.Initialize();
+  UpdatePads();
+  Fm_hash.TransformBytes(Fm_ipad);
+end;
+
+function THMACNotBuildInAdapter.TransformFinal: IHashResult;
+begin
+  result := Fm_hash.TransformFinal();
+  Fm_hash.TransformBytes(Fm_opad);
+  Fm_hash.TransformBytes(result.GetBytes());
+  result := Fm_hash.TransformFinal();
+  Initialize();
+
+end;
+
+procedure THMACNotBuildInAdapter.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF}
+  Fm_hash.TransformBytes(a_data, a_index, a_length);
+end;
+
+function THMACNotBuildInAdapter.GetName: String;
+begin
+  result := Format('%s(%s)', [Self.ClassName, (Self.Fm_hash as THash)
+    .ClassName]);
+
+end;
+
+end.

+ 367 - 0
src/libraries/hashlib4pascal/HashLib/src/Base/HlpHash.pas

@@ -0,0 +1,367 @@
+unit HlpHash;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF HAS_UNITSCOPE}
+  System.Classes,
+  System.SysUtils,
+{$ELSE}
+  Classes,
+  SysUtils,
+{$ENDIF HAS_UNITSCOPE}
+  HlpHashLibTypes,
+  HlpConverters,
+  HlpIHash,
+  HlpIHashResult;
+
+resourcestring
+  SIndexOutOfRange = 'Current Index Is Out Of Range';
+  SInvalidBufferSize = '"BufferSize" Must Be Greater Than Zero';
+  // SInvalidBlockSize = '"BlockSize" Must Be Greater Than Zero';
+  // SInvalidHashSize = '"HashSize" Must Be Greater Than Zero';
+  SUnAssignedStream = 'Input Stream Is Unassigned';
+  SFileNotExist = 'Specified File Not Found';
+
+type
+  THash = class abstract(TInterfacedObject, IHash)
+
+  strict private
+
+    Fm_buffer_size, Fm_block_size, Fm_hash_size: Int32;
+
+  const
+    BUFFER_SIZE = Int32(64 * 1024); // 64Kb
+
+    function GetBlockSize: Int32; virtual;
+    procedure SetBlockSize(value: Int32); virtual;
+
+    function GetHashSize: Int32; virtual;
+    procedure SetHashSize(value: Int32); virtual;
+
+    function GetBufferSize: Int32; inline;
+    procedure SetBufferSize(value: Int32); inline;
+
+  strict protected
+
+    function GetName: String; virtual;
+
+  public
+
+    constructor Create(a_hash_size, a_block_size: Int32);
+    property Name: String read GetName;
+    property BlockSize: Int32 read GetBlockSize write SetBlockSize;
+    property HashSize: Int32 read GetHashSize write SetHashSize;
+    function ComputeString(const a_data: String; a_encoding: TEncoding)
+      : IHashResult; virtual;
+    function ComputeBytes(a_data: THashLibByteArray): IHashResult; virtual;
+    function ComputeUntyped(const a_data; a_length: Int64): IHashResult;
+    function ComputeStream(a_stream: TStream; a_length: Int64 = -1)
+      : IHashResult;
+    function ComputeFile(const a_file_name: String; a_from: Int64 = 0;
+      a_length: Int64 = -1): IHashResult;
+    procedure TransformString(const a_data: String; a_encoding: TEncoding);
+    procedure TransformBytes(a_data: THashLibByteArray); overload;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index: Int32); overload;
+    procedure TransformBytes(a_data: THashLibByteArray; a_index: Int32;
+      a_length: Int32); overload; virtual; abstract;
+    procedure TransformUntyped(const a_data; a_length: Int64);
+    procedure TransformStream(a_stream: TStream; a_length: Int64 = -1);
+    procedure TransformFile(const a_file_name: String; a_from: Int64 = 0;
+      a_length: Int64 = -1);
+    procedure Initialize(); virtual; abstract;
+    function TransformFinal(): IHashResult; virtual; abstract;
+
+    property BufferSize: Int32 read GetBufferSize write SetBufferSize;
+  end;
+
+implementation
+
+{ THash }
+
+constructor THash.Create(a_hash_size, a_block_size: Int32);
+begin
+{$IFDEF DEBUG}
+  System.Assert((a_block_size > 0) or (a_block_size = -1));
+  System.Assert((a_hash_size > 0) or (a_hash_size = -1));
+{$ENDIF DEBUG}
+  Fm_block_size := a_block_size;
+  Fm_hash_size := a_hash_size;
+  Fm_buffer_size := BUFFER_SIZE;
+end;
+
+function THash.GetName: String;
+begin
+  result := Self.ClassName;
+end;
+
+function THash.GetBufferSize: Int32;
+begin
+  result := Fm_buffer_size;
+end;
+
+procedure THash.SetBufferSize(value: Int32);
+begin
+  if value > 0 then
+  begin
+    Fm_buffer_size := value;
+  end
+  else
+  begin
+    raise EArgumentHashLibException.CreateRes(@SInvalidBufferSize);
+  end;
+end;
+
+function THash.GetBlockSize: Int32;
+begin
+  result := Fm_block_size;
+end;
+
+procedure THash.SetBlockSize(value: Int32);
+begin
+  // if value > 0 then
+  // begin
+  Fm_block_size := value;
+  // end
+  // else
+  // begin
+  // raise EArgumentHashLibException.CreateRes(@SInvalidBlockSize);
+  // end;
+end;
+
+function THash.GetHashSize: Int32;
+begin
+  result := Fm_hash_size;
+end;
+
+procedure THash.SetHashSize(value: Int32);
+begin
+  // if value > 0 then
+  // begin
+  Fm_hash_size := value;
+  // end
+  // else
+  // begin
+  // raise EArgumentHashLibException.CreateRes(@SInvalidHashSize);
+  // end;
+end;
+
+function THash.ComputeString(const a_data: String; a_encoding: TEncoding)
+  : IHashResult;
+begin
+  result := ComputeBytes(TConverters.ConvertStringToBytes(a_data, a_encoding));
+end;
+
+function THash.ComputeUntyped(const a_data; a_length: Int64): IHashResult;
+
+begin
+
+  Initialize();
+  TransformUntyped(a_data, a_length);
+  result := TransformFinal();
+
+end;
+
+procedure THash.TransformUntyped(const a_data; a_length: Int64);
+var
+  PtrBuffer, PtrEnd: PByte;
+  ArrBuffer: THashLibByteArray;
+  LBufferSize: Int32;
+begin
+  PtrBuffer := @a_data;
+
+  if BufferSize > a_length then // Sanity Check
+  begin
+    LBufferSize := BUFFER_SIZE;
+  end
+  else
+  begin
+    LBufferSize := BufferSize;
+  end;
+
+  if PtrBuffer <> Nil then
+  begin
+    System.SetLength(ArrBuffer, LBufferSize);
+    PtrEnd := (PtrBuffer) + a_length;
+
+    while PtrBuffer < PtrEnd do
+    begin
+
+      if (PtrEnd - PtrBuffer) >= LBufferSize then
+      begin
+        System.Move(PtrBuffer^, ArrBuffer[0], LBufferSize);
+        TransformBytes(ArrBuffer);
+        System.Inc(PtrBuffer, LBufferSize);
+      end
+      else
+      begin
+        System.SetLength(ArrBuffer, PtrEnd - PtrBuffer);
+        System.Move(PtrBuffer^, ArrBuffer[0], System.Length(ArrBuffer));
+        TransformBytes(ArrBuffer);
+        break;
+      end;
+
+    end;
+
+  end;
+end;
+
+function THash.ComputeStream(a_stream: TStream; a_length: Int64): IHashResult;
+begin
+  Initialize();
+  TransformStream(a_stream, a_length);
+  result := TransformFinal();
+
+end;
+
+function THash.ComputeFile(const a_file_name: String; a_from, a_length: Int64)
+  : IHashResult;
+begin
+  Initialize();
+  TransformFile(a_file_name, a_from, a_length);
+  result := TransformFinal();
+
+end;
+
+function THash.ComputeBytes(a_data: THashLibByteArray): IHashResult;
+begin
+  Initialize();
+  TransformBytes(a_data);
+  result := TransformFinal();
+
+end;
+
+procedure THash.TransformString(const a_data: String; a_encoding: TEncoding);
+begin
+  TransformBytes(TConverters.ConvertStringToBytes(a_data, a_encoding));
+end;
+
+procedure THash.TransformBytes(a_data: THashLibByteArray);
+begin
+  TransformBytes(a_data, 0, System.Length(a_data));
+end;
+
+procedure THash.TransformBytes(a_data: THashLibByteArray; a_index: Int32);
+var
+  &Length: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+{$ENDIF DEBUG}
+  Length := System.Length(a_data) - a_index;
+
+{$IFDEF DEBUG}
+  System.Assert(Length >= 0);
+{$ENDIF DEBUG}
+  TransformBytes(a_data, a_index, Length);
+end;
+
+procedure THash.TransformStream(a_stream: TStream; a_length: Int64);
+var
+  data: THashLibByteArray;
+  readed, LBufferSize: Int32;
+  total: Int64;
+begin
+{$IFDEF DEBUG}
+  System.Assert((a_length = -1) or (a_length > 0));
+{$ENDIF DEBUG}
+  total := 0;
+  if (a_stream <> Nil) then
+  begin
+    if (a_length > -1) then
+    begin
+
+      if ((a_stream.Position + a_length) > a_stream.Size) then
+        raise EIndexOutOfRangeHashLibException.CreateRes(@SIndexOutOfRange);
+    end;
+
+    if (a_stream.Position >= a_stream.Size) then
+      Exit;
+  end
+  else
+  begin
+    raise EArgumentNilHashLibException.CreateRes(@SUnAssignedStream);
+  end;
+
+  if BufferSize > a_stream.Size then // Sanity Check
+  begin
+    LBufferSize := BUFFER_SIZE;
+  end
+  else
+  begin
+    LBufferSize := BufferSize;
+  end;
+
+  System.SetLength(data, LBufferSize);
+
+  if (a_length = -1) then
+  begin
+
+    while true do
+    begin
+
+      readed := a_stream.Read(data[0], LBufferSize);
+
+      if (readed <> LBufferSize) then
+      begin
+        TransformBytes(data, 0, readed);
+        break;
+      end
+      else
+      begin
+        TransformBytes(data, 0, readed);
+        total := total + readed;
+      end;
+    end
+
+  end
+  else
+  begin
+    while true do
+    begin
+
+      readed := a_stream.Read(data[0], LBufferSize);
+
+      if ((total + Int64(readed)) >= a_length) then
+      begin
+        TransformBytes(data, 0, Int32(a_length - total));
+        break;
+      end
+      else
+      begin
+        TransformBytes(data, 0, readed);
+        total := total + readed;
+      end;
+    end
+
+  end;
+
+end;
+
+procedure THash.TransformFile(const a_file_name: String;
+  a_from, a_length: Int64);
+var
+  MyFileStream: TFileStream;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_from >= 0);
+  System.Assert((a_length = -1) or (a_length > 0));
+{$ENDIF DEBUG}
+  if not FileExists(a_file_name) then
+    raise EArgumentHashLibException.CreateRes(@SFileNotExist);
+
+  MyFileStream := TFileStream.Create(a_file_name, fmOpenRead or
+    fmShareDenyWrite);
+
+  try
+    MyFileStream.Seek(a_from, TSeekOrigin.soBeginning);
+    TransformStream(MyFileStream, a_length);
+  finally
+    MyFileStream.Free;
+  end;
+end;
+
+end.

+ 183 - 0
src/libraries/hashlib4pascal/HashLib/src/Base/HlpHashBuffer.pas

@@ -0,0 +1,183 @@
+unit HlpHashBuffer;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF HAS_UNITSCOPE}
+  System.SysUtils,
+{$ELSE}
+  SysUtils,
+{$ENDIF HAS_UNITSCOPE}
+  HlpHashLibTypes;
+
+type
+  THashBuffer = record
+
+  strict private
+
+    Fm_data: THashLibByteArray;
+    Fm_pos: Int32;
+
+    function GetIsEmpty: Boolean; inline;
+    function GetIsFull: Boolean; inline;
+    function GetPos: Int32; inline;
+    function GetLength: Int32; inline;
+
+  public
+    constructor Create(a_length: Int32);
+    procedure Initialize();
+    function GetBytes(): THashLibByteArray; inline;
+    function GetBytesZeroPadded(): THashLibByteArray; inline;
+    function Feed(a_data: PByte; a_length_a_data: Int32;
+      var a_start_index: Int32; var a_length: Int32;
+      var a_processed_bytes: UInt64): Boolean; overload;
+    function Feed(a_data: PByte; a_length_a_data: Int32; a_length: Int32)
+      : Boolean; overload;
+    function ToString(): String;
+
+    property IsEmpty: Boolean read GetIsEmpty;
+    property IsFull: Boolean read GetIsFull;
+    property Pos: Int32 read GetPos;
+    property Length: Int32 read GetLength;
+  end;
+
+implementation
+
+{ THashBuffer }
+
+constructor THashBuffer.Create(a_length: Int32);
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_length > 0);
+{$ENDIF DEBUG}
+  System.SetLength(Fm_data, a_length);
+  Initialize();
+
+end;
+
+function THashBuffer.Feed(a_data: PByte; a_length_a_data: Int32;
+  a_length: Int32): Boolean;
+var
+  &Length: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_length >= 0);
+  System.Assert(a_length <= a_length_a_data);
+  System.Assert(not IsFull);
+{$ENDIF DEBUG}
+  if (a_length_a_data = 0) then
+  begin
+    result := false;
+    Exit;
+  end;
+
+  if (a_length = 0) then
+  begin
+    result := false;
+    Exit;
+  end;
+  Length := System.Length(Fm_data) - Fm_pos;
+  if (Length > a_length) then
+  begin
+    Length := a_length;
+  end;
+
+  System.Move(a_data[0], Fm_data[Fm_pos], Length * System.SizeOf(Byte));
+
+  Fm_pos := Fm_pos + Length;
+
+  result := IsFull;
+end;
+
+function THashBuffer.Feed(a_data: PByte; a_length_a_data: Int32;
+  var a_start_index, a_length: Int32; var a_processed_bytes: UInt64): Boolean;
+var
+  &Length: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_start_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert((a_start_index + a_length) <= a_length_a_data);
+  System.Assert(not IsFull);
+{$ENDIF DEBUG}
+  if (a_length_a_data = 0) then
+  begin
+    result := false;
+    Exit;
+  end;
+
+  if (a_length = 0) then
+  begin
+    result := false;
+    Exit;
+  end;
+
+  Length := System.Length(Fm_data) - Fm_pos;
+  if (Length > a_length) then
+  begin
+    Length := a_length;
+  end;
+
+  System.Move(a_data[a_start_index], Fm_data[Fm_pos],
+    Length * System.SizeOf(Byte));
+
+  Fm_pos := Fm_pos + Length;
+  a_start_index := a_start_index + Length;
+  a_length := a_length - Length;
+  a_processed_bytes := a_processed_bytes + UInt64(Length);
+
+  result := IsFull;
+end;
+
+function THashBuffer.GetBytes: THashLibByteArray;
+begin
+{$IFDEF DEBUG}
+  System.Assert(IsFull);
+{$ENDIF DEBUG}
+  Fm_pos := 0;
+  result := Fm_data;
+end;
+
+function THashBuffer.GetBytesZeroPadded: THashLibByteArray;
+begin
+  System.FillChar(Fm_data[Fm_pos], (System.Length(Fm_data) - Fm_pos) *
+    System.SizeOf(Byte), 0);
+  Fm_pos := 0;
+  result := Fm_data;
+end;
+
+function THashBuffer.GetIsEmpty: Boolean;
+begin
+  result := Fm_pos = 0;
+end;
+
+function THashBuffer.GetIsFull: Boolean;
+begin
+  result := Fm_pos = System.Length(Fm_data);
+end;
+
+function THashBuffer.GetLength: Int32;
+begin
+  result := System.Length(Fm_data);
+end;
+
+function THashBuffer.GetPos: Int32;
+begin
+  result := Fm_pos;
+end;
+
+procedure THashBuffer.Initialize;
+begin
+  Fm_pos := 0;
+  System.FillChar(Fm_data[0], System.Length(Fm_data) * System.SizeOf(Byte), 0);
+end;
+
+function THashBuffer.ToString: String;
+begin
+  result := Format('HashBuffer, Length: %d, Pos: %d, IsEmpty: %s',
+    [Self.Length, Self.Pos, BoolToStr(Self.IsEmpty, True)]);
+end;
+
+end.

+ 124 - 0
src/libraries/hashlib4pascal/HashLib/src/Base/HlpHashCryptoNotBuildIn.pas

@@ -0,0 +1,124 @@
+unit HlpHashCryptoNotBuildIn;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpHashBuffer,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TBlockHash = class abstract(THash, IBlockHash)
+  strict protected
+
+    Fm_buffer: THashBuffer;
+    Fm_processed_bytes: UInt64;
+
+    procedure TransformBuffer(); inline;
+    procedure Finish(); virtual; abstract;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); virtual; abstract;
+    function GetResult(): THashLibByteArray; virtual; abstract;
+
+  public
+    constructor Create(a_hash_size, a_block_size: Int32;
+      a_buffer_size: Int32 = -1);
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    procedure Initialize(); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TBlockHash }
+
+constructor TBlockHash.Create(a_hash_size, a_block_size, a_buffer_size: Int32);
+begin
+  Inherited Create(a_hash_size, a_block_size);
+  if (a_buffer_size = -1) then
+  begin
+    a_buffer_size := a_block_size;
+  end;
+
+  Fm_buffer := THashBuffer.Create(a_buffer_size);
+
+end;
+
+procedure TBlockHash.Initialize;
+begin
+  Fm_buffer.Initialize();
+  Fm_processed_bytes := 0;
+
+end;
+
+procedure TBlockHash.TransformBuffer;
+begin
+{$IFDEF DEBUG}
+  System.Assert(Fm_buffer.IsFull);
+{$ENDIF DEBUG}
+  TransformBlock(PByte(Fm_buffer.GetBytes()), Fm_buffer.Length, 0);
+end;
+
+procedure TBlockHash.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  ptr_a_data: PByte;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  ptr_a_data := PByte(a_data);
+
+  if (not Fm_buffer.IsEmpty) then
+  begin
+    if (Fm_buffer.Feed(ptr_a_data, System.Length(a_data), a_index, a_length,
+      Fm_processed_bytes)) then
+    begin
+      TransformBuffer();
+    end;
+  end;
+
+  while (a_length >= (Fm_buffer.Length)) do
+  begin
+    Fm_processed_bytes := Fm_processed_bytes + UInt64(Fm_buffer.Length);
+    TransformBlock(ptr_a_data, Fm_buffer.Length, a_index);
+    // TransformBlock(ptr_a_data, a_length, a_index);
+    a_index := a_index + (Fm_buffer.Length);
+    a_length := a_length - (Fm_buffer.Length);
+  end;
+
+  if (a_length > 0) then
+  begin
+    Fm_buffer.Feed(ptr_a_data, System.Length(a_data), a_index, a_length,
+      Fm_processed_bytes);
+  end;
+
+end;
+
+function TBlockHash.TransformFinal: IHashResult;
+var
+  tempresult: THashLibByteArray;
+begin
+  Finish();
+
+{$IFDEF DEBUG}
+  System.Assert(Fm_buffer.IsEmpty);
+{$ENDIF DEBUG}
+  tempresult := GetResult();
+{$IFDEF DEBUG}
+  System.Assert(System.Length(tempresult) = HashSize);
+{$ENDIF DEBUG}
+  Initialize();
+
+  result := THashResult.Create(tempresult);
+end;
+
+end.

+ 1180 - 0
src/libraries/hashlib4pascal/HashLib/src/Base/HlpHashFactory.pas

@@ -0,0 +1,1180 @@
+unit HlpHashFactory;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF HAS_UNITSCOPE}
+  System.SysUtils,
+{$ELSE}
+  SysUtils,
+{$ENDIF HAS_UNITSCOPE}
+  HlpHashRounds,
+  HlpHashSize,
+  HlpIHash,
+  HlpIHashInfo,
+  HlpHashLibTypes,
+  // NullDigest Unit //
+  HlpNullDigest,
+  // Checksum Units //
+  HlpAdler32,
+  HlpCRC,
+  HlpCRC16,
+  HlpCRC32,
+  HlpCRC64,
+  // Hash32 Units //
+  HlpAP,
+  HlpBernstein,
+  HlpBernstein1,
+  HlpBKDR,
+  HlpDEK,
+  HlpDJB,
+  HlpELF,
+  HlpFNV,
+  HlpFNV1a,
+  HlpJenkins3,
+  HlpJS,
+  HlpMurmur2,
+  HlpMurmurHash3_x86_32,
+  HlpOneAtTime,
+  HlpPJW,
+  HlpRotating,
+  HlpRS,
+  HlpSDBM,
+  HlpShiftAndXor,
+  HlpSuperFast,
+  HlpXXHash32,
+  // Hash64 Units //
+  HlpFNV64,
+  HlpFNV1a64,
+  HlpMurmur2_64,
+  HlpSipHash,
+  HlpXXHash64,
+  // Hash128 Units //
+  HlpMurmurHash3_x86_128,
+  HlpMurmurHash3_x64_128,
+  // Crypto Units
+  HlpTiger,
+  HlpTiger2,
+  HlpMD2,
+  HlpMD4,
+  HlpMD5,
+  HlpSHA0,
+  HlpSHA1,
+  HlpSHA2_224,
+  HlpSHA2_256,
+  HlpSHA2_384,
+  HlpSHA2_512,
+  HlpSHA2_512_224,
+  HlpSHA2_512_256,
+  HlpGrindahl256,
+  HlpGrindahl512,
+  HlpPanama,
+  HlpWhirlPool,
+  HlpRadioGatun32,
+  HlpRadioGatun64,
+  HlpSnefru,
+  HlpHaval,
+  HlpGost,
+  HlpGOST3411_2012,
+  HlpHAS160,
+  HlpRIPEMD,
+  HlpRIPEMD128,
+  HlpRIPEMD160,
+  HlpRIPEMD256,
+  HlpRIPEMD320,
+  HlpSHA3,
+  HlpBlake2B,
+  HlpIBlake2BConfig,
+  HlpBlake2BConfig,
+  HlpBlake2S,
+  HlpBlake2SConfig,
+  HlpIBlake2SConfig,
+  // HMAC Unit
+  HlpHMACNotBuildInAdapter,
+  // PBKDF2_HMAC Unit
+  HlpPBKDF2_HMACNotBuildInAdapter;
+
+type
+  THashFactory = class sealed(TObject)
+
+    // ====================== TNullDigestFactory ====================== //
+
+  type
+    TNullDigestFactory = class sealed(TObject)
+
+    public
+      class function CreateNullDigest(): IHash; static;
+
+    end;
+
+    // ====================== TChecksum ====================== //
+
+  type
+    TChecksum = class sealed(TObject)
+
+    public
+
+      class function CreateCRC(_Width: Int32; _poly, _Init: UInt64;
+        _refIn, _refOut: Boolean; _XorOut, _check: UInt64;
+        _Names: THashLibStringArray): IHash; overload; static;
+
+      class function CreateCRC(_value: TCRCStandard): IHash; overload; static;
+
+      class function CreateCRC16(_poly, _Init: UInt64; _refIn, _refOut: Boolean;
+        _XorOut, _check: UInt64; _Names: THashLibStringArray): IHash; static;
+
+      class function CreateCRC32(_poly, _Init: UInt64; _refIn, _refOut: Boolean;
+        _XorOut, _check: UInt64; _Names: THashLibStringArray): IHash; static;
+
+      class function CreateCRC64(_poly, _Init: UInt64; _refIn, _refOut: Boolean;
+        _XorOut, _check: UInt64; _Names: THashLibStringArray): IHash; static;
+
+      /// <summary>
+      /// BUYPASS, polynomial = $8005
+      /// </summary>
+      /// <returns></returns>
+      class function CreateCRC16_BUYPASS(): IHash; static;
+
+      /// <summary>
+      /// PKZIP, polynomial = $04C11DB7
+      /// </summary>
+      /// <returns></returns>
+      class function CreateCRC32_PKZIP(): IHash; static;
+      /// <summary>
+      /// Castagnoli, polynomial = $1EDC6F41
+      /// </summary>
+      /// <returns></returns>
+      class function CreateCRC32_CASTAGNOLI(): IHash; static;
+      /// <summary>
+      /// ECMA-182, polynomial = $42F0E1EBA9EA3693
+      /// </summary>
+      /// <returns></returns>
+      class function CreateCRC64_ECMA(): IHash; static;
+
+      class function CreateAdler32: IHash; static;
+    end;
+
+    // ====================== THash32 ====================== //
+
+  type
+    THash32 = class sealed(TObject)
+
+    public
+      class function CreateAP(): IHash; static;
+
+      class function CreateBernstein(): IHash; static;
+      class function CreateBernstein1(): IHash; static;
+
+      class function CreateBKDR(): IHash; static;
+
+      class function CreateDEK(): IHash; static;
+
+      class function CreateDJB(): IHash; static;
+
+      class function CreateELF(): IHash; static;
+
+      class function CreateFNV(): IHash; static;
+      class function CreateFNV1a(): IHash; static;
+
+      class function CreateJenkins3(): IHash; static;
+
+      class function CreateJS(): IHash; static;
+
+      class function CreateMurmur2(): IHashWithKey; static;
+
+      class function CreateMurmurHash3_x86_32(): IHashWithKey; static;
+
+      class function CreateOneAtTime(): IHash; static;
+
+      class function CreatePJW(): IHash; static;
+
+      class function CreateRotating(): IHash; static;
+
+      class function CreateRS(): IHash; static;
+
+      class function CreateSDBM(): IHash; static;
+
+      class function CreateShiftAndXor(): IHash; static;
+
+      class function CreateSuperFast(): IHash; static;
+
+      class function CreateXXHash32(): IHashWithKey; static;
+
+    end;
+
+    // ====================== THash64 ====================== //
+
+  type
+    THash64 = class sealed(TObject)
+
+    public
+
+      class function CreateFNV(): IHash; static;
+      class function CreateFNV1a(): IHash; static;
+
+      class function CreateMurmur2(): IHashWithKey; static;
+
+      class function CreateSipHash2_4(): IHashWithKey; static;
+
+      class function CreateXXHash64(): IHashWithKey; static;
+
+    end;
+
+    // ====================== THash128 ====================== //
+
+  type
+    THash128 = class sealed(TObject)
+
+    public
+
+      class function CreateMurmurHash3_x86_128(): IHashWithKey; static;
+      class function CreateMurmurHash3_x64_128(): IHashWithKey; static;
+
+    end;
+
+    // ====================== TCrypto ====================== //
+
+  type
+    TCrypto = class sealed(TObject)
+
+    public
+
+      /// <summary>
+      ///
+      /// </summary>
+      /// <param name="a_hash_size">16, 20 or 24 bytes. </param>
+      /// <param name="a_rounds">no of rounds (standard rounds are 3, 4 and 5)</param>
+      /// <returns></returns>
+      class function CreateTiger(a_hash_size: Int32; a_rounds: THashRounds)
+        : IHash; static;
+      class function CreateTiger_3_128(): IHash; static;
+      class function CreateTiger_3_160(): IHash; static;
+      class function CreateTiger_3_192(): IHash; static;
+
+      class function CreateTiger_4_128(): IHash; static;
+      class function CreateTiger_4_160(): IHash; static;
+      class function CreateTiger_4_192(): IHash; static;
+
+      class function CreateTiger_5_128(): IHash; static;
+      class function CreateTiger_5_160(): IHash; static;
+      class function CreateTiger_5_192(): IHash; static;
+
+      /// <summary>
+      ///
+      /// </summary>
+      /// <param name="a_hash_size">16, 20 or 24 bytes. </param>
+      /// <param name="a_rounds">no of rounds (standard rounds are 3, 4 and 5)</param>
+      /// <returns></returns>
+      class function CreateTiger2(a_hash_size: Int32; a_rounds: THashRounds)
+        : IHash; static;
+
+      class function CreateTiger2_3_128(): IHash; static;
+      class function CreateTiger2_3_160(): IHash; static;
+      class function CreateTiger2_3_192(): IHash; static;
+
+      class function CreateTiger2_4_128(): IHash; static;
+      class function CreateTiger2_4_160(): IHash; static;
+      class function CreateTiger2_4_192(): IHash; static;
+
+      class function CreateTiger2_5_128(): IHash; static;
+      class function CreateTiger2_5_160(): IHash; static;
+      class function CreateTiger2_5_192(): IHash; static;
+
+      class function CreateMD2(): IHash; static;
+      class function CreateMD4(): IHash; static;
+      class function CreateMD5(): IHash; static;
+
+      class function CreateSHA0(): IHash; static;
+      class function CreateSHA1(): IHash; static;
+
+      class function CreateSHA2_224(): IHash; static;
+      class function CreateSHA2_256(): IHash; static;
+      class function CreateSHA2_384(): IHash; static;
+      class function CreateSHA2_512(): IHash; static;
+      class function CreateSHA2_512_224(): IHash; static;
+      class function CreateSHA2_512_256(): IHash; static;
+
+      class function CreateGrindahl256(): IHash; static;
+      class function CreateGrindahl512(): IHash; static;
+
+      class function CreatePanama(): IHash; static;
+
+      class function CreateWhirlPool(): IHash; static;
+
+      class function CreateRadioGatun32(): IHash; static;
+      class function CreateRadioGatun64(): IHash; static;
+
+      /// <summary>
+      ///
+      /// </summary>
+      /// <param name="a_security_level">any Integer value greater than 0. Standard is 8. </param>
+      /// <param name="a_hash_size">128bit, 256bit</param>
+      /// <returns></returns>
+      class function CreateSnefru(a_security_level: Int32;
+        a_hash_size: THashSize): IHash; static;
+      class function CreateSnefru_8_128(): IHash; static;
+      class function CreateSnefru_8_256(): IHash; static;
+
+      /// <summary>
+      ///
+      /// </summary>
+      /// <param name="a_rounds">3, 4, 5</param>
+      /// <param name="a_hash_size">128, 160, 192, 224, 256</param>
+      /// <returns></returns>
+      class function CreateHaval(a_rounds: THashRounds; a_hash_size: THashSize)
+        : IHash; static;
+
+      class function CreateHaval_3_128(): IHash; static;
+      class function CreateHaval_4_128(): IHash; static;
+      class function CreateHaval_5_128(): IHash; static;
+
+      class function CreateHaval_3_160(): IHash; static;
+      class function CreateHaval_4_160(): IHash; static;
+      class function CreateHaval_5_160(): IHash; static;
+
+      class function CreateHaval_3_192(): IHash; static;
+      class function CreateHaval_4_192(): IHash; static;
+      class function CreateHaval_5_192(): IHash; static;
+
+      class function CreateHaval_3_224(): IHash; static;
+      class function CreateHaval_4_224(): IHash; static;
+      class function CreateHaval_5_224(): IHash; static;
+
+      class function CreateHaval_3_256(): IHash; static;
+      class function CreateHaval_4_256(): IHash; static;
+      class function CreateHaval_5_256(): IHash; static;
+
+      class function CreateGost(): IHash; static;
+
+      // Streebog 256
+      class function CreateGOST3411_2012_256(): IHash; static;
+
+      // Streebog 512
+      class function CreateGOST3411_2012_512(): IHash; static;
+
+      class function CreateHAS160(): IHash; static;
+
+      class function CreateRIPEMD(): IHash; static;
+      class function CreateRIPEMD128(): IHash; static;
+      class function CreateRIPEMD160(): IHash; static;
+      class function CreateRIPEMD256(): IHash; static;
+      class function CreateRIPEMD320(): IHash; static;
+
+      class function CreateSHA3_224(): IHash; static;
+      class function CreateSHA3_256(): IHash; static;
+      class function CreateSHA3_384(): IHash; static;
+      class function CreateSHA3_512(): IHash; static;
+
+      class function CreateBlake2B(config: IBlake2BConfig = Nil): IHash; static;
+
+      class function CreateBlake2B_160(): IHash; static;
+      class function CreateBlake2B_256(): IHash; static;
+      class function CreateBlake2B_384(): IHash; static;
+      class function CreateBlake2B_512(): IHash; static;
+
+      class function CreateBlake2S(config: IBlake2SConfig = Nil): IHash; static;
+
+      class function CreateBlake2S_128(): IHash; static;
+      class function CreateBlake2S_160(): IHash; static;
+      class function CreateBlake2S_224(): IHash; static;
+      class function CreateBlake2S_256(): IHash; static;
+
+    end;
+
+    // ====================== THMAC ====================== //
+
+  type
+    THMAC = class sealed(TObject)
+
+    public
+
+      class function CreateHMAC(a_hash: IHash): IHMAC; static;
+
+    end;
+
+  end;
+
+type
+  TKDF = class sealed(TObject)
+
+    // ====================== TPBKDF2_HMAC ====================== //
+
+  type
+    TPBKDF2_HMAC = class sealed(TObject)
+
+    public
+
+      /// <summary>
+      /// Initializes a new interface instance of the TPBKDF2_HMAC class using a password, a salt, a number of iterations and an Instance of an "IHash" to be used as an "IHMAC" hashing implementation to derive the key.
+      /// </summary>
+      /// <param name="a_hash">The name of the "IHash" implementation to be transformed to an "IHMAC" Instance so it can be used to derive the key.</param>
+      /// <param name="password">The password to derive the key for.</param>
+      /// <param name="salt">The salt to use to derive the key.</param>
+      /// <param name="iterations">The number of iterations to use to derive the key.</param>
+      /// <exception cref="EArgumentNilHashLibException">The password, salt or algorithm is Nil.</exception>
+      /// <exception cref="EArgumentHashLibException">The iteration is less than 1.</exception>
+
+      class function CreatePBKDF2_HMAC(a_hash: IHash;
+        a_password, a_salt: THashLibByteArray; a_iterations: UInt32)
+        : IPBKDF2_HMAC; static;
+
+    end;
+
+  end;
+
+implementation
+
+{ THashFactory.TNullDigestFactory }
+
+class function THashFactory.TNullDigestFactory.CreateNullDigest: IHash;
+begin
+  Result := TNullDigest.Create();
+end;
+
+{ THashFactory.TChecksum }
+
+class function THashFactory.TChecksum.CreateCRC(_Width: Int32;
+  _poly, _Init: UInt64; _refIn, _refOut: Boolean; _XorOut, _check: UInt64;
+  _Names: THashLibStringArray): IHash;
+begin
+  Result := TCRC.Create(_Width, _poly, _Init, _refIn, _refOut, _XorOut,
+    _check, _Names);
+end;
+
+class function THashFactory.TChecksum.CreateCRC(_value: TCRCStandard): IHash;
+begin
+  Result := TCRC.CreateCRCObject(_value);
+end;
+
+class function THashFactory.TChecksum.CreateCRC16(_poly, _Init: UInt64;
+  _refIn, _refOut: Boolean; _XorOut, _check: UInt64;
+  _Names: THashLibStringArray): IHash;
+begin
+  Result := TCRC16.Create(_poly, _Init, _refIn, _refOut, _XorOut,
+    _check, _Names);
+end;
+
+class function THashFactory.TChecksum.CreateCRC16_BUYPASS: IHash;
+begin
+  Result := TCRC16_BUYPASS.Create();
+end;
+
+class function THashFactory.TChecksum.CreateCRC32(_poly, _Init: UInt64;
+  _refIn, _refOut: Boolean; _XorOut, _check: UInt64;
+  _Names: THashLibStringArray): IHash;
+begin
+  Result := TCRC32.Create(_poly, _Init, _refIn, _refOut, _XorOut,
+    _check, _Names);
+end;
+
+class function THashFactory.TChecksum.CreateCRC32_CASTAGNOLI: IHash;
+begin
+  Result := TCRC32_CASTAGNOLI.Create();
+end;
+
+class function THashFactory.TChecksum.CreateCRC32_PKZIP: IHash;
+begin
+  Result := TCRC32_PKZIP.Create();
+end;
+
+class function THashFactory.TChecksum.CreateCRC64(_poly, _Init: UInt64;
+  _refIn, _refOut: Boolean; _XorOut, _check: UInt64;
+  _Names: THashLibStringArray): IHash;
+begin
+  Result := TCRC64.Create(_poly, _Init, _refIn, _refOut, _XorOut,
+    _check, _Names);
+end;
+
+class function THashFactory.TChecksum.CreateCRC64_ECMA: IHash;
+begin
+  Result := TCRC64_ECMA.Create();
+end;
+
+class function THashFactory.TChecksum.CreateAdler32: IHash;
+begin
+  Result := TAdler32.Create();
+end;
+
+{ THashFactory.THash32 }
+
+class function THashFactory.THash32.CreateAP: IHash;
+begin
+  Result := TAP.Create();
+end;
+
+class function THashFactory.THash32.CreateBernstein: IHash;
+begin
+  Result := TBernstein.Create();
+end;
+
+class function THashFactory.THash32.CreateBernstein1: IHash;
+begin
+  Result := TBernstein1.Create();
+end;
+
+class function THashFactory.THash32.CreateBKDR: IHash;
+begin
+  Result := TBKDR.Create();
+end;
+
+class function THashFactory.THash32.CreateDEK: IHash;
+begin
+  Result := TDEK.Create();
+end;
+
+class function THashFactory.THash32.CreateDJB: IHash;
+begin
+  Result := TDJB.Create();
+end;
+
+class function THashFactory.THash32.CreateELF: IHash;
+begin
+  Result := TELF.Create();
+end;
+
+class function THashFactory.THash32.CreateFNV: IHash;
+begin
+  Result := TFNV.Create();
+end;
+
+class function THashFactory.THash32.CreateFNV1a: IHash;
+begin
+  Result := TFNV1a.Create();
+end;
+
+class function THashFactory.THash32.CreateJenkins3: IHash;
+begin
+  Result := TJenkins3.Create();
+end;
+
+class function THashFactory.THash32.CreateJS: IHash;
+begin
+  Result := TJS.Create();
+end;
+
+class function THashFactory.THash32.CreateMurmur2: IHashWithKey;
+begin
+  Result := TMurmur2.Create();
+end;
+
+class function THashFactory.THash32.CreateMurmurHash3_x86_32: IHashWithKey;
+begin
+  Result := TMurmurHash3_x86_32.Create();
+end;
+
+class function THashFactory.THash32.CreateOneAtTime: IHash;
+begin
+  Result := TOneAtTime.Create();
+end;
+
+class function THashFactory.THash32.CreatePJW: IHash;
+begin
+  Result := TPJW.Create();
+end;
+
+class function THashFactory.THash32.CreateRotating: IHash;
+begin
+  Result := TRotating.Create();
+end;
+
+class function THashFactory.THash32.CreateRS: IHash;
+begin
+  Result := TRS.Create();
+end;
+
+class function THashFactory.THash32.CreateSDBM: IHash;
+begin
+  Result := TSDBM.Create();
+end;
+
+class function THashFactory.THash32.CreateShiftAndXor: IHash;
+begin
+  Result := TShiftAndXor.Create();
+end;
+
+class function THashFactory.THash32.CreateSuperFast: IHash;
+begin
+  Result := TSuperFast.Create();
+end;
+
+class function THashFactory.THash32.CreateXXHash32: IHashWithKey;
+begin
+  Result := TXXHash32.Create();
+end;
+
+{ THashFactory.THash64 }
+
+class function THashFactory.THash64.CreateFNV: IHash;
+begin
+  Result := TFNV64.Create();
+end;
+
+class function THashFactory.THash64.CreateFNV1a: IHash;
+begin
+  Result := TFNV1a64.Create();
+end;
+
+class function THashFactory.THash64.CreateMurmur2: IHashWithKey;
+begin
+  Result := TMurmur2_64.Create();
+end;
+
+class function THashFactory.THash64.CreateSipHash2_4: IHashWithKey;
+begin
+  Result := TSipHash2_4.Create();
+end;
+
+class function THashFactory.THash64.CreateXXHash64: IHashWithKey;
+begin
+  Result := TXXHash64.Create();
+end;
+
+{ THashFactory.THash128 }
+
+class function THashFactory.THash128.CreateMurmurHash3_x86_128: IHashWithKey;
+begin
+  Result := TMurmurHash3_x86_128.Create();
+end;
+
+class function THashFactory.THash128.CreateMurmurHash3_x64_128: IHashWithKey;
+begin
+  Result := TMurmurHash3_x64_128.Create();
+end;
+
+{ THashFactory.TCrypto }
+
+class function THashFactory.TCrypto.CreateGost: IHash;
+begin
+  Result := TGost.Create();
+end;
+
+class function THashFactory.TCrypto.CreateGOST3411_2012_256: IHash;
+begin
+  Result := TGOST3411_2012_256.Create();
+end;
+
+class function THashFactory.TCrypto.CreateGOST3411_2012_512: IHash;
+begin
+  Result := TGOST3411_2012_512.Create();
+end;
+
+class function THashFactory.TCrypto.CreateGrindahl256: IHash;
+begin
+  Result := TGrindahl256.Create();
+end;
+
+class function THashFactory.TCrypto.CreateGrindahl512: IHash;
+begin
+  Result := TGrindahl512.Create();
+end;
+
+class function THashFactory.TCrypto.CreateHAS160: IHash;
+begin
+  Result := THAS160.Create();
+end;
+
+class function THashFactory.TCrypto.CreateHaval(a_rounds: THashRounds;
+  a_hash_size: THashSize): IHash;
+begin
+  case a_rounds of
+    hrRounds3:
+      case a_hash_size of
+        hsHashSize128:
+          Result := CreateHaval_3_128();
+        hsHashSize160:
+          Result := CreateHaval_3_160();
+        hsHashSize192:
+          Result := CreateHaval_3_192();
+        hsHashSize224:
+          Result := CreateHaval_3_224();
+        hsHashSize256:
+          Result := CreateHaval_3_256();
+      else
+        raise EArgumentHashLibException.CreateRes(@SInvalidHavalHashSize);
+      end;
+
+    hrRounds4:
+      case a_hash_size of
+        hsHashSize128:
+          Result := CreateHaval_4_128();
+        hsHashSize160:
+          Result := CreateHaval_4_160();
+        hsHashSize192:
+          Result := CreateHaval_4_192();
+        hsHashSize224:
+          Result := CreateHaval_4_224();
+        hsHashSize256:
+          Result := CreateHaval_4_256();
+      else
+        raise EArgumentHashLibException.CreateRes(@SInvalidHavalHashSize);
+      end;
+
+    hrRounds5:
+      case a_hash_size of
+        hsHashSize128:
+          Result := CreateHaval_5_128();
+        hsHashSize160:
+          Result := CreateHaval_5_160();
+        hsHashSize192:
+          Result := CreateHaval_5_192();
+        hsHashSize224:
+          Result := CreateHaval_5_224();
+        hsHashSize256:
+          Result := CreateHaval_5_256();
+      else
+        raise EArgumentHashLibException.CreateRes(@SInvalidHavalHashSize);
+      end;
+
+  else
+    raise EArgumentHashLibException.CreateRes(@SInvalidHavalRound);
+  end;
+end;
+
+class function THashFactory.TCrypto.CreateHaval_3_128: IHash;
+begin
+  Result := THaval_3_128.Create();
+end;
+
+class function THashFactory.TCrypto.CreateHaval_3_160: IHash;
+begin
+  Result := THaval_3_160.Create();
+end;
+
+class function THashFactory.TCrypto.CreateHaval_3_192: IHash;
+begin
+  Result := THaval_3_192.Create();
+end;
+
+class function THashFactory.TCrypto.CreateHaval_3_224: IHash;
+begin
+  Result := THaval_3_224.Create();
+end;
+
+class function THashFactory.TCrypto.CreateHaval_3_256: IHash;
+begin
+  Result := THaval_3_256.Create();
+end;
+
+class function THashFactory.TCrypto.CreateHaval_4_128: IHash;
+begin
+  Result := THaval_4_128.Create();
+end;
+
+class function THashFactory.TCrypto.CreateHaval_4_160: IHash;
+begin
+  Result := THaval_4_160.Create();
+end;
+
+class function THashFactory.TCrypto.CreateHaval_4_192: IHash;
+begin
+  Result := THaval_4_192.Create();
+end;
+
+class function THashFactory.TCrypto.CreateHaval_4_224: IHash;
+begin
+  Result := THaval_4_224.Create();
+end;
+
+class function THashFactory.TCrypto.CreateHaval_4_256: IHash;
+begin
+  Result := THaval_4_256.Create();
+end;
+
+class function THashFactory.TCrypto.CreateHaval_5_128: IHash;
+begin
+  Result := THaval_5_128.Create();
+end;
+
+class function THashFactory.TCrypto.CreateHaval_5_160: IHash;
+begin
+  Result := THaval_5_160.Create();
+end;
+
+class function THashFactory.TCrypto.CreateHaval_5_192: IHash;
+begin
+  Result := THaval_5_192.Create();
+end;
+
+class function THashFactory.TCrypto.CreateHaval_5_224: IHash;
+begin
+  Result := THaval_5_224.Create();
+end;
+
+class function THashFactory.TCrypto.CreateHaval_5_256: IHash;
+begin
+  Result := THaval_5_256.Create();
+end;
+
+class function THashFactory.TCrypto.CreateMD2: IHash;
+begin
+  Result := TMD2.Create();
+end;
+
+class function THashFactory.TCrypto.CreateMD4: IHash;
+begin
+  Result := TMD4.Create();
+end;
+
+class function THashFactory.TCrypto.CreateMD5: IHash;
+begin
+  Result := TMD5.Create();
+end;
+
+class function THashFactory.TCrypto.CreatePanama: IHash;
+begin
+  Result := TPanama.Create();
+end;
+
+class function THashFactory.TCrypto.CreateRadioGatun32: IHash;
+begin
+  Result := TRadioGatun32.Create();
+end;
+
+class function THashFactory.TCrypto.CreateRadioGatun64: IHash;
+begin
+  Result := TRadioGatun64.Create();
+end;
+
+class function THashFactory.TCrypto.CreateRIPEMD: IHash;
+begin
+  Result := TRIPEMD.Create();
+end;
+
+class function THashFactory.TCrypto.CreateRIPEMD128: IHash;
+begin
+  Result := TRIPEMD128.Create();
+end;
+
+class function THashFactory.TCrypto.CreateRIPEMD160: IHash;
+begin
+  Result := TRIPEMD160.Create();
+end;
+
+class function THashFactory.TCrypto.CreateRIPEMD256: IHash;
+begin
+  Result := TRIPEMD256.Create();
+end;
+
+class function THashFactory.TCrypto.CreateRIPEMD320: IHash;
+begin
+  Result := TRIPEMD320.Create();
+end;
+
+class function THashFactory.TCrypto.CreateSHA0: IHash;
+begin
+  Result := TSHA0.Create();
+end;
+
+class function THashFactory.TCrypto.CreateSHA1: IHash;
+begin
+  Result := TSHA1.Create();
+end;
+
+class function THashFactory.TCrypto.CreateSHA2_224: IHash;
+begin
+  Result := TSHA2_224.Create();
+end;
+
+class function THashFactory.TCrypto.CreateSHA2_256: IHash;
+begin
+  Result := TSHA2_256.Create();
+end;
+
+class function THashFactory.TCrypto.CreateSHA2_384: IHash;
+begin
+  Result := TSHA2_384.Create();
+end;
+
+class function THashFactory.TCrypto.CreateSHA2_512: IHash;
+begin
+  Result := TSHA2_512.Create();
+end;
+
+class function THashFactory.TCrypto.CreateSHA2_512_224: IHash;
+begin
+  Result := TSHA2_512_224.Create();
+end;
+
+class function THashFactory.TCrypto.CreateSHA2_512_256: IHash;
+begin
+  Result := TSHA2_512_256.Create();
+end;
+
+class function THashFactory.TCrypto.CreateSHA3_224: IHash;
+begin
+  Result := TSHA3_224.Create();
+end;
+
+class function THashFactory.TCrypto.CreateSHA3_256: IHash;
+begin
+  Result := TSHA3_256.Create();
+end;
+
+class function THashFactory.TCrypto.CreateSHA3_384: IHash;
+begin
+  Result := TSHA3_384.Create();
+end;
+
+class function THashFactory.TCrypto.CreateSHA3_512: IHash;
+begin
+  Result := TSHA3_512.Create();
+end;
+
+class function THashFactory.TCrypto.CreateBlake2B
+  (config: IBlake2BConfig): IHash;
+begin
+  if config = Nil then
+  begin
+    Result := TBlake2B.Create()
+  end
+  else
+  begin
+    Result := TBlake2B.Create(config);
+  end;
+end;
+
+class function THashFactory.TCrypto.CreateBlake2B_160: IHash;
+begin
+  Result := THashFactory.TCrypto.CreateBlake2B
+    (TBlake2BConfig.Create(THashSize.hsHashSize160));
+end;
+
+class function THashFactory.TCrypto.CreateBlake2B_256: IHash;
+begin
+  Result := THashFactory.TCrypto.CreateBlake2B
+    (TBlake2BConfig.Create(THashSize.hsHashSize256));
+end;
+
+class function THashFactory.TCrypto.CreateBlake2B_384: IHash;
+begin
+  Result := THashFactory.TCrypto.CreateBlake2B
+    (TBlake2BConfig.Create(THashSize.hsHashSize384));
+end;
+
+class function THashFactory.TCrypto.CreateBlake2B_512: IHash;
+begin
+  Result := THashFactory.TCrypto.CreateBlake2B
+    (TBlake2BConfig.Create(THashSize.hsHashSize512));
+end;
+
+class function THashFactory.TCrypto.CreateBlake2S
+  (config: IBlake2SConfig): IHash;
+begin
+  if config = Nil then
+  begin
+    Result := TBlake2S.Create()
+  end
+  else
+  begin
+    Result := TBlake2S.Create(config);
+  end;
+end;
+
+class function THashFactory.TCrypto.CreateBlake2S_128: IHash;
+begin
+  Result := THashFactory.TCrypto.CreateBlake2S
+    (TBlake2SConfig.Create(THashSize.hsHashSize128));
+end;
+
+class function THashFactory.TCrypto.CreateBlake2S_160: IHash;
+begin
+  Result := THashFactory.TCrypto.CreateBlake2S
+    (TBlake2SConfig.Create(THashSize.hsHashSize160));
+end;
+
+class function THashFactory.TCrypto.CreateBlake2S_224: IHash;
+begin
+  Result := THashFactory.TCrypto.CreateBlake2S
+    (TBlake2SConfig.Create(THashSize.hsHashSize224));
+end;
+
+class function THashFactory.TCrypto.CreateBlake2S_256: IHash;
+begin
+  Result := THashFactory.TCrypto.CreateBlake2S
+    (TBlake2SConfig.Create(THashSize.hsHashSize256));
+end;
+
+class function THashFactory.TCrypto.CreateSnefru(a_security_level: Int32;
+  a_hash_size: THashSize): IHash;
+begin
+  if a_security_level < Int32(1) then
+    raise EArgumentHashLibException.CreateRes(@SInvalidSnefruLevel);
+
+  if ((a_hash_size = THashSize.hsHashSize128) or
+    (a_hash_size = THashSize.hsHashSize256)) then
+  begin
+    Result := TSnefru.Create(a_security_level, a_hash_size);
+  end
+  else
+  begin
+    raise EArgumentHashLibException.CreateRes(@SInvalidSnefruHashSize);
+  end
+
+end;
+
+class function THashFactory.TCrypto.CreateSnefru_8_128: IHash;
+begin
+  Result := CreateSnefru(8, THashSize.hsHashSize128);
+end;
+
+class function THashFactory.TCrypto.CreateSnefru_8_256: IHash;
+begin
+  Result := CreateSnefru(8, THashSize.hsHashSize256);
+end;
+
+class function THashFactory.TCrypto.CreateTiger_3_128: IHash;
+begin
+  Result := TTiger_128.CreateRound3();
+end;
+
+class function THashFactory.TCrypto.CreateTiger_3_160: IHash;
+begin
+  Result := TTiger_160.CreateRound3();
+end;
+
+class function THashFactory.TCrypto.CreateTiger_3_192: IHash;
+begin
+  Result := TTiger_192.CreateRound3();
+end;
+
+class function THashFactory.TCrypto.CreateTiger_4_128: IHash;
+begin
+  Result := TTiger_128.CreateRound4();
+end;
+
+class function THashFactory.TCrypto.CreateTiger_4_160: IHash;
+begin
+  Result := TTiger_160.CreateRound4();
+end;
+
+class function THashFactory.TCrypto.CreateTiger_4_192: IHash;
+begin
+  Result := TTiger_192.CreateRound4();
+end;
+
+class function THashFactory.TCrypto.CreateTiger_5_128: IHash;
+begin
+  Result := TTiger_128.CreateRound5();
+end;
+
+class function THashFactory.TCrypto.CreateTiger_5_160: IHash;
+begin
+  Result := TTiger_160.CreateRound5();
+end;
+
+class function THashFactory.TCrypto.CreateTiger_5_192: IHash;
+begin
+  Result := TTiger_192.CreateRound5();
+end;
+
+class function THashFactory.TCrypto.CreateWhirlPool: IHash;
+begin
+  Result := TWhirlPool.Create();
+end;
+
+class function THashFactory.TCrypto.CreateTiger(a_hash_size: Int32;
+  a_rounds: THashRounds): IHash;
+begin
+  if ((a_hash_size <> 16) and (a_hash_size <> 20) and (a_hash_size <> 24)) then
+    raise EArgumentHashLibException.CreateRes(@SInvalidTigerHashSize);
+
+  Result := TTiger_Base.Create(a_hash_size, a_rounds);
+end;
+
+class function THashFactory.TCrypto.CreateTiger2(a_hash_size: Int32;
+  a_rounds: THashRounds): IHash;
+begin
+  if ((a_hash_size <> 16) and (a_hash_size <> 20) and (a_hash_size <> 24)) then
+    raise EArgumentHashLibException.CreateRes(@SInvalidTiger2HashSize);
+
+  Result := TTiger2_Base.Create(a_hash_size, a_rounds);
+end;
+
+class function THashFactory.TCrypto.CreateTiger2_3_128: IHash;
+begin
+  Result := TTiger2_128.CreateRound3();
+end;
+
+class function THashFactory.TCrypto.CreateTiger2_3_160: IHash;
+begin
+  Result := TTiger2_160.CreateRound3();
+end;
+
+class function THashFactory.TCrypto.CreateTiger2_3_192: IHash;
+begin
+  Result := TTiger2_192.CreateRound3();
+end;
+
+class function THashFactory.TCrypto.CreateTiger2_4_128: IHash;
+begin
+  Result := TTiger2_128.CreateRound4();
+end;
+
+class function THashFactory.TCrypto.CreateTiger2_4_160: IHash;
+begin
+  Result := TTiger2_160.CreateRound4();
+end;
+
+class function THashFactory.TCrypto.CreateTiger2_4_192: IHash;
+begin
+  Result := TTiger2_192.CreateRound4();
+end;
+
+class function THashFactory.TCrypto.CreateTiger2_5_128: IHash;
+begin
+  Result := TTiger2_128.CreateRound5();
+end;
+
+class function THashFactory.TCrypto.CreateTiger2_5_160: IHash;
+begin
+  Result := TTiger2_160.CreateRound5();
+end;
+
+class function THashFactory.TCrypto.CreateTiger2_5_192: IHash;
+begin
+  Result := TTiger2_192.CreateRound5();
+end;
+
+{ THashFactory.THMAC }
+
+class function THashFactory.THMAC.CreateHMAC(a_hash: IHash): IHMAC;
+begin
+
+  if Supports(a_hash, IHMAC) then
+  begin
+    Result := (a_hash) as IHMAC;
+    Exit;
+  end
+  else
+  begin
+    Result := THMACNotBuildInAdapter.Create(a_hash);
+    Exit;
+  end;
+
+end;
+
+{ TKDF.TPBKDF2_HMAC }
+
+class function TKDF.TPBKDF2_HMAC.CreatePBKDF2_HMAC(a_hash: IHash;
+  a_password, a_salt: THashLibByteArray; a_iterations: UInt32): IPBKDF2_HMAC;
+begin
+
+  if not(System.Assigned(a_hash)) then
+    raise EArgumentNilHashLibException.CreateRes(@SUninitializedInstance);
+
+  if (a_password = Nil) then
+    raise EArgumentNilHashLibException.CreateRes(@SEmptyPassword);
+
+  if (a_salt = Nil) then
+    raise EArgumentNilHashLibException.CreateRes(@SEmptySalt);
+
+  if (a_iterations < 1) then
+    raise EArgumentHashLibException.CreateRes(@SIterationtooSmall);
+
+  Result := TPBKDF2_HMACNotBuildInAdapter.Create(a_hash, a_password, a_salt,
+    a_iterations);
+end;
+
+end.

+ 274 - 0
src/libraries/hashlib4pascal/HashLib/src/Base/HlpHashResult.pas

@@ -0,0 +1,274 @@
+unit HlpHashResult;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+
+{$IFDEF HAS_UNITSCOPE}
+  System.SysUtils,
+{$IFDEF DELPHIXE7_UP}
+  System.NetEncoding,
+{$ELSE}
+  System.Classes,
+  Soap.EncdDecd,
+{$ENDIF DELPHIXE7_UP}
+{$ELSE}
+  SysUtils,
+{$IFDEF DELPHI}
+  Classes,
+  EncdDecd,
+{$ENDIF DELPHI}
+{$IFDEF FPC}
+  base64,
+{$ENDIF FPC}
+{$ENDIF HAS_UNITSCOPE}
+  HlpBits,
+  HlpHashLibTypes,
+  HlpIHashResult,
+  HlpConverters;
+
+resourcestring
+  SImpossibleRepresentationInt32 =
+    'Current Data Structure cannot be Represented as an "Int32" Type.';
+  SImpossibleRepresentationUInt8 =
+    'Current Data Structure cannot be Represented as an "UInt8" Type.';
+  SImpossibleRepresentationUInt16 =
+    'Current Data Structure cannot be Represented as an "UInt16" Type.';
+  SImpossibleRepresentationUInt32 =
+    'Current Data Structure cannot be Represented as an "UInt32" Type.';
+  SImpossibleRepresentationUInt64 =
+    'Current Data Structure cannot be Represented as an "UInt64" Type.';
+
+type
+  THashResult = class sealed(TInterfacedObject, IHashResult)
+
+  strict private
+
+    Fm_hash: THashLibByteArray;
+
+    class function SlowEquals(a_ar1, a_ar2: THashLibByteArray): Boolean; static;
+
+  public
+
+    constructor Create(a_hash: Int32); overload;
+    constructor Create(a_hash: UInt8); overload;
+    constructor Create(a_hash: UInt16); overload;
+    constructor Create(a_hash: UInt32); overload;
+    constructor Create(a_hash: UInt64); overload;
+    constructor Create(a_hash: THashLibByteArray); overload;
+
+    function GetBytes(): THashLibByteArray;
+    function GetUInt8(): UInt8;
+    function GetUInt16(): UInt16;
+    function GetUInt32(): UInt32;
+    function GetInt32(): Int32;
+    function GetUInt64(): UInt64;
+    function ToString(a_group: Boolean = false): String; reintroduce;
+    function Equals(a_hashResult: IHashResult): Boolean; reintroduce;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+  end;
+
+implementation
+
+{ THashResult }
+
+constructor THashResult.Create(a_hash: UInt64);
+begin
+
+  Fm_hash := THashLibByteArray.Create(Byte(a_hash shr 56), Byte(a_hash shr 48),
+    Byte(a_hash shr 40), Byte(a_hash shr 32), Byte(a_hash shr 24),
+    Byte(a_hash shr 16), Byte(a_hash shr 8), Byte(a_hash));
+end;
+
+constructor THashResult.Create(a_hash: THashLibByteArray);
+begin
+  Fm_hash := a_hash;
+end;
+
+constructor THashResult.Create(a_hash: UInt32);
+begin
+  Fm_hash := THashLibByteArray.Create(Byte(a_hash shr 24), Byte(a_hash shr 16),
+    Byte(a_hash shr 8), Byte(a_hash));
+end;
+
+constructor THashResult.Create(a_hash: UInt8);
+begin
+  Fm_hash := THashLibByteArray.Create(a_hash);
+end;
+
+constructor THashResult.Create(a_hash: UInt16);
+begin
+  Fm_hash := THashLibByteArray.Create(Byte(a_hash shr 8), Byte(a_hash));
+end;
+
+constructor THashResult.Create(a_hash: Int32);
+begin
+  Fm_hash := THashLibByteArray.Create(Byte(TBits.Asr32(a_hash, 24)),
+    Byte(TBits.Asr32(a_hash, 16)), Byte(TBits.Asr32(a_hash, 8)), Byte(a_hash));
+end;
+
+function THashResult.Equals(a_hashResult: IHashResult): Boolean;
+
+begin
+  result := THashResult.SlowEquals(a_hashResult.GetBytes(), Fm_hash);
+end;
+
+function THashResult.GetBytes: THashLibByteArray;
+begin
+  result := Fm_hash;
+end;
+
+function THashResult.GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}
+
+var
+  LResult: UInt32;
+  I, Top: Int32;
+  Temp: string;
+{$IFDEF DELPHIXE7_UP}
+  TempHolder: THashLibByteArray;
+{$ELSE}
+{$IFDEF DELPHI}
+  TempHolder: TBytesStream;
+{$ENDIF DELPHI}
+{$ENDIF DELPHIXE7_UP}
+{$IFDEF FPC}
+  TempHolder: String;
+{$ENDIF FPC}
+begin
+
+{$IFDEF DELPHIXE7_UP}
+  TempHolder := Self.Fm_hash;
+{$ELSE}
+{$IFDEF DELPHI}
+  TempHolder := TBytesStream.Create(Self.Fm_hash);
+{$ENDIF DELPHI}
+{$ENDIF DELPHIXE7_UP}
+{$IFDEF FPC}
+  TempHolder := EncodeStringBase64
+    (String(TEncoding.UTF8.GetString(Self.Fm_hash)));
+{$ENDIF FPC}
+{$IFDEF DELPHIXE7_UP}
+  Temp := StringReplace(TNetEncoding.base64.EncodeBytesToString(TempHolder),
+    sLineBreak, '', [rfReplaceAll]);
+{$ELSE}
+{$IFDEF DELPHI}
+  try
+    Temp := StringReplace(String(EncodeBase64(TempHolder.Memory,
+      TempHolder.Size)), sLineBreak, '', [rfReplaceAll]);
+  finally
+    TempHolder.Free;
+  end;
+{$ENDIF DELPHI}
+{$ENDIF DELPHIXE7_UP}
+{$IFDEF FPC}
+  Temp := TempHolder;
+{$ENDIF FPC}
+  Temp := AnsiUpperCase(Temp);
+
+  LResult := 0;
+{$IFDEF DELPHIXE3_UP}
+  I := System.Low(Temp);
+  Top := System.High(Temp);
+{$ELSE}
+  I := 1;
+  Top := System.Length(Temp);
+{$ENDIF DELPHIXE3_UP}
+  while I <= Top do
+  begin
+
+    LResult := TBits.RotateLeft32(LResult, 5);
+    LResult := LResult xor UInt32(Temp[I]);
+    System.Inc(I);
+  end;
+
+  result := LResult;
+end;
+
+function THashResult.GetInt32: Int32;
+begin
+  if (System.Length(Fm_hash) <> 4) then
+    raise EInvalidOperationHashLibException.CreateRes
+      (@SImpossibleRepresentationInt32);
+
+  result := Int32((Int32(Fm_hash[0]) shl 24) or (Int32(Fm_hash[1]) shl 16) or
+    (Int32(Fm_hash[2]) shl 8) or (Int32(Fm_hash[3])));
+
+end;
+
+function THashResult.GetUInt8: UInt8;
+begin
+  if (System.Length(Fm_hash) <> 1) then
+    raise EInvalidOperationHashLibException.CreateRes
+      (@SImpossibleRepresentationUInt8);
+
+  result := (UInt8(Fm_hash[0]));
+end;
+
+function THashResult.GetUInt16: UInt16;
+begin
+  if (System.Length(Fm_hash) <> 2) then
+    raise EInvalidOperationHashLibException.CreateRes
+      (@SImpossibleRepresentationUInt16);
+
+  result := (UInt16(Fm_hash[0]) shl 8) or (UInt16(Fm_hash[1]));
+
+end;
+
+function THashResult.GetUInt32: UInt32;
+begin
+  if (System.Length(Fm_hash) <> 4) then
+    raise EInvalidOperationHashLibException.CreateRes
+      (@SImpossibleRepresentationUInt32);
+
+  result := (UInt32(Fm_hash[0]) shl 24) or (UInt32(Fm_hash[1]) shl 16) or
+    (UInt32(Fm_hash[2]) shl 8) or (UInt32(Fm_hash[3]));
+
+end;
+
+function THashResult.GetUInt64: UInt64;
+begin
+  if (System.Length(Fm_hash) <> 8) then
+    raise EInvalidOperationHashLibException.CreateRes
+      (@SImpossibleRepresentationUInt64);
+
+  result := (UInt64(Fm_hash[0]) shl 56) or (UInt64(Fm_hash[1]) shl 48) or
+    (UInt64(Fm_hash[2]) shl 40) or (UInt64(Fm_hash[3]) shl 32) or
+    (UInt64(Fm_hash[4]) shl 24) or (UInt64(Fm_hash[5]) shl 16) or
+    (UInt64(Fm_hash[6]) shl 8) or (UInt64(Fm_hash[7]));
+
+end;
+
+{$B+}
+
+class function THashResult.SlowEquals(a_ar1, a_ar2: THashLibByteArray): Boolean;
+var
+  I: Int32;
+  diff: UInt32;
+
+begin
+  diff := UInt32(System.Length(a_ar1)) xor UInt32(System.Length(a_ar2));
+
+  I := 0;
+
+  while (I <= System.High(a_ar1)) and (I <= System.High(a_ar2)) do
+  begin
+    diff := diff or (UInt32(a_ar1[I] xor a_ar2[I]));
+    System.Inc(I);
+  end;
+
+  result := diff = 0;
+end;
+
+{$B-}
+
+function THashResult.ToString(a_group: Boolean): String;
+begin
+  result := TConverters.ConvertBytesToHexString(Fm_hash, a_group);
+end;
+
+end.

+ 10 - 0
src/libraries/hashlib4pascal/HashLib/src/Base/HlpHashRounds.pas

@@ -0,0 +1,10 @@
+unit HlpHashRounds;
+
+interface
+
+type
+  THashRounds = (hrRounds3 = 3, hrRounds4 = 4, hrRounds5 = 5, hrRounds8 = 8);
+
+implementation
+
+end.

+ 12 - 0
src/libraries/hashlib4pascal/HashLib/src/Base/HlpHashSize.pas

@@ -0,0 +1,12 @@
+unit HlpHashSize;
+
+interface
+
+type
+  THashSize = (hsHashSize128 = 16, hsHashSize160 = 20, hsHashSize192 = 24,
+    hsHashSize224 = 28, hsHashSize256 = 32, hsHashSize384 = 48,
+    hsHashSize512 = 64);
+
+implementation
+
+end.

+ 43 - 0
src/libraries/hashlib4pascal/HashLib/src/Base/HlpKDF.pas

@@ -0,0 +1,43 @@
+unit HlpKDF;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpIKDF,
+  HlpHashLibTypes;
+
+type
+  TKDF = class abstract(TInterfacedObject, IKDF)
+
+  strict protected
+
+    // Not really needed because there is an Intristic default constructor always
+    // called for classes if none is defined by the developer but I just put it
+    // for readability reasons.
+    constructor Create();
+
+  public
+
+    /// <summary>
+    /// Returns the pseudo-random bytes for this object.
+    /// </summary>
+    /// <param name="bc">The number of pseudo-random key bytes to generate.</param>
+    /// <returns>A byte array filled with pseudo-random key bytes.</returns>
+    /// <exception cref="EArgumentOutOfRangeHashLibException">bc must be greater than zero.</exception>
+    /// <exception cref="EArgumentHashLibException">invalid start index or end index of internal buffer.</exception>
+    function GetBytes(bc: Int32): THashLibByteArray; virtual; abstract;
+
+  end;
+
+implementation
+
+{ TKDF }
+
+constructor TKDF.Create;
+begin
+  Inherited Create();
+end;
+
+end.

+ 95 - 0
src/libraries/hashlib4pascal/HashLib/src/Base/HlpMultipleTransformNonBlock.pas

@@ -0,0 +1,95 @@
+unit HlpMultipleTransformNonBlock;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF HAS_UNITSCOPE}
+  System.Classes,
+{$ELSE}
+  Classes,
+{$ENDIF HAS_UNITSCOPE}
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpIHashResult;
+
+type
+
+  TMultipleTransformNonBlock = class abstract(THash, INonBlockHash)
+
+  strict private
+    FBuffer: TMemoryStream;
+
+    function Aggregate(): THashLibByteArray;
+
+  strict protected
+    function ComputeAggregatedBytes(a_data: THashLibByteArray): IHashResult;
+      virtual; abstract;
+
+  public
+    constructor Create(a_hash_size, a_block_size: Int32);
+    destructor Destroy; override;
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+    function ComputeBytes(a_data: THashLibByteArray): IHashResult; override;
+
+  end;
+
+implementation
+
+{ TMultipleTransformNonBlock }
+
+function TMultipleTransformNonBlock.Aggregate: THashLibByteArray;
+begin
+  FBuffer.Position := 0;
+  System.SetLength(result, FBuffer.Size);
+  FBuffer.Read(result[0], FBuffer.Size);
+end;
+
+constructor TMultipleTransformNonBlock.Create(a_hash_size, a_block_size: Int32);
+begin
+  Inherited Create(a_hash_size, a_block_size);
+  FBuffer := TMemoryStream.Create();
+end;
+
+destructor TMultipleTransformNonBlock.Destroy;
+begin
+  FBuffer.Free;
+  inherited Destroy;
+end;
+
+procedure TMultipleTransformNonBlock.Initialize;
+begin
+  FBuffer.Clear;
+  FBuffer.SetSize(0);
+end;
+
+procedure TMultipleTransformNonBlock.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  FBuffer.Write(a_data[a_index], a_length);
+end;
+
+function TMultipleTransformNonBlock.TransformFinal: IHashResult;
+begin
+  result := ComputeAggregatedBytes(Aggregate());
+  Initialize();
+end;
+
+function TMultipleTransformNonBlock.ComputeBytes(a_data: THashLibByteArray)
+  : IHashResult;
+begin
+  Initialize();
+  result := ComputeAggregatedBytes(a_data);
+end;
+
+end.

+ 105 - 0
src/libraries/hashlib4pascal/HashLib/src/Checksum/HlpAdler32.pas

@@ -0,0 +1,105 @@
+unit HlpAdler32;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpIHashInfo,
+  HlpHash,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TAdler32 = class sealed(THash, IChecksum, IBlockHash, IHash32,
+    ITransformBlock)
+
+  strict private
+
+    Fm_a, Fm_b: UInt32;
+
+  const
+    MOD_ADLER = UInt32(65521);
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal: IHashResult; override;
+
+  end;
+
+implementation
+
+{ TAdler32 }
+
+constructor TAdler32.Create;
+begin
+  Inherited Create(4, 1);
+
+end;
+
+procedure TAdler32.Initialize;
+begin
+  Fm_a := 1;
+  Fm_b := 0;
+end;
+
+procedure TAdler32.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i, n: Int32;
+
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+
+  { while a_length > 0 do
+    begin
+    Fm_a := (Fm_a + a_data[i]) mod MOD_ADLER;
+    Fm_b := (Fm_b + Fm_a) mod MOD_ADLER;
+    System.Inc(i);
+    System.Dec(a_length);
+    end; }
+
+  // lifted from PngEncoder Adler32.cs
+
+  while a_length > 0 do
+  begin
+    // We can defer the modulo operation:
+    // Fm_a maximally grows from 65521 to 65521 + 255 * 3800
+    // Fm_b maximally grows by3800 * median(Fm_a) = 2090079800 < 2^31
+    n := 3800;
+    if (n > a_length) then
+    begin
+      n := a_length;
+    end;
+    a_length := a_length - n;
+
+    while (n - 1) >= 0 do
+    begin
+      Fm_a := (Fm_a + a_data[i]);
+      Fm_b := (Fm_b + Fm_a);
+      System.Inc(i);
+      System.Dec(n);
+    end;
+    Fm_a := Fm_a mod MOD_ADLER;
+    Fm_b := Fm_b mod MOD_ADLER;
+
+  end;
+
+end;
+
+function TAdler32.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(UInt32((Fm_b shl 16) or Fm_a));
+  Initialize();
+end;
+
+end.

+ 1423 - 0
src/libraries/hashlib4pascal/HashLib/src/Checksum/HlpCRC.pas

@@ -0,0 +1,1423 @@
+unit HlpCRC;
+
+// A vast majority if not all of the parameters for these CRC standards
+// were gotten from http://reveng.sourceforge.net/crc-catalogue/.
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF HAS_UNITSCOPE}
+  System.TypInfo,
+{$ELSE}
+  TypInfo,
+{$ENDIF HAS_UNITSCOPE}
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult,
+  HlpICRC;
+
+resourcestring
+  SUnSupportedCRCType = 'UnSupported CRC Type: "%s"';
+
+{$REGION 'CRC Standards'}
+
+type
+  /// <summary>
+  /// Enum of all defined and implemented CRC standards.
+  /// </summary>
+  TCRCStandard = (
+
+    /// <summary>
+    /// CRC standard named "CRC3_GSM".
+    /// </summary>
+    CRC3_GSM,
+
+    /// <summary>
+    /// CRC standard named "CRC3_ROHC".
+    /// </summary>
+    CRC3_ROHC,
+
+    /// <summary>
+    /// CRC standard named "CRC4_INTERLAKEN".
+    /// </summary>
+    CRC4_INTERLAKEN,
+
+    /// <summary>
+    /// CRC standard named "CRC4_ITU".
+    /// </summary>
+    CRC4_ITU,
+
+    /// <summary>
+    /// CRC standard named "CRC5_EPC".
+    /// </summary>
+    CRC5_EPC,
+
+    /// <summary>
+    /// CRC standard named "CRC5_ITU".
+    /// </summary>
+    CRC5_ITU,
+
+    /// <summary>
+    /// CRC standard named "CRC5_USB".
+    /// </summary>
+    CRC5_USB,
+
+    /// <summary>
+    /// CRC standard named "CRC6_CDMA2000A".
+    /// </summary>
+    CRC6_CDMA2000A,
+
+    /// <summary>
+    /// CRC standard named "CRC6_CDMA2000B".
+    /// </summary>
+    CRC6_CDMA2000B,
+
+    /// <summary>
+    /// CRC standard named "CRC6_DARC".
+    /// </summary>
+    CRC6_DARC,
+
+    /// <summary>
+    /// CRC standard named "CRC6_GSM".
+    /// </summary>
+    CRC6_GSM,
+
+    /// <summary>
+    /// CRC standard named "CRC6_ITU".
+    /// </summary>
+    CRC6_ITU,
+
+    /// <summary>
+    /// CRC standard named "CRC7".
+    /// </summary>
+    CRC7,
+
+    /// <summary>
+    /// CRC standard named "CRC7_ROHC".
+    /// </summary>
+    CRC7_ROHC,
+
+    /// <summary>
+    /// CRC standard named "CRC7_UMTS".
+    /// </summary>
+    CRC7_UMTS,
+
+    /// <summary>
+    /// CRC standard named "CRC8".
+    /// </summary>
+    CRC8,
+
+    /// <summary>
+    /// CRC standard named "CRC8_AUTOSAR".
+    /// </summary>
+    CRC8_AUTOSAR,
+
+    /// <summary>
+    /// CRC standard named "CRC8_BLUETOOTH".
+    /// </summary>
+    CRC8_BLUETOOTH,
+
+    /// <summary>
+    /// CRC standard named "CRC8_CDMA2000".
+    /// </summary>
+    CRC8_CDMA2000,
+
+    /// <summary>
+    /// CRC standard named "CRC8_DARC".
+    /// </summary>
+    CRC8_DARC,
+
+    /// <summary>
+    /// CRC standard named "CRC8_DVBS2".
+    /// </summary>
+    CRC8_DVBS2,
+
+    /// <summary>
+    /// CRC standard named "CRC8_EBU".
+    /// </summary>
+    CRC8_EBU,
+
+    /// <summary>
+    /// CRC standard named "CRC8_GSMA".
+    /// </summary>
+    CRC8_GSMA,
+
+    /// <summary>
+    /// CRC standard named "CRC8_GSMB".
+    /// </summary>
+    CRC8_GSMB,
+
+    /// <summary>
+    /// CRC standard named "CRC8_ICODE".
+    /// </summary>
+    CRC8_ICODE,
+
+    /// <summary>
+    /// CRC standard named "CRC8_ITU".
+    /// </summary>
+    CRC8_ITU,
+
+    /// <summary>
+    /// CRC standard named "CRC8_LTE".
+    /// </summary>
+    CRC8_LTE,
+
+    /// <summary>
+    /// CRC standard named "CRC8_MAXIM".
+    /// </summary>
+    CRC8_MAXIM,
+
+    /// <summary>
+    /// CRC standard named "CRC8_OPENSAFETY".
+    /// </summary>
+    CRC8_OPENSAFETY,
+
+    /// <summary>
+    /// CRC standard named "CRC8_ROHC".
+    /// </summary>
+    CRC8_ROHC,
+
+    /// <summary>
+    /// CRC standard named "CRC8_SAEJ1850".
+    /// </summary>
+    CRC8_SAEJ1850,
+
+    /// <summary>
+    /// CRC standard named "CRC8_WCDMA".
+    /// </summary>
+    CRC8_WCDMA,
+
+    /// <summary>
+    /// CRC standard named "CRC10".
+    /// </summary>
+    CRC10,
+
+    /// <summary>
+    /// CRC standard named "CRC10_CDMA2000".
+    /// </summary>
+    CRC10_CDMA2000,
+
+    /// <summary>
+    /// CRC standard named "CRC10_GSM".
+    /// </summary>
+    CRC10_GSM,
+
+    /// <summary>
+    /// CRC standard named "CRC11".
+    /// </summary>
+    CRC11,
+
+    /// <summary>
+    /// CRC standard named "CRC11_UMTS".
+    /// </summary>
+    CRC11_UMTS,
+
+    /// <summary>
+    /// CRC standard named "CRC12_CDMA2000".
+    /// </summary>
+    CRC12_CDMA2000,
+
+    /// <summary>
+    /// CRC standard named "CRC12_DECT".
+    /// </summary>
+    CRC12_DECT,
+
+    /// <summary>
+    /// CRC standard named "CRC12_GSM".
+    /// </summary>
+    CRC12_GSM,
+
+    /// <summary>
+    /// CRC standard named "CRC12_UMTS".
+    /// </summary>
+    CRC12_UMTS,
+
+    /// <summary>
+    /// CRC standard named "CRC13_BBC".
+    /// </summary>
+    CRC13_BBC,
+
+    /// <summary>
+    /// CRC standard named "CRC14_DARC".
+    /// </summary>
+    CRC14_DARC,
+
+    /// <summary>
+    /// CRC standard named "CRC14_GSM".
+    /// </summary>
+    CRC14_GSM,
+
+    /// <summary>
+    /// CRC standard named "CRC15".
+    /// </summary>
+    CRC15,
+
+    /// <summary>
+    /// CRC standard named "CRC15_MPT1327".
+    /// </summary>
+    CRC15_MPT1327,
+
+    /// <summary>
+    /// CRC standard named "ARC".
+    /// </summary>
+    ARC,
+
+    /// <summary>
+    /// CRC standard named "CRC16_AUGCCITT".
+    /// </summary>
+    CRC16_AUGCCITT,
+
+    /// <summary>
+    /// CRC standard named "CRC16_BUYPASS".
+    /// </summary>
+    CRC16_BUYPASS,
+
+    /// <summary>
+    /// CRC standard named "CRC16_CCITTFALSE".
+    /// </summary>
+    CRC16_CCITTFALSE,
+
+    /// <summary>
+    /// CRC standard named "CRC16_CDMA2000".
+    /// </summary>
+    CRC16_CDMA2000,
+
+    /// <summary>
+    /// CRC standard named "CRC16_CMS".
+    /// </summary>
+    CRC16_CMS,
+
+    /// <summary>
+    /// CRC standard named "CRC16_DDS110".
+    /// </summary>
+    CRC16_DDS110,
+
+    /// <summary>
+    /// CRC standard named "CRC16_DECTR".
+    /// </summary>
+    CRC16_DECTR,
+
+    /// <summary>
+    /// CRC standard named "CRC16_DECTX".
+    /// </summary>
+    CRC16_DECTX,
+
+    /// <summary>
+    /// CRC standard named "CRC16_DNP".
+    /// </summary>
+    CRC16_DNP,
+
+    /// <summary>
+    /// CRC standard named "CRC16_EN13757".
+    /// </summary>
+    CRC16_EN13757,
+
+    /// <summary>
+    /// CRC standard named "CRC16_GENIBUS".
+    /// </summary>
+    CRC16_GENIBUS,
+
+    /// <summary>
+    /// CRC standard named "CRC16_GSM".
+    /// </summary>
+    CRC16_GSM,
+
+    /// <summary>
+    /// CRC standard named "CRC16_LJ1200".
+    /// </summary>
+    CRC16_LJ1200,
+
+    /// <summary>
+    /// CRC standard named "CRC16_MAXIM".
+    /// </summary>
+    CRC16_MAXIM,
+
+    /// <summary>
+    /// CRC standard named "CRC16_MCRF4XX".
+    /// </summary>
+    CRC16_MCRF4XX,
+
+    /// <summary>
+    /// CRC standard named "CRC16_OPENSAFETYA".
+    /// </summary>
+    CRC16_OPENSAFETYA,
+
+    /// <summary>
+    /// CRC standard named "CRC16_OPENSAFETYB".
+    /// </summary>
+    CRC16_OPENSAFETYB,
+
+    /// <summary>
+    /// CRC standard named "CRC16_PROFIBUS".
+    /// </summary>
+    CRC16_PROFIBUS,
+
+    /// <summary>
+    /// CRC standard named "CRC16_RIELLO".
+    /// </summary>
+    CRC16_RIELLO,
+
+    /// <summary>
+    /// CRC standard named "CRC16_T10DIF".
+    /// </summary>
+    CRC16_T10DIF,
+
+    /// <summary>
+    /// CRC standard named "CRC16_TELEDISK".
+    /// </summary>
+    CRC16_TELEDISK,
+
+    /// <summary>
+    /// CRC standard named "CRC16_TMS37157".
+    /// </summary>
+    CRC16_TMS37157,
+
+    /// <summary>
+    /// CRC standard named "CRC16_USB".
+    /// </summary>
+    CRC16_USB,
+
+    /// <summary>
+    /// CRC standard named "CRCA".
+    /// </summary>
+    CRCA,
+
+    /// <summary>
+    /// CRC standard named "KERMIT".
+    /// </summary>
+    KERMIT,
+
+    /// <summary>
+    /// CRC standard named "MODBUS".
+    /// </summary>
+    MODBUS,
+
+    /// <summary>
+    /// CRC standard named "X25".
+    /// </summary>
+    X25,
+
+    /// <summary>
+    /// CRC standard named "XMODEM".
+    /// </summary>
+    XMODEM,
+
+    /// <summary>
+    /// CRC standard named "CRC17_CANFD".
+    /// </summary>
+    CRC17_CANFD,
+
+    /// <summary>
+    /// CRC standard named "CRC21_CANFD".
+    /// </summary>
+    CRC21_CANFD,
+
+    /// <summary>
+    /// CRC standard named "CRC24".
+    /// </summary>
+    CRC24,
+
+    /// <summary>
+    /// CRC standard named "CRC24_BLE".
+    /// </summary>
+    CRC24_BLE,
+
+    /// <summary>
+    /// CRC standard named "CRC24_FLEXRAYA".
+    /// </summary>
+    CRC24_FLEXRAYA,
+
+    /// <summary>
+    /// CRC standard named "CRC24_FLEXRAYB".
+    /// </summary>
+    CRC24_FLEXRAYB,
+
+    /// <summary>
+    /// CRC standard named "CRC24_INTERLAKEN".
+    /// </summary>
+    CRC24_INTERLAKEN,
+
+    /// <summary>
+    /// CRC standard named "CRC24_LTEA".
+    /// </summary>
+    CRC24_LTEA,
+
+    /// <summary>
+    /// CRC standard named "CRC24_LTEB".
+    /// </summary>
+    CRC24_LTEB,
+
+    /// <summary>
+    /// CRC standard named "CRC30_CDMA".
+    /// </summary>
+    CRC30_CDMA,
+
+    /// <summary>
+    /// CRC standard named "CRC31_PHILIPS".
+    /// </summary>
+    CRC31_PHILIPS,
+
+    /// <summary>
+    /// CRC standard named "CRC32".
+    /// </summary>
+    CRC32,
+
+    /// <summary>
+    /// CRC standard named "CRC32_AUTOSAR".
+    /// </summary>
+    CRC32_AUTOSAR,
+
+    /// <summary>
+    /// CRC standard named "CRC32_BZIP2".
+    /// </summary>
+    CRC32_BZIP2,
+
+    /// <summary>
+    /// CRC standard named "CRC32C".
+    /// </summary>
+    CRC32C,
+
+    /// <summary>
+    /// CRC standard named "CRC32D".
+    /// </summary>
+    CRC32D,
+
+    /// <summary>
+    /// CRC standard named "CRC32_MPEG2".
+    /// </summary>
+    CRC32_MPEG2,
+
+    /// <summary>
+    /// CRC standard named "CRC32_POSIX".
+    /// </summary>
+    CRC32_POSIX,
+
+    /// <summary>
+    /// CRC standard named "CRC32Q".
+    /// </summary>
+    CRC32Q,
+
+    /// <summary>
+    /// CRC standard named "JAMCRC".
+    /// </summary>
+    JAMCRC,
+
+    /// <summary>
+    /// CRC standard named "XFER".
+    /// </summary>
+    XFER,
+
+    /// <summary>
+    /// CRC standard named "CRC40_GSM".
+    /// </summary>
+    CRC40_GSM,
+
+    /// <summary>
+    /// CRC standard named "CRC64".
+    /// </summary>
+    CRC64,
+
+    /// <summary>
+    /// CRC standard named "CRC64_GOISO".
+    /// </summary>
+    CRC64_GOISO,
+
+    /// <summary>
+    /// CRC standard named "CRC64_WE".
+    /// </summary>
+    CRC64_WE,
+
+    /// <summary>
+    /// CRC standard named "CRC64_XZ".
+    /// </summary>
+    CRC64_XZ);
+
+{$ENDREGION}
+
+type
+  TCRC = class sealed(THash, IChecksum, ICRC, ITransformBlock)
+
+  strict private
+
+    FNames: THashLibStringArray;
+    FWidth: Int32;
+    FPolynomial, FInit, FXorOut, FCheckValue, Fm_CRCMask, Fm_CRCHighBitMask,
+      Fm_hash: UInt64;
+    FReflectIn, FReflectOut, FIsTableGenerated: Boolean;
+
+    Fm_CRCTable: THashLibUInt64Array;
+    Fptr_Fm_CRCTable: PUInt64;
+
+  const
+    Delta = Int32(7);
+
+    function GetNames: THashLibStringArray; inline;
+    procedure SetNames(value: THashLibStringArray); inline;
+    function GetWidth: Int32; inline;
+    procedure SetWidth(value: Int32); inline;
+    function GetPolynomial: UInt64; inline;
+    procedure SetPolynomial(value: UInt64); inline;
+    function GetInit: UInt64; inline;
+    procedure SetInit(value: UInt64); inline;
+    function GetReflectIn: Boolean; inline;
+    procedure SetReflectIn(value: Boolean); inline;
+    function GetReflectOut: Boolean; inline;
+    procedure SetReflectOut(value: Boolean); inline;
+    function GetXOROut: UInt64; inline;
+    procedure SetXOROut(value: UInt64); inline;
+    function GetCheckValue: UInt64; inline;
+    procedure SetCheckValue(value: UInt64); inline;
+
+    procedure GenerateTable();
+    // tables work only for 8, 16, 24, 32 bit CRC
+    procedure CalculateCRCbyTable(a_data: PByte; a_data_length, a_index: Int32);
+    // fast bit by bit algorithm without augmented zero bytes.
+    // does not use lookup table, suited for polynomial orders between 1...32.
+    procedure CalculateCRCdirect(a_data: PByte; a_data_length, a_index: Int32);
+
+    // reflects the lower 'width' bits of 'value'
+    class function Reflect(a_value: UInt64; a_width: Int32): UInt64; static;
+
+    property Names: THashLibStringArray read GetNames write SetNames;
+    property Width: Int32 read GetWidth write SetWidth;
+    property Polynomial: UInt64 read GetPolynomial write SetPolynomial;
+    property Init: UInt64 read GetInit write SetInit;
+    property ReflectIn: Boolean read GetReflectIn write SetReflectIn;
+    property ReflectOut: Boolean read GetReflectOut write SetReflectOut;
+    property XOROut: UInt64 read GetXOROut write SetXOROut;
+    property CheckValue: UInt64 read GetCheckValue write SetCheckValue;
+
+  public
+
+    constructor Create(_Width: Int32; _poly, _Init: UInt64;
+      _refIn, _refOut: Boolean; _XorOut, _check: UInt64;
+      _Names: THashLibStringArray);
+
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+
+    class function CreateCRCObject(a_value: TCRCStandard): ICRC; static;
+
+  end;
+
+implementation
+
+{ TCRC }
+
+procedure TCRC.CalculateCRCbyTable(a_data: PByte;
+  a_data_length, a_index: Int32);
+var
+  &Length, i: Int32;
+  tmp: UInt64;
+begin
+
+  &Length := a_data_length;
+  i := a_index;
+  tmp := Fm_hash;
+
+  if (ReflectIn) then
+  begin
+    while Length > 0 do
+    begin
+      tmp := (tmp shr 8) xor Fptr_Fm_CRCTable[Byte(tmp xor a_data[i])];
+      System.Inc(i);
+      System.Dec(Length);
+    end;
+
+  end
+  else
+  begin
+
+    while Length > 0 do
+    begin
+      tmp := (tmp shl 8) xor Fptr_Fm_CRCTable
+        [Byte((tmp shr (Width - 8)) xor a_data[i])];
+      System.Inc(i);
+      System.Dec(Length);
+    end;
+
+  end;
+
+  Fm_hash := tmp;
+
+end;
+
+procedure TCRC.CalculateCRCdirect(a_data: PByte; a_data_length, a_index: Int32);
+var
+  &Length, i: Int32;
+  c, bit, j: UInt64;
+begin
+
+  &Length := a_data_length;
+  i := a_index;
+  while Length > 0 do
+  begin
+    c := UInt64(a_data[i]);
+    if (ReflectIn) then
+    begin
+      c := Reflect(c, 8);
+    end;
+
+    j := $80;
+    while j > 0 do
+    begin
+      bit := Fm_hash and Fm_CRCHighBitMask;
+      Fm_hash := Fm_hash shl 1;
+      if ((c and j) > 0) then
+        bit := bit xor Fm_CRCHighBitMask;
+      if (bit > 0) then
+        Fm_hash := Fm_hash xor Polynomial;
+      j := j shr 1;
+    end;
+    System.Inc(i);
+    System.Dec(Length);
+  end;
+
+end;
+
+constructor TCRC.Create(_Width: Int32; _poly, _Init: UInt64;
+  _refIn, _refOut: Boolean; _XorOut, _check: UInt64;
+  _Names: THashLibStringArray);
+begin
+
+  FIsTableGenerated := False;
+
+  Inherited Create(-1, -1); // Dummy State
+
+  case _Width of
+    0 .. 7:
+      begin
+        Self.HashSize := 1;
+        Self.BlockSize := 1;
+      end;
+
+    8 .. 16:
+      begin
+        Self.HashSize := 2;
+        Self.BlockSize := 1;
+      end;
+
+    17 .. 39:
+      begin
+        Self.HashSize := 4;
+        Self.BlockSize := 1;
+      end;
+
+  else
+    begin
+      Self.HashSize := 8;
+      Self.BlockSize := 1;
+    end;
+
+  end;
+
+  Names := _Names;
+  Width := _Width;
+  Polynomial := _poly;
+  Init := _Init;
+  ReflectIn := _refIn;
+  ReflectOut := _refOut;
+  XOROut := _XorOut;
+  CheckValue := _check;
+
+end;
+
+{$REGION 'CRC Standards Implementation'}
+
+class function TCRC.CreateCRCObject(a_value: TCRCStandard): ICRC;
+begin
+  case a_value of
+
+    TCRCStandard.CRC3_GSM:
+      result := TCRC.Create(3, $3, $0, False, False, $7, $4,
+        THashLibStringArray.Create('CRC-3/GSM'));
+
+    TCRCStandard.CRC3_ROHC:
+      result := TCRC.Create(3, $3, $7, True, True, $0, $6,
+        THashLibStringArray.Create('CRC-3/ROHC'));
+
+    TCRCStandard.CRC4_INTERLAKEN:
+      result := TCRC.Create(4, $3, $F, False, False, $F, $B,
+        THashLibStringArray.Create('CRC-4/INTERLAKEN'));
+
+    TCRCStandard.CRC4_ITU:
+      result := TCRC.Create(4, $3, $0, True, True, $0, $7,
+        THashLibStringArray.Create('CRC-4/ITU'));
+
+    TCRCStandard.CRC5_EPC:
+      result := TCRC.Create(5, $9, $9, False, False, $00, $00,
+        THashLibStringArray.Create('CRC-5/EPC'));
+
+    TCRCStandard.CRC5_ITU:
+      result := TCRC.Create(5, $15, $00, True, True, $00, $07,
+        THashLibStringArray.Create('CRC-5/ITU'));
+
+    TCRCStandard.CRC5_USB:
+      result := TCRC.Create(5, $05, $1F, True, True, $1F, $19,
+        THashLibStringArray.Create('CRC-5/USB'));
+
+    TCRCStandard.CRC6_CDMA2000A:
+      result := TCRC.Create(6, $27, $3F, False, False, $00, $0D,
+        THashLibStringArray.Create('CRC-6/CDMA2000-A'));
+
+    TCRCStandard.CRC6_CDMA2000B:
+      result := TCRC.Create(6, $07, $3F, False, False, $00, $3B,
+        THashLibStringArray.Create('CRC-6/CDMA2000-B'));
+
+    TCRCStandard.CRC6_DARC:
+      result := TCRC.Create(6, $19, $00, True, True, $00, $26,
+        THashLibStringArray.Create('CRC-6/DARC'));
+
+    TCRCStandard.CRC6_GSM:
+      result := TCRC.Create(6, $2F, $00, False, False, $3F, $13,
+        THashLibStringArray.Create('CRC-6/GSM'));
+
+    TCRCStandard.CRC6_ITU:
+      result := TCRC.Create(6, $03, $00, True, True, $00, $06,
+        THashLibStringArray.Create('CRC-6/ITU'));
+
+    TCRCStandard.CRC7:
+      result := TCRC.Create(7, $09, $00, False, False, $00, $75,
+        THashLibStringArray.Create('CRC-7'));
+
+    TCRCStandard.CRC7_ROHC:
+      result := TCRC.Create(7, $4F, $7F, True, True, $00, $53,
+        THashLibStringArray.Create('CRC-7/ROHC'));
+
+    TCRCStandard.CRC7_UMTS:
+      result := TCRC.Create(7, $45, $00, False, False, $00, $61,
+        THashLibStringArray.Create('CRC-7/UMTS'));
+
+    TCRCStandard.CRC8:
+      result := TCRC.Create(8, $07, $00, False, False, $00, $F4,
+        THashLibStringArray.Create('CRC-8'));
+
+    TCRCStandard.CRC8_AUTOSAR:
+      result := TCRC.Create(8, $2F, $FF, False, False, $FF, $DF,
+        THashLibStringArray.Create('CRC-8/AUTOSAR'));
+
+    TCRCStandard.CRC8_BLUETOOTH:
+      result := TCRC.Create(8, $A7, $00, True, True, $00, $26,
+        THashLibStringArray.Create('CRC-8/BLUETOOTH'));
+
+    TCRCStandard.CRC8_CDMA2000:
+      result := TCRC.Create(8, $9B, $FF, False, False, $00, $DA,
+        THashLibStringArray.Create('CRC-8/CDMA2000'));
+
+    TCRCStandard.CRC8_DARC:
+      result := TCRC.Create(8, $39, $00, True, True, $00, $15,
+        THashLibStringArray.Create('CRC-8/DARC'));
+
+    TCRCStandard.CRC8_DVBS2:
+      result := TCRC.Create(8, $D5, $00, False, False, $00, $BC,
+        THashLibStringArray.Create('CRC-8/DVB-S2'));
+
+    TCRCStandard.CRC8_EBU:
+      result := TCRC.Create(8, $1D, $FF, True, True, $00, $97,
+        THashLibStringArray.Create('CRC-8/EBU', 'CRC-8/AES'));
+
+    TCRCStandard.CRC8_GSMA:
+      result := TCRC.Create(8, $1D, $00, False, False, $00, $37,
+        THashLibStringArray.Create('CRC-8/GSM-A'));
+
+    TCRCStandard.CRC8_GSMB:
+      result := TCRC.Create(8, $49, $00, False, False, $FF, $94,
+        THashLibStringArray.Create('CRC-8/GSM-B'));
+
+    TCRCStandard.CRC8_ICODE:
+      result := TCRC.Create(8, $1D, $FD, False, False, $00, $7E,
+        THashLibStringArray.Create('CRC-8/I-CODE'));
+
+    TCRCStandard.CRC8_ITU:
+      result := TCRC.Create(8, $07, $00, False, False, $55, $A1,
+        THashLibStringArray.Create('CRC-8/ITU'));
+
+    TCRCStandard.CRC8_LTE:
+      result := TCRC.Create(8, $9B, $00, False, False, $00, $EA,
+        THashLibStringArray.Create('CRC-8/LTE'));
+
+    TCRCStandard.CRC8_MAXIM:
+      result := TCRC.Create(8, $31, $00, True, True, $00, $A1,
+        THashLibStringArray.Create('CRC-8/MAXIM', 'DOW-CRC'));
+
+    TCRCStandard.CRC8_OPENSAFETY:
+      result := TCRC.Create(8, $2F, $00, False, False, $00, $3E,
+        THashLibStringArray.Create('CRC-8/OPENSAFETY'));
+
+    TCRCStandard.CRC8_ROHC:
+      result := TCRC.Create(8, $07, $FF, True, True, $00, $D0,
+        THashLibStringArray.Create('CRC-8/ROHC'));
+
+    TCRCStandard.CRC8_SAEJ1850:
+      result := TCRC.Create(8, $1D, $FF, False, False, $FF, $4B,
+        THashLibStringArray.Create('CRC-8/SAE-J1850'));
+
+    TCRCStandard.CRC8_WCDMA:
+      result := TCRC.Create(8, $9B, $00, True, True, $00, $25,
+        THashLibStringArray.Create('CRC-8/WCDMA'));
+
+    TCRCStandard.CRC10:
+      result := TCRC.Create(10, $233, $000, False, False, $000, $199,
+        THashLibStringArray.Create('CRC-10'));
+
+    TCRCStandard.CRC10_CDMA2000:
+      result := TCRC.Create(10, $3D9, $3FF, False, False, $000, $233,
+        THashLibStringArray.Create('CRC-10/CDMA2000'));
+
+    TCRCStandard.CRC10_GSM:
+      result := TCRC.Create(10, $175, $000, False, False, $3FF, $12A,
+        THashLibStringArray.Create('CRC-10/GSM'));
+
+    TCRCStandard.CRC11:
+      result := TCRC.Create(11, $385, $01A, False, False, $000, $5A3,
+        THashLibStringArray.Create('CRC-11'));
+
+    TCRCStandard.CRC11_UMTS:
+      result := TCRC.Create(11, $307, $000, False, False, $000, $061,
+        THashLibStringArray.Create('CRC-11/UMTS'));
+
+    TCRCStandard.CRC12_CDMA2000:
+      result := TCRC.Create(12, $F13, $FFF, False, False, $000, $D4D,
+        THashLibStringArray.Create('CRC-12/CDMA2000'));
+
+    TCRCStandard.CRC12_DECT:
+      result := TCRC.Create(12, $80F, $000, False, False, $000, $F5B,
+        THashLibStringArray.Create('CRC-12/DECT', 'X-CRC-12'));
+
+    TCRCStandard.CRC12_GSM:
+      result := TCRC.Create(12, $D31, $000, False, False, $FFF, $B34,
+        THashLibStringArray.Create('CRC-12/GSM'));
+
+    TCRCStandard.CRC12_UMTS:
+      result := TCRC.Create(12, $80F, $000, False, True, $000, $DAF,
+        THashLibStringArray.Create('CRC-12/UMTS', 'CRC-12/3GPP'));
+
+    TCRCStandard.CRC13_BBC:
+      result := TCRC.Create(13, $1CF5, $0000, False, False, $0000, $04FA,
+        THashLibStringArray.Create('CRC-13/BBC'));
+
+    TCRCStandard.CRC14_DARC:
+      result := TCRC.Create(14, $0805, $0000, True, True, $0000, $082D,
+        THashLibStringArray.Create('CRC-14/DARC'));
+
+    TCRCStandard.CRC14_GSM:
+      result := TCRC.Create(14, $202D, $0000, False, False, $3FFF, $30AE,
+        THashLibStringArray.Create('CRC-14/GSM'));
+
+    TCRCStandard.CRC15:
+      result := TCRC.Create(15, $4599, $0000, False, False, $0000, $059E,
+        THashLibStringArray.Create('CRC-15'));
+
+    TCRCStandard.CRC15_MPT1327:
+      result := TCRC.Create(15, $6815, $0000, False, False, $0001, $2566,
+        THashLibStringArray.Create('CRC-15/MPT1327'));
+
+    TCRCStandard.ARC:
+      result := TCRC.Create(16, $8005, $0000, True, True, $0000, $BB3D,
+        THashLibStringArray.Create('CRC-16', 'ARC', 'CRC-IBM', 'CRC-16/ARC',
+        'CRC-16/LHA'));
+
+    TCRCStandard.CRC16_AUGCCITT:
+      result := TCRC.Create(16, $1021, $1D0F, False, False, $0000, $E5CC,
+        THashLibStringArray.Create('CRC-16/AUG-CCITT', 'CRC-16/SPI-FUJITSU'));
+
+    TCRCStandard.CRC16_BUYPASS:
+      result := TCRC.Create(16, $8005, $0000, False, False, $0000, $FEE8,
+        THashLibStringArray.Create('CRC-16/BUYPASS', 'CRC-16/VERIFONE'));
+
+    TCRCStandard.CRC16_CCITTFALSE:
+      result := TCRC.Create(16, $1021, $FFFF, False, False, $0000, $29B1,
+        THashLibStringArray.Create('CRC-16/CCITT-FALSE'));
+
+    TCRCStandard.CRC16_CDMA2000:
+      result := TCRC.Create(16, $C867, $FFFF, False, False, $0000, $4C06,
+        THashLibStringArray.Create('CRC-16/CDMA2000'));
+
+    TCRCStandard.CRC16_CMS:
+      result := TCRC.Create(16, $8005, $FFFF, False, False, $0000, $AEE7,
+        THashLibStringArray.Create('CRC-16/CMS'));
+
+    TCRCStandard.CRC16_DDS110:
+      result := TCRC.Create(16, $8005, $800D, False, False, $0000, $9ECF,
+        THashLibStringArray.Create('CRC-16/DDS-110'));
+
+    TCRCStandard.CRC16_DECTR:
+      result := TCRC.Create(16, $0589, $0000, False, False, $0001, $007E,
+        THashLibStringArray.Create('CRC-16/DECT-R', 'R-CRC-16'));
+
+    TCRCStandard.CRC16_DECTX:
+      result := TCRC.Create(16, $0589, $0000, False, False, $0000, $007F,
+        THashLibStringArray.Create('CRC-16/DECT-X', 'X-CRC-16'));
+
+    TCRCStandard.CRC16_DNP:
+      result := TCRC.Create(16, $3D65, $0000, True, True, $FFFF, $EA82,
+        THashLibStringArray.Create('CRC-16/DNP'));
+
+    TCRCStandard.CRC16_EN13757:
+      result := TCRC.Create(16, $3D65, $0000, False, False, $FFFF, $C2B7,
+        THashLibStringArray.Create('CRC-16/EN13757'));
+
+    TCRCStandard.CRC16_GENIBUS:
+      result := TCRC.Create(16, $1021, $FFFF, False, False, $FFFF, $D64E,
+        THashLibStringArray.Create('CRC-16/GENIBUS', 'CRC-16/EPC',
+        'CRC-16/I-CODE', 'CRC-16/DARC'));
+
+    TCRCStandard.CRC16_GSM:
+      result := TCRC.Create(16, $1021, $0000, False, False, $FFFF, $CE3C,
+        THashLibStringArray.Create('CRC-16/GSM'));
+
+    TCRCStandard.CRC16_LJ1200:
+      result := TCRC.Create(16, $6F63, $0000, False, False, $0000, $BDF4,
+        THashLibStringArray.Create('CRC-16/LJ1200'));
+
+    TCRCStandard.CRC16_MAXIM:
+      result := TCRC.Create(16, $8005, $0000, True, True, $FFFF, $44C2,
+        THashLibStringArray.Create('CRC-16/MAXIM'));
+
+    TCRCStandard.CRC16_MCRF4XX:
+      result := TCRC.Create(16, $1021, $FFFF, True, True, $0000, $6F91,
+        THashLibStringArray.Create('CRC-16/MCRF4XX'));
+
+    TCRCStandard.CRC16_OPENSAFETYA:
+      result := TCRC.Create(16, $5935, $0000, False, False, $0000, $5D38,
+        THashLibStringArray.Create('CRC-16/OPENSAFETY-A'));
+
+    TCRCStandard.CRC16_OPENSAFETYB:
+      result := TCRC.Create(16, $755B, $0000, False, False, $0000, $20FE,
+        THashLibStringArray.Create('CRC-16/OPENSAFETY-B'));
+
+    TCRCStandard.CRC16_PROFIBUS:
+      result := TCRC.Create(16, $1DCF, $FFFF, False, False, $FFFF, $A819,
+        THashLibStringArray.Create('CRC-16/PROFIBUS', 'CRC-16/IEC-61158-2'));
+
+    TCRCStandard.CRC16_RIELLO:
+      result := TCRC.Create(16, $1021, $B2AA, True, True, $0000, $63D0,
+        THashLibStringArray.Create('CRC-16/RIELLO'));
+
+    TCRCStandard.CRC16_T10DIF:
+      result := TCRC.Create(16, $8BB7, $0000, False, False, $0000, $D0DB,
+        THashLibStringArray.Create('CRC-16/T10-DIF'));
+
+    TCRCStandard.CRC16_TELEDISK:
+      result := TCRC.Create(16, $A097, $0000, False, False, $0000, $0FB3,
+        THashLibStringArray.Create('CRC-16/TELEDISK'));
+
+    TCRCStandard.CRC16_TMS37157:
+      result := TCRC.Create(16, $1021, $89EC, True, True, $0000, $26B1,
+        THashLibStringArray.Create('CRC-16/TMS37157'));
+
+    TCRCStandard.CRC16_USB:
+      result := TCRC.Create(16, $8005, $FFFF, True, True, $FFFF, $B4C8,
+        THashLibStringArray.Create('CRC-16/USB'));
+
+    TCRCStandard.CRCA:
+      result := TCRC.Create(16, $1021, $C6C6, True, True, $0000, $BF05,
+        THashLibStringArray.Create('CRC-A'));
+
+    TCRCStandard.KERMIT:
+      result := TCRC.Create(16, $1021, $0000, True, True, $0000, $2189,
+        THashLibStringArray.Create('KERMIT', 'CRC-16/CCITT',
+        'CRC-16/CCITT-TRUE', 'CRC-CCITT'));
+
+    TCRCStandard.MODBUS:
+      result := TCRC.Create(16, $8005, $FFFF, True, True, $0000, $4B37,
+        THashLibStringArray.Create('MODBUS'));
+
+    TCRCStandard.X25:
+      result := TCRC.Create(16, $1021, $FFFF, True, True, $FFFF, $906E,
+        THashLibStringArray.Create('X-25', 'CRC-16/IBM-SDLC', 'CRC-16/ISO-HDLC',
+        'CRC-B'));
+
+    TCRCStandard.XMODEM:
+      result := TCRC.Create(16, $1021, $0000, False, False, $0000, $31C3,
+        THashLibStringArray.Create('XMODEM', 'ZMODEM', 'CRC-16/ACORN'));
+
+    TCRCStandard.CRC17_CANFD:
+      result := TCRC.Create(17, $1685B, $00000, False, False, $00000, $04F03,
+        THashLibStringArray.Create('CRC-17/CAN-FD'));
+
+    TCRCStandard.CRC21_CANFD:
+      result := TCRC.Create(21, $102899, $00000, False, False, $00000, $0ED841,
+        THashLibStringArray.Create('CRC-21/CAN-FD'));
+
+    TCRCStandard.CRC24:
+      result := TCRC.Create(24, $864CFB, $B704CE, False, False, $000000,
+        $21CF02, THashLibStringArray.Create('CRC-24', 'CRC-24/OPENPGP'));
+
+    TCRCStandard.CRC24_BLE:
+      result := TCRC.Create(24, $00065B, $555555, True, True, $000000, $C25A56,
+        THashLibStringArray.Create('CRC-24/BLE'));
+
+    TCRCStandard.CRC24_FLEXRAYA:
+      result := TCRC.Create(24, $5D6DCB, $FEDCBA, False, False, $000000,
+        $7979BD, THashLibStringArray.Create('CRC-24/FLEXRAY-A'));
+
+    TCRCStandard.CRC24_FLEXRAYB:
+      result := TCRC.Create(24, $5D6DCB, $ABCDEF, False, False, $000000,
+        $1F23B8, THashLibStringArray.Create('CRC-24/FLEXRAY-B'));
+
+    TCRCStandard.CRC24_INTERLAKEN:
+      result := TCRC.Create(24, $328B63, $FFFFFF, False, False, $FFFFFF,
+        $B4F3E6, THashLibStringArray.Create('CRC-24/INTERLAKEN'));
+
+    TCRCStandard.CRC24_LTEA:
+      result := TCRC.Create(24, $864CFB, $000000, False, False, $000000,
+        $CDE703, THashLibStringArray.Create('CRC-24/LTE-A'));
+
+    TCRCStandard.CRC24_LTEB:
+      result := TCRC.Create(24, $800063, $000000, False, False, $000000,
+        $23EF52, THashLibStringArray.Create('CRC-24/LTE-B'));
+
+    TCRCStandard.CRC30_CDMA:
+      result := TCRC.Create(30, $2030B9C7, $3FFFFFFF, False, False, $3FFFFFFF,
+        $04C34ABF, THashLibStringArray.Create('CRC-30/CDMA'));
+
+    TCRCStandard.CRC31_PHILIPS:
+      result := TCRC.Create(31, $04C11DB7, $7FFFFFFF, False, False, $7FFFFFFF,
+        $0CE9E46C, THashLibStringArray.Create('CRC-31/PHILLIPS'));
+
+    TCRCStandard.CRC32:
+      result := TCRC.Create(32, $04C11DB7, $FFFFFFFF, True, True, $FFFFFFFF,
+        $CBF43926, THashLibStringArray.Create('CRC-32', 'CRC-32/ADCCP',
+        'PKZIP'));
+
+    TCRCStandard.CRC32_AUTOSAR:
+      result := TCRC.Create(32, $F4ACFB13, $FFFFFFFF, True, True, $FFFFFFFF,
+        $1697D06A, THashLibStringArray.Create('CRC-32/AUTOSAR'));
+
+    TCRCStandard.CRC32_BZIP2:
+      result := TCRC.Create(32, $04C11DB7, $FFFFFFFF, False, False, $FFFFFFFF,
+        $FC891918, THashLibStringArray.Create('CRC-32/BZIP2', 'CRC-32/AAL5',
+        'CRC-32/DECT-B', 'B-CRC-32'));
+
+    TCRCStandard.CRC32C:
+      result := TCRC.Create(32, $1EDC6F41, $FFFFFFFF, True, True, $FFFFFFFF,
+        $E3069283, THashLibStringArray.Create('CRC-32C', 'CRC-32/ISCSI',
+        'CRC-32/CASTAGNOLI', 'CRC-32/INTERLAKEN'));
+
+    TCRCStandard.CRC32D:
+      result := TCRC.Create(32, $A833982B, $FFFFFFFF, True, True, $FFFFFFFF,
+        $87315576, THashLibStringArray.Create('CRC-32D'));
+
+    TCRCStandard.CRC32_MPEG2:
+      result := TCRC.Create(32, $04C11DB7, $FFFFFFFF, False, False, $00000000,
+        $0376E6E7, THashLibStringArray.Create('CRC-32/MPEG-2'));
+
+    TCRCStandard.CRC32_POSIX:
+      result := TCRC.Create(32, $04C11DB7, $FFFFFFFF, False, False, $00000000,
+        $0376E6E7, THashLibStringArray.Create('CRC-32/POSIX', 'CKSUM'));
+
+    TCRCStandard.CRC32Q:
+      result := TCRC.Create(32, $814141AB, $00000000, False, False, $00000000,
+        $3010BF7F, THashLibStringArray.Create('CRC-32Q'));
+
+    TCRCStandard.JAMCRC:
+      result := TCRC.Create(32, $04C11DB7, $FFFFFFFF, True, True, $00000000,
+        $340BC6D9, THashLibStringArray.Create('JAMCRC'));
+
+    TCRCStandard.XFER:
+      result := TCRC.Create(32, $000000AF, $00000000, False, False, $00000000,
+        $BD0BE338, THashLibStringArray.Create('XFER'));
+
+    TCRCStandard.CRC40_GSM:
+      result := TCRC.Create(40, $0004820009, $0000000000, False, False,
+        $FFFFFFFFFF, $D4164FC646, THashLibStringArray.Create('CRC-40/GSM'));
+
+    TCRCStandard.CRC64:
+      result := TCRC.Create(64, $42F0E1EBA9EA3693, $0000000000000000, False,
+        False, $0000000000000000, $6C40DF5F0B497347,
+        THashLibStringArray.Create('CRC-64', 'CRC-64/ECMA-182'));
+
+    TCRCStandard.CRC64_GOISO:
+      result := TCRC.Create(64, $000000000000001B, UInt64($FFFFFFFFFFFFFFFF), True,
+        True, UInt64($FFFFFFFFFFFFFFFF), UInt64($B90956C775A41001),
+        THashLibStringArray.Create('CRC-64/GO-ISO'));
+
+    TCRCStandard.CRC64_WE:
+      result := TCRC.Create(64, $42F0E1EBA9EA3693, UInt64($FFFFFFFFFFFFFFFF),
+        False, False, UInt64($FFFFFFFFFFFFFFFF), $62EC59E3F1A4F00A,
+        THashLibStringArray.Create('CRC-64/WE'));
+
+    TCRCStandard.CRC64_XZ:
+      result := TCRC.Create(64, $42F0E1EBA9EA3693, UInt64($FFFFFFFFFFFFFFFF),
+        True, True, UInt64($FFFFFFFFFFFFFFFF), UInt64($995DC9BBDF1939FA),
+        THashLibStringArray.Create('CRC-64/XZ', 'CRC-64/GO-ECMA'))
+
+  else
+    raise EArgumentInvalidHashLibException.CreateResFmt(@SUnSupportedCRCType,
+      [GetEnumName(TypeInfo(TCRCStandard), Ord(a_value))]);
+
+  end;
+end;
+
+{$ENDREGION}
+
+procedure TCRC.GenerateTable;
+var
+  bit, crc: UInt64;
+  i, j: Int32;
+begin
+  System.SetLength(Fm_CRCTable, 256);
+  Fptr_Fm_CRCTable := PUInt64(Fm_CRCTable);
+  i := 0;
+  while i < 256 do
+  begin
+    crc := UInt64(i);
+    if (ReflectIn) then
+    begin
+      crc := Reflect(crc, 8);
+    end;
+    crc := crc shl (Width - 8);
+    j := 0;
+    while j < 8 do
+    begin
+
+      bit := crc and Fm_CRCHighBitMask;
+      crc := crc shl 1;
+      if (bit <> 0) then
+        crc := (crc xor Polynomial);
+      System.Inc(j);
+    end;
+
+    if (ReflectIn) then
+    begin
+      crc := Reflect(crc, Width);
+    end;
+    crc := crc and Fm_CRCMask;
+    Fptr_Fm_CRCTable[i] := crc;
+    System.Inc(i);
+  end;
+
+  FIsTableGenerated := True;
+end;
+
+function TCRC.GetCheckValue: UInt64;
+begin
+  result := FCheckValue;
+end;
+
+function TCRC.GetInit: UInt64;
+begin
+  result := FInit;
+end;
+
+function TCRC.GetNames: THashLibStringArray;
+begin
+  result := FNames;
+end;
+
+function TCRC.GetPolynomial: UInt64;
+begin
+  result := FPolynomial;
+end;
+
+function TCRC.GetReflectIn: Boolean;
+begin
+  result := FReflectIn;
+end;
+
+function TCRC.GetReflectOut: Boolean;
+begin
+  result := FReflectOut;
+end;
+
+function TCRC.GetWidth: Int32;
+begin
+  result := FWidth;
+end;
+
+function TCRC.GetXOROut: UInt64;
+begin
+  result := FXorOut;
+end;
+
+procedure TCRC.Initialize;
+begin
+  // initialize some bitmasks
+  Fm_CRCMask := (((UInt64(1) shl (Width - 1)) - 1) shl 1) or 1;
+  Fm_CRCHighBitMask := UInt64(1) shl (Width - 1);
+  Fm_hash := Init;
+
+  if (Width > Delta) then // then use table
+  begin
+
+    if not FIsTableGenerated then
+    begin
+      GenerateTable();
+    end;
+
+    if (ReflectIn) then
+      Fm_hash := Reflect(Fm_hash, Width);
+
+  end;
+
+end;
+
+class function TCRC.Reflect(a_value: UInt64; a_width: Int32): UInt64;
+var
+  j, i: UInt64;
+begin
+  j := 1;
+  result := 0;
+  i := UInt64(1) shl (a_width - 1);
+  while i <> 0 do
+  begin
+
+    if ((a_value and i) <> 0) then
+    begin
+      result := result or j;
+    end;
+    j := j shl 1;
+    i := i shr 1;
+  end;
+end;
+
+procedure TCRC.SetCheckValue(value: UInt64);
+begin
+  FCheckValue := value;
+end;
+
+procedure TCRC.SetInit(value: UInt64);
+begin
+  FInit := value;
+end;
+
+procedure TCRC.SetNames(value: THashLibStringArray);
+begin
+  FNames := value;
+end;
+
+procedure TCRC.SetPolynomial(value: UInt64);
+begin
+  FPolynomial := value;
+end;
+
+procedure TCRC.SetReflectIn(value: Boolean);
+begin
+  FReflectIn := value;
+end;
+
+procedure TCRC.SetReflectOut(value: Boolean);
+begin
+  FReflectOut := value;
+end;
+
+procedure TCRC.SetWidth(value: Int32);
+begin
+  FWidth := value;
+end;
+
+procedure TCRC.SetXOROut(value: UInt64);
+begin
+  FXorOut := value;
+end;
+
+procedure TCRC.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+  ptr_a_data: PByte;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+
+  // table driven CRC reportedly only works for 8, 16, 24, 32 bits
+  // HOWEVER, it seems to work for everything > 7 bits, so use it
+  // accordingly
+
+  i := a_index;
+
+  ptr_a_data := PByte(a_data);
+
+  if (Width > Delta) then
+  begin
+    CalculateCRCbyTable(ptr_a_data, a_length, i);
+  end
+  else
+  begin
+    CalculateCRCdirect(ptr_a_data, a_length, i);
+  end;
+
+end;
+
+function TCRC.TransformFinal: IHashResult;
+var
+  LUInt64: UInt64;
+  LUInt32: UInt32;
+  LUInt16: UInt16;
+  LUInt8: UInt8;
+
+begin
+
+  if Width > Delta then
+  begin
+    if (ReflectIn xor ReflectOut) then
+    begin
+      Fm_hash := Reflect(Fm_hash, Width);
+    end;
+  end
+  else
+  begin
+    if (ReflectOut) then
+    begin
+      Fm_hash := Reflect(Fm_hash, Width);
+    end;
+  end;
+
+  Fm_hash := Fm_hash xor XOROut;
+  Fm_hash := Fm_hash and Fm_CRCMask;
+
+  if Width = 21 then // special case
+  begin
+    LUInt32 := UInt32(Fm_hash);
+
+    result := THashResult.Create(LUInt32);
+
+    Initialize();
+
+    Exit;
+  end;
+
+  case Width shr 3 of
+    0:
+      begin
+        LUInt8 := UInt8(Fm_hash);
+        result := THashResult.Create(LUInt8);
+
+      end;
+
+    1 .. 2:
+      begin
+        LUInt16 := UInt16(Fm_hash);
+
+        result := THashResult.Create(LUInt16);
+      end;
+
+    3 .. 4:
+      begin
+        LUInt32 := UInt32(Fm_hash);
+
+        result := THashResult.Create(LUInt32);
+      end
+  else
+    begin
+      LUInt64 := (Fm_hash);
+
+      result := THashResult.Create(LUInt64);
+    end;
+  end;
+
+  Initialize();
+
+end;
+
+end.

+ 85 - 0
src/libraries/hashlib4pascal/HashLib/src/Checksum/HlpCRC16.pas

@@ -0,0 +1,85 @@
+unit HlpCRC16;
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpICRC,
+  HlpIHashResult,
+  HlpIHashInfo,
+  HlpCRC;
+
+type
+
+  TCRC16Polynomials = class sealed(TObject)
+
+  private
+
+    const
+
+    BUYPASS = UInt16($8005);
+
+  end;
+
+  TCRC16 = class(THash, IChecksum, IBlockHash, IHash16, ITransformBlock)
+
+  strict private
+
+    FCRCAlgorithm: ICRC;
+
+  public
+    constructor Create(_poly, _Init: UInt64; _refIn, _refOut: Boolean;
+      _XorOut, _check: UInt64; _Names: THashLibStringArray);
+
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+
+  end;
+
+  TCRC16_BUYPASS = class sealed(TCRC16)
+
+  public
+    constructor Create();
+
+  end;
+
+implementation
+
+{ TCRC16 }
+
+constructor TCRC16.Create(_poly, _Init: UInt64; _refIn, _refOut: Boolean;
+  _XorOut, _check: UInt64; _Names: THashLibStringArray);
+begin
+  Inherited Create(2, 1);
+  FCRCAlgorithm := TCRC.Create(16, _poly, _Init, _refIn, _refOut, _XorOut,
+    _check, _Names);
+end;
+
+procedure TCRC16.Initialize;
+begin
+  FCRCAlgorithm.Initialize;
+end;
+
+procedure TCRC16.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+begin
+  FCRCAlgorithm.TransformBytes(a_data, a_index, a_length);
+end;
+
+function TCRC16.TransformFinal: IHashResult;
+begin
+  result := FCRCAlgorithm.TransformFinal();
+end;
+
+{ TCRC16_BUYPASS }
+
+constructor TCRC16_BUYPASS.Create;
+begin
+  Inherited Create(TCRC16Polynomials.BUYPASS, $0000, false, false, $0000, $FEE8,
+    THashLibStringArray.Create('CRC-16/BUYPASS', 'CRC-16/VERIFONE'));
+end;
+
+end.

+ 106 - 0
src/libraries/hashlib4pascal/HashLib/src/Checksum/HlpCRC32.pas

@@ -0,0 +1,106 @@
+unit HlpCRC32;
+
+interface
+
+uses
+
+  HlpHashLibTypes,
+  HlpHash,
+  HlpICRC,
+  HlpIHashResult,
+  HlpIHashInfo,
+  HlpCRC;
+
+type
+
+  TCRC32Polynomials = class sealed(TObject)
+
+  private
+
+    const
+
+    PKZIP = UInt32($04C11DB7);
+    Castagnoli = UInt32($1EDC6F41);
+
+  end;
+
+  TCRC32 = class(THash, IChecksum, IBlockHash, IHash32, ITransformBlock)
+
+  strict private
+
+    FCRCAlgorithm: ICRC;
+
+  public
+
+    constructor Create(_poly, _Init: UInt64; _refIn, _refOut: Boolean;
+      _XorOut, _check: UInt64; _Names: THashLibStringArray);
+
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+
+  end;
+
+  TCRC32_PKZIP = class sealed(TCRC32)
+
+  public
+    constructor Create();
+
+  end;
+
+  TCRC32_CASTAGNOLI = class sealed(TCRC32)
+
+  public
+    constructor Create();
+
+  end;
+
+implementation
+
+{ TCRC32 }
+
+constructor TCRC32.Create(_poly, _Init: UInt64; _refIn, _refOut: Boolean;
+  _XorOut, _check: UInt64; _Names: THashLibStringArray);
+begin
+  Inherited Create(4, 1);
+  FCRCAlgorithm := TCRC.Create(32, _poly, _Init, _refIn, _refOut, _XorOut,
+    _check, _Names);
+end;
+
+procedure TCRC32.Initialize;
+begin
+  FCRCAlgorithm.Initialize;
+end;
+
+procedure TCRC32.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+begin
+  FCRCAlgorithm.TransformBytes(a_data, a_index, a_length);
+end;
+
+function TCRC32.TransformFinal: IHashResult;
+begin
+  result := FCRCAlgorithm.TransformFinal();
+end;
+
+{ TCRC32_PKZIP }
+
+constructor TCRC32_PKZIP.Create;
+begin
+  Inherited Create(TCRC32Polynomials.PKZIP, $FFFFFFFF, true, true, $FFFFFFFF,
+    $CBF43926, THashLibStringArray.Create('CRC-32', 'CRC-32/ADCCP', 'PKZIP'));
+
+end;
+
+{ TCRC32_CASTAGNOLI }
+
+constructor TCRC32_CASTAGNOLI.Create;
+begin
+  Inherited Create(TCRC32Polynomials.Castagnoli, $FFFFFFFF, true, true,
+    $FFFFFFFF, $E3069283, THashLibStringArray.Create('CRC-32C', 'CRC-32/ISCSI',
+    'CRC-32/CASTAGNOLI'));
+
+end;
+
+end.

+ 86 - 0
src/libraries/hashlib4pascal/HashLib/src/Checksum/HlpCRC64.pas

@@ -0,0 +1,86 @@
+unit HlpCRC64;
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpICRC,
+  HlpIHashResult,
+  HlpIHashInfo,
+  HlpCRC;
+
+type
+
+  TCRC64Polynomials = class sealed(TObject)
+
+  private
+
+    const
+
+    ECMA_182 = UInt64($42F0E1EBA9EA3693);
+
+  end;
+
+  TCRC64 = class(THash, IChecksum, IBlockHash, IHash64, ITransformBlock)
+
+  strict private
+
+    FCRCAlgorithm: ICRC;
+
+  public
+    constructor Create(_poly, _Init: UInt64; _refIn, _refOut: Boolean;
+      _XorOut, _check: UInt64; _Names: THashLibStringArray);
+
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+
+  end;
+
+  TCRC64_ECMA = class sealed(TCRC64)
+
+  public
+    constructor Create();
+
+  end;
+
+implementation
+
+{ TCRC64 }
+
+constructor TCRC64.Create(_poly, _Init: UInt64; _refIn, _refOut: Boolean;
+  _XorOut, _check: UInt64; _Names: THashLibStringArray);
+begin
+  Inherited Create(8, 1);
+  FCRCAlgorithm := TCRC.Create(64, _poly, _Init, _refIn, _refOut, _XorOut,
+    _check, _Names);
+end;
+
+procedure TCRC64.Initialize;
+begin
+  FCRCAlgorithm.Initialize;
+end;
+
+procedure TCRC64.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+begin
+  FCRCAlgorithm.TransformBytes(a_data, a_index, a_length);
+end;
+
+function TCRC64.TransformFinal: IHashResult;
+begin
+  result := FCRCAlgorithm.TransformFinal();
+end;
+
+{ TCRC64_ECMA }
+
+constructor TCRC64_ECMA.Create;
+begin
+  Inherited Create(TCRC64Polynomials.ECMA_182, $0000000000000000, false, false,
+    $0000000000000000, $6C40DF5F0B497347,
+    THashLibStringArray.Create('CRC-64/ECMA'));
+end;
+
+end.

+ 102 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/Blake2BConfigurations/HlpBlake2BConfig.pas

@@ -0,0 +1,102 @@
+unit HlpBlake2BConfig;
+
+{$I ..\..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpIBlake2BConfig,
+  HlpHashSize,
+  HlpHashLibTypes;
+
+resourcestring
+  SInvalidHashSize =
+    'BLAKE2B HashSize must be restricted to one of the following [20, 32, 48, 64]';
+
+type
+
+  TBlake2BConfig = class sealed(TInterfacedObject, IBlake2BConfig)
+
+  strict private
+
+  var
+
+    FHashSize: Int32;
+    FPersonalisation, FSalt, FKey: THashLibByteArray;
+
+    function GetPersonalisation: THashLibByteArray; inline;
+    procedure SetPersonalisation(value: THashLibByteArray); inline;
+
+    function GetSalt: THashLibByteArray; inline;
+    procedure SetSalt(value: THashLibByteArray); inline;
+
+    function GetKey: THashLibByteArray; inline;
+    procedure SetKey(value: THashLibByteArray); inline;
+
+    function GetHashSize: Int32; inline;
+    procedure SetHashSize(value: Int32); inline;
+
+  public
+    constructor Create(AHashSize: THashSize = THashSize.hsHashSize512);
+    property Personalisation: THashLibByteArray read GetPersonalisation
+      write SetPersonalisation;
+    property Salt: THashLibByteArray read GetSalt write SetSalt;
+    property Key: THashLibByteArray read GetKey write SetKey;
+    property HashSize: Int32 read GetHashSize write SetHashSize;
+
+  end;
+
+implementation
+
+{ TBlake2BConfig }
+
+constructor TBlake2BConfig.Create(AHashSize: THashSize);
+begin
+  if not (Int32(AHashSize) in [20, 32, 48, 64]) then
+  begin
+    raise EArgumentHashLibException.CreateRes(@SInvalidHashSize);
+  end;
+  HashSize := Int32(AHashSize);
+end;
+
+function TBlake2BConfig.GetHashSize: Int32;
+begin
+  result := FHashSize;
+end;
+
+function TBlake2BConfig.GetKey: THashLibByteArray;
+begin
+  result := FKey;
+end;
+
+function TBlake2BConfig.GetPersonalisation: THashLibByteArray;
+begin
+  result := FPersonalisation;
+end;
+
+function TBlake2BConfig.GetSalt: THashLibByteArray;
+begin
+  result := FSalt;
+end;
+
+procedure TBlake2BConfig.SetHashSize(value: Int32);
+begin
+  FHashSize := value;
+end;
+
+procedure TBlake2BConfig.SetKey(value: THashLibByteArray);
+begin
+  FKey := value;
+end;
+
+procedure TBlake2BConfig.SetPersonalisation(value: THashLibByteArray);
+begin
+  FPersonalisation := value;
+end;
+
+procedure TBlake2BConfig.SetSalt(value: THashLibByteArray);
+begin
+  FSalt := value;
+end;
+
+end.

+ 139 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/Blake2BConfigurations/HlpBlake2BIvBuilder.pas

@@ -0,0 +1,139 @@
+unit HlpBlake2BIvBuilder;
+
+{$I ..\..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpConverters,
+  HlpBlake2BTreeConfig,
+  HlpIBlake2BConfig,
+  HlpIBlake2BTreeConfig,
+  HlpHashLibTypes;
+
+resourcestring
+  SInvalidHashSize =
+    '"HashSize" Must Be Greater Than 0 And Less Than or Equal To 64';
+  SInvalidKeyLength = '"Key" Length Must Not Be Greater Than 64';
+  SInvalidPersonalisationLength =
+    '"Personalisation" Length Must Be Equal To 16';
+  SInvalidSaltLength = '"Salt" Length Must Be Equal To 16';
+
+type
+  TBlake2BIvBuilder = class sealed(TObject)
+
+  strict private
+    class var
+
+      FSequentialTreeConfig: IBlake2BTreeConfig;
+
+    class constructor Blake2BIvBuilder();
+
+  public
+    class function ConfigB(config: IBlake2BConfig;
+      treeConfig: IBlake2BTreeConfig): THashLibUInt64Array; static;
+
+    class procedure ConfigBSetNode(rawConfig: THashLibUInt64Array; depth: Byte;
+      nodeOffset: UInt64); static; inline;
+
+  end;
+
+implementation
+
+{ TBlake2BIvBuilder }
+
+class constructor TBlake2BIvBuilder.Blake2BIvBuilder;
+begin
+  FSequentialTreeConfig := TBlake2BTreeConfig.Create();
+  FSequentialTreeConfig.IntermediateHashSize := 0;
+  FSequentialTreeConfig.LeafSize := 0;
+  FSequentialTreeConfig.FanOut := 1;
+  FSequentialTreeConfig.MaxHeight := 1;
+end;
+
+class function TBlake2BIvBuilder.ConfigB(config: IBlake2BConfig;
+  treeConfig: IBlake2BTreeConfig): THashLibUInt64Array;
+var
+  isSequential: Boolean;
+  rawConfig: THashLibUInt64Array;
+begin
+  isSequential := treeConfig = Nil;
+  if (isSequential) then
+  begin
+    treeConfig := FSequentialTreeConfig;
+  end;
+  System.SetLength(rawConfig, 8);
+
+  // digest length
+  if ((config.HashSize <= 0) or (config.HashSize > 64)) then
+  begin
+    raise EArgumentOutOfRangeHashLibException.CreateRes(@SInvalidHashSize);
+  end;
+
+  rawConfig[0] := rawConfig[0] or (UInt64(UInt32(config.HashSize)));
+
+  // Key length
+  if (config.Key <> Nil) then
+  begin
+    if (System.Length(config.Key) > 64) then
+    begin
+      raise EArgumentOutOfRangeHashLibException.CreateRes(@SInvalidKeyLength);
+    end;
+    rawConfig[0] := rawConfig[0] or
+      UInt64(UInt32(System.Length(config.Key)) shl 8);
+  end;
+
+  // FanOut
+  rawConfig[0] := rawConfig[0] or (UInt32(treeConfig.FanOut) shl 16);
+  // Depth
+  rawConfig[0] := rawConfig[0] or (UInt32(treeConfig.MaxHeight) shl 24);
+  // Leaf length
+  rawConfig[0] := rawConfig[0] or
+    ((UInt64(UInt32(treeConfig.LeafSize))) shl 32);
+
+  // Inner length
+  if ((not isSequential) and ((treeConfig.IntermediateHashSize <= 0) or
+    (treeConfig.IntermediateHashSize > 64))) then
+  begin
+    raise EArgumentOutOfRangeHashLibException.Create
+      ('treeConfig.TreeIntermediateHashSize');
+  end;
+  rawConfig[2] := rawConfig[2] or
+    (UInt32(treeConfig.IntermediateHashSize) shl 8);
+
+  // Salt
+  if (config.Salt <> Nil) then
+  begin
+    if (System.Length(config.Salt) <> 16) then
+    begin
+      raise EArgumentOutOfRangeHashLibException.CreateRes(@SInvalidSaltLength);
+    end;
+    rawConfig[4] := TConverters.ReadBytesAsUInt64LE(PByte(config.Salt), 0);
+    rawConfig[5] := TConverters.ReadBytesAsUInt64LE(PByte(config.Salt), 8);
+  end;
+
+  // Personalisation
+  if (config.Personalisation <> Nil) then
+  begin
+    if (System.Length(config.Personalisation) <> 16) then
+    begin
+      raise EArgumentOutOfRangeHashLibException.CreateRes
+        (@SInvalidPersonalisationLength);
+    end;
+    rawConfig[6] := TConverters.ReadBytesAsUInt64LE
+      (PByte(config.Personalisation), 0);
+    rawConfig[7] := TConverters.ReadBytesAsUInt64LE
+      (PByte(config.Personalisation), 8);
+  end;
+
+  result := rawConfig;
+end;
+
+class procedure TBlake2BIvBuilder.ConfigBSetNode(rawConfig: THashLibUInt64Array;
+  depth: Byte; nodeOffset: UInt64);
+begin
+  rawConfig[1] := nodeOffset;
+  rawConfig[2] := (rawConfig[2] and (not UInt64($FF))) or depth;
+end;
+
+end.

+ 100 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/Blake2BConfigurations/HlpBlake2BTreeConfig.pas

@@ -0,0 +1,100 @@
+unit HlpBlake2BTreeConfig;
+
+{$I ..\..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpIBlake2BTreeConfig;
+
+type
+
+  TBlake2BTreeConfig = class sealed(TInterfacedObject, IBlake2BTreeConfig)
+
+  strict private
+
+    FIntermediateHashSize, FMaxHeight, FFanOut: Int32;
+    FLeafSize: Int64;
+
+    function GetIntermediateHashSize: Int32; inline;
+    procedure SetIntermediateHashSize(value: Int32); inline;
+    function GetMaxHeight: Int32; inline;
+    procedure SetMaxHeight(value: Int32); inline;
+    function GetLeafSize: Int64; inline;
+    procedure SetLeafSize(value: Int64); inline;
+    function GetFanOut: Int32; inline;
+    procedure SetFanOut(value: Int32); inline;
+
+  public
+    constructor Create();
+    property IntermediateHashSize: Int32 read GetIntermediateHashSize
+      write SetIntermediateHashSize;
+    property MaxHeight: Int32 read GetMaxHeight write SetMaxHeight;
+
+    property LeafSize: Int64 read GetLeafSize write SetLeafSize;
+    property FanOut: Int32 read GetFanOut write SetFanOut;
+
+    class function CreateInterleaved(parallelism: Int32)
+      : IBlake2BTreeConfig; static;
+
+  end;
+
+implementation
+
+{ TBlake2BTreeConfig }
+
+constructor TBlake2BTreeConfig.Create;
+begin
+  IntermediateHashSize := 64;
+end;
+
+class function TBlake2BTreeConfig.CreateInterleaved(parallelism: Int32)
+  : IBlake2BTreeConfig;
+begin
+  result := TBlake2BTreeConfig.Create();
+  result.FanOut := parallelism;
+  result.MaxHeight := 2;
+  result.IntermediateHashSize := 64;
+end;
+
+function TBlake2BTreeConfig.GetFanOut: Int32;
+begin
+  result := FFanOut;
+end;
+
+function TBlake2BTreeConfig.GetIntermediateHashSize: Int32;
+begin
+  result := FIntermediateHashSize;
+end;
+
+function TBlake2BTreeConfig.GetLeafSize: Int64;
+begin
+  result := FLeafSize;
+end;
+
+function TBlake2BTreeConfig.GetMaxHeight: Int32;
+begin
+  result := FMaxHeight;
+end;
+
+procedure TBlake2BTreeConfig.SetFanOut(value: Int32);
+begin
+  FFanOut := value;
+end;
+
+procedure TBlake2BTreeConfig.SetIntermediateHashSize(value: Int32);
+begin
+  FIntermediateHashSize := value;
+end;
+
+procedure TBlake2BTreeConfig.SetLeafSize(value: Int64);
+begin
+  FLeafSize := value;
+end;
+
+procedure TBlake2BTreeConfig.SetMaxHeight(value: Int32);
+begin
+  FMaxHeight := value;
+end;
+
+end.

+ 102 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/Blake2SConfigurations/HlpBlake2SConfig.pas

@@ -0,0 +1,102 @@
+unit HlpBlake2SConfig;
+
+{$I ..\..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpIBlake2SConfig,
+  HlpHashSize,
+  HlpHashLibTypes;
+
+resourcestring
+  SInvalidHashSize =
+    'BLAKE2S HashSize must be restricted to one of the following [16, 20, 28, 32]';
+
+type
+
+  TBlake2SConfig = class sealed(TInterfacedObject, IBlake2SConfig)
+
+  strict private
+
+  var
+
+    FHashSize: Int32;
+    FPersonalisation, FSalt, FKey: THashLibByteArray;
+
+    function GetPersonalisation: THashLibByteArray; inline;
+    procedure SetPersonalisation(value: THashLibByteArray); inline;
+
+    function GetSalt: THashLibByteArray; inline;
+    procedure SetSalt(value: THashLibByteArray); inline;
+
+    function GetKey: THashLibByteArray; inline;
+    procedure SetKey(value: THashLibByteArray); inline;
+
+    function GetHashSize: Int32; inline;
+    procedure SetHashSize(value: Int32); inline;
+
+  public
+    constructor Create(AHashSize: THashSize = THashSize.hsHashSize256);
+    property Personalisation: THashLibByteArray read GetPersonalisation
+      write SetPersonalisation;
+    property Salt: THashLibByteArray read GetSalt write SetSalt;
+    property Key: THashLibByteArray read GetKey write SetKey;
+    property HashSize: Int32 read GetHashSize write SetHashSize;
+
+  end;
+
+implementation
+
+{ TBlake2SConfig }
+
+constructor TBlake2SConfig.Create(AHashSize: THashSize);
+begin
+  if not (Int32(AHashSize) in [16, 20, 28, 32]) then
+  begin
+    raise EArgumentHashLibException.CreateRes(@SInvalidHashSize);
+  end;
+  HashSize := Int32(AHashSize);
+end;
+
+function TBlake2SConfig.GetHashSize: Int32;
+begin
+  result := FHashSize;
+end;
+
+function TBlake2SConfig.GetKey: THashLibByteArray;
+begin
+  result := FKey;
+end;
+
+function TBlake2SConfig.GetPersonalisation: THashLibByteArray;
+begin
+  result := FPersonalisation;
+end;
+
+function TBlake2SConfig.GetSalt: THashLibByteArray;
+begin
+  result := FSalt;
+end;
+
+procedure TBlake2SConfig.SetHashSize(value: Int32);
+begin
+  FHashSize := value;
+end;
+
+procedure TBlake2SConfig.SetKey(value: THashLibByteArray);
+begin
+  FKey := value;
+end;
+
+procedure TBlake2SConfig.SetPersonalisation(value: THashLibByteArray);
+begin
+  FPersonalisation := value;
+end;
+
+procedure TBlake2SConfig.SetSalt(value: THashLibByteArray);
+begin
+  FSalt := value;
+end;
+
+end.

+ 137 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/Blake2SConfigurations/HlpBlake2SIvBuilder.pas

@@ -0,0 +1,137 @@
+unit HlpBlake2SIvBuilder;
+
+{$I ..\..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpConverters,
+  HlpBlake2STreeConfig,
+  HlpIBlake2SConfig,
+  HlpIBlake2STreeConfig,
+  HlpHashLibTypes;
+
+resourcestring
+  SInvalidHashSize =
+    '"HashSize" Must Be Greater Than 0 And Less Than or Equal To 32';
+  SInvalidKeyLength = '"Key" Length Must Not Be Greater Than 32';
+  SInvalidPersonalisationLength = '"Personalisation" Length Must Be Equal To 8';
+  SInvalidSaltLength = '"Salt" Length Must Be Equal To 8';
+
+type
+  TBlake2SIvBuilder = class sealed(TObject)
+
+  strict private
+    class var
+
+      FSequentialTreeConfig: IBlake2STreeConfig;
+
+    class constructor Blake2SIvBuilder();
+
+  public
+    class function ConfigS(config: IBlake2SConfig;
+      treeConfig: IBlake2STreeConfig): THashLibUInt32Array; static;
+
+    // class procedure ConfigSSetNode(rawConfig: THashLibUInt32Array; depth: Byte;
+    // nodeOffset: UInt32); static; inline;
+
+  end;
+
+implementation
+
+{ TBlake2SIvBuilder }
+
+class constructor TBlake2SIvBuilder.Blake2SIvBuilder;
+begin
+  FSequentialTreeConfig := TBlake2STreeConfig.Create();
+  FSequentialTreeConfig.IntermediateHashSize := 0;
+  FSequentialTreeConfig.LeafSize := 0;
+  FSequentialTreeConfig.FanOut := 1;
+  FSequentialTreeConfig.MaxHeight := 1;
+end;
+
+class function TBlake2SIvBuilder.ConfigS(config: IBlake2SConfig;
+  treeConfig: IBlake2STreeConfig): THashLibUInt32Array;
+var
+  isSequential: Boolean;
+  rawConfig: THashLibUInt32Array;
+begin
+  isSequential := treeConfig = Nil;
+  if (isSequential) then
+  begin
+    treeConfig := FSequentialTreeConfig;
+  end;
+  System.SetLength(rawConfig, 8);
+
+  // digest length
+  if ((config.HashSize <= 0) or (config.HashSize > 32)) then
+  begin
+    raise EArgumentOutOfRangeHashLibException.CreateRes(@SInvalidHashSize);
+  end;
+
+  rawConfig[0] := rawConfig[0] or (UInt32(config.HashSize));
+
+  // Key length
+  if (config.Key <> Nil) then
+  begin
+    if (System.Length(config.Key) > 32) then
+    begin
+      raise EArgumentOutOfRangeHashLibException.CreateRes(@SInvalidKeyLength);
+    end;
+    rawConfig[0] := rawConfig[0] or UInt32(System.Length(config.Key)) shl 8;
+  end;
+
+  // FanOut
+  rawConfig[0] := rawConfig[0] or (UInt32(treeConfig.FanOut) shl 16);
+  // Depth
+  rawConfig[0] := rawConfig[0] or (UInt32(treeConfig.MaxHeight) shl 24);
+  // Leaf length
+  rawConfig[0] := rawConfig[0] or
+    ((UInt64(UInt32(treeConfig.LeafSize))) shl 32);
+
+  // Inner length
+  if ((not isSequential) and ((treeConfig.IntermediateHashSize <= 0) or
+    (treeConfig.IntermediateHashSize > 32))) then
+  begin
+    raise EArgumentOutOfRangeHashLibException.Create
+      ('treeConfig.TreeIntermediateHashSize');
+  end;
+  rawConfig[2] := rawConfig[2] or
+    (UInt32(treeConfig.IntermediateHashSize) shl 8);
+
+  // Salt
+  if (config.Salt <> Nil) then
+  begin
+    if (System.Length(config.Salt) <> 8) then
+    begin
+      raise EArgumentOutOfRangeHashLibException.CreateRes(@SInvalidSaltLength);
+    end;
+    rawConfig[4] := TConverters.ReadBytesAsUInt32LE(PByte(config.Salt), 0);
+    rawConfig[5] := TConverters.ReadBytesAsUInt32LE(PByte(config.Salt), 4);
+  end;
+
+  // Personalisation
+  if (config.Personalisation <> Nil) then
+  begin
+    if (System.Length(config.Personalisation) <> 8) then
+    begin
+      raise EArgumentOutOfRangeHashLibException.CreateRes
+        (@SInvalidPersonalisationLength);
+    end;
+    rawConfig[6] := TConverters.ReadBytesAsUInt32LE
+      (PByte(config.Personalisation), 0);
+    rawConfig[7] := TConverters.ReadBytesAsUInt32LE
+      (PByte(config.Personalisation), 4);
+  end;
+
+  result := rawConfig;
+end;
+
+// class procedure TBlake2SIvBuilder.ConfigSSetNode(rawConfig: THashLibUInt32Array;
+// depth: Byte; nodeOffset: UInt32);
+// begin
+// rawConfig[1] := nodeOffset;
+// rawConfig[2] := (rawConfig[2] and (not UInt32($FF))) or depth;
+// end;
+
+end.

+ 100 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/Blake2SConfigurations/HlpBlake2STreeConfig.pas

@@ -0,0 +1,100 @@
+unit HlpBlake2STreeConfig;
+
+{$I ..\..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpIBlake2STreeConfig;
+
+type
+
+  TBlake2STreeConfig = class sealed(TInterfacedObject, IBlake2STreeConfig)
+
+  strict private
+
+    FIntermediateHashSize, FMaxHeight, FFanOut: Int32;
+    FLeafSize: Int64;
+
+    function GetIntermediateHashSize: Int32; inline;
+    procedure SetIntermediateHashSize(value: Int32); inline;
+    function GetMaxHeight: Int32; inline;
+    procedure SetMaxHeight(value: Int32); inline;
+    function GetLeafSize: Int64; inline;
+    procedure SetLeafSize(value: Int64); inline;
+    function GetFanOut: Int32; inline;
+    procedure SetFanOut(value: Int32); inline;
+
+  public
+    constructor Create();
+    property IntermediateHashSize: Int32 read GetIntermediateHashSize
+      write SetIntermediateHashSize;
+    property MaxHeight: Int32 read GetMaxHeight write SetMaxHeight;
+
+    property LeafSize: Int64 read GetLeafSize write SetLeafSize;
+    property FanOut: Int32 read GetFanOut write SetFanOut;
+
+    class function CreateInterleaved(parallelism: Int32)
+      : IBlake2STreeConfig; static;
+
+  end;
+
+implementation
+
+{ TBlake2STreeConfig }
+
+constructor TBlake2STreeConfig.Create;
+begin
+  IntermediateHashSize := 32;
+end;
+
+class function TBlake2STreeConfig.CreateInterleaved(parallelism: Int32)
+  : IBlake2STreeConfig;
+begin
+  result := TBlake2STreeConfig.Create();
+  result.FanOut := parallelism;
+  result.MaxHeight := 2;
+  result.IntermediateHashSize := 32;
+end;
+
+function TBlake2STreeConfig.GetFanOut: Int32;
+begin
+  result := FFanOut;
+end;
+
+function TBlake2STreeConfig.GetIntermediateHashSize: Int32;
+begin
+  result := FIntermediateHashSize;
+end;
+
+function TBlake2STreeConfig.GetLeafSize: Int64;
+begin
+  result := FLeafSize;
+end;
+
+function TBlake2STreeConfig.GetMaxHeight: Int32;
+begin
+  result := FMaxHeight;
+end;
+
+procedure TBlake2STreeConfig.SetFanOut(value: Int32);
+begin
+  FFanOut := value;
+end;
+
+procedure TBlake2STreeConfig.SetIntermediateHashSize(value: Int32);
+begin
+  FIntermediateHashSize := value;
+end;
+
+procedure TBlake2STreeConfig.SetLeafSize(value: Int64);
+begin
+  FLeafSize := value;
+end;
+
+procedure TBlake2STreeConfig.SetMaxHeight(value: Int32);
+begin
+  FMaxHeight := value;
+end;
+
+end.

+ 1756 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpBlake2B.pas

@@ -0,0 +1,1756 @@
+unit HlpBlake2B;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF HAS_UNITSCOPE}
+  System.SysUtils,
+{$ELSE}
+  SysUtils,
+{$ENDIF HAS_UNITSCOPE}
+{$IFDEF DELPHI}
+  HlpBitConverter,
+  HlpHashBuffer,
+{$ENDIF DELPHI}
+  HlpBits,
+  HlpHash,
+  HlpHashResult,
+  HlpIHashResult,
+  HlpIBlake2BConfig,
+  HlpBlake2BConfig,
+  HlpBlake2BIvBuilder,
+  HlpIHashInfo,
+  HlpConverters,
+  HlpHashLibTypes;
+
+resourcestring
+  SInvalidConfigLength = 'Config Length Must Be 8 Words';
+
+type
+  TBlake2B = class sealed(THash, ICryptoNotBuildIn, ITransformBlock)
+  strict private
+
+{$REGION 'Consts'}
+  const
+
+{$IFNDEF USE_UNROLLED_VARIANT}
+    NumberOfRounds = Int32(12);
+{$ENDIF USE_UNROLLED_VARIANT}
+    BlockSizeInBytes = Int32(128);
+
+    IV0 = UInt64($6A09E667F3BCC908);
+    IV1 = UInt64($BB67AE8584CAA73B);
+    IV2 = UInt64($3C6EF372FE94F82B);
+    IV3 = UInt64($A54FF53A5F1D36F1);
+    IV4 = UInt64($510E527FADE682D1);
+    IV5 = UInt64($9B05688C2B3E6C1F);
+    IV6 = UInt64($1F83D9ABFB41BD6B);
+    IV7 = UInt64($5BE0CD19137E2179);
+
+{$IFNDEF USE_UNROLLED_VARIANT}
+    Sigma: array [0 .. ((NumberOfRounds * 16) - 1)] of Int32 = (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);
+{$ENDIF USE_UNROLLED_VARIANT}
+{$ENDREGION}
+    class var
+
+      FDefaultConfig: IBlake2BConfig;
+
+  var
+    FrawConfig, Fm_state: THashLibUInt64Array;
+    FKey, F_buf: THashLibByteArray;
+    F_m: array [0 .. 15] of UInt64;
+{$IFNDEF USE_UNROLLED_VARIANT}
+    F_v: array [0 .. 15] of UInt64;
+{$ENDIF USE_UNROLLED_VARIANT}
+    F_bufferFilled: Int32;
+
+    F_counter0, F_counter1, F_finalizationFlag0, F_finalizationFlag1: UInt64;
+
+    class constructor Blake2BConfig();
+
+{$IFNDEF USE_UNROLLED_VARIANT}
+    procedure G(a, b, c, d, r, i: Int32); inline;
+{$ENDIF USE_UNROLLED_VARIANT}
+    procedure Compress(block: PByte; start: Int32); inline;
+
+    procedure Finish(); inline;
+
+  strict protected
+
+    FHashSize, FBlockSize: Int32;
+    function GetName: String; override;
+
+  public
+    constructor Create(); overload;
+    constructor Create(config: IBlake2BConfig); overload;
+    procedure Initialize; override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_data_length: Int32); override;
+    function TransformFinal: IHashResult; override;
+
+  end;
+
+implementation
+
+{ TBlake2B }
+
+class constructor TBlake2B.Blake2BConfig;
+begin
+  FDefaultConfig := TBlake2BConfig.Create();
+end;
+
+constructor TBlake2B.Create();
+begin
+  Create(TBlake2BConfig.Create());
+end;
+
+{$IFNDEF USE_UNROLLED_VARIANT}
+
+procedure TBlake2B.G(a, b, c, d, r, i: Int32);
+var
+  p, p0, p1: Int32;
+begin
+  p := (r shl 4) + i;
+  p0 := Sigma[p];
+  p1 := Sigma[p + 1];
+
+  F_v[a] := F_v[a] + (F_v[b] + F_m[p0]);
+  F_v[d] := TBits.RotateRight64(F_v[d] xor F_v[a], 32);
+  F_v[c] := F_v[c] + F_v[d];
+  F_v[b] := TBits.RotateRight64(F_v[b] xor F_v[c], 24);
+  F_v[a] := F_v[a] + (F_v[b] + F_m[p1]);
+  F_v[d] := TBits.RotateRight64(F_v[d] xor F_v[a], 16);
+  F_v[c] := F_v[c] + F_v[d];
+  F_v[b] := TBits.RotateRight64(F_v[b] xor F_v[c], 63);
+end;
+
+{$ENDIF USE_UNROLLED_VARIANT}
+
+procedure TBlake2B.Compress(block: PByte; start: Int32);
+var
+{$IFDEF USE_UNROLLED_VARIANT}
+  m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, v0, v1,
+    v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15: UInt64;
+
+{$ELSE}
+  i, r: Int32;
+
+{$ENDIF USE_UNROLLED_VARIANT}
+begin
+  TConverters.le64_copy(block, start, @(F_m[0]), 0, FBlockSize);
+
+{$IFDEF USE_UNROLLED_VARIANT}
+  m0 := F_m[0];
+  m1 := F_m[1];
+  m2 := F_m[2];
+  m3 := F_m[3];
+  m4 := F_m[4];
+  m5 := F_m[5];
+  m6 := F_m[6];
+  m7 := F_m[7];
+  m8 := F_m[8];
+  m9 := F_m[9];
+  m10 := F_m[10];
+  m11 := F_m[11];
+  m12 := F_m[12];
+  m13 := F_m[13];
+  m14 := F_m[14];
+  m15 := F_m[15];
+
+  v0 := Fm_state[0];
+  v1 := Fm_state[1];
+  v2 := Fm_state[2];
+  v3 := Fm_state[3];
+  v4 := Fm_state[4];
+  v5 := Fm_state[5];
+  v6 := Fm_state[6];
+  v7 := Fm_state[7];
+
+  v8 := IV0;
+  v9 := IV1;
+  v10 := IV2;
+  v11 := IV3;
+  v12 := IV4 xor F_counter0;
+  v13 := IV5 xor F_counter1;
+  v14 := IV6 xor F_finalizationFlag0;
+  v15 := IV7 xor F_finalizationFlag1;
+
+  // Rounds
+
+  // ##### Round(0)
+  // G(0, 0, v0, v4, v8, v12)
+  v0 := v0 + v4 + m0;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 32);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 24);
+  v0 := v0 + v4 + m1;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // G(0, 1, v1, v5, v9, v13)
+  v1 := v1 + v5 + m2;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 32);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 24);
+  v1 := v1 + v5 + m3;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(0, 2, v2, v6, v10, v14)
+  v2 := v2 + v6 + m4;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 32);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 24);
+  v2 := v2 + v6 + m5;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(0, 3, v3, v7, v11, v15)
+  v3 := v3 + v7 + m6;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 32);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 24);
+  v3 := v3 + v7 + m7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(0, 4, v0, v5, v10, v15)
+  v0 := v0 + v5 + m8;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 32);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 24);
+  v0 := v0 + v5 + m9;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(0, 5, v1, v6, v11, v12)
+  v1 := v1 + v6 + m10;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 32);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 24);
+  v1 := v1 + v6 + m11;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(0, 6, v2, v7, v8, v13)
+  v2 := v2 + v7 + m12;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 32);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 24);
+  v2 := v2 + v7 + m13;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(0, 7, v3, v4, v9, v14)
+  v3 := v3 + v4 + m14;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 32);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 24);
+  v3 := v3 + v4 + m15;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // ##### Round(1)
+  // G(1, 0, v0, v4, v8, v12)
+  v0 := v0 + v4 + m14;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 32);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 24);
+  v0 := v0 + v4 + m10;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // G(1, 1, v1, v5, v9, v13)
+  v1 := v1 + v5 + m4;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 32);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 24);
+  v1 := v1 + v5 + m8;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(1, 2, v2, v6, v10, v14)
+  v2 := v2 + v6 + m9;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 32);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 24);
+  v2 := v2 + v6 + m15;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(1, 3, v3, v7, v11, v15)
+  v3 := v3 + v7 + m13;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 32);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 24);
+  v3 := v3 + v7 + m6;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(1, 4, v0, v5, v10, v15)
+  v0 := v0 + v5 + m1;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 32);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 24);
+  v0 := v0 + v5 + m12;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(1, 5, v1, v6, v11, v12)
+  v1 := v1 + v6 + m0;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 32);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 24);
+  v1 := v1 + v6 + m2;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(1, 6, v2, v7, v8, v13)
+  v2 := v2 + v7 + m11;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 32);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 24);
+  v2 := v2 + v7 + m7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(1, 7, v3, v4, v9, v14)
+  v3 := v3 + v4 + m5;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 32);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 24);
+  v3 := v3 + v4 + m3;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // ##### Round(2)
+  // G(2, 0, v0, v4, v8, v12)
+  v0 := v0 + v4 + m11;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 32);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 24);
+  v0 := v0 + v4 + m8;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // G(2, 1, v1, v5, v9, v13)
+  v1 := v1 + v5 + m12;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 32);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 24);
+  v1 := v1 + v5 + m0;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(2, 2, v2, v6, v10, v14)
+  v2 := v2 + v6 + m5;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 32);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 24);
+  v2 := v2 + v6 + m2;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(2, 3, v3, v7, v11, v15)
+  v3 := v3 + v7 + m15;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 32);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 24);
+  v3 := v3 + v7 + m13;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(2, 4, v0, v5, v10, v15)
+  v0 := v0 + v5 + m10;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 32);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 24);
+  v0 := v0 + v5 + m14;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(2, 5, v1, v6, v11, v12)
+  v1 := v1 + v6 + m3;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 32);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 24);
+  v1 := v1 + v6 + m6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(2, 6, v2, v7, v8, v13)
+  v2 := v2 + v7 + m7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 32);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 24);
+  v2 := v2 + v7 + m1;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(2, 7, v3, v4, v9, v14)
+  v3 := v3 + v4 + m9;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 32);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 24);
+  v3 := v3 + v4 + m4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // ##### Round(3)
+  // G(3, 0, v0, v4, v8, v12)
+  v0 := v0 + v4 + m7;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 32);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 24);
+  v0 := v0 + v4 + m9;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // G(3, 1, v1, v5, v9, v13)
+  v1 := v1 + v5 + m3;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 32);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 24);
+  v1 := v1 + v5 + m1;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(3, 2, v2, v6, v10, v14)
+  v2 := v2 + v6 + m13;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 32);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 24);
+  v2 := v2 + v6 + m12;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(3, 3, v3, v7, v11, v15)
+  v3 := v3 + v7 + m11;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 32);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 24);
+  v3 := v3 + v7 + m14;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(3, 4, v0, v5, v10, v15)
+  v0 := v0 + v5 + m2;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 32);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 24);
+  v0 := v0 + v5 + m6;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(3, 5, v1, v6, v11, v12)
+  v1 := v1 + v6 + m5;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 32);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 24);
+  v1 := v1 + v6 + m10;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(3, 6, v2, v7, v8, v13)
+  v2 := v2 + v7 + m4;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 32);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 24);
+  v2 := v2 + v7 + m0;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(3, 7, v3, v4, v9, v14)
+  v3 := v3 + v4 + m15;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 32);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 24);
+  v3 := v3 + v4 + m8;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // ##### Round(4)
+  // G(4, 0, v0, v4, v8, v12)
+  v0 := v0 + v4 + m9;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 32);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 24);
+  v0 := v0 + v4 + m0;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // G(4, 1, v1, v5, v9, v13)
+  v1 := v1 + v5 + m5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 32);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 24);
+  v1 := v1 + v5 + m7;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(4, 2, v2, v6, v10, v14)
+  v2 := v2 + v6 + m2;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 32);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 24);
+  v2 := v2 + v6 + m4;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(4, 3, v3, v7, v11, v15)
+  v3 := v3 + v7 + m10;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 32);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 24);
+  v3 := v3 + v7 + m15;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(4, 4, v0, v5, v10, v15)
+  v0 := v0 + v5 + m14;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 32);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 24);
+  v0 := v0 + v5 + m1;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(4, 5, v1, v6, v11, v12)
+  v1 := v1 + v6 + m11;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 32);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 24);
+  v1 := v1 + v6 + m12;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(4, 6, v2, v7, v8, v13)
+  v2 := v2 + v7 + m6;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 32);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 24);
+  v2 := v2 + v7 + m8;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(4, 7, v3, v4, v9, v14)
+  v3 := v3 + v4 + m3;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 32);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 24);
+  v3 := v3 + v4 + m13;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // ##### Round(5)
+  // G(5, 0, v0, v4, v8, v12)
+  v0 := v0 + v4 + m2;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 32);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 24);
+  v0 := v0 + v4 + m12;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // G(5, 1, v1, v5, v9, v13)
+  v1 := v1 + v5 + m6;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 32);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 24);
+  v1 := v1 + v5 + m10;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(5, 2, v2, v6, v10, v14)
+  v2 := v2 + v6 + m0;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 32);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 24);
+  v2 := v2 + v6 + m11;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(5, 3, v3, v7, v11, v15)
+  v3 := v3 + v7 + m8;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 32);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 24);
+  v3 := v3 + v7 + m3;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(5, 4, v0, v5, v10, v15)
+  v0 := v0 + v5 + m4;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 32);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 24);
+  v0 := v0 + v5 + m13;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(5, 5, v1, v6, v11, v12)
+  v1 := v1 + v6 + m7;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 32);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 24);
+  v1 := v1 + v6 + m5;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(5, 6, v2, v7, v8, v13)
+  v2 := v2 + v7 + m15;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 32);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 24);
+  v2 := v2 + v7 + m14;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(5, 7, v3, v4, v9, v14)
+  v3 := v3 + v4 + m1;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 32);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 24);
+  v3 := v3 + v4 + m9;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // ##### Round(6)
+  // G(6, 0, v0, v4, v8, v12)
+  v0 := v0 + v4 + m12;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 32);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 24);
+  v0 := v0 + v4 + m5;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // G(6, 1, v1, v5, v9, v13)
+  v1 := v1 + v5 + m1;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 32);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 24);
+  v1 := v1 + v5 + m15;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(6, 2, v2, v6, v10, v14)
+  v2 := v2 + v6 + m14;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 32);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 24);
+  v2 := v2 + v6 + m13;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(6, 3, v3, v7, v11, v15)
+  v3 := v3 + v7 + m4;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 32);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 24);
+  v3 := v3 + v7 + m10;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(6, 4, v0, v5, v10, v15)
+  v0 := v0 + v5 + m0;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 32);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 24);
+  v0 := v0 + v5 + m7;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(6, 5, v1, v6, v11, v12)
+  v1 := v1 + v6 + m6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 32);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 24);
+  v1 := v1 + v6 + m3;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(6, 6, v2, v7, v8, v13)
+  v2 := v2 + v7 + m9;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 32);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 24);
+  v2 := v2 + v7 + m2;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(6, 7, v3, v4, v9, v14)
+  v3 := v3 + v4 + m8;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 32);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 24);
+  v3 := v3 + v4 + m11;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // ##### Round(7)
+  // G(7, 0, v0, v4, v8, v12)
+  v0 := v0 + v4 + m13;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 32);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 24);
+  v0 := v0 + v4 + m11;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // G(7, 1, v1, v5, v9, v13)
+  v1 := v1 + v5 + m7;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 32);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 24);
+  v1 := v1 + v5 + m14;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(7, 2, v2, v6, v10, v14)
+  v2 := v2 + v6 + m12;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 32);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 24);
+  v2 := v2 + v6 + m1;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(7, 3, v3, v7, v11, v15)
+  v3 := v3 + v7 + m3;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 32);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 24);
+  v3 := v3 + v7 + m9;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(7, 4, v0, v5, v10, v15)
+  v0 := v0 + v5 + m5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 32);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 24);
+  v0 := v0 + v5 + m0;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(7, 5, v1, v6, v11, v12)
+  v1 := v1 + v6 + m15;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 32);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 24);
+  v1 := v1 + v6 + m4;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(7, 6, v2, v7, v8, v13)
+  v2 := v2 + v7 + m8;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 32);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 24);
+  v2 := v2 + v7 + m6;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(7, 7, v3, v4, v9, v14)
+  v3 := v3 + v4 + m2;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 32);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 24);
+  v3 := v3 + v4 + m10;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // ##### Round(8)
+  // G(8, 0, v0, v4, v8, v12)
+  v0 := v0 + v4 + m6;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 32);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 24);
+  v0 := v0 + v4 + m15;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // G(8, 1, v1, v5, v9, v13)
+  v1 := v1 + v5 + m14;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 32);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 24);
+  v1 := v1 + v5 + m9;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(8, 2, v2, v6, v10, v14)
+  v2 := v2 + v6 + m11;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 32);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 24);
+  v2 := v2 + v6 + m3;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(8, 3, v3, v7, v11, v15)
+  v3 := v3 + v7 + m0;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 32);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 24);
+  v3 := v3 + v7 + m8;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(8, 4, v0, v5, v10, v15)
+  v0 := v0 + v5 + m12;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 32);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 24);
+  v0 := v0 + v5 + m2;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(8, 5, v1, v6, v11, v12)
+  v1 := v1 + v6 + m13;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 32);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 24);
+  v1 := v1 + v6 + m7;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(8, 6, v2, v7, v8, v13)
+  v2 := v2 + v7 + m1;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 32);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 24);
+  v2 := v2 + v7 + m4;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(8, 7, v3, v4, v9, v14)
+  v3 := v3 + v4 + m10;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 32);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 24);
+  v3 := v3 + v4 + m5;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // ##### Round(9)
+  // G(9, 0, v0, v4, v8, v12)
+  v0 := v0 + v4 + m10;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 32);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 24);
+  v0 := v0 + v4 + m2;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // G(9, 1, v1, v5, v9, v13)
+  v1 := v1 + v5 + m8;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 32);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 24);
+  v1 := v1 + v5 + m4;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(9, 2, v2, v6, v10, v14)
+  v2 := v2 + v6 + m7;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 32);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 24);
+  v2 := v2 + v6 + m6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(9, 3, v3, v7, v11, v15)
+  v3 := v3 + v7 + m1;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 32);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 24);
+  v3 := v3 + v7 + m5;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(9, 4, v0, v5, v10, v15)
+  v0 := v0 + v5 + m15;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 32);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 24);
+  v0 := v0 + v5 + m11;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(9, 5, v1, v6, v11, v12)
+  v1 := v1 + v6 + m9;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 32);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 24);
+  v1 := v1 + v6 + m14;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(9, 6, v2, v7, v8, v13)
+  v2 := v2 + v7 + m3;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 32);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 24);
+  v2 := v2 + v7 + m12;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(9, 7, v3, v4, v9, v14)
+  v3 := v3 + v4 + m13;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 32);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 24);
+  v3 := v3 + v4 + m0;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // ##### Round(10)
+  // G(10, 0, v0, v4, v8, v12)
+  v0 := v0 + v4 + m0;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 32);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 24);
+  v0 := v0 + v4 + m1;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // G(10, 1, v1, v5, v9, v13)
+  v1 := v1 + v5 + m2;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 32);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 24);
+  v1 := v1 + v5 + m3;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(10, 2, v2, v6, v10, v14)
+  v2 := v2 + v6 + m4;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 32);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 24);
+  v2 := v2 + v6 + m5;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(10, 3, v3, v7, v11, v15)
+  v3 := v3 + v7 + m6;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 32);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 24);
+  v3 := v3 + v7 + m7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(10, 4, v0, v5, v10, v15)
+  v0 := v0 + v5 + m8;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 32);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 24);
+  v0 := v0 + v5 + m9;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(10, 5, v1, v6, v11, v12)
+  v1 := v1 + v6 + m10;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 32);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 24);
+  v1 := v1 + v6 + m11;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(10, 6, v2, v7, v8, v13)
+  v2 := v2 + v7 + m12;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 32);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 24);
+  v2 := v2 + v7 + m13;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(10, 7, v3, v4, v9, v14)
+  v3 := v3 + v4 + m14;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 32);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 24);
+  v3 := v3 + v4 + m15;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // ##### Round(11)
+  // G(11, 0, v0, v4, v8, v12)
+  v0 := v0 + v4 + m14;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 32);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 24);
+  v0 := v0 + v4 + m10;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight64(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // G(11, 1, v1, v5, v9, v13)
+  v1 := v1 + v5 + m4;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 32);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 24);
+  v1 := v1 + v5 + m8;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight64(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(11, 2, v2, v6, v10, v14)
+  v2 := v2 + v6 + m9;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 32);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 24);
+  v2 := v2 + v6 + m15;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight64(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(11, 3, v3, v7, v11, v15)
+  v3 := v3 + v7 + m13;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 32);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 24);
+  v3 := v3 + v7 + m6;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight64(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(11, 4, v0, v5, v10, v15)
+  v0 := v0 + v5 + m1;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 32);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 24);
+  v0 := v0 + v5 + m12;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight64(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight64(v5, 63);
+
+  // G(11, 5, v1, v6, v11, v12)
+  v1 := v1 + v6 + m0;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 32);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 24);
+  v1 := v1 + v6 + m2;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight64(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight64(v6, 63);
+
+  // G(11, 6, v2, v7, v8, v13)
+  v2 := v2 + v7 + m11;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 32);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 24);
+  v2 := v2 + v7 + m7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight64(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight64(v7, 63);
+
+  // G(11, 7, v3, v4, v9, v14)
+  v3 := v3 + v4 + m5;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 32);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 24);
+  v3 := v3 + v4 + m3;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight64(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight64(v4, 63);
+
+  // Finalization
+  Fm_state[0] := Fm_state[0] xor (v0 xor v8);
+  Fm_state[1] := Fm_state[1] xor (v1 xor v9);
+  Fm_state[2] := Fm_state[2] xor (v2 xor v10);
+  Fm_state[3] := Fm_state[3] xor (v3 xor v11);
+  Fm_state[4] := Fm_state[4] xor (v4 xor v12);
+  Fm_state[5] := Fm_state[5] xor (v5 xor v13);
+  Fm_state[6] := Fm_state[6] xor (v6 xor v14);
+  Fm_state[7] := Fm_state[7] xor (v7 xor v15);
+
+{$ELSE}
+  F_v[0] := Fm_state[0];
+  F_v[1] := Fm_state[1];
+  F_v[2] := Fm_state[2];
+  F_v[3] := Fm_state[3];
+  F_v[4] := Fm_state[4];
+  F_v[5] := Fm_state[5];
+  F_v[6] := Fm_state[6];
+  F_v[7] := Fm_state[7];
+
+  F_v[8] := IV0;
+  F_v[9] := IV1;
+  F_v[10] := IV2;
+  F_v[11] := IV3;
+  F_v[12] := IV4 xor F_counter0;
+  F_v[13] := IV5 xor F_counter1;
+
+  F_v[14] := IV6 xor F_finalizationFlag0;
+
+  F_v[15] := IV7 xor F_finalizationFlag1;
+
+  for r := 0 to System.Pred(NumberOfRounds) do
+
+  begin
+    G(0, 4, 8, 12, r, 0);
+    G(1, 5, 9, 13, r, 2);
+    G(2, 6, 10, 14, r, 4);
+    G(3, 7, 11, 15, r, 6);
+    G(3, 4, 9, 14, r, 14);
+    G(2, 7, 8, 13, r, 12);
+    G(0, 5, 10, 15, r, 8);
+    G(1, 6, 11, 12, r, 10);
+  end;
+
+  for i := 0 to 7 do
+  begin
+    Fm_state[i] := Fm_state[i] xor (F_v[i] xor F_v[i + 8]);
+  end;
+
+{$ENDIF USE_UNROLLED_VARIANT}
+end;
+
+constructor TBlake2B.Create(config: IBlake2BConfig);
+begin
+
+  FBlockSize := BlockSizeInBytes;
+
+  if (config = Nil) then
+  begin
+    config := FDefaultConfig;
+  end;
+
+  FrawConfig := TBlake2BIvBuilder.ConfigB(config, Nil);
+  if ((config.Key <> Nil) and (System.Length(config.Key) <> 0)) then
+  begin
+
+    FKey := System.Copy(config.Key, System.Low(config.Key),
+      System.Length(config.Key));
+
+    System.SetLength(FKey, FBlockSize);
+
+  end;
+  FHashSize := config.HashSize;
+
+  System.SetLength(Fm_state, 8);
+
+  Inherited Create(FHashSize, FBlockSize);
+
+end;
+
+procedure TBlake2B.Finish;
+
+begin
+
+  // Last compression
+
+  F_counter0 := F_counter0 + UInt64(F_bufferFilled);
+
+  F_finalizationFlag0 := System.High(UInt64);
+
+  System.FillChar(F_buf[F_bufferFilled],
+    (System.Length(F_buf) - F_bufferFilled), Byte(0));
+
+  Compress(PByte(F_buf), 0);
+
+end;
+
+procedure TBlake2B.Initialize;
+var
+  i: Integer;
+begin
+  if (FrawConfig = Nil) then
+    raise EArgumentNilHashLibException.Create('config');
+  if (System.Length(FrawConfig) <> 8) then
+  begin
+    raise EArgumentHashLibException.CreateRes(@SInvalidConfigLength);
+  end;
+
+  Fm_state[0] := IV0;
+  Fm_state[1] := IV1;
+  Fm_state[2] := IV2;
+  Fm_state[3] := IV3;
+  Fm_state[4] := IV4;
+  Fm_state[5] := IV5;
+  Fm_state[6] := IV6;
+  Fm_state[7] := IV7;
+
+  F_counter0 := 0;
+  F_counter1 := 0;
+  F_finalizationFlag0 := 0;
+  F_finalizationFlag1 := 0;
+
+  F_bufferFilled := 0;
+
+  System.SetLength(F_buf, BlockSizeInBytes);
+
+  for i := 0 to 7 do
+  begin
+    Fm_state[i] := Fm_state[i] xor FrawConfig[i];
+  end;
+
+  if (FKey <> Nil) then
+  begin
+
+    TransformBytes(FKey, 0, System.Length(FKey));
+
+  end;
+
+end;
+
+procedure TBlake2B.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_data_length: Int32);
+var
+  offset, bufferRemaining: Int32;
+
+begin
+  offset := a_index;
+  bufferRemaining := BlockSizeInBytes - F_bufferFilled;
+
+  if ((F_bufferFilled > 0) and (a_data_length > bufferRemaining)) then
+  begin
+
+    System.Move(a_data[offset], F_buf[F_bufferFilled], bufferRemaining);
+    F_counter0 := F_counter0 + BlockSizeInBytes;
+    if (F_counter0 = 0) then
+    begin
+      System.Inc(F_counter1);
+    end;
+    Compress(PByte(F_buf), 0);
+    offset := offset + bufferRemaining;
+    a_data_length := a_data_length - bufferRemaining;
+    F_bufferFilled := 0;
+  end;
+
+  while (a_data_length > BlockSizeInBytes) do
+  begin
+    F_counter0 := F_counter0 + BlockSizeInBytes;
+    if (F_counter0 = 0) then
+    begin
+      System.Inc(F_counter1);
+    end;
+    Compress(PByte(a_data), offset);
+    offset := offset + BlockSizeInBytes;
+    a_data_length := a_data_length - BlockSizeInBytes;
+  end;
+
+  if (a_data_length > 0) then
+  begin
+
+    System.Move(a_data[offset], F_buf[F_bufferFilled], a_data_length);
+
+    F_bufferFilled := F_bufferFilled + a_data_length;
+
+  end;
+end;
+
+function TBlake2B.TransformFinal: IHashResult;
+var
+  tempRes: THashLibByteArray;
+begin
+
+  Finish();
+
+  System.SetLength(tempRes, FHashSize);
+
+  TConverters.le64_copy(PUInt64(Fm_state), 0, PByte(tempRes), 0,
+    System.Length(tempRes));
+
+  result := THashResult.Create(tempRes);
+
+  Initialize();
+
+end;
+
+function TBlake2B.GetName: String;
+begin
+  result := Format('%s_%u', [Self.ClassName, Self.HashSize * 8]);
+end;
+
+end.

+ 1537 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpBlake2S.pas

@@ -0,0 +1,1537 @@
+unit HlpBlake2S;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF HAS_UNITSCOPE}
+  System.SysUtils,
+{$ELSE}
+  SysUtils,
+{$ENDIF HAS_UNITSCOPE}
+{$IFDEF DELPHI}
+  HlpBitConverter,
+  HlpHashBuffer,
+{$ENDIF DELPHI}
+  HlpBits,
+  HlpHash,
+  HlpHashResult,
+  HlpIHashResult,
+  HlpIBlake2SConfig,
+  HlpBlake2SConfig,
+  HlpBlake2SIvBuilder,
+  HlpIHashInfo,
+  HlpConverters,
+  HlpHashLibTypes;
+
+resourcestring
+  SInvalidConfigLength = 'Config Length Must Be 8 Words';
+
+type
+  TBlake2S = class sealed(THash, ICryptoNotBuildIn, ITransformBlock)
+  strict private
+
+{$REGION 'Consts'}
+  const
+
+{$IFNDEF USE_UNROLLED_VARIANT}
+    NumberOfRounds = Int32(10);
+{$ENDIF USE_UNROLLED_VARIANT}
+    BlockSizeInBytes = Int32(64);
+
+    IV0 = UInt32($66A09E667);
+    IV1 = UInt32($BB67AE85);
+    IV2 = UInt32($3C6EF372);
+    IV3 = UInt32($A54FF53A);
+    IV4 = UInt32($510E527F);
+    IV5 = UInt32($9B05688C);
+    IV6 = UInt32($1F83D9AB);
+    IV7 = UInt32($5BE0CD19);
+
+{$IFNDEF USE_UNROLLED_VARIANT}
+    Sigma: array [0 .. 9, 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));
+{$ENDIF USE_UNROLLED_VARIANT}
+{$ENDREGION}
+    class var
+
+      FDefaultConfig: IBlake2SConfig;
+
+  var
+    FrawConfig, Fm_state: THashLibUInt32Array;
+    FKey, F_buf: THashLibByteArray;
+    F_m: array [0 .. 15] of UInt32;
+{$IFNDEF USE_UNROLLED_VARIANT}
+    F_v: array [0 .. 15] of UInt32;
+{$ENDIF USE_UNROLLED_VARIANT}
+    F_bufferFilled: Int32;
+
+    F_counter0, F_counter1, F_finalizationFlag0, F_finalizationFlag1: UInt32;
+
+    class constructor Blake2SConfig();
+
+{$IFNDEF USE_UNROLLED_VARIANT}
+    procedure G(a, b, c, d, r, i: Int32); inline;
+{$ENDIF USE_UNROLLED_VARIANT}
+    procedure Compress(block: PByte; start: Int32); inline;
+
+    procedure Finish(); inline;
+
+  strict protected
+
+    FHashSize, FBlockSize: Int32;
+    function GetName: String; override;
+
+  public
+    constructor Create(); overload;
+    constructor Create(config: IBlake2SConfig); overload;
+    procedure Initialize; override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_data_length: Int32); override;
+    function TransformFinal: IHashResult; override;
+
+  end;
+
+implementation
+
+{ TBlake2S }
+
+class constructor TBlake2S.Blake2SConfig;
+begin
+  FDefaultConfig := TBlake2SConfig.Create();
+end;
+
+constructor TBlake2S.Create();
+begin
+  Create(TBlake2SConfig.Create());
+end;
+
+{$IFNDEF USE_UNROLLED_VARIANT}
+
+procedure TBlake2S.G(a, b, c, d, r, i: Int32);
+begin
+
+  F_v[a] := F_v[a] + (F_v[b] + F_m[Sigma[r][2 * i + 0]]);
+  F_v[d] := TBits.RotateRight32(F_v[d] xor F_v[a], 16);
+  F_v[c] := F_v[c] + F_v[d];
+  F_v[b] := TBits.RotateRight32(F_v[b] xor F_v[c], 12);
+  F_v[a] := F_v[a] + (F_v[b] + F_m[Sigma[r][2 * i + 1]]);
+  F_v[d] := TBits.RotateRight32(F_v[d] xor F_v[a], 8);
+  F_v[c] := F_v[c] + F_v[d];
+  F_v[b] := TBits.RotateRight32(F_v[b] xor F_v[c], 7);
+end;
+
+{$ENDIF USE_UNROLLED_VARIANT}
+
+procedure TBlake2S.Compress(block: PByte; start: Int32);
+var
+{$IFDEF USE_UNROLLED_VARIANT}
+  m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, v0, v1,
+    v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15: UInt32;
+
+{$ELSE}
+  i, r: Int32;
+
+{$ENDIF USE_UNROLLED_VARIANT}
+begin
+  TConverters.le32_copy(block, start, @(F_m[0]), 0, FBlockSize);
+
+{$IFDEF USE_UNROLLED_VARIANT}
+  m0 := F_m[0];
+  m1 := F_m[1];
+  m2 := F_m[2];
+  m3 := F_m[3];
+  m4 := F_m[4];
+  m5 := F_m[5];
+  m6 := F_m[6];
+  m7 := F_m[7];
+  m8 := F_m[8];
+  m9 := F_m[9];
+  m10 := F_m[10];
+  m11 := F_m[11];
+  m12 := F_m[12];
+  m13 := F_m[13];
+  m14 := F_m[14];
+  m15 := F_m[15];
+
+  v0 := Fm_state[0];
+  v1 := Fm_state[1];
+  v2 := Fm_state[2];
+  v3 := Fm_state[3];
+  v4 := Fm_state[4];
+  v5 := Fm_state[5];
+  v6 := Fm_state[6];
+  v7 := Fm_state[7];
+
+  v8 := IV0;
+  v9 := IV1;
+  v10 := IV2;
+  v11 := IV3;
+  v12 := IV4 xor F_counter0;
+  v13 := IV5 xor F_counter1;
+  v14 := IV6 xor F_finalizationFlag0;
+  v15 := IV7 xor F_finalizationFlag1;
+
+  // Rounds
+  // *
+  // Round 1.
+  v0 := v0 + m0;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 12);
+  v1 := v1 + m2;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 12);
+  v2 := v2 + m4;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 12);
+  v3 := v3 + m6;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 12);
+  v2 := v2 + m5;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 8);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 7);
+  v3 := v3 + m7;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 8);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 7);
+  v1 := v1 + m3;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 8);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 7);
+  v0 := v0 + m1;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 8);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 7);
+  v0 := v0 + m8;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 12);
+  v1 := v1 + m10;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 12);
+  v2 := v2 + m12;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 12);
+  v3 := v3 + m14;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 12);
+  v2 := v2 + m13;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 8);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 7);
+  v3 := v3 + m15;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 8);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 7);
+  v1 := v1 + m11;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 8);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 7);
+  v0 := v0 + m9;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 8);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 7);
+
+  // Round 2.
+  v0 := v0 + m14;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 12);
+  v1 := v1 + m4;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 12);
+  v2 := v2 + m9;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 12);
+  v3 := v3 + m13;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 12);
+  v2 := v2 + m15;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 8);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 7);
+  v3 := v3 + m6;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 8);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 7);
+  v1 := v1 + m8;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 8);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 7);
+  v0 := v0 + m10;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 8);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 7);
+  v0 := v0 + m1;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 12);
+  v1 := v1 + m0;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 12);
+  v2 := v2 + m11;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 12);
+  v3 := v3 + m5;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 12);
+  v2 := v2 + m7;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 8);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 7);
+  v3 := v3 + m3;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 8);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 7);
+  v1 := v1 + m2;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 8);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 7);
+  v0 := v0 + m12;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 8);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 7);
+
+  // Round 3.
+  v0 := v0 + m11;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 12);
+  v1 := v1 + m12;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 12);
+  v2 := v2 + m5;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 12);
+  v3 := v3 + m15;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 12);
+  v2 := v2 + m2;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 8);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 7);
+  v3 := v3 + m13;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 8);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 7);
+  v1 := v1 + m0;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 8);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 7);
+  v0 := v0 + m8;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 8);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 7);
+  v0 := v0 + m10;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 12);
+  v1 := v1 + m3;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 12);
+  v2 := v2 + m7;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 12);
+  v3 := v3 + m9;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 12);
+  v2 := v2 + m1;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 8);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 7);
+  v3 := v3 + m4;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 8);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 7);
+  v1 := v1 + m6;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 8);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 7);
+  v0 := v0 + m14;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 8);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 7);
+
+  // Round 4.
+  v0 := v0 + m7;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 12);
+  v1 := v1 + m3;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 12);
+  v2 := v2 + m13;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 12);
+  v3 := v3 + m11;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 12);
+  v2 := v2 + m12;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 8);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 7);
+  v3 := v3 + m14;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 8);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 7);
+  v1 := v1 + m1;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 8);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 7);
+  v0 := v0 + m9;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 8);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 7);
+  v0 := v0 + m2;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 12);
+  v1 := v1 + m5;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 12);
+  v2 := v2 + m4;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 12);
+  v3 := v3 + m15;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 12);
+  v2 := v2 + m0;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 8);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 7);
+  v3 := v3 + m8;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 8);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 7);
+  v1 := v1 + m10;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 8);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 7);
+  v0 := v0 + m6;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 8);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 7);
+
+  // Round 5.
+  v0 := v0 + m9;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 12);
+  v1 := v1 + m5;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 12);
+  v2 := v2 + m2;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 12);
+  v3 := v3 + m10;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 12);
+  v2 := v2 + m4;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 8);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 7);
+  v3 := v3 + m15;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 8);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 7);
+  v1 := v1 + m7;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 8);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 7);
+  v0 := v0 + m0;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 8);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 7);
+  v0 := v0 + m14;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 12);
+  v1 := v1 + m11;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 12);
+  v2 := v2 + m6;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 12);
+  v3 := v3 + m3;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 12);
+  v2 := v2 + m8;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 8);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 7);
+  v3 := v3 + m13;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 8);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 7);
+  v1 := v1 + m12;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 8);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 7);
+  v0 := v0 + m1;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 8);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 7);
+
+  // Round 6.
+  v0 := v0 + m2;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 12);
+  v1 := v1 + m6;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 12);
+  v2 := v2 + m0;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 12);
+  v3 := v3 + m8;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 12);
+  v2 := v2 + m11;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 8);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 7);
+  v3 := v3 + m3;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 8);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 7);
+  v1 := v1 + m10;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 8);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 7);
+  v0 := v0 + m12;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 8);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 7);
+  v0 := v0 + m4;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 12);
+  v1 := v1 + m7;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 12);
+  v2 := v2 + m15;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 12);
+  v3 := v3 + m1;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 12);
+  v2 := v2 + m14;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 8);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 7);
+  v3 := v3 + m9;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 8);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 7);
+  v1 := v1 + m5;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 8);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 7);
+  v0 := v0 + m13;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 8);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 7);
+
+  // Round 7.
+  v0 := v0 + m12;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 12);
+  v1 := v1 + m1;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 12);
+  v2 := v2 + m14;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 12);
+  v3 := v3 + m4;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 12);
+  v2 := v2 + m13;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 8);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 7);
+  v3 := v3 + m10;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 8);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 7);
+  v1 := v1 + m15;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 8);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 7);
+  v0 := v0 + m5;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 8);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 7);
+  v0 := v0 + m0;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 12);
+  v1 := v1 + m6;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 12);
+  v2 := v2 + m9;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 12);
+  v3 := v3 + m8;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 12);
+  v2 := v2 + m2;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 8);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 7);
+  v3 := v3 + m11;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 8);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 7);
+  v1 := v1 + m3;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 8);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 7);
+  v0 := v0 + m7;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 8);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 7);
+
+  // Round 8.
+  v0 := v0 + m13;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 12);
+  v1 := v1 + m7;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 12);
+  v2 := v2 + m12;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 12);
+  v3 := v3 + m3;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 12);
+  v2 := v2 + m1;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 8);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 7);
+  v3 := v3 + m9;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 8);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 7);
+  v1 := v1 + m14;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 8);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 7);
+  v0 := v0 + m11;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 8);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 7);
+  v0 := v0 + m5;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 12);
+  v1 := v1 + m15;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 12);
+  v2 := v2 + m8;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 12);
+  v3 := v3 + m2;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 12);
+  v2 := v2 + m6;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 8);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 7);
+  v3 := v3 + m10;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 8);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 7);
+  v1 := v1 + m4;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 8);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 7);
+  v0 := v0 + m0;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 8);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 7);
+
+  // Round 9.
+  v0 := v0 + m6;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 12);
+  v1 := v1 + m14;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 12);
+  v2 := v2 + m11;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 12);
+  v3 := v3 + m0;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 12);
+  v2 := v2 + m3;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 8);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 7);
+  v3 := v3 + m8;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 8);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 7);
+  v1 := v1 + m9;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 8);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 7);
+  v0 := v0 + m15;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 8);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 7);
+  v0 := v0 + m12;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 12);
+  v1 := v1 + m13;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 12);
+  v2 := v2 + m1;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 12);
+  v3 := v3 + m10;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 12);
+  v2 := v2 + m4;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 8);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 7);
+  v3 := v3 + m5;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 8);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 7);
+  v1 := v1 + m7;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 8);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 7);
+  v0 := v0 + m2;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 8);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 7);
+
+  // Round 10.
+  v0 := v0 + m10;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 16);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 12);
+  v1 := v1 + m8;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 16);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 12);
+  v2 := v2 + m7;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 16);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 12);
+  v3 := v3 + m1;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 16);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 12);
+  v2 := v2 + m6;
+  v2 := v2 + v6;
+  v14 := v14 xor v2;
+  v14 := TBits.RotateRight32(v14, 8);
+  v10 := v10 + v14;
+  v6 := v6 xor v10;
+  v6 := TBits.RotateRight32(v6, 7);
+  v3 := v3 + m5;
+  v3 := v3 + v7;
+  v15 := v15 xor v3;
+  v15 := TBits.RotateRight32(v15, 8);
+  v11 := v11 + v15;
+  v7 := v7 xor v11;
+  v7 := TBits.RotateRight32(v7, 7);
+  v1 := v1 + m4;
+  v1 := v1 + v5;
+  v13 := v13 xor v1;
+  v13 := TBits.RotateRight32(v13, 8);
+  v9 := v9 + v13;
+  v5 := v5 xor v9;
+  v5 := TBits.RotateRight32(v5, 7);
+  v0 := v0 + m2;
+  v0 := v0 + v4;
+  v12 := v12 xor v0;
+  v12 := TBits.RotateRight32(v12, 8);
+  v8 := v8 + v12;
+  v4 := v4 xor v8;
+  v4 := TBits.RotateRight32(v4, 7);
+  v0 := v0 + m15;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 16);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 12);
+  v1 := v1 + m9;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 16);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 12);
+  v2 := v2 + m3;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 16);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 12);
+  v3 := v3 + m13;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 16);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 12);
+  v2 := v2 + m12;
+  v2 := v2 + v7;
+  v13 := v13 xor v2;
+  v13 := TBits.RotateRight32(v13, 8);
+  v8 := v8 + v13;
+  v7 := v7 xor v8;
+  v7 := TBits.RotateRight32(v7, 7);
+  v3 := v3 + m0;
+  v3 := v3 + v4;
+  v14 := v14 xor v3;
+  v14 := TBits.RotateRight32(v14, 8);
+  v9 := v9 + v14;
+  v4 := v4 xor v9;
+  v4 := TBits.RotateRight32(v4, 7);
+  v1 := v1 + m14;
+  v1 := v1 + v6;
+  v12 := v12 xor v1;
+  v12 := TBits.RotateRight32(v12, 8);
+  v11 := v11 + v12;
+  v6 := v6 xor v11;
+  v6 := TBits.RotateRight32(v6, 7);
+  v0 := v0 + m11;
+  v0 := v0 + v5;
+  v15 := v15 xor v0;
+  v15 := TBits.RotateRight32(v15, 8);
+  v10 := v10 + v15;
+  v5 := v5 xor v10;
+  v5 := TBits.RotateRight32(v5, 7);
+  // */
+  // Finalization
+
+  Fm_state[0] := Fm_state[0] xor (v0 xor v8);
+  Fm_state[1] := Fm_state[1] xor (v1 xor v9);
+  Fm_state[2] := Fm_state[2] xor (v2 xor v10);
+  Fm_state[3] := Fm_state[3] xor (v3 xor v11);
+  Fm_state[4] := Fm_state[4] xor (v4 xor v12);
+  Fm_state[5] := Fm_state[5] xor (v5 xor v13);
+  Fm_state[6] := Fm_state[6] xor (v6 xor v14);
+  Fm_state[7] := Fm_state[7] xor (v7 xor v15);
+
+{$ELSE}
+  F_v[0] := Fm_state[0];
+  F_v[1] := Fm_state[1];
+  F_v[2] := Fm_state[2];
+  F_v[3] := Fm_state[3];
+  F_v[4] := Fm_state[4];
+  F_v[5] := Fm_state[5];
+  F_v[6] := Fm_state[6];
+  F_v[7] := Fm_state[7];
+
+  F_v[8] := IV0;
+  F_v[9] := IV1;
+  F_v[10] := IV2;
+  F_v[11] := IV3;
+  F_v[12] := IV4 xor F_counter0;
+  F_v[13] := IV5 xor F_counter1;
+
+  F_v[14] := IV6 xor F_finalizationFlag0;
+
+  F_v[15] := IV7 xor F_finalizationFlag1;
+
+  for r := 0 to System.Pred(NumberOfRounds) do
+
+  begin
+    G(0, 4, 8, 12, r, 0);
+    G(1, 5, 9, 13, r, 1);
+    G(2, 6, 10, 14, r, 2);
+    G(3, 7, 11, 15, r, 3);
+    G(0, 5, 10, 15, r, 4);
+    G(1, 6, 11, 12, r, 5);
+    G(2, 7, 8, 13, r, 6);
+    G(3, 4, 9, 14, r, 7);
+
+  end;
+
+  for i := 0 to 7 do
+  begin
+    Fm_state[i] := Fm_state[i] xor (F_v[i] xor F_v[i + 8]);
+  end;
+
+{$ENDIF USE_UNROLLED_VARIANT}
+end;
+
+constructor TBlake2S.Create(config: IBlake2SConfig);
+begin
+
+  FBlockSize := BlockSizeInBytes;
+
+  if (config = Nil) then
+  begin
+    config := FDefaultConfig;
+  end;
+
+  FrawConfig := TBlake2SIvBuilder.ConfigS(config, Nil);
+  if ((config.Key <> Nil) and (System.Length(config.Key) <> 0)) then
+  begin
+
+    FKey := System.Copy(config.Key, System.Low(config.Key),
+      System.Length(config.Key));
+
+    System.SetLength(FKey, FBlockSize);
+
+  end;
+  FHashSize := config.HashSize;
+
+  System.SetLength(Fm_state, 8);
+
+  Inherited Create(FHashSize, FBlockSize);
+
+end;
+
+procedure TBlake2S.Finish;
+
+begin
+
+  // Last compression
+
+  F_counter0 := F_counter0 + UInt32(F_bufferFilled);
+
+  F_finalizationFlag0 := System.High(UInt32);
+
+  System.FillChar(F_buf[F_bufferFilled],
+    (System.Length(F_buf) - F_bufferFilled), Byte(0));
+
+  Compress(PByte(F_buf), 0);
+
+end;
+
+procedure TBlake2S.Initialize;
+var
+  i: Integer;
+begin
+  if (FrawConfig = Nil) then
+    raise EArgumentNilHashLibException.Create('config');
+  if (System.Length(FrawConfig) <> 8) then
+  begin
+    raise EArgumentHashLibException.CreateRes(@SInvalidConfigLength);
+  end;
+
+  Fm_state[0] := IV0;
+  Fm_state[1] := IV1;
+  Fm_state[2] := IV2;
+  Fm_state[3] := IV3;
+  Fm_state[4] := IV4;
+  Fm_state[5] := IV5;
+  Fm_state[6] := IV6;
+  Fm_state[7] := IV7;
+
+  F_counter0 := 0;
+  F_counter1 := 0;
+  F_finalizationFlag0 := 0;
+  F_finalizationFlag1 := 0;
+
+  F_bufferFilled := 0;
+
+  System.SetLength(F_buf, BlockSizeInBytes);
+
+  for i := 0 to 7 do
+  begin
+    Fm_state[i] := Fm_state[i] xor FrawConfig[i];
+  end;
+
+  if (FKey <> Nil) then
+  begin
+
+    TransformBytes(FKey, 0, System.Length(FKey));
+
+  end;
+
+end;
+
+procedure TBlake2S.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_data_length: Int32);
+var
+  offset, bufferRemaining: Int32;
+
+begin
+  offset := a_index;
+  bufferRemaining := BlockSizeInBytes - F_bufferFilled;
+
+  if ((F_bufferFilled > 0) and (a_data_length > bufferRemaining)) then
+  begin
+
+    System.Move(a_data[offset], F_buf[F_bufferFilled], bufferRemaining);
+    F_counter0 := F_counter0 + UInt32(BlockSizeInBytes);
+    if (F_counter0 = 0) then
+    begin
+      System.Inc(F_counter1);
+    end;
+    Compress(PByte(F_buf), 0);
+    offset := offset + bufferRemaining;
+    a_data_length := a_data_length - bufferRemaining;
+    F_bufferFilled := 0;
+  end;
+
+  while (a_data_length > BlockSizeInBytes) do
+  begin
+    F_counter0 := F_counter0 + UInt32(BlockSizeInBytes);
+    if (F_counter0 = 0) then
+    begin
+      System.Inc(F_counter1);
+    end;
+    Compress(PByte(a_data), offset);
+    offset := offset + BlockSizeInBytes;
+    a_data_length := a_data_length - BlockSizeInBytes;
+  end;
+
+  if (a_data_length > 0) then
+  begin
+
+    System.Move(a_data[offset], F_buf[F_bufferFilled], a_data_length);
+
+    F_bufferFilled := F_bufferFilled + a_data_length;
+
+  end;
+end;
+
+function TBlake2S.TransformFinal: IHashResult;
+var
+  tempRes: THashLibByteArray;
+begin
+
+  Finish();
+
+  System.SetLength(tempRes, FHashSize);
+
+  TConverters.le32_copy(PCardinal(Fm_state), 0, PByte(tempRes), 0,
+    System.Length(tempRes));
+
+  result := THashResult.Create(tempRes);
+
+  Initialize();
+
+end;
+
+function TBlake2S.GetName: String;
+begin
+  result := Format('%s_%u', [Self.ClassName, Self.HashSize * 8]);
+end;
+
+end.

+ 1669 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpGOST3411_2012.pas

@@ -0,0 +1,1669 @@
+unit HlpGOST3411_2012;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult,
+  HlpBits,
+  HlpHashLibTypes;
+
+type
+  TGOST3411_2012 = class abstract(THash, ICryptoNotBuildIn, ITransformBlock)
+  strict private
+  class var
+    FZero: THashLibByteArray;
+    FC: THashLibMatrixByteArray;
+    FT: THashLibMatrixUInt64Array;
+
+  var
+    FIV, FN, FSigma, FKi, Fm, Fh, Ftmp, Fblock: THashLibByteArray;
+
+    FbOff: Int32;
+
+    procedure InternalUpdate(input: Byte); inline;
+    procedure xor512(A, B: THashLibByteArray); inline;
+    procedure E(K, a_m: THashLibByteArray);
+    procedure F(V: THashLibByteArray);
+    procedure g_N(a_h, a_N, a_m: THashLibByteArray); inline;
+    procedure addMod512(A: THashLibByteArray; num: Int32); overload;
+    procedure addMod512(A, B: THashLibByteArray); overload;
+    procedure reverse(src, dst: THashLibByteArray);
+
+    class constructor GOST3411_2012();
+
+  strict protected
+    constructor Create(a_hash_size: Int32; IV: THashLibByteArray);
+
+  public
+    procedure Initialize; override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_data_length: Int32); override;
+    function TransformFinal: IHashResult; override;
+
+  end;
+
+type
+  TGOST3411_2012_256 = class sealed(TGOST3411_2012)
+
+  strict private
+    class var
+
+      FIV_256: THashLibByteArray;
+
+    class constructor TGOST3411_2012_256();
+  public
+    constructor Create();
+    function TransformFinal: IHashResult; override;
+  end;
+
+type
+  TGOST3411_2012_512 = class sealed(TGOST3411_2012)
+
+  strict private
+    class var
+
+      FIV_512: THashLibByteArray;
+
+    class constructor TGOST3411_2012_512();
+  public
+    constructor Create();
+  end;
+
+implementation
+
+{ TGOST3411_2012Base }
+
+procedure TGOST3411_2012.xor512(A, B: THashLibByteArray);
+var
+  i: Integer;
+begin
+  for i := 0 to System.Pred(64) do
+  begin
+    A[i] := A[i] xor B[i];
+  end;
+end;
+
+procedure TGOST3411_2012.addMod512(A: THashLibByteArray; num: Int32);
+var
+  c, i: Int32;
+begin
+  c := (A[63] and $FF) + (num and $FF);
+  A[63] := Byte(c);
+
+  c := (A[62] and $FF) + ((TBits.Asr32(num, 8)) and $FF) + (TBits.Asr32(c, 8));
+  A[62] := Byte(c);
+
+  i := 61;
+
+  while ((i >= 0) and (c > 0)) do
+  begin
+    c := (A[i] and $FF) + (TBits.Asr32(c, 8));
+    A[i] := Byte(c);
+    System.Dec(i);
+  end;
+
+end;
+
+procedure TGOST3411_2012.addMod512(A, B: THashLibByteArray);
+var
+  i, c: Int32;
+begin
+  c := 0;
+  i := 63;
+
+  while i >= 0 do
+  begin
+    c := Int32(A[i] and $FF) + Int32(B[i] and $FF) + (TBits.Asr32(c, 8));
+    A[i] := Byte(c);
+    System.Dec(i);
+  end;
+end;
+
+constructor TGOST3411_2012.Create(a_hash_size: Int32; IV: THashLibByteArray);
+begin
+  Inherited Create(a_hash_size, 64);
+  System.SetLength(FIV, 64);
+  System.SetLength(FN, 64);
+  System.SetLength(FSigma, 64);
+  System.SetLength(FKi, 64);
+  System.SetLength(Fm, 64);
+  System.SetLength(Fh, 64);
+
+  // Temporary buffers
+  System.SetLength(Ftmp, 64);
+  System.SetLength(Fblock, 64);
+
+  FbOff := 64;
+
+  System.Move(IV[0], FIV[0], 64 * System.SizeOf(Byte));
+  System.Move(IV[0], Fh[0], 64 * System.SizeOf(Byte));
+end;
+
+procedure TGOST3411_2012.E(K, a_m: THashLibByteArray);
+var
+  i: Int32;
+begin
+  System.Move(K[0], FKi[0], 64 * System.SizeOf(Byte));
+  xor512(K, a_m);
+  F(K);
+  for i := 0 to System.Pred(11) do
+  begin
+    xor512(FKi, FC[i]);
+    F(FKi);
+    xor512(K, FKi);
+    F(K);
+  end;
+  xor512(FKi, FC[11]);
+  F(FKi);
+  xor512(K, FKi);
+end;
+
+procedure TGOST3411_2012.F(V: THashLibByteArray);
+var
+  res: array [0 .. 7] of UInt64;
+  r: UInt64;
+begin
+
+  r := 0;
+  r := r xor (FT[0][(V[56] and $FF)]);
+  r := r xor (FT[1][(V[48] and $FF)]);
+  r := r xor (FT[2][(V[40] and $FF)]);
+  r := r xor (FT[3][(V[32] and $FF)]);
+  r := r xor (FT[4][(V[24] and $FF)]);
+  r := r xor (FT[5][(V[16] and $FF)]);
+  r := r xor (FT[6][(V[8] and $FF)]);
+  r := r xor (FT[7][(V[0] and $FF)]);
+  res[0] := r;
+
+  r := 0;
+  r := r xor (FT[0][(V[57] and $FF)]);
+  r := r xor (FT[1][(V[49] and $FF)]);
+  r := r xor (FT[2][(V[41] and $FF)]);
+  r := r xor (FT[3][(V[33] and $FF)]);
+  r := r xor (FT[4][(V[25] and $FF)]);
+  r := r xor (FT[5][(V[17] and $FF)]);
+  r := r xor (FT[6][(V[9] and $FF)]);
+  r := r xor (FT[7][(V[1] and $FF)]);
+  res[1] := r;
+
+  r := 0;
+  r := r xor (FT[0][(V[58] and $FF)]);
+  r := r xor (FT[1][(V[50] and $FF)]);
+  r := r xor (FT[2][(V[42] and $FF)]);
+  r := r xor (FT[3][(V[34] and $FF)]);
+  r := r xor (FT[4][(V[26] and $FF)]);
+  r := r xor (FT[5][(V[18] and $FF)]);
+  r := r xor (FT[6][(V[10] and $FF)]);
+  r := r xor (FT[7][(V[2] and $FF)]);
+  res[2] := r;
+
+  r := 0;
+  r := r xor (FT[0][(V[59] and $FF)]);
+  r := r xor (FT[1][(V[51] and $FF)]);
+  r := r xor (FT[2][(V[43] and $FF)]);
+  r := r xor (FT[3][(V[35] and $FF)]);
+  r := r xor (FT[4][(V[27] and $FF)]);
+  r := r xor (FT[5][(V[19] and $FF)]);
+  r := r xor (FT[6][(V[11] and $FF)]);
+  r := r xor (FT[7][(V[3] and $FF)]);
+  res[3] := r;
+
+  r := 0;
+  r := r xor (FT[0][(V[60] and $FF)]);
+  r := r xor (FT[1][(V[52] and $FF)]);
+  r := r xor (FT[2][(V[44] and $FF)]);
+  r := r xor (FT[3][(V[36] and $FF)]);
+  r := r xor (FT[4][(V[28] and $FF)]);
+  r := r xor (FT[5][(V[20] and $FF)]);
+  r := r xor (FT[6][(V[12] and $FF)]);
+  r := r xor (FT[7][(V[4] and $FF)]);
+  res[4] := r;
+
+  r := 0;
+  r := r xor (FT[0][(V[61] and $FF)]);
+  r := r xor (FT[1][(V[53] and $FF)]);
+  r := r xor (FT[2][(V[45] and $FF)]);
+  r := r xor (FT[3][(V[37] and $FF)]);
+  r := r xor (FT[4][(V[29] and $FF)]);
+  r := r xor (FT[5][(V[21] and $FF)]);
+  r := r xor (FT[6][(V[13] and $FF)]);
+  r := r xor (FT[7][(V[5] and $FF)]);
+  res[5] := r;
+
+  r := 0;
+  r := r xor (FT[0][(V[62] and $FF)]);
+  r := r xor (FT[1][(V[54] and $FF)]);
+  r := r xor (FT[2][(V[46] and $FF)]);
+  r := r xor (FT[3][(V[38] and $FF)]);
+  r := r xor (FT[4][(V[30] and $FF)]);
+  r := r xor (FT[5][(V[22] and $FF)]);
+  r := r xor (FT[6][(V[14] and $FF)]);
+  r := r xor (FT[7][(V[6] and $FF)]);
+  res[6] := r;
+
+  r := 0;
+  r := r xor (FT[0][(V[63] and $FF)]);
+  r := r xor (FT[1][(V[55] and $FF)]);
+  r := r xor (FT[2][(V[47] and $FF)]);
+  r := r xor (FT[3][(V[39] and $FF)]);
+  r := r xor (FT[4][(V[31] and $FF)]);
+  r := r xor (FT[5][(V[23] and $FF)]);
+  r := r xor (FT[6][(V[15] and $FF)]);
+  r := r xor (FT[7][(V[7] and $FF)]);
+  res[7] := r;
+
+  r := res[0];
+  V[7] := Byte(r shr 56);
+  V[6] := Byte(r shr 48);
+  V[5] := Byte(r shr 40);
+  V[4] := Byte(r shr 32);
+  V[3] := Byte(r shr 24);
+  V[2] := Byte(r shr 16);
+  V[1] := Byte(r shr 8);
+  V[0] := Byte(r);
+
+  r := res[1];
+  V[15] := Byte(r shr 56);
+  V[14] := Byte(r shr 48);
+  V[13] := Byte(r shr 40);
+  V[12] := Byte(r shr 32);
+  V[11] := Byte(r shr 24);
+  V[10] := Byte(r shr 16);
+  V[9] := Byte(r shr 8);
+  V[8] := Byte(r);
+
+  r := res[2];
+  V[23] := Byte(r shr 56);
+  V[22] := Byte(r shr 48);
+  V[21] := Byte(r shr 40);
+  V[20] := Byte(r shr 32);
+  V[19] := Byte(r shr 24);
+  V[18] := Byte(r shr 16);
+  V[17] := Byte(r shr 8);
+  V[16] := Byte(r);
+
+  r := res[3];
+  V[31] := Byte(r shr 56);
+  V[30] := Byte(r shr 48);
+  V[29] := Byte(r shr 40);
+  V[28] := Byte(r shr 32);
+  V[27] := Byte(r shr 24);
+  V[26] := Byte(r shr 16);
+  V[25] := Byte(r shr 8);
+  V[24] := Byte(r);
+
+  r := res[4];
+  V[39] := Byte(r shr 56);
+  V[38] := Byte(r shr 48);
+  V[37] := Byte(r shr 40);
+  V[36] := Byte(r shr 32);
+  V[35] := Byte(r shr 24);
+  V[34] := Byte(r shr 16);
+  V[33] := Byte(r shr 8);
+  V[32] := Byte(r);
+
+  r := res[5];
+  V[47] := Byte(r shr 56);
+  V[46] := Byte(r shr 48);
+  V[45] := Byte(r shr 40);
+  V[44] := Byte(r shr 32);
+  V[43] := Byte(r shr 24);
+  V[42] := Byte(r shr 16);
+  V[41] := Byte(r shr 8);
+  V[40] := Byte(r);
+
+  r := res[6];
+  V[55] := Byte(r shr 56);
+  V[54] := Byte(r shr 48);
+  V[53] := Byte(r shr 40);
+  V[52] := Byte(r shr 32);
+  V[51] := Byte(r shr 24);
+  V[50] := Byte(r shr 16);
+  V[49] := Byte(r shr 8);
+  V[48] := Byte(r);
+
+  r := res[7];
+  V[63] := Byte(r shr 56);
+  V[62] := Byte(r shr 48);
+  V[61] := Byte(r shr 40);
+  V[60] := Byte(r shr 32);
+  V[59] := Byte(r shr 24);
+  V[58] := Byte(r shr 16);
+  V[57] := Byte(r shr 8);
+  V[56] := Byte(r);
+
+  System.FillChar(res, System.SizeOf(res), 0);
+end;
+
+class constructor TGOST3411_2012.GOST3411_2012;
+begin
+{$REGION 'Consts'}
+  FC := THashLibMatrixByteArray.Create(THashLibByteArray.Create(Byte($B1),
+    Byte($08), Byte($5B), Byte($DA), Byte($1E), Byte($CA), Byte($DA), Byte($E9),
+    Byte($EB), Byte($CB), Byte($2F), Byte($81), Byte($C0), Byte($65), Byte($7C),
+    Byte($1F), Byte($2F), Byte($6A), Byte($76), Byte($43), Byte($2E), Byte($45),
+    Byte($D0), Byte($16), Byte($71), Byte($4E), Byte($B8), Byte($8D), Byte($75),
+    Byte($85), Byte($C4), Byte($FC), Byte($4B), Byte($7C), Byte($E0), Byte($91),
+    Byte($92), Byte($67), Byte($69), Byte($01), Byte($A2), Byte($42), Byte($2A),
+    Byte($08), Byte($A4), Byte($60), Byte($D3), Byte($15), Byte($05), Byte($76),
+    Byte($74), Byte($36), Byte($CC), Byte($74), Byte($4D), Byte($23), Byte($DD),
+    Byte($80), Byte($65), Byte($59), Byte($F2), Byte($A6), Byte($45),
+    Byte($07)),
+
+    THashLibByteArray.Create(Byte($6F), Byte($A3), Byte($B5), Byte($8A),
+    Byte($A9), Byte($9D), Byte($2F), Byte($1A), Byte($4F), Byte($E3), Byte($9D),
+    Byte($46), Byte($0F), Byte($70), Byte($B5), Byte($D7), Byte($F3), Byte($FE),
+    Byte($EA), Byte($72), Byte($0A), Byte($23), Byte($2B), Byte($98), Byte($61),
+    Byte($D5), Byte($5E), Byte($0F), Byte($16), Byte($B5), Byte($01), Byte($31),
+    Byte($9A), Byte($B5), Byte($17), Byte($6B), Byte($12), Byte($D6), Byte($99),
+    Byte($58), Byte($5C), Byte($B5), Byte($61), Byte($C2), Byte($DB), Byte($0A),
+    Byte($A7), Byte($CA), Byte($55), Byte($DD), Byte($A2), Byte($1B), Byte($D7),
+    Byte($CB), Byte($CD), Byte($56), Byte($E6), Byte($79), Byte($04), Byte($70),
+    Byte($21), Byte($B1), Byte($9B), Byte($B7)),
+    THashLibByteArray.Create(Byte($F5), Byte($74), Byte($DC), Byte($AC),
+    Byte($2B), Byte($CE), Byte($2F), Byte($C7), Byte($0A), Byte($39), Byte($FC),
+    Byte($28), Byte($6A), Byte($3D), Byte($84), Byte($35), Byte($06), Byte($F1),
+    Byte($5E), Byte($5F), Byte($52), Byte($9C), Byte($1F), Byte($8B), Byte($F2),
+    Byte($EA), Byte($75), Byte($14), Byte($B1), Byte($29), Byte($7B), Byte($7B),
+    Byte($D3), Byte($E2), Byte($0F), Byte($E4), Byte($90), Byte($35), Byte($9E),
+    Byte($B1), Byte($C1), Byte($C9), Byte($3A), Byte($37), Byte($60), Byte($62),
+    Byte($DB), Byte($09), Byte($C2), Byte($B6), Byte($F4), Byte($43), Byte($86),
+    Byte($7A), Byte($DB), Byte($31), Byte($99), Byte($1E), Byte($96), Byte($F5),
+    Byte($0A), Byte($BA), Byte($0A), Byte($B2)),
+    THashLibByteArray.Create(Byte($EF), Byte($1F), Byte($DF), Byte($B3),
+    Byte($E8), Byte($15), Byte($66), Byte($D2), Byte($F9), Byte($48), Byte($E1),
+    Byte($A0), Byte($5D), Byte($71), Byte($E4), Byte($DD), Byte($48), Byte($8E),
+    Byte($85), Byte($7E), Byte($33), Byte($5C), Byte($3C), Byte($7D), Byte($9D),
+    Byte($72), Byte($1C), Byte($AD), Byte($68), Byte($5E), Byte($35), Byte($3F),
+    Byte($A9), Byte($D7), Byte($2C), Byte($82), Byte($ED), Byte($03), Byte($D6),
+    Byte($75), Byte($D8), Byte($B7), Byte($13), Byte($33), Byte($93), Byte($52),
+    Byte($03), Byte($BE), Byte($34), Byte($53), Byte($EA), Byte($A1), Byte($93),
+    Byte($E8), Byte($37), Byte($F1), Byte($22), Byte($0C), Byte($BE), Byte($BC),
+    Byte($84), Byte($E3), Byte($D1), Byte($2E)),
+    THashLibByteArray.Create(Byte($4B), Byte($EA), Byte($6B), Byte($AC),
+    Byte($AD), Byte($47), Byte($47), Byte($99), Byte($9A), Byte($3F), Byte($41),
+    Byte($0C), Byte($6C), Byte($A9), Byte($23), Byte($63), Byte($7F), Byte($15),
+    Byte($1C), Byte($1F), Byte($16), Byte($86), Byte($10), Byte($4A), Byte($35),
+    Byte($9E), Byte($35), Byte($D7), Byte($80), Byte($0F), Byte($FF), Byte($BD),
+    Byte($BF), Byte($CD), Byte($17), Byte($47), Byte($25), Byte($3A), Byte($F5),
+    Byte($A3), Byte($DF), Byte($FF), Byte($00), Byte($B7), Byte($23), Byte($27),
+    Byte($1A), Byte($16), Byte($7A), Byte($56), Byte($A2), Byte($7E), Byte($A9),
+    Byte($EA), Byte($63), Byte($F5), Byte($60), Byte($17), Byte($58), Byte($FD),
+    Byte($7C), Byte($6C), Byte($FE), Byte($57)),
+    THashLibByteArray.Create(Byte($AE), Byte($4F), Byte($AE), Byte($AE),
+    Byte($1D), Byte($3A), Byte($D3), Byte($D9), Byte($6F), Byte($A4), Byte($C3),
+    Byte($3B), Byte($7A), Byte($30), Byte($39), Byte($C0), Byte($2D), Byte($66),
+    Byte($C4), Byte($F9), Byte($51), Byte($42), Byte($A4), Byte($6C), Byte($18),
+    Byte($7F), Byte($9A), Byte($B4), Byte($9A), Byte($F0), Byte($8E), Byte($C6),
+    Byte($CF), Byte($FA), Byte($A6), Byte($B7), Byte($1C), Byte($9A), Byte($B7),
+    Byte($B4), Byte($0A), Byte($F2), Byte($1F), Byte($66), Byte($C2), Byte($BE),
+    Byte($C6), Byte($B6), Byte($BF), Byte($71), Byte($C5), Byte($72), Byte($36),
+    Byte($90), Byte($4F), Byte($35), Byte($FA), Byte($68), Byte($40), Byte($7A),
+    Byte($46), Byte($64), Byte($7D), Byte($6E)),
+    THashLibByteArray.Create(Byte($F4), Byte($C7), Byte($0E), Byte($16),
+    Byte($EE), Byte($AA), Byte($C5), Byte($EC), Byte($51), Byte($AC), Byte($86),
+    Byte($FE), Byte($BF), Byte($24), Byte($09), Byte($54), Byte($39), Byte($9E),
+    Byte($C6), Byte($C7), Byte($E6), Byte($BF), Byte($87), Byte($C9), Byte($D3),
+    Byte($47), Byte($3E), Byte($33), Byte($19), Byte($7A), Byte($93), Byte($C9),
+    Byte($09), Byte($92), Byte($AB), Byte($C5), Byte($2D), Byte($82), Byte($2C),
+    Byte($37), Byte($06), Byte($47), Byte($69), Byte($83), Byte($28), Byte($4A),
+    Byte($05), Byte($04), Byte($35), Byte($17), Byte($45), Byte($4C), Byte($A2),
+    Byte($3C), Byte($4A), Byte($F3), Byte($88), Byte($86), Byte($56), Byte($4D),
+    Byte($3A), Byte($14), Byte($D4), Byte($93)),
+    THashLibByteArray.Create(Byte($9B), Byte($1F), Byte($5B), Byte($42),
+    Byte($4D), Byte($93), Byte($C9), Byte($A7), Byte($03), Byte($E7), Byte($AA),
+    Byte($02), Byte($0C), Byte($6E), Byte($41), Byte($41), Byte($4E), Byte($B7),
+    Byte($F8), Byte($71), Byte($9C), Byte($36), Byte($DE), Byte($1E), Byte($89),
+    Byte($B4), Byte($44), Byte($3B), Byte($4D), Byte($DB), Byte($C4), Byte($9A),
+    Byte($F4), Byte($89), Byte($2B), Byte($CB), Byte($92), Byte($9B), Byte($06),
+    Byte($90), Byte($69), Byte($D1), Byte($8D), Byte($2B), Byte($D1), Byte($A5),
+    Byte($C4), Byte($2F), Byte($36), Byte($AC), Byte($C2), Byte($35), Byte($59),
+    Byte($51), Byte($A8), Byte($D9), Byte($A4), Byte($7F), Byte($0D), Byte($D4),
+    Byte($BF), Byte($02), Byte($E7), Byte($1E)),
+    THashLibByteArray.Create(Byte($37), Byte($8F), Byte($5A), Byte($54),
+    Byte($16), Byte($31), Byte($22), Byte($9B), Byte($94), Byte($4C), Byte($9A),
+    Byte($D8), Byte($EC), Byte($16), Byte($5F), Byte($DE), Byte($3A), Byte($7D),
+    Byte($3A), Byte($1B), Byte($25), Byte($89), Byte($42), Byte($24), Byte($3C),
+    Byte($D9), Byte($55), Byte($B7), Byte($E0), Byte($0D), Byte($09), Byte($84),
+    Byte($80), Byte($0A), Byte($44), Byte($0B), Byte($DB), Byte($B2), Byte($CE),
+    Byte($B1), Byte($7B), Byte($2B), Byte($8A), Byte($9A), Byte($A6), Byte($07),
+    Byte($9C), Byte($54), Byte($0E), Byte($38), Byte($DC), Byte($92), Byte($CB),
+    Byte($1F), Byte($2A), Byte($60), Byte($72), Byte($61), Byte($44), Byte($51),
+    Byte($83), Byte($23), Byte($5A), Byte($DB)),
+    THashLibByteArray.Create(Byte($AB), Byte($BE), Byte($DE), Byte($A6),
+    Byte($80), Byte($05), Byte($6F), Byte($52), Byte($38), Byte($2A), Byte($E5),
+    Byte($48), Byte($B2), Byte($E4), Byte($F3), Byte($F3), Byte($89), Byte($41),
+    Byte($E7), Byte($1C), Byte($FF), Byte($8A), Byte($78), Byte($DB), Byte($1F),
+    Byte($FF), Byte($E1), Byte($8A), Byte($1B), Byte($33), Byte($61), Byte($03),
+    Byte($9F), Byte($E7), Byte($67), Byte($02), Byte($AF), Byte($69), Byte($33),
+    Byte($4B), Byte($7A), Byte($1E), Byte($6C), Byte($30), Byte($3B), Byte($76),
+    Byte($52), Byte($F4), Byte($36), Byte($98), Byte($FA), Byte($D1), Byte($15),
+    Byte($3B), Byte($B6), Byte($C3), Byte($74), Byte($B4), Byte($C7), Byte($FB),
+    Byte($98), Byte($45), Byte($9C), Byte($ED)),
+    THashLibByteArray.Create(Byte($7B), Byte($CD), Byte($9E), Byte($D0),
+    Byte($EF), Byte($C8), Byte($89), Byte($FB), Byte($30), Byte($02), Byte($C6),
+    Byte($CD), Byte($63), Byte($5A), Byte($FE), Byte($94), Byte($D8), Byte($FA),
+    Byte($6B), Byte($BB), Byte($EB), Byte($AB), Byte($07), Byte($61), Byte($20),
+    Byte($01), Byte($80), Byte($21), Byte($14), Byte($84), Byte($66), Byte($79),
+    Byte($8A), Byte($1D), Byte($71), Byte($EF), Byte($EA), Byte($48), Byte($B9),
+    Byte($CA), Byte($EF), Byte($BA), Byte($CD), Byte($1D), Byte($7D), Byte($47),
+    Byte($6E), Byte($98), Byte($DE), Byte($A2), Byte($59), Byte($4A), Byte($C0),
+    Byte($6F), Byte($D8), Byte($5D), Byte($6B), Byte($CA), Byte($A4), Byte($CD),
+    Byte($81), Byte($F3), Byte($2D), Byte($1B)),
+    THashLibByteArray.Create(Byte($37), Byte($8E), Byte($E7), Byte($67),
+    Byte($F1), Byte($16), Byte($31), Byte($BA), Byte($D2), Byte($13), Byte($80),
+    Byte($B0), Byte($04), Byte($49), Byte($B1), Byte($7A), Byte($CD), Byte($A4),
+    Byte($3C), Byte($32), Byte($BC), Byte($DF), Byte($1D), Byte($77), Byte($F8),
+    Byte($20), Byte($12), Byte($D4), Byte($30), Byte($21), Byte($9F), Byte($9B),
+    Byte($5D), Byte($80), Byte($EF), Byte($9D), Byte($18), Byte($91), Byte($CC),
+    Byte($86), Byte($E7), Byte($1D), Byte($A4), Byte($AA), Byte($88), Byte($E1),
+    Byte($28), Byte($52), Byte($FA), Byte($F4), Byte($17), Byte($D5), Byte($D9),
+    Byte($B2), Byte($1B), Byte($99), Byte($48), Byte($BC), Byte($92), Byte($4A),
+    Byte($F1), Byte($1B), Byte($D7), Byte($20)));
+
+  FZero := THashLibByteArray.Create($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, $00);
+
+  FT := THashLibMatrixUInt64Array.Create
+    (THashLibUInt64Array.Create(UInt64($E6F87E5C5B711FD0),
+    UInt64($258377800924FA16), UInt64($C849E07E852EA4A8),
+    UInt64($5B4686A18F06C16A), UInt64($0B32E9A2D77B416E),
+    UInt64($ABDA37A467815C66), UInt64($F61796A81A686676),
+    UInt64($F5DC0B706391954B), UInt64($4862F38DB7E64BF1),
+    UInt64($FF5C629A68BD85C5), UInt64($CB827DA6FCD75795),
+    UInt64($66D36DAF69B9F089), UInt64($356C9F74483D83B0),
+    UInt64($7CBCECB1238C99A1), UInt64($36A702AC31C4708D),
+    UInt64($9EB6A8D02FBCDFD6), UInt64($8B19FA51E5B3AE37),
+    UInt64($9CCFB5408A127D0B), UInt64($BC0C78B508208F5A),
+    UInt64($E533E3842288ECED), UInt64($CEC2C7D377C15FD2),
+    UInt64($EC7817B6505D0F5E), UInt64($B94CC2C08336871D),
+    UInt64($8C205DB4CB0B04AD), UInt64($763C855B28A0892F),
+    UInt64($588D1B79F6FF3257), UInt64($3FECF69E4311933E),
+    UInt64($0FC0D39F803A18C9), UInt64($EE010A26F5F3AD83),
+    UInt64($10EFE8F4411979A6), UInt64($5DCDA10C7DE93A10),
+    UInt64($4A1BEE1D1248E92C), UInt64($53BFF2DB21847339),
+    UInt64($B4F50CCFA6A23D09), UInt64($5FB4BC9CD84798CD),
+    UInt64($E88A2D8B071C56F9), UInt64($7F7771695A756A9C),
+    UInt64($C5F02E71A0BA1EBC), UInt64($A663F9AB4215E672),
+    UInt64($2EB19E22DE5FBB78), UInt64($0DB9CE0F2594BA14),
+    UInt64($82520E6397664D84), UInt64($2F031E6A0208EA98),
+    UInt64($5C7F2144A1BE6BF0), UInt64($7A37CB1CD16362DB),
+    UInt64($83E08E2B4B311C64), UInt64($CF70479BAB960E32),
+    UInt64($856BA986B9DEE71E), UInt64($B5478C877AF56CE9),
+    UInt64($B8FE42885F61D6FD), UInt64($1BDD0156966238C8),
+    UInt64($622157923EF8A92E), UInt64($FC97FF42114476F8),
+    UInt64($9D7D350856452CEB), UInt64($4C90C9B0E0A71256),
+    UInt64($2308502DFBCB016C), UInt64($2D7A03FAA7A64845),
+    UInt64($F46E8B38BFC6C4AB), UInt64($BDBEF8FDD477DEBA),
+    UInt64($3AAC4CEBC8079B79), UInt64($F09CB105E8879D0C),
+    UInt64($27FA6A10AC8A58CB), UInt64($8960E7C1401D0CEA),
+    UInt64($1A6F811E4A356928), UInt64($90C4FB0773D196FF),
+    UInt64($43501A2F609D0A9F), UInt64($F7A516E0C63F3796),
+    UInt64($1CE4A6B3B8DA9252), UInt64($1324752C38E08A9B),
+    UInt64($A5A864733BEC154F), UInt64($2BF124575549B33F),
+    UInt64($D766DB15440DC5C7), UInt64($A7D179E39E42B792),
+    UInt64($DADF151A61997FD3), UInt64($86A0345EC0271423),
+    UInt64($38D5517B6DA939A4), UInt64($6518F077104003B4),
+    UInt64($02791D90A5AEA2DD), UInt64($88D267899C4A5D0A),
+    UInt64($930F66DF0A2865C2), UInt64($4EE9D4204509B08B),
+    UInt64($325538916685292A), UInt64($412907BFC533A842),
+    UInt64($B27E2B62544DC673), UInt64($6C5304456295E007),
+    UInt64($5AF406E95351908A), UInt64($1F2F3B6BC123616F),
+    UInt64($C37B09DC5255E5C6), UInt64($3967D133B1FE6844),
+    UInt64($298839C7F0E711E2), UInt64($409B87F71964F9A2),
+    UInt64($E938ADC3DB4B0719), UInt64($0C0B4E47F9C3EBF4),
+    UInt64($5534D576D36B8843), UInt64($4610A05AEB8B02D8),
+    UInt64($20C3CDF58232F251), UInt64($6DE1840DBEC2B1E7),
+    UInt64($A0E8DE06B0FA1D08), UInt64($7B854B540D34333B),
+    UInt64($42E29A67BCCA5B7F), UInt64($D8A6088AC437DD0E),
+    UInt64($C63BB3A9D943ED81), UInt64($21714DBD5E65A3B1),
+    UInt64($6761EDE7B5EEA169), UInt64($2431F7C8D573ABF6),
+    UInt64($D51FC685E1A3671A), UInt64($5E063CD40410C92D),
+    UInt64($283AB98F2CB04002), UInt64($8FEBC06CB2F2F790),
+    UInt64($17D64F116FA1D33C), UInt64($E07359F1A99EE4AA),
+    UInt64($784ED68C74CDC006), UInt64($6E2A19D5C73B42DA),
+    UInt64($8712B4161C7045C3), UInt64($371582E4ED93216D),
+    UInt64($ACE390414939F6FC), UInt64($7EC5F12186223B7C),
+    UInt64($C0B094042BAC16FB), UInt64($F9D745379A527EBF),
+    UInt64($737C3F2EA3B68168), UInt64($33E7B8D9BAD278CA),
+    UInt64($A9A32A34C22FFEBB), UInt64($E48163CCFEDFBD0D),
+    UInt64($8E5940246EA5A670), UInt64($51C6EF4B842AD1E4),
+    UInt64($22BAD065279C508C), UInt64($D91488C218608CEE),
+    UInt64($319EA5491F7CDA17), UInt64($D394E128134C9C60),
+    UInt64($094BF43272D5E3B3), UInt64($9BF612A5A4AAD791),
+    UInt64($CCBBDA43D26FFD0F), UInt64($34DE1F3C946AD250),
+    UInt64($4F5B5468995EE16B), UInt64($DF9FAF6FEA8F7794),
+    UInt64($2648EA5870DD092B), UInt64($BFC7E56D71D97C67),
+    UInt64($DDE6B2FF4F21D549), UInt64($3C276B463AE86003),
+    UInt64($91767B4FAF86C71F), UInt64($68A13E7835D4B9A0),
+    UInt64($B68C115F030C9FD4), UInt64($141DD2C916582001),
+    UInt64($983D8F7DDD5324AC), UInt64($64AA703FCC175254),
+    UInt64($C2C989948E02B426), UInt64($3E5E76D69F46C2DE),
+    UInt64($50746F03587D8004), UInt64($45DB3D829272F1E5),
+    UInt64($60584A029B560BF3), UInt64($FBAE58A73FFCDC62),
+    UInt64($A15A5E4E6CAD4CE8), UInt64($4BA96E55CE1FB8CC),
+    UInt64($08F9747AAE82B253), UInt64($C102144CF7FB471B),
+    UInt64($9F042898F3EB8E36), UInt64($068B27ADF2EFFB7A),
+    UInt64($EDCA97FE8C0A5EBE), UInt64($778E0513F4F7D8CF),
+    UInt64($302C2501C32B8BF7), UInt64($8D92DDFC175C554D),
+    UInt64($F865C57F46052F5F), UInt64($EAF3301BA2B2F424),
+    UInt64($AA68B7ECBBD60D86), UInt64($998F0F350104754C),
+    UInt64($0000000000000000), UInt64($F12E314D34D0CCEC),
+    UInt64($710522BE061823B5), UInt64($AF280D9930C005C1),
+    UInt64($97FD5CE25D693C65), UInt64($19A41CC633CC9A15),
+    UInt64($95844172F8C79EB8), UInt64($DC5432B7937684A9),
+    UInt64($9436C13A2490CF58), UInt64($802B13F332C8EF59),
+    UInt64($C442AE397CED4F5C), UInt64($FA1CD8EFE3AB8D82),
+    UInt64($F2E5AC954D293FD1), UInt64($6AD823E8907A1B7D),
+    UInt64($4D2249F83CF043B6), UInt64($03CB9DD879F9F33D),
+    UInt64($DE2D2F2736D82674), UInt64($2A43A41F891EE2DF),
+    UInt64($6F98999D1B6C133A), UInt64($D4AD46CD3DF436FA),
+    UInt64($BB35DF50269825C0), UInt64($964FDCAA813E6D85),
+    UInt64($EB41B0537EE5A5C4), UInt64($0540BA758B160847),
+    UInt64($A41AE43BE7BB44AF), UInt64($E3B8C429D0671797),
+    UInt64($819993BBEE9FBEB9), UInt64($AE9A8DD1EC975421),
+    UInt64($F3572CDD917E6E31), UInt64($6393D7DAE2AFF8CE),
+    UInt64($47A2201237DC5338), UInt64($A32343DEC903EE35),
+    UInt64($79FC56C4A89A91E6), UInt64($01B28048DC5751E0),
+    UInt64($1296F564E4B7DB7B), UInt64($75F7188351597A12),
+    UInt64($DB6D9552BDCE2E33), UInt64($1E9DBB231D74308F),
+    UInt64($520D7293FDD322D9), UInt64($E20A44610C304677),
+    UInt64($FEEEE2D2B4EAD425), UInt64($CA30FDEE20800675),
+    UInt64($61EACA4A47015A13), UInt64($E74AFE1487264E30),
+    UInt64($2CC883B27BF119A5), UInt64($1664CF59B3F682DC),
+    UInt64($A811AA7C1E78AF5B), UInt64($1D5626FB648DC3B2),
+    UInt64($B73E9117DF5BCE34), UInt64($D05F7CF06AB56F5D),
+    UInt64($FD257F0ACD132718), UInt64($574DC8E676C52A9E),
+    UInt64($0739A7E52EB8AA9A), UInt64($5486553E0F3CD9A3),
+    UInt64($56FF48AEAA927B7E), UInt64($BE756525AD8E2D87),
+    UInt64($7D0E6CF9FFDBC841), UInt64($3B1ECCA31450CA99),
+    UInt64($6913BE30E983E840), UInt64($AD511009956EA71C),
+    UInt64($B1B5B6BA2DB4354E), UInt64($4469BDCA4E25A005),
+    UInt64($15AF5281CA0F71E1), UInt64($744598CB8D0E2BF2),
+    UInt64($593F9B312AA863B7), UInt64($EFB38A6E29A4FC63),
+    UInt64($6B6AA3A04C2D4A9D), UInt64($3D95EB0EE6BF31E3),
+    UInt64($A291C3961554BFD5), UInt64($18169C8EEF9BCBF5),
+    UInt64($115D68BC9D4E2846), UInt64($BA875F18FACF7420),
+    UInt64($D1EDFCB8B6E23EBD), UInt64($B00736F2F1E364AE),
+    UInt64($84D929CE6589B6FE), UInt64($70B7A2F6DA4F7255),
+    UInt64($0E7253D75C6D4929), UInt64($04F23A3D574159A7),
+    UInt64($0A8069EA0B2C108E), UInt64($49D073C56BB11A11),
+    UInt64($8AAB7A1939E4FFD7), UInt64($CD095A0B0E38ACEF),
+    UInt64($C9FB60365979F548), UInt64($92BDE697D67F3422),
+    UInt64($C78933E10514BC61), UInt64($E1C1D9B975C9B54A),
+    UInt64($D2266160CF1BCD80), UInt64($9A4492ED78FD8671),
+    UInt64($B3CCAB2A881A9793), UInt64($72CEBF667FE1D088),
+    UInt64($D6D45B5D985A9427)),
+    THashLibUInt64Array.Create(UInt64($C811A8058C3F55DE),
+    UInt64($65F5B43196B50619), UInt64($F74F96B1D6706E43),
+    UInt64($859D1E8BCB43D336), UInt64($5AAB8A85CCFA3D84),
+    UInt64($F9C7BF99C295FCFD), UInt64($A21FD5A1DE4B630F),
+    UInt64($CDB3EF763B8B456D), UInt64($803F59F87CF7C385),
+    UInt64($B27C73BE5F31913C), UInt64($98E3AC6633B04821),
+    UInt64($BF61674C26B8F818), UInt64($0FFBC995C4C130C8),
+    UInt64($AAA0862010761A98), UInt64($6057F342210116AA),
+    UInt64($F63C760C0654CC35), UInt64($2DDB45CC667D9042),
+    UInt64($BCF45A964BD40382), UInt64($68E8A0C3EF3C6F3D),
+    UInt64($A7BD92D269FF73BC), UInt64($290AE20201ED2287),
+    UInt64($B7DE34CDE885818F), UInt64($D901EEA7DD61059B),
+    UInt64($D6FA273219A03553), UInt64($D56F1AE874CCCEC9),
+    UInt64($EA31245C2E83F554), UInt64($7034555DA07BE499),
+    UInt64($CE26D2AC56E7BEF7), UInt64($FD161857A5054E38),
+    UInt64($6A0E7DA4527436D1), UInt64($5BD86A381CDE9FF2),
+    UInt64($CAF7756231770C32), UInt64($B09AAED9E279C8D0),
+    UInt64($5DEF1091C60674DB), UInt64($111046A2515E5045),
+    UInt64($23536CE4729802FC), UInt64($C50CBCF7F5B63CFA),
+    UInt64($73A16887CD171F03), UInt64($7D2941AFD9F28DBD),
+    UInt64($3F5E3EB45A4F3B9D), UInt64($84EEFE361B677140),
+    UInt64($3DB8E3D3E7076271), UInt64($1A3A28F9F20FD248),
+    UInt64($7EBC7C75B49E7627), UInt64($74E5F293C7EB565C),
+    UInt64($18DCF59E4F478BA4), UInt64($0C6EF44FA9ADCB52),
+    UInt64($C699812D98DAC760), UInt64($788B06DC6E469D0E),
+    UInt64($FC65F8EA7521EC4E), UInt64($30A5F7219E8E0B55),
+    UInt64($2BEC3F65BCA57B6B), UInt64($DDD04969BAF1B75E),
+    UInt64($99904CDBE394EA57), UInt64($14B201D1E6EA40F6),
+    UInt64($BBB0C08241284ADD), UInt64($50F20463BF8F1DFF),
+    UInt64($E8D7F93B93CBACB8), UInt64($4D8CB68E477C86E8),
+    UInt64($C1DD1B3992268E3F), UInt64($7C5AA11209D62FCB),
+    UInt64($2F3D98ABDB35C9AE), UInt64($671369562BFD5FF5),
+    UInt64($15C1E16C36CEE280), UInt64($1D7EB2EDF8F39B17),
+    UInt64($DA94D37DB00DFE01), UInt64($877BC3EC760B8ADA),
+    UInt64($CB8495DFE153AE44), UInt64($05A24773B7B410B3),
+    UInt64($12857B783C32ABDF), UInt64($8EB770D06812513B),
+    UInt64($536739B9D2E3E665), UInt64($584D57E271B26468),
+    UInt64($D789C78FC9849725), UInt64($A935BBFA7D1AE102),
+    UInt64($8B1537A3DFA64188), UInt64($D0CD5D9BC378DE7A),
+    UInt64($4AC82C9A4D80CFB7), UInt64($42777F1B83BDB620),
+    UInt64($72D2883A1D33BD75), UInt64($5E7A2D4BAB6A8F41),
+    UInt64($F4DAAB6BBB1C95D9), UInt64($905CFFE7FD8D31B6),
+    UInt64($83AA6422119B381F), UInt64($C0AEFB8442022C49),
+    UInt64($A0F908C663033AE3), UInt64($A428AF0804938826),
+    UInt64($ADE41C341A8A53C7), UInt64($AE7121EE77E6A85D),
+    UInt64($C47F5C4A25929E8C), UInt64($B538E9AA55CDD863),
+    UInt64($06377AA9DAD8EB29), UInt64($A18AE87BB3279895),
+    UInt64($6EDFDA6A35E48414), UInt64($6B7D9D19825094A7),
+    UInt64($D41CFA55A4E86CBF), UInt64($E5CAEDC9EA42C59C),
+    UInt64($A36C351C0E6FC179), UInt64($5181E4DE6FABBF89),
+    UInt64($FFF0C530184D17D4), UInt64($9D41EB1584045892),
+    UInt64($1C0D525028D73961), UInt64($F178EC180CA8856A),
+    UInt64($9A0571018EF811CD), UInt64($4091A27C3EF5EFCC),
+    UInt64($19AF15239F6329D2), UInt64($347450EFF91EB990),
+    UInt64($E11B4A078DD27759), UInt64($B9561DE5FC601331),
+    UInt64($912F1F5A2DA993C0), UInt64($1654DCB65BA2191A),
+    UInt64($3E2DDE098A6B99EB), UInt64($8A66D71E0F82E3FE),
+    UInt64($8C51ADB7D55A08D7), UInt64($4533E50F8941FF7F),
+    UInt64($02E6DD67BD4859EC), UInt64($E068AABA5DF6D52F),
+    UInt64($C24826E3FF4A75A5), UInt64($6C39070D88ACDDF8),
+    UInt64($6486548C4691A46F), UInt64($D1BEBD26135C7C0C),
+    UInt64($B30F93038F15334A), UInt64($82D9849FC1BF9A69),
+    UInt64($9C320BA85420FAE4), UInt64($FA528243AFF90767),
+    UInt64($9ED4D6CFE968A308), UInt64($B825FD582C44B147),
+    UInt64($9B7691BC5EDCB3BB), UInt64($C7EA619048FE6516),
+    UInt64($1063A61F817AF233), UInt64($47D538683409A693),
+    UInt64($63C2CE984C6DED30), UInt64($2A9FDFD86C81D91D),
+    UInt64($7B1E3B06032A6694), UInt64($666089EBFBD9FD83),
+    UInt64($0A598EE67375207B), UInt64($07449A140AFC495F),
+    UInt64($2CA8A571B6593234), UInt64($1F986F8A45BBC2FB),
+    UInt64($381AA4A050B372C2), UInt64($5423A3ADD81FAF3A),
+    UInt64($17273C0B8B86BB6C), UInt64($FE83258DC869B5A2),
+    UInt64($287902BFD1C980F1), UInt64($F5A94BD66B3837AF),
+    UInt64($88800A79B2CABA12), UInt64($55504310083B0D4C),
+    UInt64($DF36940E07B9EEB2), UInt64($04D1A7CE6790B2C5),
+    UInt64($612413FFF125B4DC), UInt64($26F12B97C52C124F),
+    UInt64($86082351A62F28AC), UInt64($EF93632F9937E5E7),
+    UInt64($3507B052293A1BE6), UInt64($E72C30AE570A9C70),
+    UInt64($D3586041AE1425E0), UInt64($DE4574B3D79D4CC4),
+    UInt64($92BA228040C5685A), UInt64($F00B0CA5DC8C271C),
+    UInt64($BE1287F1F69C5A6E), UInt64($F39E317FB1E0DC86),
+    UInt64($495D114020EC342D), UInt64($699B407E3F18CD4B),
+    UInt64($DCA3A9D46AD51528), UInt64($0D1D14F279896924),
+    UInt64($0000000000000000), UInt64($593EB75FA196C61E),
+    UInt64($2E4E78160B116BD8), UInt64($6D4AE7B058887F8E),
+    UInt64($E65FD013872E3E06), UInt64($7A6DDBBBD30EC4E2),
+    UInt64($AC97FC89CAAEF1B1), UInt64($09CCB33C1E19DBE1),
+    UInt64($89F3EAC462EE1864), UInt64($7770CF49AA87ADC6),
+    UInt64($56C57ECA6557F6D6), UInt64($03953DDA6D6CFB9A),
+    UInt64($36928D884456E07C), UInt64($1EEB8F37959F608D),
+    UInt64($31D6179C4EAAA923), UInt64($6FAC3AD7E5C02662),
+    UInt64($43049FA653991456), UInt64($ABD3669DC052B8EE),
+    UInt64($AF02C153A7C20A2B), UInt64($3CCB036E3723C007),
+    UInt64($93C9C23D90E1CA2C), UInt64($C33BC65E2F6ED7D3),
+    UInt64($4CFF56339758249E), UInt64($B1E94E64325D6AA6),
+    UInt64($37E16D359472420A), UInt64($79F8E661BE623F78),
+    UInt64($5214D90402C74413), UInt64($482EF1FDF0C8965B),
+    UInt64($13F69BC5EC1609A9), UInt64($0E88292814E592BE),
+    UInt64($4E198B542A107D72), UInt64($CCC00FCBEBAFE71B),
+    UInt64($1B49C844222B703E), UInt64($2564164DA840E9D5),
+    UInt64($20C6513E1FF4F966), UInt64($BAC3203F910CE8AB),
+    UInt64($F2EDD1C261C47EF0), UInt64($814CB945ACD361F3),
+    UInt64($95FEB8944A392105), UInt64($5C9CF02C1622D6AD),
+    UInt64($971865F3F77178E9), UInt64($BD87BA2B9BF0A1F4),
+    UInt64($444005B259655D09), UInt64($ED75BE48247FBC0B),
+    UInt64($7596122E17CFF42A), UInt64($B44B091785E97A15),
+    UInt64($966B854E2755DA9F), UInt64($EEE0839249134791),
+    UInt64($32432A4623C652B9), UInt64($A8465B47AD3E4374),
+    UInt64($F8B45F2412B15E8B), UInt64($2417F6F078644BA3),
+    UInt64($FB2162FE7FDDA511), UInt64($4BBBCC279DA46DC1),
+    UInt64($0173E0BDD024A276), UInt64($22208C59A2BCA08A),
+    UInt64($8FC4906DB836F34D), UInt64($E4B90D743A6667EA),
+    UInt64($7147B5E0705F46EF), UInt64($2782CB2A1508B039),
+    UInt64($EC065EF5F45B1E7D), UInt64($21B5B183CFD05B10),
+    UInt64($DBE733C060295C77), UInt64($9FA73672394C017E),
+    UInt64($CF55321186C31C81), UInt64($D8720E1A0D45A7ED),
+    UInt64($3B8F997A3DDF8958), UInt64($3AFC79C7EDFB2B2E),
+    UInt64($E9A4198643EF0ECE), UInt64($5F09CDF67B4E2D37),
+    UInt64($4F6A6BE9FA34DF04), UInt64($B6ADD47038A123F9),
+    UInt64($8D224D0A057EAAA1), UInt64($C96248B85C1BF7A8),
+    UInt64($E3FD9760309A2EB5), UInt64($0B2A6E5BA351820D),
+    UInt64($EB42C4E1FEA75722), UInt64($948D58299A1D8373),
+    UInt64($7FCF9CC864BAD451), UInt64($A55B4FB5D4B72A50),
+    UInt64($08BF5381CE3D7997), UInt64($46A6D8D5E42D04E5),
+    UInt64($D22B80FC7E308796), UInt64($57B69E77B57354A0),
+    UInt64($3969441D8097D0B4), UInt64($3330CAFBF3E2F0CF),
+    UInt64($E28E77DDE0BE8CC3), UInt64($62B12E259C494F46),
+    UInt64($A6CE726FB9DBD1CA), UInt64($41E242C1EED14DBA),
+    UInt64($76032FF47AA30FB0)),
+    THashLibUInt64Array.Create(UInt64($45B268A93ACDE4CC),
+    UInt64($AF7F0BE884549D08), UInt64($048354B3C1468263),
+    UInt64($925435C2C80EFED2), UInt64($EE4E37F27FDFFBA7),
+    UInt64($167A33920C60F14D), UInt64($FB123B52EA03E584),
+    UInt64($4A0CAB53FDBB9007), UInt64($9DEAF6380F788A19),
+    UInt64($CB48EC558F0CB32A), UInt64($B59DC4B2D6FEF7E0),
+    UInt64($DCDBCA22F4F3ECB6), UInt64($11DF5813549A9C40),
+    UInt64($E33FDEDF568ACED3), UInt64($A0C1C8124322E9C3),
+    UInt64($07A56B8158FA6D0D), UInt64($77279579B1E1F3DD),
+    UInt64($D9B18B74422AC004), UInt64($B8EC2D9FFFABC294),
+    UInt64($F4ACF8A82D75914F), UInt64($7BBF69B1EF2B6878),
+    UInt64($C4F62FAF487AC7E1), UInt64($76CE809CC67E5D0C),
+    UInt64($6711D88F92E4C14C), UInt64($627B99D9243DEDFE),
+    UInt64($234AA5C3DFB68B51), UInt64($909B1F15262DBF6D),
+    UInt64($4F66EA054B62BCB5), UInt64($1AE2CF5A52AA6AE8),
+    UInt64($BEA053FBD0CE0148), UInt64($ED6808C0E66314C9),
+    UInt64($43FE16CD15A82710), UInt64($CD049231A06970F6),
+    UInt64($E7BC8A6C97CC4CB0), UInt64($337CE835FCB3B9C0),
+    UInt64($65DEF2587CC780F3), UInt64($52214EDE4132BB50),
+    UInt64($95F15E4390F493DF), UInt64($870839625DD2E0F1),
+    UInt64($41313C1AFB8B66AF), UInt64($91720AF051B211BC),
+    UInt64($477D427ED4EEA573), UInt64($2E3B4CEEF6E3BE25),
+    UInt64($82627834EB0BCC43), UInt64($9C03E3DD78E724C8),
+    UInt64($2877328AD9867DF9), UInt64($14B51945E243B0F2),
+    UInt64($574B0F88F7EB97E2), UInt64($88B6FA989AA4943A),
+    UInt64($19C4F068CB168586), UInt64($50EE6409AF11FAEF),
+    UInt64($7DF317D5C04EABA4), UInt64($7A567C5498B4C6A9),
+    UInt64($B6BBFB804F42188E), UInt64($3CC22BCF3BC5CD0B),
+    UInt64($D04336EAAA397713), UInt64($F02FAC1BEC33132C),
+    UInt64($2506DBA7F0D3488D), UInt64($D7E65D6BF2C31A1E),
+    UInt64($5EB9B2161FF820F5), UInt64($842E0650C46E0F9F),
+    UInt64($716BEB1D9E843001), UInt64($A933758CAB315ED4),
+    UInt64($3FE414FDA2792265), UInt64($27C9F1701EF00932),
+    UInt64($73A4C1CA70A771BE), UInt64($94184BA6E76B3D0E),
+    UInt64($40D829FF8C14C87E), UInt64($0FBEC3FAC77674CB),
+    UInt64($3616A9634A6A9572), UInt64($8F139119C25EF937),
+    UInt64($F545ED4D5AEA3F9E), UInt64($E802499650BA387B),
+    UInt64($6437E7BD0B582E22), UInt64($E6559F89E053E261),
+    UInt64($80AD52E305288DFC), UInt64($6DC55A23E34B9935),
+    UInt64($DE14E0F51AD0AD09), UInt64($C6390578A659865E),
+    UInt64($96D7617109487CB1), UInt64($E2D6CB3A21156002),
+    UInt64($01E915E5779FAED1), UInt64($ADB0213F6A77DCB7),
+    UInt64($9880B76EB9A1A6AB), UInt64($5D9F8D248644CF9B),
+    UInt64($FD5E4536C5662658), UInt64($F1C6B9FE9BACBDFD),
+    UInt64($EACD6341BE9979C4), UInt64($EFA7221708405576),
+    UInt64($510771ECD88E543E), UInt64($C2BA51CB671F043D),
+    UInt64($0AD482AC71AF5879), UInt64($FE787A045CDAC936),
+    UInt64($B238AF338E049AED), UInt64($BD866CC94972EE26),
+    UInt64($615DA6EBBD810290), UInt64($3295FDD08B2C1711),
+    UInt64($F834046073BF0AEA), UInt64($F3099329758FFC42),
+    UInt64($1CAEB13E7DCFA934), UInt64($BA2307481188832B),
+    UInt64($24EFCE42874CE65C), UInt64($0E57D61FB0E9DA1A),
+    UInt64($B3D1BAD6F99B343C), UInt64($C0757B1C893C4582),
+    UInt64($2B510DB8403A9297), UInt64($5C7698C1F1DB614A),
+    UInt64($3E0D0118D5E68CB4), UInt64($D60F488E855CB4CF),
+    UInt64($AE961E0DF3CB33D9), UInt64($3A8E55AB14A00ED7),
+    UInt64($42170328623789C1), UInt64($838B6DD19C946292),
+    UInt64($895FEF7DED3B3AEB), UInt64($CFCBB8E64E4A3149),
+    UInt64($064C7E642F65C3DC), UInt64($3D2B3E2A4C5A63DA),
+    UInt64($5BD3F340A9210C47), UInt64($B474D157A1615931),
+    UInt64($AC5934DA1DE87266), UInt64($6EE365117AF7765B),
+    UInt64($C86ED36716B05C44), UInt64($9BA6885C201D49C5),
+    UInt64($B905387A88346C45), UInt64($131072C4BAB9DDFF),
+    UInt64($BF49461EA751AF99), UInt64($D52977BC1CE05BA1),
+    UInt64($B0F785E46027DB52), UInt64($546D30BA6E57788C),
+    UInt64($305AD707650F56AE), UInt64($C987C682612FF295),
+    UInt64($A5AB8944F5FBC571), UInt64($7ED528E759F244CA),
+    UInt64($8DDCBBCE2C7DB888), UInt64($AA154ABE328DB1BA),
+    UInt64($1E619BE993ECE88B), UInt64($09F2BD9EE813B717),
+    UInt64($7401AA4B285D1CB3), UInt64($21858F143195CAEE),
+    UInt64($48C381841398D1B8), UInt64($FCB750D3B2F98889),
+    UInt64($39A86A998D1CE1B9), UInt64($1F888E0CE473465A),
+    UInt64($7899568376978716), UInt64($02CF2AD7EE2341BF),
+    UInt64($85C713B5B3F1A14E), UInt64($FF916FE12B4567E7),
+    UInt64($7C1A0230B7D10575), UInt64($0C98FCC85ECA9BA5),
+    UInt64($A3E7F720DA9E06AD), UInt64($6A6031A2BBB1F438),
+    UInt64($973E74947ED7D260), UInt64($2CF4663918C0FF9A),
+    UInt64($5F50A7F368678E24), UInt64($34D983B4A449D4CD),
+    UInt64($68AF1B755592B587), UInt64($7F3C3D022E6DEA1B),
+    UInt64($ABFC5F5B45121F6B), UInt64($0D71E92D29553574),
+    UInt64($DFFDF5106D4F03D8), UInt64($081BA87B9F8C19C6),
+    UInt64($DB7EA1A3AC0981BB), UInt64($BBCA12AD66172DFA),
+    UInt64($79704366010829C7), UInt64($179326777BFF5F9C),
+    UInt64($0000000000000000), UInt64($EB2476A4C906D715),
+    UInt64($724DD42F0738DF6F), UInt64($B752EE6538DDB65F),
+    UInt64($37FFBC863DF53BA3), UInt64($8EFA84FCB5C157E6),
+    UInt64($E9EB5C73272596AA), UInt64($1B0BDABF2535C439),
+    UInt64($86E12C872A4D4E20), UInt64($9969A28BCE3E087A),
+    UInt64($FAFB2EB79D9C4B55), UInt64($056A4156B6D92CB2),
+    UInt64($5A3AE6A5DEBEA296), UInt64($22A3B026A8292580),
+    UInt64($53C85B3B36AD1581), UInt64($B11E900117B87583),
+    UInt64($C51F3A4A3FE56930), UInt64($E019E1EDCF3621BD),
+    UInt64($EC811D2591FCBA18), UInt64($445B7D4C4D524A1D),
+    UInt64($A8DA6069DCAEF005), UInt64($58F5CC72309DE329),
+    UInt64($D4C062596B7FF570), UInt64($CE22AD0339D59F98),
+    UInt64($591CD99747024DF8), UInt64($8B90C5AA03187B54),
+    UInt64($F663D27FC356D0F0), UInt64($D8589E9135B56ED5),
+    UInt64($35309651D3D67A1C), UInt64($12F96721CD26732E),
+    UInt64($D28C1C3D441A36AC), UInt64($492A946164077F69),
+    UInt64($2D1D73DC6F5F514B), UInt64($6F0A70F40D68D88A),
+    UInt64($60B4B30ECA1EAC41), UInt64($D36509D83385987D),
+    UInt64($0B3D97490630F6A8), UInt64($9ECCC90A96C46577),
+    UInt64($A20EE2C5AD01A87C), UInt64($E49AB55E0E70A3DE),
+    UInt64($A4429CA182646BA0), UInt64($DA97B446DB962F6A),
+    UInt64($CCED87D4D7F6DE27), UInt64($2AB8185D37A53C46),
+    UInt64($9F25DCEFE15BCBA6), UInt64($C19C6EF9FEA3EB53),
+    UInt64($A764A3931BD884CE), UInt64($2FD2590B817C10F4),
+    UInt64($56A21A6D80743933), UInt64($E573A0BB79EF0D0F),
+    UInt64($155C0CA095DC1E23), UInt64($6C2C4FC694D437E4),
+    UInt64($10364DF623053291), UInt64($DD32DFC7836C4267),
+    UInt64($03263F3299BCEF6E), UInt64($66F8CD6AE57B6F9D),
+    UInt64($8C35AE2B5BE21659), UInt64($31B3C2E21290F87F),
+    UInt64($93BD2027BF915003), UInt64($69460E90220D1B56),
+    UInt64($299E276FAE19D328), UInt64($63928C3C53A2432F),
+    UInt64($7082FEF8E91B9ED0), UInt64($BC6F792C3EED40F7),
+    UInt64($4C40D537D2DE53DB), UInt64($75E8BFAE5FC2B262),
+    UInt64($4DA9C0D2A541FD0A), UInt64($4E8FFFE03CFD1264),
+    UInt64($2620E495696FA7E3), UInt64($E1F0F408B8A98F6C),
+    UInt64($D1AA230FDDA6D9C2), UInt64($C7D0109DD1C6288F),
+    UInt64($8A79D04F7487D585), UInt64($4694579BA3710BA2),
+    UInt64($38417F7CFA834F68), UInt64($1D47A4DB0A5007E5),
+    UInt64($206C9AF1460A643F), UInt64($A128DDF734BD4712),
+    UInt64($8144470672B7232D), UInt64($F2E086CC02105293),
+    UInt64($182DE58DBC892B57), UInt64($CAA1F9B0F8931DFB),
+    UInt64($6B892447CC2E5AE9), UInt64($F9DD11850420A43B),
+    UInt64($4BE5BEB68A243ED6), UInt64($5584255F19C8D65D),
+    UInt64($3B67404E633FA006), UInt64($A68DB6766C472A1F),
+    UInt64($F78AC79AB4C97E21), UInt64($C353442E1080AAEC),
+    UInt64($9A4F9DB95782E714)),
+    THashLibUInt64Array.Create(UInt64($05BA7BC82C9B3220),
+    UInt64($31A54665F8B65E4F), UInt64($B1B651F77547F4D4),
+    UInt64($8BFA0D857BA46682), UInt64($85A96C5AA16A98BB),
+    UInt64($990FAEF908EB79C9), UInt64($A15E37A247F4A62D),
+    UInt64($76857DCD5D27741E), UInt64($F8C50B800A1820BC),
+    UInt64($BE65DCB201F7A2B4), UInt64($666D1B986F9426E7),
+    UInt64($4CC921BF53C4E648), UInt64($95410A0F93D9CA42),
+    UInt64($20CDCCAA647BA4EF), UInt64($429A4060890A1871),
+    UInt64($0C4EA4F69B32B38B), UInt64($CCDA362DDE354CD3),
+    UInt64($96DC23BC7C5B2FA9), UInt64($C309BB68AA851AB3),
+    UInt64($D26131A73648E013), UInt64($021DC52941FC4DB2),
+    UInt64($CD5ADAB7704BE48A), UInt64($A77965D984ED71E6),
+    UInt64($32386FD61734BBA4), UInt64($E82D6DD538AB7245),
+    UInt64($5C2147EA6177B4B1), UInt64($5DA1AB70CF091CE8),
+    UInt64($AC907FCE72B8BDFF), UInt64($57C85DFD972278A8),
+    UInt64($A4E44C6A6B6F940D), UInt64($3851995B4F1FDFE4),
+    UInt64($62578CCAED71BC9E), UInt64($D9882BB0C01D2C0A),
+    UInt64($917B9D5D113C503B), UInt64($A2C31E11A87643C6),
+    UInt64($E463C923A399C1CE), UInt64($F71686C57EA876DC),
+    UInt64($87B4A973E096D509), UInt64($AF0D567D9D3A5814),
+    UInt64($B40C2A3F59DCC6F4), UInt64($3602F88495D121DD),
+    UInt64($D3E1DD3D9836484A), UInt64($F945E71AA46688E5),
+    UInt64($7518547EB2A591F5), UInt64($9366587450C01D89),
+    UInt64($9EA81018658C065B), UInt64($4F54080CBC4603A3),
+    UInt64($2D0384C65137BF3D), UInt64($DC325078EC861E2A),
+    UInt64($EA30A8FC79573FF7), UInt64($214D2030CA050CB6),
+    UInt64($65F0322B8016C30C), UInt64($69BE96DD1B247087),
+    UInt64($DB95EE9981E161B8), UInt64($D1FC1814D9CA05F8),
+    UInt64($820ED2BBCC0DE729), UInt64($63D76050430F14C7),
+    UInt64($3BCCB0E8A09D3A0F), UInt64($8E40764D573F54A2),
+    UInt64($39D175C1E16177BD), UInt64($12F5A37C734F1F4B),
+    UInt64($AB37C12F1FDFC26D), UInt64($5648B167395CD0F1),
+    UInt64($6C04ED1537BF42A7), UInt64($ED97161D14304065),
+    UInt64($7D6C67DAAB72B807), UInt64($EC17FA87BA4EE83C),
+    UInt64($DFAF79CB0304FBC1), UInt64($733F060571BC463E),
+    UInt64($78D61C1287E98A27), UInt64($D07CF48E77B4ADA1),
+    UInt64($B9C262536C90DD26), UInt64($E2449B5860801605),
+    UInt64($8FC09AD7F941FCFB), UInt64($FAD8CEA94BE46D0E),
+    UInt64($A343F28B0608EB9F), UInt64($9B126BD04917347B),
+    UInt64($9A92874AE7699C22), UInt64($1B017C42C4E69EE0),
+    UInt64($3A4C5C720EE39256), UInt64($4B6E9F5E3EA399DA),
+    UInt64($6BA353F45AD83D35), UInt64($E7FEE0904C1B2425),
+    UInt64($22D009832587E95D), UInt64($842980C00F1430E2),
+    UInt64($C6B3C0A0861E2893), UInt64($087433A419D729F2),
+    UInt64($341F3DADD42D6C6F), UInt64($EE0A3FAEFBB2A58E),
+    UInt64($4AEE73C490DD3183), UInt64($AAB72DB5B1A16A34),
+    UInt64($A92A04065E238FDF), UInt64($7B4B35A1686B6FCC),
+    UInt64($6A23BF6EF4A6956C), UInt64($191CB96B851AD352),
+    UInt64($55D598D4D6DE351A), UInt64($C9604DE5F2AE7EF3),
+    UInt64($1CA6C2A3A981E172), UInt64($DE2F9551AD7A5398),
+    UInt64($3025AAFF56C8F616), UInt64($15521D9D1E2860D9),
+    UInt64($506FE31CFA45073A), UInt64($189C55F12B647B0B),
+    UInt64($0180EC9AAE7EA859), UInt64($7CEC8B40050C105E),
+    UInt64($2350E5198BF94104), UInt64($EF8AD33455CC0DD7),
+    UInt64($07A7BEE16D677F92), UInt64($E5E325B90DE76997),
+    UInt64($5A061591A26E637A), UInt64($B611EF1618208B46),
+    UInt64($09F4DF3EB7A981AB), UInt64($1EBB078AE87DACC0),
+    UInt64($B791038CB65E231F), UInt64($0FD38D4574B05660),
+    UInt64($67EDF702C1EA8EBE), UInt64($BA5F4BE0831238CD),
+    UInt64($E3C477C2CEFEBE5C), UInt64($0DCE486C354C1BD2),
+    UInt64($8C5DB36416C31910), UInt64($26EA9ED1A7627324),
+    UInt64($039D29B3EF82E5EB), UInt64($9F28FC82CBF2AE02),
+    UInt64($A8AAE89CF05D2786), UInt64($431AACFA2774B028),
+    UInt64($CF471F9E31B7A938), UInt64($581BD0B8E3922EC8),
+    UInt64($BC78199B400BEF06), UInt64($90FB71C7BF42F862),
+    UInt64($1F3BEB1046030499), UInt64($683E7A47B55AD8DE),
+    UInt64($988F4263A695D190), UInt64($D808C72A6E638453),
+    UInt64($0627527BC319D7CB), UInt64($EBB04466D72997AE),
+    UInt64($E67E0C0AE2658C7C), UInt64($14D2F107B056C880),
+    UInt64($7122C32C30400B8C), UInt64($8A7AE11FD5DACEDB),
+    UInt64($A0DEDB38E98A0E74), UInt64($AD109354DCC615A6),
+    UInt64($0BE91A17F655CC19), UInt64($8DDD5FFEB8BDB149),
+    UInt64($BFE53028AF890AED), UInt64($D65BA6F5B4AD7A6A),
+    UInt64($7956F0882997227E), UInt64($10E8665532B352F9),
+    UInt64($0E5361DFDACEFE39), UInt64($CEC7F3049FC90161),
+    UInt64($FF62B561677F5F2E), UInt64($975CCF26D22587F0),
+    UInt64($51EF0F86543BAF63), UInt64($2F1E41EF10CBF28F),
+    UInt64($52722635BBB94A88), UInt64($AE8DBAE73344F04D),
+    UInt64($410769D36688FD9A), UInt64($B3AB94DE34BBB966),
+    UInt64($801317928DF1AA9B), UInt64($A564A0F0C5113C54),
+    UInt64($F131D4BEBDB1A117), UInt64($7F71A2F3EA8EF5B5),
+    UInt64($40878549C8F655C3), UInt64($7EF14E6944F05DEC),
+    UInt64($D44663DCF55137D8), UInt64($F2ACFD0D523344FC),
+    UInt64($0000000000000000), UInt64($5FBC6E598EF5515A),
+    UInt64($16CF342EF1AA8532), UInt64($B036BD6DDB395C8D),
+    UInt64($13754FE6DD31B712), UInt64($BBDFA77A2D6C9094),
+    UInt64($89E7C8AC3A582B30), UInt64($3C6B0E09CDFA459D),
+    UInt64($C4AE0589C7E26521), UInt64($49735A777F5FD468),
+    UInt64($CAFD64561D2C9B18), UInt64($DA1502032F9FC9E1),
+    UInt64($8867243694268369), UInt64($3782141E3BAF8984),
+    UInt64($9CB5D53124704BE9), UInt64($D7DB4A6F1AD3D233),
+    UInt64($A6F989432A93D9BF), UInt64($9D3539AB8A0EE3B0),
+    UInt64($53F2CAAF15C7E2D1), UInt64($6E19283C76430F15),
+    UInt64($3DEBE2936384EDC4), UInt64($5E3C82C3208BF903),
+    UInt64($33B8834CB94A13FD), UInt64($6470DEB12E686B55),
+    UInt64($359FD1377A53C436), UInt64($61CAA57902F35975),
+    UInt64($043A975282E59A79), UInt64($FD7F70482683129C),
+    UInt64($C52EE913699CCD78), UInt64($28B9FF0E7DAC8D1D),
+    UInt64($5455744E78A09D43), UInt64($CB7D88CCB3523341),
+    UInt64($44BD121B4A13CFBA), UInt64($4D49CD25FDBA4E11),
+    UInt64($3E76CB208C06082F), UInt64($3FF627BA2278A076),
+    UInt64($C28957F204FBB2EA), UInt64($453DFE81E46D67E3),
+    UInt64($94C1E6953DA7621B), UInt64($2C83685CFF491764),
+    UInt64($F32C1197FC4DECA5), UInt64($2B24D6BD922E68F6),
+    UInt64($B22B78449AC5113F), UInt64($48F3B6EDD1217C31),
+    UInt64($2E9EAD75BEB55AD6), UInt64($174FD8B45FD42D6B),
+    UInt64($4ED4E4961238ABFA), UInt64($92E6B4EEFEBEB5D0),
+    UInt64($46A0D7320BEF8208), UInt64($47203BA8A5912A51),
+    UInt64($24F75BF8E69E3E96), UInt64($F0B1382413CF094E),
+    UInt64($FEE259FBC901F777), UInt64($276A724B091CDB7D),
+    UInt64($BDF8F501EE75475F), UInt64($599B3C224DEC8691),
+    UInt64($6D84018F99C1EAFE), UInt64($7498B8E41CDB39AC),
+    UInt64($E0595E71217C5BB7), UInt64($2AA43A273C50C0AF),
+    UInt64($F50B43EC3F543B6E), UInt64($838E3E2162734F70),
+    UInt64($C09492DB4507FF58), UInt64($72BFEA9FDFC2EE67),
+    UInt64($11688ACF9CCDFAA0), UInt64($1A8190D86A9836B9),
+    UInt64($7ACBD93BC615C795), UInt64($C7332C3A286080CA),
+    UInt64($863445E94EE87D50), UInt64($F6966A5FD0D6DE85),
+    UInt64($E9AD814F96D5DA1C), UInt64($70A22FB69E3EA3D5),
+    UInt64($0A69F68D582B6440), UInt64($B8428EC9C2EE757F),
+    UInt64($604A49E3AC8DF12C), UInt64($5B86F90B0C10CB23),
+    UInt64($E1D9B2EB8F02F3EE), UInt64($29391394D3D22544),
+    UInt64($C8E0A17F5CD0D6AA), UInt64($B58CC6A5F7A26EAD),
+    UInt64($8193FB08238F02C2), UInt64($D5C68F465B2F9F81),
+    UInt64($FCFF9CD288FDBAC5), UInt64($77059157F359DC47),
+    UInt64($1D262E3907FF492B), UInt64($FB582233E59AC557),
+    UInt64($DDB2BCE242F8B673), UInt64($2577B76248E096CF),
+    UInt64($6F99C4A6D83DA74C), UInt64($C1147E41EB795701),
+    UInt64($F48BAF76912A9337)),
+    THashLibUInt64Array.Create(UInt64($3EF29D249B2C0A19),
+    UInt64($E9E16322B6F8622F), UInt64($5536994047757F7A),
+    UInt64($9F4D56D5A47B0B33), UInt64($822567466AA1174C),
+    UInt64($B8F5057DEB082FB2), UInt64($CC48C10BF4475F53),
+    UInt64($373088D4275DEC3A), UInt64($968F4325180AED10),
+    UInt64($173D232CF7016151), UInt64($AE4ED09F946FCC13),
+    UInt64($FD4B4741C4539873), UInt64($1B5B3F0DD9933765),
+    UInt64($2FFCB0967B644052), UInt64($E02376D20A89840C),
+    UInt64($A3AE3A70329B18D7), UInt64($419CBD2335DE8526),
+    UInt64($FAFEBF115B7C3199), UInt64($0397074F85AA9B0D),
+    UInt64($C58AD4FB4836B970), UInt64($BEC60BE3FC4104A8),
+    UInt64($1EFF36DC4B708772), UInt64($131FDC33ED8453B6),
+    UInt64($0844E33E341764D3), UInt64($0FF11B6EAB38CD39),
+    UInt64($64351F0A7761B85A), UInt64($3B5694F509CFBA0E),
+    UInt64($30857084B87245D0), UInt64($47AFB3BD2297AE3C),
+    UInt64($F2BA5C2F6F6B554A), UInt64($74BDC4761F4F70E1),
+    UInt64($CFDFC64471EDC45E), UInt64($E610784C1DC0AF16),
+    UInt64($7ACA29D63C113F28), UInt64($2DED411776A859AF),
+    UInt64($AC5F211E99A3D5EE), UInt64($D484F949A87EF33B),
+    UInt64($3CE36CA596E013E4), UInt64($D120F0983A9D432C),
+    UInt64($6BC40464DC597563), UInt64($69D5F5E5D1956C9E),
+    UInt64($9AE95F043698BB24), UInt64($C9ECC8DA66A4EF44),
+    UInt64($D69508C8A5B2EAC6), UInt64($C40C2235C0503B80),
+    UInt64($38C193BA8C652103), UInt64($1CEEC75D46BC9E8F),
+    UInt64($D331011937515AD1), UInt64($D8E2E56886ECA50F),
+    UInt64($B137108D5779C991), UInt64($709F3B6905CA4206),
+    UInt64($4FEB50831680CAEF), UInt64($EC456AF3241BD238),
+    UInt64($58D673AFE181ABBE), UInt64($242F54E7CAD9BF8C),
+    UInt64($0211F1810DCC19FD), UInt64($90BC4DBB0F43C60A),
+    UInt64($9518446A9DA0761D), UInt64($A1BFCBF13F57012A),
+    UInt64($2BDE4F8961E172B5), UInt64($27B853A84F732481),
+    UInt64($B0B1E643DF1F4B61), UInt64($18CC38425C39AC68),
+    UInt64($D2B7F7D7BF37D821), UInt64($3103864A3014C720),
+    UInt64($14AA246372ABFA5C), UInt64($6E600DB54EBAC574),
+    UInt64($394765740403A3F3), UInt64($09C215F0BC71E623),
+    UInt64($2A58B947E987F045), UInt64($7B4CDF18B477BDD8),
+    UInt64($9709B5EB906C6FE0), UInt64($73083C268060D90B),
+    UInt64($FEDC400E41F9037E), UInt64($284948C6E44BE9B8),
+    UInt64($728ECAE808065BFB), UInt64($06330E9E17492B1A),
+    UInt64($5950856169E7294E), UInt64($BAE4F4FCE6C4364F),
+    UInt64($CA7BCF95E30E7449), UInt64($7D7FD186A33E96C2),
+    UInt64($52836110D85AD690), UInt64($4DFAA1021B4CD312),
+    UInt64($913ABB75872544FA), UInt64($DD46ECB9140F1518),
+    UInt64($3D659A6B1E869114), UInt64($C23F2CABD719109A),
+    UInt64($D713FE062DD46836), UInt64($D0A60656B2FBC1DC),
+    UInt64($221C5A79DD909496), UInt64($EFD26DBCA1B14935),
+    UInt64($0E77EDA0235E4FC9), UInt64($CBFD395B6B68F6B9),
+    UInt64($0DE0EAEFA6F4D4C4), UInt64($0422FF1F1A8532E7),
+    UInt64($F969B85EDED6AA94), UInt64($7F6E2007AEF28F3F),
+    UInt64($3AD0623B81A938FE), UInt64($6624EE8B7AADA1A7),
+    UInt64($B682E8DDC856607B), UInt64($A78CC56F281E2A30),
+    UInt64($C79B257A45FAA08D), UInt64($5B4174E0642B30B3),
+    UInt64($5F638BFF7EAE0254), UInt64($4BC9AF9C0C05F808),
+    UInt64($CE59308AF98B46AE), UInt64($8FC58DA9CC55C388),
+    UInt64($803496C7676D0EB1), UInt64($F33CAAE1E70DD7BA),
+    UInt64($BB6202326EA2B4BF), UInt64($D5020F87201871CB),
+    UInt64($9D5CA754A9B712CE), UInt64($841669D87DE83C56),
+    UInt64($8A6184785EB6739F), UInt64($420BBA6CB0741E2B),
+    UInt64($F12D5B60EAC1CE47), UInt64($76AC35F71283691C),
+    UInt64($2C6BB7D9FECEDB5F), UInt64($FCCDB18F4C351A83),
+    UInt64($1F79C012C3160582), UInt64($F0ABADAE62A74CB7),
+    UInt64($E1A5801C82EF06FC), UInt64($67A21845F2CB2357),
+    UInt64($5114665F5DF04D9D), UInt64($BF40FD2D74278658),
+    UInt64($A0393D3FB73183DA), UInt64($05A409D192E3B017),
+    UInt64($A9FB28CF0B4065F9), UInt64($25A9A22942BF3D7C),
+    UInt64($DB75E22703463E02), UInt64($B326E10C5AB5D06C),
+    UInt64($E7968E8295A62DE6), UInt64($B973F3B3636EAD42),
+    UInt64($DF571D3819C30CE5), UInt64($EE549B7229D7CBC5),
+    UInt64($12992AFD65E2D146), UInt64($F8EF4E9056B02864),
+    UInt64($B7041E134030E28B), UInt64($C02EDD2ADAD50967),
+    UInt64($932B4AF48AE95D07), UInt64($6FE6FB7BC6DC4784),
+    UInt64($239AACB755F61666), UInt64($401A4BEDBDB807D6),
+    UInt64($485EA8D389AF6305), UInt64($A41BC220ADB4B13D),
+    UInt64($753B32B89729F211), UInt64($997E584BB3322029),
+    UInt64($1D683193CEDA1C7F), UInt64($FF5AB6C0C99F818E),
+    UInt64($16BBD5E27F67E3A1), UInt64($A59D34EE25D233CD),
+    UInt64($98F8AE853B54A2D9), UInt64($6DF70AFACB105E79),
+    UInt64($795D2E99B9BBA425), UInt64($8E437B6744334178),
+    UInt64($0186F6CE886682F0), UInt64($EBF092A3BB347BD2),
+    UInt64($BCD7FA62F18D1D55), UInt64($ADD9D7D011C5571E),
+    UInt64($0BD3E471B1BDFFDE), UInt64($AA6C2F808EEAFEF4),
+    UInt64($5EE57D31F6C880A4), UInt64($F50FA47FF044FCA0),
+    UInt64($1ADDC9C351F5B595), UInt64($EA76646D3352F922),
+    UInt64($0000000000000000), UInt64($85909F16F58EBEA6),
+    UInt64($46294573AAF12CCC), UInt64($0A5512BF39DB7D2E),
+    UInt64($78DBD85731DD26D5), UInt64($29CFBE086C2D6B48),
+    UInt64($218B5D36583A0F9B), UInt64($152CD2ADFACD78AC),
+    UInt64($83A39188E2C795BC), UInt64($C3B9DA655F7F926A),
+    UInt64($9ECBA01B2C1D89C3), UInt64($07B5F8509F2FA9EA),
+    UInt64($7EE8D6C926940DCF), UInt64($36B67E1AAF3B6ECA),
+    UInt64($86079859702425AB), UInt64($FB7849DFD31AB369),
+    UInt64($4C7C57CC932A51E2), UInt64($D96413A60E8A27FF),
+    UInt64($263EA566C715A671), UInt64($6C71FC344376DC89),
+    UInt64($4A4F595284637AF8), UInt64($DAF314E98B20BCF2),
+    UInt64($572768C14AB96687), UInt64($1088DB7C682EC8BB),
+    UInt64($887075F9537A6A62), UInt64($2E7A4658F302C2A2),
+    UInt64($619116DBE582084D), UInt64($A87DDE018326E709),
+    UInt64($DCC01A779C6997E8), UInt64($EDC39C3DAC7D50C8),
+    UInt64($A60A33A1A078A8C0), UInt64($C1A82BE452B38B97),
+    UInt64($3F746BEA134A88E9), UInt64($A228CCBEBAFD9A27),
+    UInt64($ABEAD94E068C7C04), UInt64($F48952B178227E50),
+    UInt64($5CF48CB0FB049959), UInt64($6017E0156DE48ABD),
+    UInt64($4438B4F2A73D3531), UInt64($8C528AE649FF5885),
+    UInt64($B515EF924DFCFB76), UInt64($0C661C212E925634),
+    UInt64($B493195CC59A7986), UInt64($9CDA519A21D1903E),
+    UInt64($32948105B5BE5C2D), UInt64($194ACE8CD45F2E98),
+    UInt64($438D4CA238129CDB), UInt64($9B6FA9CABEFE39D4),
+    UInt64($81B26009EF0B8C41), UInt64($DED1EBF691A58E15),
+    UInt64($4E6DA64D9EE6481F), UInt64($54B06F8ECF13FD8A),
+    UInt64($49D85E1D01C9E1F5), UInt64($AFC826511C094EE3),
+    UInt64($F698A33075EE67AD), UInt64($5AC7822EEC4DB243),
+    UInt64($8DD47C28C199DA75), UInt64($89F68337DB1CE892),
+    UInt64($CDCE37C57C21DDA3), UInt64($530597DE503C5460),
+    UInt64($6A42F2AA543FF793), UInt64($5D727A7E73621BA9),
+    UInt64($E232875307459DF1), UInt64($56A19E0FC2DFE477),
+    UInt64($C61DD3B4CD9C227D), UInt64($E5877F03986A341B),
+    UInt64($949EB2A415C6F4ED), UInt64($6206119460289340),
+    UInt64($6380E75AE84E11B0), UInt64($8BE772B6D6D0F16F),
+    UInt64($50929091D596CF6D), UInt64($E86795EC3E9EE0DF),
+    UInt64($7CF927482B581432), UInt64($C86A3E14EEC26DB4),
+    UInt64($7119CDA78DACC0F6), UInt64($E40189CD100CB6EB),
+    UInt64($92ADBC3A028FDFF7), UInt64($B2A017C2D2D3529C),
+    UInt64($200DABF8D05C8D6B), UInt64($34A78F9BA2F77737),
+    UInt64($E3B4719D8F231F01), UInt64($45BE423C2F5BB7C1),
+    UInt64($F71E55FEFD88E55D), UInt64($6853032B59F3EE6E),
+    UInt64($65B3E9C4FF073AAA), UInt64($772AC3399AE5EBEC),
+    UInt64($87816E97F842A75B), UInt64($110E2DB2E0484A4B),
+    UInt64($331277CB3DD8DEDD), UInt64($BD510CAC79EB9FA5),
+    UInt64($352179552A91F5C7)),
+    THashLibUInt64Array.Create(UInt64($8AB0A96846E06A6D),
+    UInt64($43C7E80B4BF0B33A), UInt64($08C9B3546B161EE5),
+    UInt64($39F1C235EBA990BE), UInt64($C1BEF2376606C7B2),
+    UInt64($2C209233614569AA), UInt64($EB01523B6FC3289A),
+    UInt64($946953AB935ACEDD), UInt64($272838F63E13340E),
+    UInt64($8B0455ECA12BA052), UInt64($77A1B2C4978FF8A2),
+    UInt64($A55122CA13E54086), UInt64($2276135862D3F1CD),
+    UInt64($DB8DDFDE08B76CFE), UInt64($5D1E12C89E4A178A),
+    UInt64($0E56816B03969867), UInt64($EE5F79953303ED59),
+    UInt64($AFED748BAB78D71D), UInt64($6D929F2DF93E53EE),
+    UInt64($F5D8A8F8BA798C2A), UInt64($F619B1698E39CF6B),
+    UInt64($95DDAF2F749104E2), UInt64($EC2A9C80E0886427),
+    UInt64($CE5C8FD8825B95EA), UInt64($C4E0D9993AC60271),
+    UInt64($4699C3A5173076F9), UInt64($3D1B151F50A29F42),
+    UInt64($9ED505EA2BC75946), UInt64($34665ACFDC7F4B98),
+    UInt64($61B1FB53292342F7), UInt64($C721C0080E864130),
+    UInt64($8693CD1696FD7B74), UInt64($872731927136B14B),
+    UInt64($D3446C8A63A1721B), UInt64($669A35E8A6680E4A),
+    UInt64($CAB658F239509A16), UInt64($A4E5DE4EF42E8AB9),
+    UInt64($37A7435EE83F08D9), UInt64($134E6239E26C7F96),
+    UInt64($82791A3C2DF67488), UInt64($3F6EF00A8329163C),
+    UInt64($8E5A7E42FDEB6591), UInt64($5CAAEE4C7981DDB5),
+    UInt64($19F234785AF1E80D), UInt64($255DDDE3ED98BD70),
+    UInt64($50898A32A99CCCAC), UInt64($28CA4519DA4E6656),
+    UInt64($AE59880F4CB31D22), UInt64($0D9798FA37D6DB26),
+    UInt64($32F968F0B4FFCD1A), UInt64($A00F09644F258545),
+    UInt64($FA3AD5175E24DE72), UInt64($F46C547C5DB24615),
+    UInt64($713E80FBFF0F7E20), UInt64($7843CF2B73D2AAFA),
+    UInt64($BD17EA36AEDF62B4), UInt64($FD111BACD16F92CF),
+    UInt64($4ABAA7DBC72D67E0), UInt64($B3416B5DAD49FAD3),
+    UInt64($BCA316B24914A88B), UInt64($15D150068AECF914),
+    UInt64($E27C1DEBE31EFC40), UInt64($4FE48C759BEDA223),
+    UInt64($7EDCFD141B522C78), UInt64($4E5070F17C26681C),
+    UInt64($E696CAC15815F3BC), UInt64($35D2A64B3BB481A7),
+    UInt64($800CFF29FE7DFDF6), UInt64($1ED9FAC3D5BAA4B0),
+    UInt64($6C2663A91EF599D1), UInt64($03C1199134404341),
+    UInt64($F7AD4DED69F20554), UInt64($CD9D9649B61BD6AB),
+    UInt64($C8C3BDE7EADB1368), UInt64($D131899FB02AFB65),
+    UInt64($1D18E352E1FAE7F1), UInt64($DA39235AEF7CA6C1),
+    UInt64($A1BBF5E0A8EE4F7A), UInt64($91377805CF9A0B1E),
+    UInt64($3138716180BF8E5B), UInt64($D9F83ACBDB3CE580),
+    UInt64($0275E515D38B897E), UInt64($472D3F21F0FBBCC6),
+    UInt64($2D946EB7868EA395), UInt64($BA3C248D21942E09),
+    UInt64($E7223645BFDE3983), UInt64($FF64FEB902E41BB1),
+    UInt64($C97741630D10D957), UInt64($C3CB1722B58D4ECC),
+    UInt64($A27AEC719CAE0C3B), UInt64($99FECB51A48C15FB),
+    UInt64($1465AC826D27332B), UInt64($E1BD047AD75EBF01),
+    UInt64($79F733AF941960C5), UInt64($672EC96C41A3C475),
+    UInt64($C27FEBA6524684F3), UInt64($64EFD0FD75E38734),
+    UInt64($ED9E60040743AE18), UInt64($FB8E2993B9EF144D),
+    UInt64($38453EB10C625A81), UInt64($6978480742355C12),
+    UInt64($48CF42CE14A6EE9E), UInt64($1CAC1FD606312DCE),
+    UInt64($7B82D6BA4792E9BB), UInt64($9D141C7B1F871A07),
+    UInt64($5616B80DC11C4A2E), UInt64($B849C198F21FA777),
+    UInt64($7CA91801C8D9A506), UInt64($B1348E487EC273AD),
+    UInt64($41B20D1E987B3A44), UInt64($7460AB55A3CFBBE3),
+    UInt64($84E628034576F20A), UInt64($1B87D16D897A6173),
+    UInt64($0FE27DEFE45D5258), UInt64($83CDE6B8CA3DBEB7),
+    UInt64($0C23647ED01D1119), UInt64($7A362A3EA0592384),
+    UInt64($B61F40F3F1893F10), UInt64($75D457D1440471DC),
+    UInt64($4558DA34237035B8), UInt64($DCA6116587FC2043),
+    UInt64($8D9B67D3C9AB26D0), UInt64($2B0B5C88EE0E2517),
+    UInt64($6FE77A382AB5DA90), UInt64($269CC472D9D8FE31),
+    UInt64($63C41E46FAA8CB89), UInt64($B7ABBC771642F52F),
+    UInt64($7D1DE4852F126F39), UInt64($A8C6BA3024339BA0),
+    UInt64($600507D7CEE888C8), UInt64($8FEE82C61A20AFAE),
+    UInt64($57A2448926D78011), UInt64($FCA5E72836A458F0),
+    UInt64($072BCEBB8F4B4CBD), UInt64($497BBE4AF36D24A1),
+    UInt64($3CAFE99BB769557D), UInt64($12FA9EBD05A7B5A9),
+    UInt64($E8C04BAA5B836BDB), UInt64($4273148FAC3B7905),
+    UInt64($908384812851C121), UInt64($E557D3506C55B0FD),
+    UInt64($72FF996ACB4F3D61), UInt64($3EDA0C8E64E2DC03),
+    UInt64($F0868356E6B949E9), UInt64($04EAD72ABB0B0FFC),
+    UInt64($17A4B5135967706A), UInt64($E3C8E16F04D5367F),
+    UInt64($F84F30028DAF570C), UInt64($1846C8FCBD3A2232),
+    UInt64($5B8120F7F6CA9108), UInt64($D46FA231ECEA3EA6),
+    UInt64($334D947453340725), UInt64($58403966C28AD249),
+    UInt64($BED6F3A79A9F21F5), UInt64($68CCB483A5FE962D),
+    UInt64($D085751B57E1315A), UInt64($FED0023DE52FD18E),
+    UInt64($4B0E5B5F20E6ADDF), UInt64($1A332DE96EB1AB4C),
+    UInt64($A3CE10F57B65C604), UInt64($108F7BA8D62C3CD7),
+    UInt64($AB07A3A11073D8E1), UInt64($6B0DAD1291BED56C),
+    UInt64($F2F366433532C097), UInt64($2E557726B2CEE0D4),
+    UInt64($0000000000000000), UInt64($CB02A476DE9B5029),
+    UInt64($E4E32FD48B9E7AC2), UInt64($734B65EE2C84F75E),
+    UInt64($6E5386BCCD7E10AF), UInt64($01B4FC84E7CBCA3F),
+    UInt64($CFE8735C65905FD5), UInt64($3613BFDA0FF4C2E6),
+    UInt64($113B872C31E7F6E8), UInt64($2FE18BA255052AEB),
+    UInt64($E974B72EBC48A1E4), UInt64($0ABC5641B89D979B),
+    UInt64($B46AA5E62202B66E), UInt64($44EC26B0C4BBFF87),
+    UInt64($A6903B5B27A503C7), UInt64($7F680190FC99E647),
+    UInt64($97A84A3AA71A8D9C), UInt64($DD12EDE16037EA7C),
+    UInt64($C554251DDD0DC84E), UInt64($88C54C7D956BE313),
+    UInt64($4D91696048662B5D), UInt64($B08072CC9909B992),
+    UInt64($B5DE5962C5C97C51), UInt64($81B803AD19B637C9),
+    UInt64($B2F597D94A8230EC), UInt64($0B08AAC55F565DA4),
+    UInt64($F1327FD2017283D6), UInt64($AD98919E78F35E63),
+    UInt64($6AB9519676751F53), UInt64($24E921670A53774F),
+    UInt64($B9FD3D1C15D46D48), UInt64($92F66194FBDA485F),
+    UInt64($5A35DC7311015B37), UInt64($DED3F4705477A93D),
+    UInt64($C00A0EB381CD0D8D), UInt64($BB88D809C65FE436),
+    UInt64($16104997BEACBA55), UInt64($21B70AC95693B28C),
+    UInt64($59F4C5E225411876), UInt64($D5DB5EB50B21F499),
+    UInt64($55D7A19CF55C096F), UInt64($A97246B4C3F8519F),
+    UInt64($8552D487A2BD3835), UInt64($54635D181297C350),
+    UInt64($23C2EFDC85183BF2), UInt64($9F61F96ECC0C9379),
+    UInt64($534893A39DDC8FED), UInt64($5EDF0B59AA0A54CB),
+    UInt64($AC2C6D1A9F38945C), UInt64($D7AEBBA0D8AA7DE7),
+    UInt64($2ABFA00C09C5EF28), UInt64($D84CC64F3CF72FBF),
+    UInt64($2003F64DB15878B3), UInt64($A724C7DFC06EC9F8),
+    UInt64($069F323F68808682), UInt64($CC296ACD51D01C94),
+    UInt64($055E2BAE5CC0C5C3), UInt64($6270E2C21D6301B6),
+    UInt64($3B842720382219C0), UInt64($D2F0900E846AB824),
+    UInt64($52FC6F277A1745D2), UInt64($C6953C8CE94D8B0F),
+    UInt64($E009F8FE3095753E), UInt64($655B2C7992284D0B),
+    UInt64($984A37D54347DFC4), UInt64($EAB5AEBF8808E2A5),
+    UInt64($9A3FD2C090CC56BA), UInt64($9CA0E0FFF84CD038),
+    UInt64($4C2595E4AFADE162), UInt64($DF6708F4B3BC6302),
+    UInt64($BF620F237D54EBCA), UInt64($93429D101C118260),
+    UInt64($097D4FD08CDDD4DA), UInt64($8C2F9B572E60ECEF),
+    UInt64($708A7C7F18C4B41F), UInt64($3A30DBA4DFE9D3FF),
+    UInt64($4006F19A7FB0F07B), UInt64($5F6BF7DD4DC19EF4),
+    UInt64($1F6D064732716E8F), UInt64($F9FBCC866A649D33),
+    UInt64($308C8DE567744464), UInt64($8971B0F972A0292C),
+    UInt64($D61A47243F61B7D8), UInt64($EFEB8511D4C82766),
+    UInt64($961CB6BE40D147A3), UInt64($AAB35F25F7B812DE),
+    UInt64($76154E407044329D), UInt64($513D76B64E570693),
+    UInt64($F3479AC7D2F90AA8), UInt64($9B8B2E4477079C85),
+    UInt64($297EB99D3D85AC69)),
+    THashLibUInt64Array.Create(UInt64($7E37E62DFC7D40C3),
+    UInt64($776F25A4EE939E5B), UInt64($E045C850DD8FB5AD),
+    UInt64($86ED5BA711FF1952), UInt64($E91D0BD9CF616B35),
+    UInt64($37E0AB256E408FFB), UInt64($9607F6C031025A7A),
+    UInt64($0B02F5E116D23C9D), UInt64($F3D8486BFB50650C),
+    UInt64($621CFF27C40875F5), UInt64($7D40CB71FA5FD34A),
+    UInt64($6DAA6616DAA29062), UInt64($9F5F354923EC84E2),
+    UInt64($EC847C3DC507C3B3), UInt64($025A3668043CE205),
+    UInt64($A8BF9E6C4DAC0B19), UInt64($FA808BE2E9BEBB94),
+    UInt64($B5B99C5277C74FA3), UInt64($78D9BC95F0397BCC),
+    UInt64($E332E50CDBAD2624), UInt64($C74FCE129332797E),
+    UInt64($1729ECEB2EA709AB), UInt64($C2D6B9F69954D1F8),
+    UInt64($5D898CBFBAB8551A), UInt64($859A76FB17DD8ADB),
+    UInt64($1BE85886362F7FB5), UInt64($F6413F8FF136CD8A),
+    UInt64($D3110FA5BBB7E35C), UInt64($0A2FEED514CC4D11),
+    UInt64($E83010EDCD7F1AB9), UInt64($A1E75DE55F42D581),
+    UInt64($EEDE4A55C13B21B6), UInt64($F2F5535FF94E1480),
+    UInt64($0CC1B46D1888761E), UInt64($BCE15FDB6529913B),
+    UInt64($2D25E8975A7181C2), UInt64($71817F1CE2D7A554),
+    UInt64($2E52C5CB5C53124B), UInt64($F9F7A6BEEF9C281D),
+    UInt64($9E722E7D21F2F56E), UInt64($CE170D9B81DCA7E6),
+    UInt64($0E9B82051CB4941B), UInt64($1E712F623C49D733),
+    UInt64($21E45CFA42F9F7DC), UInt64($CB8E7A7F8BBA0F60),
+    UInt64($8E98831A010FB646), UInt64($474CCF0D8E895B23),
+    UInt64($A99285584FB27A95), UInt64($8CC2B57205335443),
+    UInt64($42D5B8E984EFF3A5), UInt64($012D1B34021E718C),
+    UInt64($57A6626AAE74180B), UInt64($FF19FC06E3D81312),
+    UInt64($35BA9D4D6A7C6DFE), UInt64($C9D44C178F86ED65),
+    UInt64($506523E6A02E5288), UInt64($03772D5C06229389),
+    UInt64($8B01F4FE0B691EC0), UInt64($F8DABD8AED825991),
+    UInt64($4C4E3AEC985B67BE), UInt64($B10DF0827FBF96A9),
+    UInt64($6A69279AD4F8DAE1), UInt64($E78689DCD3D5FF2E),
+    UInt64($812E1A2B1FA553D1), UInt64($FBAD90D6EBA0CA18),
+    UInt64($1AC543B234310E39), UInt64($1604F7DF2CB97827),
+    UInt64($A6241C6951189F02), UInt64($753513CCEAAF7C5E),
+    UInt64($64F2A59FC84C4EFA), UInt64($247D2B1E489F5F5A),
+    UInt64($DB64D718AB474C48), UInt64($79F4A7A1F2270A40),
+    UInt64($1573DA832A9BEBAE), UInt64($3497867968621C72),
+    UInt64($514838D2A2302304), UInt64($F0AF6537FD72F685),
+    UInt64($1D06023E3A6B44BA), UInt64($678588C3CE6EDD73),
+    UInt64($66A893F7CC70ACFF), UInt64($D4D24E29B5EDA9DF),
+    UInt64($3856321470EA6A6C), UInt64($07C3418C0E5A4A83),
+    UInt64($2BCBB22F5635BACD), UInt64($04B46CD00878D90A),
+    UInt64($06EE5AB80C443B0F), UInt64($3B211F4876C8F9E5),
+    UInt64($0958C38912EEDE98), UInt64($D14B39CDBF8B0159),
+    UInt64($397B292072F41BE0), UInt64($87C0409313E168DE),
+    UInt64($AD26E98847CAA39F), UInt64($4E140C849C6785BB),
+    UInt64($D5FF551DB7F3D853), UInt64($A0CA46D15D5CA40D),
+    UInt64($CD6020C787FE346F), UInt64($84B76DCF15C3FB57),
+    UInt64($DEFDA0FCA121E4CE), UInt64($4B8D7B6096012D3D),
+    UInt64($9AC642AD298A2C64), UInt64($0875D8BD10F0AF14),
+    UInt64($B357C6EA7B8374AC), UInt64($4D6321D89A451632),
+    UInt64($EDA96709C719B23F), UInt64($F76C24BBF328BC06),
+    UInt64($C662D526912C08F2), UInt64($3CE25EC47892B366),
+    UInt64($B978283F6F4F39BD), UInt64($C08C8F9E9D6833FD),
+    UInt64($4F3917B09E79F437), UInt64($593DE06FB2C08C10),
+    UInt64($D6887841B1D14BDA), UInt64($19B26EEE32139DB0),
+    UInt64($B494876675D93E2F), UInt64($825937771987C058),
+    UInt64($90E9AC783D466175), UInt64($F1827E03FF6C8709),
+    UInt64($945DC0A8353EB87F), UInt64($4516F9658AB5B926),
+    UInt64($3F9573987EB020EF), UInt64($B855330B6D514831),
+    UInt64($2AE6A91B542BCB41), UInt64($6331E413C6160479),
+    UInt64($408F8E8180D311A0), UInt64($EFF35161C325503A),
+    UInt64($D06622F9BD9570D5), UInt64($8876D9A20D4B8D49),
+    UInt64($A5533135573A0C8B), UInt64($E168D364DF91C421),
+    UInt64($F41B09E7F50A2F8F), UInt64($12B09B0F24C1A12D),
+    UInt64($DA49CC2CA9593DC4), UInt64($1F5C34563E57A6BF),
+    UInt64($54D14F36A8568B82), UInt64($AF7CDFE043F6419A),
+    UInt64($EA6A2685C943F8BC), UInt64($E5DCBFB4D7E91D2B),
+    UInt64($B27ADDDE799D0520), UInt64($6B443CAED6E6AB6D),
+    UInt64($7BAE91C9F61BE845), UInt64($3EB868AC7CAE5163),
+    UInt64($11C7B65322E332A4), UInt64($D23C1491B9A992D0),
+    UInt64($8FB5982E0311C7CA), UInt64($70AC6428E0C9D4D8),
+    UInt64($895BC2960F55FCC5), UInt64($76423E90EC8DEFD7),
+    UInt64($6FF0507EDE9E7267), UInt64($3DCF45F07A8CC2EA),
+    UInt64($4AA06054941F5CB1), UInt64($5810FB5BB0DEFD9C),
+    UInt64($5EFEA1E3BC9AC693), UInt64($6EDD4B4ADC8003EB),
+    UInt64($741808F8E8B10DD2), UInt64($145EC1B728859A22),
+    UInt64($28BC9F7350172944), UInt64($270A06424EBDCCD3),
+    UInt64($972AEDF4331C2BF6), UInt64($059977E40A66A886),
+    UInt64($2550302A4A812ED6), UInt64($DD8A8DA0A7037747),
+    UInt64($C515F87A970E9B7B), UInt64($3023EAA9601AC578),
+    UInt64($B7E3AA3A73FBADA6), UInt64($0FB699311EAAE597),
+    UInt64($0000000000000000), UInt64($310EF19D6204B4F4),
+    UInt64($229371A644DB6455), UInt64($0DECAF591A960792),
+    UInt64($5CA4978BB8A62496), UInt64($1C2B190A38753536),
+    UInt64($41A295B582CD602C), UInt64($3279DCC16426277D),
+    UInt64($C1A194AA9F764271), UInt64($139D803B26DFD0A1),
+    UInt64($AE51C4D441E83016), UInt64($D813FA44AD65DFC1),
+    UInt64($AC0BF2BC45D4D213), UInt64($23BE6A9246C515D9),
+    UInt64($49D74D08923DCF38), UInt64($9D05032127D066E7),
+    UInt64($2F7FDEFF5E4D63C7), UInt64($A47E2A0155247D07),
+    UInt64($99B16FF12FA8BFED), UInt64($4661D4398C972AAF),
+    UInt64($DFD0BBC8A33F9542), UInt64($DCA79694A51D06CB),
+    UInt64($B020EBB67DA1E725), UInt64($BA0F0563696DAA34),
+    UInt64($E4F1A480D5F76CA7), UInt64($C438E34E9510EAF7),
+    UInt64($939E81243B64F2FC), UInt64($8DEFAE46072D25CF),
+    UInt64($2C08F3A3586FF04E), UInt64($D7A56375B3CF3A56),
+    UInt64($20C947CE40E78650), UInt64($43F8A3DD86F18229),
+    UInt64($568B795EAC6A6987), UInt64($8003011F1DBB225D),
+    UInt64($F53612D3F7145E03), UInt64($189F75DA300DEC3C),
+    UInt64($9570DB9C3720C9F3), UInt64($BB221E576B73DBB8),
+    UInt64($72F65240E4F536DD), UInt64($443BE25188ABC8AA),
+    UInt64($E21FFE38D9B357A8), UInt64($FD43CA6EE7E4F117),
+    UInt64($CAA3614B89A47EEC), UInt64($FE34E732E1C6629E),
+    UInt64($83742C431B99B1D4), UInt64($CF3A16AF83C2D66A),
+    UInt64($AAE5A8044990E91C), UInt64($26271D764CA3BD5F),
+    UInt64($91C4B74C3F5810F9), UInt64($7C6DD045F841A2C6),
+    UInt64($7F1AFD19FE63314F), UInt64($C8F957238D989CE9),
+    UInt64($A709075D5306EE8E), UInt64($55FC5402AA48FA0E),
+    UInt64($48FA563C9023BEB4), UInt64($65DFBEABCA523F76),
+    UInt64($6C877D22D8BCE1EE), UInt64($CC4D3BF385E045E3),
+    UInt64($BEBB69B36115733E), UInt64($10EAAD6720FD4328),
+    UInt64($B6CEB10E71E5DC2A), UInt64($BDCC44EF6737E0B7),
+    UInt64($523F158EA412B08D), UInt64($989C74C52DB6CE61),
+    UInt64($9BEB59992B945DE8), UInt64($8A2CEFCA09776F4C),
+    UInt64($A3BD6B8D5B7E3784), UInt64($EB473DB1CB5D8930),
+    UInt64($C3FBA2C29B4AA074), UInt64($9C28181525CE176B),
+    UInt64($683311F2D0C438E4), UInt64($5FD3BAD7BE84B71F),
+    UInt64($FC6ED15AE5FA809B), UInt64($36CDB0116C5EFE77),
+    UInt64($29918447520958C8), UInt64($A29070B959604608),
+    UInt64($53120EBAA60CC101), UInt64($3A0C047C74D68869),
+    UInt64($691E0AC6D2DA4968), UInt64($73DB4974E6EB4751),
+    UInt64($7A838AFDF40599C9), UInt64($5A4ACD33B4E21F99),
+    UInt64($6046C94FC03497F0), UInt64($E6AB92E8D1CB8EA2),
+    UInt64($3354C7F5663856F1), UInt64($D93EE170AF7BAE4D),
+    UInt64($616BD27BC22AE67C), UInt64($92B39A10397A8370),
+    UInt64($ABC8B3304B8E9890), UInt64($BF967287630B02B2),
+    UInt64($5B67D607B6FC6E15)),
+    THashLibUInt64Array.Create(UInt64($D031C397CE553FE6),
+    UInt64($16BA5B01B006B525), UInt64($A89BADE6296E70C8),
+    UInt64($6A1F525D77D3435B), UInt64($6E103570573DFA0B),
+    UInt64($660EFB2A17FC95AB), UInt64($76327A9E97634BF6),
+    UInt64($4BAD9D6462458BF5), UInt64($F1830CAEDBC3F748),
+    UInt64($C5C8F542669131FF), UInt64($95044A1CDC48B0CB),
+    UInt64($892962DF3CF8B866), UInt64($B0B9E208E930C135),
+    UInt64($A14FB3F0611A767C), UInt64($8D2605F21C160136),
+    UInt64($D6B71922FECC549E), UInt64($37089438A5907D8B),
+    UInt64($0B5DA38E5803D49C), UInt64($5A5BCC9CEA6F3CBC),
+    UInt64($EDAE246D3B73FFE5), UInt64($D2B87E0FDE22EDCE),
+    UInt64($5E54ABB1CA8185EC), UInt64($1DE7F88FE80561B9),
+    UInt64($AD5E1A870135A08C), UInt64($2F2ADBD665CECC76),
+    UInt64($5780B5A782F58358), UInt64($3EDC8A2EEDE47B3F),
+    UInt64($C9D95C3506BEE70F), UInt64($83BE111D6C4E05EE),
+    UInt64($A603B90959367410), UInt64($103C81B4809FDE5D),
+    UInt64($2C69B6027D0C774A), UInt64($399080D7D5C87953),
+    UInt64($09D41E16487406B4), UInt64($CDD63B1826505E5F),
+    UInt64($F99DC2F49B0298E8), UInt64($9CD0540A943CB67F),
+    UInt64($BCA84B7F891F17C5), UInt64($723D1DB3B78DF2A6),
+    UInt64($78AA6E71E73B4F2E), UInt64($1433E699A071670D),
+    UInt64($84F21BE454620782), UInt64($98DF3327B4D20F2F),
+    UInt64($F049DCE2D3769E5C), UInt64($DB6C60199656EB7A),
+    UInt64($648746B2078B4783), UInt64($32CD23598DCBADCF),
+    UInt64($1EA4955BF0C7DA85), UInt64($E9A143401B9D46B5),
+    UInt64($FD92A5D9BBEC21B8), UInt64($C8138C790E0B8E1B),
+    UInt64($2EE00B9A6D7BA562), UInt64($F85712B893B7F1FC),
+    UInt64($EB28FED80BEA949D), UInt64($564A65EB8A40EA4C),
+    UInt64($6C9988E8474A2823), UInt64($4535898B121D8F2D),
+    UInt64($ABD8C03231ACCBF4), UInt64($BA2E91CAB9867CBD),
+    UInt64($7960BE3DEF8E263A), UInt64($0C11A977602FD6F0),
+    UInt64($CB50E1AD16C93527), UInt64($EAE22E94035FFD89),
+    UInt64($2866D12F5DE2CE1A), UInt64($FF1B1841AB9BF390),
+    UInt64($9F9339DE8CFE0D43), UInt64($964727C8C48A0BF7),
+    UInt64($524502C6AAAE531C), UInt64($9B9C5EF3AC10B413),
+    UInt64($4FA2FA4942AB32A5), UInt64($3F165A62E551122B),
+    UInt64($C74148DA76E6E3D7), UInt64($924840E5E464B2A7),
+    UInt64($D372AE43D69784DA), UInt64($233B72A105E11A86),
+    UInt64($A48A04914941A638), UInt64($B4B68525C9DE7865),
+    UInt64($DDEABAACA6CF8002), UInt64($0A9773C250B6BD88),
+    UInt64($C284FFBB5EBD3393), UInt64($8BA0DF472C8F6A4E),
+    UInt64($2AEF6CB74D951C32), UInt64($427983722A318D41),
+    UInt64($73F7CDFFBF389BB2), UInt64($074C0AF9382C026C),
+    UInt64($8A6A0F0B243A035A), UInt64($6FDAE53C5F88931F),
+    UInt64($C68B98967E538AC3), UInt64($44FF59C71AA8E639),
+    UInt64($E2FCE0CE439E9229), UInt64($A20CDE2479D8CD40),
+    UInt64($19E89FA2C8EBD8E9), UInt64($F446BBCFF398270C),
+    UInt64($43B3533E2284E455), UInt64($D82F0DCD8E945046),
+    UInt64($51066F12B26CE820), UInt64($E73957AF6BC5426D),
+    UInt64($081ECE5A40C16FA0), UInt64($3B193D4FC5BFAB7B),
+    UInt64($7FE66488DF174D42), UInt64($0E9814EF705804D8),
+    UInt64($8137AC857C39D7C6), UInt64($B1733244E185A821),
+    UInt64($695C3F896F11F867), UInt64($F6CF0657E3EFF524),
+    UInt64($1AABF276D02963D5), UInt64($2DA3664E75B91E5E),
+    UInt64($0289BD981077D228), UInt64($90C1FD7DF413608F),
+    UInt64($3C5537B6FD93A917), UInt64($AA12107E3919A2E0),
+    UInt64($0686DAB530996B78), UInt64($DAA6B0559EE3826E),
+    UInt64($C34E2FF756085A87), UInt64($6D5358A44FFF4137),
+    UInt64($FC587595B35948AC), UInt64($7CA5095CC7D5F67E),
+    UInt64($FB147F6C8B754AC0), UInt64($BFEB26AB91DDACF9),
+    UInt64($6896EFC567A49173), UInt64($CA9A31E11E7C5C33),
+    UInt64($BBE44186B13315A9), UInt64($0DDB793B689ABFE4),
+    UInt64($70B4A02BA7FA208E), UInt64($E47A3A7B7307F951),
+    UInt64($8CECD5BE14A36822), UInt64($EEED49B923B144D9),
+    UInt64($17708B4DB8B3DC31), UInt64($6088219F2765FED3),
+    UInt64($B3FA8FDCF1F27A09), UInt64($910B2D31FCA6099B),
+    UInt64($0F52C4A378ED6DCC), UInt64($50CCBF5EBAD98134),
+    UInt64($6BD582117F662A4F), UInt64($94CE9A50D4FDD9DF),
+    UInt64($2B25BCFB45207526), UInt64($67C42B661F49FCBF),
+    UInt64($492420FC723259DD), UInt64($03436DD418C2BB3C),
+    UInt64($1F6E4517F872B391), UInt64($A08563BC69AF1F68),
+    UInt64($D43EA4BAEEBB86B6), UInt64($01CAD04C08B56914),
+    UInt64($AC94CACB0980C998), UInt64($54C3D8739A373864),
+    UInt64($26FEC5C02DBACAC2), UInt64($DEA9D778BE0D3B3E),
+    UInt64($040F672D20EEB950), UInt64($E5B0EA377BB29045),
+    UInt64($F30AB136CBB42560), UInt64($62019C0737122CFB),
+    UInt64($E86B930C13282FA1), UInt64($CC1CEB542EE5374B),
+    UInt64($538FD28AA21B3A08), UInt64($1B61223AD89C0AC1),
+    UInt64($36C24474AD25149F), UInt64($7A23D3E9F74C9D06),
+    UInt64($BE21F6E79968C5ED), UInt64($CF5F868036278C77),
+    UInt64($F705D61BEB5A9C30), UInt64($4D2B47D152DCE08D),
+    UInt64($5F9E7BFDC234ECF8), UInt64($247778583DCD18EA),
+    UInt64($867BA67C4415D5AA), UInt64($4CE1979D5A698999),
+    UInt64($0000000000000000), UInt64($EC64F42133C696F1),
+    UInt64($B57C5569C16B1171), UInt64($C1C7926F467F88AF),
+    UInt64($654D96FE0F3E2E97), UInt64($15F936D5A8C40E19),
+    UInt64($B8A72C52A9F1AE95), UInt64($A9517DAA21DB19DC),
+    UInt64($58D27104FA18EE94), UInt64($5918A148F2AD8780),
+    UInt64($5CDD1629DAF657C4), UInt64($8274C15164FB6CFA),
+    UInt64($D1FB13DBC6E056F2), UInt64($7D6FD910CF609F6A),
+    UInt64($B63F38BDD9A9AA4D), UInt64($3D9FE7FAF526C003),
+    UInt64($74BBC706871499DE), UInt64($DF630734B6B8522A),
+    UInt64($3AD3ED03CD0AC26F), UInt64($FADEAF2083C023D4),
+    UInt64($C00D42234ECAE1BB), UInt64($8538CBA85CD76E96),
+    UInt64($C402250E6E2458EB), UInt64($47BC3413026A5D05),
+    UInt64($AFD7A71F114272A4), UInt64($978DF784CC3F62E3),
+    UInt64($B96DFC1EA144C781), UInt64($21B2CF391596C8AE),
+    UInt64($318E4E8D950916F3), UInt64($CE9556CC3E92E563),
+    UInt64($385A509BDD7D1047), UInt64($358129A0B5E7AFA3),
+    UInt64($E6F387E363702B79), UInt64($E0755D5653E94001),
+    UInt64($7BE903A5FFF9F412), UInt64($12B53C2C90E80C75),
+    UInt64($3307F315857EC4DB), UInt64($8FAFB86A0C61D31E),
+    UInt64($D9E5DD8186213952), UInt64($77F8AAD29FD622E2),
+    UInt64($25BDA814357871FE), UInt64($7571174A8FA1F0CA),
+    UInt64($137FEC60985D6561), UInt64($30449EC19DBC7FE7),
+    UInt64($A540D4DD41F4CF2C), UInt64($DC206AE0AE7AE916),
+    UInt64($5B911CD0E2DA55A8), UInt64($B2305F90F947131D),
+    UInt64($344BF9ECBD52C6B7), UInt64($5D17C665D2433ED0),
+    UInt64($18224FEEC05EB1FD), UInt64($9E59E992844B6457),
+    UInt64($9A568EBFA4A5DD07), UInt64($A3C60E68716DA454),
+    UInt64($7E2CB4C4D7A22456), UInt64($87B176304CA0BCBE),
+    UInt64($413AEEA632F3367D), UInt64($9915E36BBC67663B),
+    UInt64($40F03EEA3A465F69), UInt64($1C2D28C3E0B008AD),
+    UInt64($4E682A054A1E5BB1), UInt64($05C5B761285BD044),
+    UInt64($E1BF8D1A5B5C2915), UInt64($F2C0617AC3014C74),
+    UInt64($B7F5E8F1D11CC359), UInt64($63CB4C4B3FA745EF),
+    UInt64($9D1A84469C89DF6B), UInt64($E33630824B2BFB3D),
+    UInt64($D5F474F6E60EEFA2), UInt64($F58C6B83FB2D4E18),
+    UInt64($4676E45F0ADF3411), UInt64($20781F751D23A1BA),
+    UInt64($BD629B3381AA7ED1), UInt64($AE1D775319F71BB0),
+    UInt64($FED1C80DA32E9A84), UInt64($5509083F92825170),
+    UInt64($29AC01635557A70E), UInt64($A7C9694551831D04),
+    UInt64($8E65682604D4BA0A), UInt64($11F651F8882AB749),
+    UInt64($D77DC96EF6793D8A), UInt64($EF2799F52B042DCD),
+    UInt64($48EEF0B07A8730C9), UInt64($22F1A2ED0D547392),
+    UInt64($6142F1D32FD097C7), UInt64($4A674D286AF0E2E1),
+    UInt64($80FD7CC9748CBED2), UInt64($717E7067AF4F499A),
+    UInt64($938290A9ECD1DBB3), UInt64($88E3B293344DD172),
+    UInt64($2734158C250FA3D6)));
+
+{$ENDREGION}
+end;
+
+procedure TGOST3411_2012.g_N(a_h, a_N, a_m: THashLibByteArray);
+begin
+  System.Move(a_h[0], Ftmp[0], 64 * System.SizeOf(Byte));
+
+  xor512(a_h, a_N);
+  F(a_h);
+
+  E(a_h, a_m);
+  xor512(a_h, Ftmp);
+  xor512(a_h, a_m);
+end;
+
+procedure TGOST3411_2012.Initialize;
+begin
+  FbOff := 64;
+  System.FillChar(FN[0], System.Length(FN) * System.SizeOf(Byte), Byte(0));
+  System.FillChar(FSigma[0], System.Length(FSigma) *
+    System.SizeOf(Byte), Byte(0));
+  System.Move(FIV[0], Fh[0], 64 * System.SizeOf(Byte));
+  System.FillChar(Fblock[0], System.Length(Fblock) *
+    System.SizeOf(Byte), Byte(0));
+
+end;
+
+procedure TGOST3411_2012.InternalUpdate(input: Byte);
+begin
+  System.Dec(FbOff);
+  Fblock[FbOff] := input;
+  if (FbOff = 0) then
+  begin
+    g_N(Fh, FN, Fblock);
+    addMod512(FN, 512);
+    addMod512(FSigma, Fblock);
+    FbOff := 64;
+  end;
+end;
+
+procedure TGOST3411_2012.reverse(src, dst: THashLibByteArray);
+var
+  len, i: Int32;
+begin
+  len := System.Length(src);
+  for i := 0 to System.Pred(len) do
+  begin
+    dst[len - 1 - i] := src[i];
+  end;
+end;
+
+procedure TGOST3411_2012.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_data_length: Int32);
+begin
+  while ((FbOff <> 64) and (a_data_length > 0)) do
+  begin
+    InternalUpdate(a_data[a_index]);
+    System.Inc(a_index);
+    System.Dec(a_data_length);
+  end;
+  while (a_data_length >= 64) do
+  begin
+    System.Move(a_data[a_index], Ftmp[0], 64 * System.SizeOf(Byte));
+    reverse(Ftmp, Fblock);
+    g_N(Fh, FN, Fblock);
+    addMod512(FN, 512);
+    addMod512(FSigma, Fblock);
+
+    a_data_length := a_data_length - 64;
+    a_index := a_index + 64;
+  end;
+  while (a_data_length > 0) do
+  begin
+    InternalUpdate(a_data[a_index]);
+    System.Inc(a_index);
+    System.Dec(a_data_length);
+  end;
+
+end;
+
+function TGOST3411_2012.TransformFinal: IHashResult;
+var
+  tempRes: THashLibByteArray;
+  lenM, i: Int32;
+begin
+  lenM := 64 - FbOff;
+
+  // At this point it is certain that lenM is smaller than 64
+  i := 0;
+  while i <> (64 - lenM) do
+  begin
+    Fm[i] := 0;
+    System.Inc(i);
+  end;
+
+  Fm[63 - lenM] := 1;
+
+  if (FbOff <> 64) then
+  begin
+    System.Move(Fblock[FbOff], Fm[64 - lenM], lenM * System.SizeOf(Byte));
+  end;
+
+  g_N(Fh, FN, Fm);
+  addMod512(FN, lenM * 8);
+  addMod512(FSigma, Fm);
+  g_N(Fh, FZero, FN);
+  g_N(Fh, FZero, FSigma);
+
+  reverse(Fh, Ftmp);
+
+  System.SetLength(tempRes, 64);
+  System.Move(Ftmp[0], tempRes[0], 64 * System.SizeOf(Byte));
+
+  result := THashResult.Create(tempRes);
+
+  Initialize();
+end;
+
+{ TGOST3411_2012_256 }
+
+constructor TGOST3411_2012_256.Create();
+begin
+  inherited Create(32, FIV_256);
+end;
+
+class constructor TGOST3411_2012_256.TGOST3411_2012_256;
+begin
+  FIV_256 := THashLibByteArray.Create($01, $01, $01, $01, $01, $01, $01, $01,
+    $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01,
+    $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01,
+    $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01,
+    $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01);
+end;
+
+function TGOST3411_2012_256.TransformFinal: IHashResult;
+var
+  output, tempRes: THashLibByteArray;
+begin
+  output := inherited TransformFinal.GetBytes;
+  System.SetLength(tempRes, HashSize);
+  System.Move(output[32], tempRes[0], 32 * System.SizeOf(Byte));
+  result := THashResult.Create(tempRes);
+end;
+
+{ TGOST3411_2012_512 }
+
+constructor TGOST3411_2012_512.Create();
+begin
+  inherited Create(64, FIV_512);
+end;
+
+class constructor TGOST3411_2012_512.TGOST3411_2012_512;
+begin
+  FIV_512 := THashLibByteArray.Create($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, $00);
+end;
+
+end.

+ 460 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpGost.pas

@@ -0,0 +1,460 @@
+unit HlpGost;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpHashBuffer,
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpBits,
+  HlpConverters,
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn;
+
+type
+
+  TGost = class sealed(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+  strict private
+
+    Fm_state, Fm_hash: THashLibUInt32Array;
+
+    class var
+
+      Fs_sbox1, Fs_sbox2, Fs_sbox3, Fs_sbox4: THashLibUInt32Array;
+
+    procedure Compress(a_m: PCardinal);
+    class constructor Gost();
+
+  strict protected
+    procedure Finish(); override;
+    function GetResult(): THashLibByteArray; override;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TGost }
+
+procedure TGost.Compress(a_m: PCardinal);
+var
+  u0, u1, u2, u3, u4, u5, u6, u7, v0, v1, v2, v3, v4, v5, v6, v7, w0, w1, w2,
+    w3, w4, w5, w6, w7, key0, key1, key2, key3, key4, key5, key6, key7, r, l,
+    t: UInt32;
+  i: Int32;
+  s: array [0 .. 7] of UInt32;
+begin
+  u0 := Fm_hash[0];
+  u1 := Fm_hash[1];
+  u2 := Fm_hash[2];
+  u3 := Fm_hash[3];
+  u4 := Fm_hash[4];
+  u5 := Fm_hash[5];
+  u6 := Fm_hash[6];
+  u7 := Fm_hash[7];
+
+  v0 := a_m[0];
+  v1 := a_m[1];
+  v2 := a_m[2];
+  v3 := a_m[3];
+  v4 := a_m[4];
+  v5 := a_m[5];
+  v6 := a_m[6];
+  v7 := a_m[7];
+
+  i := 0;
+
+  while i < 8 do
+
+  begin
+    w0 := u0 xor v0;
+    w1 := u1 xor v1;
+    w2 := u2 xor v2;
+    w3 := u3 xor v3;
+    w4 := u4 xor v4;
+    w5 := u5 xor v5;
+    w6 := u6 xor v6;
+    w7 := u7 xor v7;
+
+    key0 := UInt32(Byte(w0)) or (UInt32(Byte(w2)) shl 8) or
+      (UInt32(Byte(w4)) shl 16) or (UInt32(Byte(w6)) shl 24);
+    key1 := UInt32(Byte(w0 shr 8)) or (w2 and $0000FF00) or
+      ((w4 and $0000FF00) shl 8) or ((w6 and $0000FF00) shl 16);
+    key2 := UInt32(Byte(w0 shr 16)) or ((w2 and $00FF0000) shr 8) or
+      (w4 and $00FF0000) or ((w6 and $00FF0000) shl 8);
+    key3 := (w0 shr 24) or ((w2 and $FF000000) shr 16) or
+      ((w4 and $FF000000) shr 8) or (w6 and $FF000000);
+    key4 := UInt32(Byte(w1)) or ((w3 and $000000FF) shl 8) or
+      ((w5 and $000000FF) shl 16) or ((w7 and $000000FF) shl 24);
+    key5 := UInt32(Byte(w1 shr 8)) or (w3 and $0000FF00) or
+      ((w5 and $0000FF00) shl 8) or ((w7 and $0000FF00) shl 16);
+    key6 := UInt32(Byte(w1 shr 16)) or ((w3 and $00FF0000) shr 8) or
+      (w5 and $00FF0000) or ((w7 and $00FF0000) shl 8);
+    key7 := (w1 shr 24) or ((w3 and $FF000000) shr 16) or
+      ((w5 and $FF000000) shr 8) or (w7 and $FF000000);
+
+    r := Fm_hash[i];
+    l := Fm_hash[i + 1];
+
+    t := key0 + r;
+    l := l xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key1 + l;
+    r := r xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key2 + r;
+    l := l xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key3 + l;
+    r := r xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key4 + r;
+    l := l xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key5 + l;
+    r := r xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key6 + r;
+    l := l xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key7 + l;
+    r := r xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key0 + r;
+    l := l xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key1 + l;
+    r := r xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key2 + r;
+    l := l xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key3 + l;
+    r := r xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key4 + r;
+    l := l xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key5 + l;
+    r := r xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key6 + r;
+    l := l xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key7 + l;
+    r := r xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key0 + r;
+    l := l xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key1 + l;
+    r := r xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key2 + r;
+    l := l xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key3 + l;
+    r := r xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key4 + r;
+    l := l xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key5 + l;
+    r := r xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key6 + r;
+    l := l xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key7 + l;
+    r := r xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key7 + r;
+    l := l xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key6 + l;
+    r := r xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key5 + r;
+    l := l xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key4 + l;
+    r := r xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key3 + r;
+    l := l xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key2 + l;
+    r := r xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key1 + r;
+    l := l xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+    t := key0 + l;
+    r := r xor (Fs_sbox1[Byte(t)] xor Fs_sbox2[Byte(t shr 8)] xor Fs_sbox3
+      [Byte(t shr 16)] xor Fs_sbox4[t shr 24]);
+
+    t := r;
+    r := l;
+    l := t;
+
+    s[i] := r;
+    s[i + 1] := l;
+
+    if (i = 6) then
+      break;
+
+    l := u0 xor u2;
+    r := u1 xor u3;
+    u0 := u2;
+    u1 := u3;
+    u2 := u4;
+    u3 := u5;
+    u4 := u6;
+    u5 := u7;
+    u6 := l;
+    u7 := r;
+
+    if (i = 2) then
+    begin
+      u0 := u0 xor $FF00FF00;
+      u1 := u1 xor $FF00FF00;
+      u2 := u2 xor $00FF00FF;
+      u3 := u3 xor $00FF00FF;
+      u4 := u4 xor $00FFFF00;
+      u5 := u5 xor $FF0000FF;
+      u6 := u6 xor $000000FF;
+      u7 := u7 xor $FF00FFFF;
+    end;
+
+    l := v0;
+    r := v2;
+    v0 := v4;
+    v2 := v6;
+    v4 := l xor r;
+    v6 := v0 xor r;
+    l := v1;
+    r := v3;
+    v1 := v5;
+    v3 := v7;
+    v5 := l xor r;
+    v7 := v1 xor r;
+
+    System.Inc(i, 2);
+  end;
+
+  u0 := a_m[0] xor s[6];
+  u1 := a_m[1] xor s[7];
+  u2 := a_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);
+  u3 := a_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);
+  u4 := a_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);
+  u5 := a_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);
+  u6 := a_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);
+  u7 := a_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);
+
+  v0 := Fm_hash[0] xor (u1 shl 16) xor (u0 shr 16);
+  v1 := Fm_hash[1] xor (u2 shl 16) xor (u1 shr 16);
+  v2 := Fm_hash[2] xor (u3 shl 16) xor (u2 shr 16);
+  v3 := Fm_hash[3] xor (u4 shl 16) xor (u3 shr 16);
+  v4 := Fm_hash[4] xor (u5 shl 16) xor (u4 shr 16);
+  v5 := Fm_hash[5] xor (u6 shl 16) xor (u5 shr 16);
+  v6 := Fm_hash[6] xor (u7 shl 16) xor (u6 shr 16);
+  v7 := Fm_hash[7] xor (u0 and $FFFF0000) xor (u0 shl 16) xor (u7 shr 16)
+    xor (u1 and $FFFF0000) xor (u1 shl 16) xor (u6 shl 16)
+    xor (u7 and $FFFF0000);
+
+  Fm_hash[0] := (v0 and $FFFF0000) xor (v0 shl 16) xor (v0 shr 16)
+    xor (v1 shr 16) xor (v1 and $FFFF0000) xor (v2 shl 16) xor (v3 shr 16)
+    xor (v4 shl 16) xor (v5 shr 16) xor v5 xor (v6 shr 16) xor (v7 shl 16)
+    xor (v7 shr 16) xor (v7 and $FFFF);
+  Fm_hash[1] := (v0 shl 16) xor (v0 shr 16) xor (v0 and $FFFF0000)
+    xor (v1 and $FFFF) xor v2 xor (v2 shr 16) xor (v3 shl 16) xor (v4 shr 16)
+    xor (v5 shl 16) xor (v6 shl 16) xor v6 xor (v7 and $FFFF0000)
+    xor (v7 shr 16);
+  Fm_hash[2] := (v0 and $FFFF) xor (v0 shl 16) xor (v1 shl 16) xor (v1 shr 16)
+    xor (v1 and $FFFF0000) xor (v2 shl 16) xor (v3 shr 16)
+    xor v3 xor (v4 shl 16) xor (v5 shr 16) xor v6 xor (v6 shr 16)
+    xor (v7 and $FFFF) xor (v7 shl 16) xor (v7 shr 16);
+  Fm_hash[3] := (v0 shl 16) xor (v0 shr 16) xor (v0 and $FFFF0000)
+    xor (v1 and $FFFF0000) xor (v1 shr 16) xor (v2 shl 16) xor (v2 shr 16)
+    xor v2 xor (v3 shl 16) xor (v4 shr 16) xor v4 xor (v5 shl 16)
+    xor (v6 shl 16) xor (v7 and $FFFF) xor (v7 shr 16);
+  Fm_hash[4] := (v0 shr 16) xor (v1 shl 16) xor v1 xor (v2 shr 16)
+    xor v2 xor (v3 shl 16) xor (v3 shr 16) xor v3 xor (v4 shl 16)
+    xor (v5 shr 16) xor v5 xor (v6 shl 16) xor (v6 shr 16) xor (v7 shl 16);
+  Fm_hash[5] := (v0 shl 16) xor (v0 and $FFFF0000) xor (v1 shl 16)
+    xor (v1 shr 16) xor (v1 and $FFFF0000) xor (v2 shl 16)
+    xor v2 xor (v3 shr 16) xor v3 xor (v4 shl 16) xor (v4 shr 16)
+    xor v4 xor (v5 shl 16) xor (v6 shl 16) xor (v6 shr 16)
+    xor v6 xor (v7 shl 16) xor (v7 shr 16) xor (v7 and $FFFF0000);
+  Fm_hash[6] := v0 xor v2 xor (v2 shr 16) xor v3 xor (v3 shl 16)
+    xor v4 xor (v4 shr 16) xor (v5 shl 16) xor (v5 shr 16)
+    xor v5 xor (v6 shl 16) xor (v6 shr 16) xor v6 xor (v7 shl 16) xor v7;
+  Fm_hash[7] := v0 xor (v0 shr 16) xor (v1 shl 16) xor (v1 shr 16)
+    xor (v2 shl 16) xor (v3 shr 16) xor v3 xor (v4 shl 16)
+    xor v4 xor (v5 shr 16) xor v5 xor (v6 shl 16) xor (v6 shr 16)
+    xor (v7 shl 16) xor v7;
+
+end;
+
+constructor TGost.Create;
+begin
+  Inherited Create(32, 32);
+  System.SetLength(Fm_state, 8);
+  System.SetLength(Fm_hash, 8);
+
+end;
+
+procedure TGost.Finish;
+var
+  bits: UInt64;
+  pad: THashLibByteArray;
+  m_length: THashLibUInt32Array;
+begin
+  bits := Fm_processed_bytes * 8;
+
+  if (Fm_buffer.Pos > 0) then
+  begin
+    System.SetLength(pad, 32 - Fm_buffer.Pos);
+    TransformBytes(pad, 0, 32 - Fm_buffer.Pos);
+  end;
+  System.SetLength(m_length, 8);
+  m_length[0] := UInt32(bits);
+  m_length[1] := UInt32(bits shr 32);
+
+  Compress(PCardinal(m_length));
+
+  Compress(PCardinal(Fm_state));
+
+end;
+
+function TGost.GetResult: THashLibByteArray;
+begin
+  System.SetLength(result, 8 * System.SizeOf(UInt32));
+  TConverters.le32_copy(PCardinal(Fm_hash), 0, PByte(result), 0,
+    System.Length(result));
+end;
+
+class constructor TGost.Gost;
+var
+  sbox: THashLibMatrixUInt32Array;
+
+  i, a, b: Int32;
+  ax, bx, cx, dx: UInt32;
+begin
+  sbox := THashLibMatrixUInt32Array.Create(THashLibUInt32Array.Create(4, 10, 9,
+    2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3), THashLibUInt32Array.Create(14,
+    11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9),
+    THashLibUInt32Array.Create(5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9,
+    11), THashLibUInt32Array.Create(7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11,
+    2, 5, 3), THashLibUInt32Array.Create(6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9,
+    14, 0, 3, 11, 2), THashLibUInt32Array.Create(4, 11, 10, 0, 7, 2, 1, 13, 3,
+    6, 8, 5, 9, 12, 15, 14), THashLibUInt32Array.Create(13, 11, 4, 1, 3, 15, 5,
+    9, 0, 10, 14, 7, 6, 8, 2, 12), THashLibUInt32Array.Create(1, 15, 13, 0, 5,
+    7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12));
+
+  System.SetLength(Fs_sbox1, 256);
+  System.SetLength(Fs_sbox2, 256);
+  System.SetLength(Fs_sbox3, 256);
+  System.SetLength(Fs_sbox4, 256);
+
+  i := 0;
+
+  for a := 0 to 15 do
+
+  begin
+    ax := sbox[1, a] shl 15;
+    bx := sbox[3, a] shl 23;
+    cx := sbox[5, a];
+    cx := TBits.RotateRight32(cx, 1);
+    dx := sbox[7, a] shl 7;
+
+    for b := 0 to 15 do
+
+    begin
+      Fs_sbox1[i] := ax or (sbox[0, b] shl 11);
+      Fs_sbox2[i] := bx or (sbox[2, b] shl 19);
+      Fs_sbox3[i] := cx or (sbox[4, b] shl 27);
+      Fs_sbox4[i] := dx or (sbox[6, b] shl 3);
+      System.Inc(i);
+    end;
+
+  end;
+
+end;
+
+procedure TGost.Initialize;
+begin
+
+  System.FillChar(Fm_state[0], System.Length(Fm_state) * System.SizeOf(UInt32),
+    UInt32(0));
+  System.FillChar(Fm_hash[0], System.Length(Fm_hash) * System.SizeOf(UInt32),
+    UInt32(0));
+
+  Inherited Initialize();
+
+end;
+
+procedure TGost.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  data, m: array [0 .. 7] of UInt32;
+  c, a, b: UInt32;
+  i: Int32;
+begin
+
+  c := 0;
+
+  TConverters.le32_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+
+  for i := 0 to 7 do
+  begin
+    a := data[i];
+    m[i] := a;
+    b := Fm_state[i];
+    c := a + c + Fm_state[i];
+    Fm_state[i] := c;
+    if ((c < a) or (c < b)) then
+
+      c := UInt32(1)
+    else
+      c := UInt32(0);
+
+  end;
+
+  Compress(@(m[0]));
+
+  System.FillChar(m, System.SizeOf(m), 0);
+  System.FillChar(data, System.SizeOf(data), 0);
+
+end;
+
+end.

+ 283 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpGrindahl256.pas

@@ -0,0 +1,283 @@
+unit HlpGrindahl256;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpConverters,
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn;
+
+type
+  TGrindahl256 = class sealed(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+  strict private
+
+    Fm_state, Fm_temp: THashLibUInt32Array;
+
+    class var
+
+      Fs_table_0, Fs_table_1, Fs_table_2, Fs_table_3: THashLibUInt32Array;
+
+{$REGION 'Consts'}
+
+  const
+
+    s_master_table: array [0 .. 255] of UInt32 = ($C66363A5, $F87C7C84,
+      $EE777799, $F67B7B8D, $FFF2F20D, $D66B6BBD, $DE6F6FB1, $91C5C554,
+      $60303050, $02010103, $CE6767A9, $562B2B7D, $E7FEFE19, $B5D7D762,
+      $4DABABE6, $EC76769A, $8FCACA45, $1F82829D, $89C9C940, $FA7D7D87,
+      $EFFAFA15, $B25959EB, $8E4747C9, $FBF0F00B, $41ADADEC, $B3D4D467,
+      $5FA2A2FD, $45AFAFEA, $239C9CBF, $53A4A4F7, $E4727296, $9BC0C05B,
+      $75B7B7C2, $E1FDFD1C, $3D9393AE, $4C26266A, $6C36365A, $7E3F3F41,
+      $F5F7F702, $83CCCC4F, $6834345C, $51A5A5F4, $D1E5E534, $F9F1F108,
+      $E2717193, $ABD8D873, $62313153, $2A15153F, $0804040C, $95C7C752,
+      $46232365, $9DC3C35E, $30181828, $379696A1, $0A05050F, $2F9A9AB5,
+      $0E070709, $24121236, $1B80809B, $DFE2E23D, $CDEBEB26, $4E272769,
+      $7FB2B2CD, $EA75759F, $1209091B, $1D83839E, $582C2C74, $341A1A2E,
+      $361B1B2D, $DC6E6EB2, $B45A5AEE, $5BA0A0FB, $A45252F6, $763B3B4D,
+      $B7D6D661, $7DB3B3CE, $5229297B, $DDE3E33E, $5E2F2F71, $13848497,
+      $A65353F5, $B9D1D168, $00000000, $C1EDED2C, $40202060, $E3FCFC1F,
+      $79B1B1C8, $B65B5BED, $D46A6ABE, $8DCBCB46, $67BEBED9, $7239394B,
+      $944A4ADE, $984C4CD4, $B05858E8, $85CFCF4A, $BBD0D06B, $C5EFEF2A,
+      $4FAAAAE5, $EDFBFB16, $864343C5, $9A4D4DD7, $66333355, $11858594,
+      $8A4545CF, $E9F9F910, $04020206, $FE7F7F81, $A05050F0, $783C3C44,
+      $259F9FBA, $4BA8A8E3, $A25151F3, $5DA3A3FE, $804040C0, $058F8F8A,
+      $3F9292AD, $219D9DBC, $70383848, $F1F5F504, $63BCBCDF, $77B6B6C1,
+      $AFDADA75, $42212163, $20101030, $E5FFFF1A, $FDF3F30E, $BFD2D26D,
+      $81CDCD4C, $180C0C14, $26131335, $C3ECEC2F, $BE5F5FE1, $359797A2,
+      $884444CC, $2E171739, $93C4C457, $55A7A7F2, $FC7E7E82, $7A3D3D47,
+      $C86464AC, $BA5D5DE7, $3219192B, $E6737395, $C06060A0, $19818198,
+      $9E4F4FD1, $A3DCDC7F, $44222266, $542A2A7E, $3B9090AB, $0B888883,
+      $8C4646CA, $C7EEEE29, $6BB8B8D3, $2814143C, $A7DEDE79, $BC5E5EE2,
+      $160B0B1D, $ADDBDB76, $DBE0E03B, $64323256, $743A3A4E, $140A0A1E,
+      $924949DB, $0C06060A, $4824246C, $B85C5CE4, $9FC2C25D, $BDD3D36E,
+      $43ACACEF, $C46262A6, $399191A8, $319595A4, $D3E4E437, $F279798B,
+      $D5E7E732, $8BC8C843, $6E373759, $DA6D6DB7, $018D8D8C, $B1D5D564,
+      $9C4E4ED2, $49A9A9E0, $D86C6CB4, $AC5656FA, $F3F4F407, $CFEAEA25,
+      $CA6565AF, $F47A7A8E, $47AEAEE9, $10080818, $6FBABAD5, $F0787888,
+      $4A25256F, $5C2E2E72, $381C1C24, $57A6A6F1, $73B4B4C7, $97C6C651,
+      $CBE8E823, $A1DDDD7C, $E874749C, $3E1F1F21, $964B4BDD, $61BDBDDC,
+      $0D8B8B86, $0F8A8A85, $E0707090, $7C3E3E42, $71B5B5C4, $CC6666AA,
+      $904848D8, $06030305, $F7F6F601, $1C0E0E12, $C26161A3, $6A35355F,
+      $AE5757F9, $69B9B9D0, $17868691, $99C1C158, $3A1D1D27, $279E9EB9,
+      $D9E1E138, $EBF8F813, $2B9898B3, $22111133, $D26969BB, $A9D9D970,
+      $078E8E89, $339494A7, $2D9B9BB6, $3C1E1E22, $15878792, $C9E9E920,
+      $87CECE49, $AA5555FF, $50282878, $A5DFDF7A, $038C8C8F, $59A1A1F8,
+      $09898980, $1A0D0D17, $65BFBFDA, $D7E6E631, $844242C6, $D06868B8,
+      $824141C3, $299999B0, $5A2D2D77, $1E0F0F11, $7BB0B0CB, $A85454FC,
+      $6DBBBBD6, $2C16163A);
+
+{$ENDREGION}
+    class function CalcTable(i: Int32): THashLibUInt32Array;
+
+    procedure InjectMsg(a_full_process: Boolean);
+
+    class constructor Grindahl256();
+
+  strict protected
+    procedure Finish(); override;
+    function GetResult(): THashLibByteArray; override;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TGrindahl256 }
+
+class function TGrindahl256.CalcTable(i: Int32): THashLibUInt32Array;
+var
+  j: Int32;
+begin
+  System.SetLength(result, 256);
+  j := 0;
+  while j < 256 do
+  begin
+    result[j] := UInt32((s_master_table[j] shr (i * 8)) or
+      (s_master_table[j] shl (32 - i * 8)));
+    System.Inc(j);
+  end;
+end;
+
+constructor TGrindahl256.Create;
+begin
+  Inherited Create(32, 4);
+  System.SetLength(Fm_state, 13);
+  System.SetLength(Fm_temp, 13);
+end;
+
+procedure TGrindahl256.Finish;
+var
+  padding_size, i: Int32;
+  msg_length: UInt64;
+  pad: THashLibByteArray;
+begin
+
+  padding_size := 12 - Int32(Fm_processed_bytes and UInt32(3));
+  msg_length := (Fm_processed_bytes shr UInt64(2)) + 1;
+
+  System.SetLength(pad, padding_size);
+
+  pad[0] := $80;
+
+  msg_length := TConverters.be2me_64(msg_length);
+
+  TConverters.ReadUInt64AsBytesLE(msg_length, pad, padding_size - 8);
+
+  TransformBytes(pad, 0, padding_size - 4);
+
+  Fm_state[0] := TConverters.ReadBytesAsUInt32LE(PByte(pad), padding_size - 4);
+
+  Fm_state[0] := TConverters.be2me_32(Fm_state[0]);
+
+  InjectMsg(true);
+
+  i := 0;
+
+  while i < 8 do
+  begin
+    InjectMsg(true);
+    System.Inc(i);
+  end;
+
+end;
+
+function TGrindahl256.GetResult: THashLibByteArray;
+begin
+
+  System.SetLength(result, 8 * System.SizeOf(UInt32));
+
+  TConverters.be32_copy(PCardinal(Fm_state) + 5, 0, PByte(result), 0,
+    System.Length(result));
+
+end;
+
+class constructor TGrindahl256.Grindahl256;
+var
+  LowVal1, LowVal2: Int32;
+begin
+
+  System.SetLength(Fs_table_0, System.Length(s_master_table));
+
+{$IFDEF DELPHIXE2_UP}
+  LowVal1 := System.Low(s_master_table);
+  LowVal2 := System.Low(Fs_table_0);
+{$ELSE}
+  LowVal1 := 0;
+  LowVal2 := 0;
+{$ENDIF DELPHIXE2_UP}
+  System.Move(s_master_table[LowVal1], Fs_table_0[LowVal2],
+    System.SizeOf(s_master_table));
+
+  Fs_table_1 := CalcTable(1);
+  Fs_table_2 := CalcTable(2);
+  Fs_table_3 := CalcTable(3);
+end;
+
+procedure TGrindahl256.Initialize;
+begin
+
+  System.FillChar(Fm_state[0], System.Length(Fm_state) * System.SizeOf(UInt32),
+    UInt32(0));
+  System.FillChar(Fm_temp[0], System.Length(Fm_temp) * System.SizeOf(UInt32),
+    UInt32(0));
+
+  Inherited Initialize();
+
+end;
+
+procedure TGrindahl256.InjectMsg(a_full_process: Boolean);
+var
+  u: THashLibUInt32Array;
+begin
+
+  Fm_state[12] := Fm_state[12] xor $01;
+
+  if (a_full_process) then
+  begin
+    Fm_temp[0] := Fs_table_0[Byte(Fm_state[12] shr 24)] xor Fs_table_1
+      [Byte(Fm_state[11] shr 16)] xor Fs_table_2[Byte(Fm_state[9] shr 8)
+      ] xor Fs_table_3[Byte(Fm_state[3])];
+  end;
+
+  Fm_temp[1] := Fs_table_0[Byte(Fm_state[0] shr 24)] xor Fs_table_1
+    [Byte(Fm_state[12] shr 16)] xor Fs_table_2[Byte(Fm_state[10] shr 8)
+    ] xor Fs_table_3[Byte(Fm_state[4])];
+
+  Fm_temp[2] := Fs_table_0[Byte(Fm_state[1] shr 24)] xor Fs_table_1
+    [Byte(Fm_state[0] shr 16)] xor Fs_table_2[Byte(Fm_state[11] shr 8)
+    ] xor Fs_table_3[Byte(Fm_state[5])];
+
+  Fm_temp[3] := Fs_table_0[Byte(Fm_state[2] shr 24)] xor Fs_table_1
+    [Byte(Fm_state[1] shr 16)] xor Fs_table_2[Byte(Fm_state[12] shr 8)
+    ] xor Fs_table_3[Byte(Fm_state[6])];
+
+  Fm_temp[4] := Fs_table_0[Byte(Fm_state[3] shr 24)] xor Fs_table_1
+    [Byte(Fm_state[2] shr 16)] xor Fs_table_2[Byte(Fm_state[0] shr 8)
+    ] xor Fs_table_3[Byte(Fm_state[7])];
+
+  Fm_temp[5] := Fs_table_0[Byte(Fm_state[4] shr 24)] xor Fs_table_1
+    [Byte(Fm_state[3] shr 16)] xor Fs_table_2[Byte(Fm_state[1] shr 8)
+    ] xor Fs_table_3[Byte(Fm_state[8])];
+
+  Fm_temp[6] := Fs_table_0[Byte(Fm_state[5] shr 24)] xor Fs_table_1
+    [Byte(Fm_state[4] shr 16)] xor Fs_table_2[Byte(Fm_state[2] shr 8)
+    ] xor Fs_table_3[Byte(Fm_state[9])];
+
+  Fm_temp[7] := Fs_table_0[Byte(Fm_state[6] shr 24)] xor Fs_table_1
+    [Byte(Fm_state[5] shr 16)] xor Fs_table_2[Byte(Fm_state[3] shr 8)
+    ] xor Fs_table_3[Byte(Fm_state[10])];
+
+  Fm_temp[8] := Fs_table_0[Byte(Fm_state[7] shr 24)] xor Fs_table_1
+    [Byte(Fm_state[6] shr 16)] xor Fs_table_2[Byte(Fm_state[4] shr 8)
+    ] xor Fs_table_3[Byte(Fm_state[11])];
+
+  Fm_temp[9] := Fs_table_0[Byte(Fm_state[8] shr 24)] xor Fs_table_1
+    [Byte(Fm_state[7] shr 16)] xor Fs_table_2[Byte(Fm_state[5] shr 8)
+    ] xor Fs_table_3[Byte(Fm_state[12])];
+
+  Fm_temp[10] := Fs_table_0[Byte(Fm_state[9] shr 24)] xor Fs_table_1
+    [Byte(Fm_state[8] shr 16)] xor Fs_table_2[Byte(Fm_state[6] shr 8)
+    ] xor Fs_table_3[Byte(Fm_state[0])];
+
+  Fm_temp[11] := Fs_table_0[Byte(Fm_state[10] shr 24)] xor Fs_table_1
+    [Byte(Fm_state[9] shr 16)] xor Fs_table_2[Byte(Fm_state[7] shr 8)
+    ] xor Fs_table_3[Byte(Fm_state[1])];
+
+  Fm_temp[12] := Fs_table_0[Byte(Fm_state[11] shr 24)] xor Fs_table_1
+    [Byte(Fm_state[10] shr 16)] xor Fs_table_2[Byte(Fm_state[8] shr 8)
+    ] xor Fs_table_3[Byte(Fm_state[2])];
+
+  u := Fm_temp;
+  Fm_temp := Fm_state;
+  Fm_state := u;
+
+end;
+
+procedure TGrindahl256.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+begin
+
+  Fm_state[0] := TConverters.ReadBytesAsUInt32LE(a_data, a_index);
+
+  Fm_state[0] := TConverters.be2me_32(Fm_state[0]);
+
+  InjectMsg(false);
+
+end;
+
+end.

+ 404 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpGrindahl512.pas

@@ -0,0 +1,404 @@
+unit HlpGrindahl512;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpBits,
+  HlpConverters,
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn;
+
+type
+  TGrindahl512 = class sealed(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+  strict private
+
+    Fm_state, Fm_temp: THashLibUInt64Array;
+
+    class var
+
+      Fs_table_0, Fs_table_1, Fs_table_2, Fs_table_3, Fs_table_4, Fs_table_5,
+      Fs_table_6, Fs_table_7: THashLibUInt64Array;
+
+{$REGION 'Consts'}
+
+  const
+
+    s_master_table: array [0 .. 255] of UInt64 = (UInt64($C6636397633551A2),
+      UInt64($F87C7CEB7CCD1326), UInt64($EE7777C777952952),
+      UInt64($F67B7BF77BF50102), UInt64($FFF2F2E5F2D11A34),
+      UInt64($D66B6BB76B7561C2), UInt64($DE6F6FA76F5579F2),
+      UInt64($91C5C539C572A84B), UInt64($603030C0309BA05B),
+      UInt64($020101040108060C), UInt64($CE67678767154992),
+      UInt64($562B2BAC2B43FAEF), UInt64($E7FEFED5FEB13264),
+      UInt64($B5D7D771D7E2C493), UInt64($4DABAB9AAB2FD7B5),
+      UInt64($EC7676C3769D2F5E), UInt64($8FCACA05CA0A8A0F),
+      UInt64($1F82823E827C2142), UInt64($89C9C909C912801B),
+      UInt64($FA7D7DEF7DC5152A), UInt64($EFFAFAC5FA912A54),
+      UInt64($B259597F59FECD81), UInt64($8E474707470E8909),
+      UInt64($FBF0F0EDF0C1162C), UInt64($41ADAD82AD1FC39D),
+      UInt64($B3D4D47DD4FACE87), UInt64($5FA2A2BEA267E1D9),
+      UInt64($45AFAF8AAF0FCF85), UInt64($239C9C469C8C65CA),
+      UInt64($53A4A4A6A457F5F1), UInt64($E47272D372BD376E),
+      UInt64($9BC0C02DC05AB677), UInt64($75B7B7EAB7CF9F25),
+      UInt64($E1FDFDD9FDA93870), UInt64($3D93937A93F4478E),
+      UInt64($4C262698262BD4B3), UInt64($6C3636D836ABB473),
+      UInt64($7E3F3FFC3FE3821F), UInt64($F5F7F7F1F7F90408),
+      UInt64($83CCCC1DCC3A9E27), UInt64($683434D034BBB86B),
+      UInt64($51A5A5A2A55FF3FD), UInt64($D1E5E5B9E56968D0),
+      UInt64($F9F1F1E9F1C91020), UInt64($E27171DF71A53D7A),
+      UInt64($ABD8D84DD89AE6D7), UInt64($623131C43193A657),
+      UInt64($2A15155415A87EFC), UInt64($0804041004201830),
+      UInt64($95C7C731C762A453), UInt64($4623238C2303CA8F),
+      UInt64($9DC3C321C342BC63), UInt64($3018186018C050A0),
+      UInt64($3796966E96DC59B2), UInt64($0A05051405281E3C),
+      UInt64($2F9A9A5E9ABC71E2), UInt64($0E07071C07381224),
+      UInt64($2412124812906CD8), UInt64($1B808036806C2D5A),
+      UInt64($DFE2E2A5E2517AF4), UInt64($CDEBEB81EB194C98),
+      UInt64($4E27279C2723D2BF), UInt64($7FB2B2FEB2E78119),
+      UInt64($EA7575CF7585254A), UInt64($120909240948366C),
+      UInt64($1D83833A8374274E), UInt64($582C2CB02C7BE8CB),
+      UInt64($341A1A681AD05CB8), UInt64($361B1B6C1BD85AB4),
+      UInt64($DC6E6EA36E5D7FFE), UInt64($B45A5A735AE6C795),
+      UInt64($5BA0A0B6A077EDC1), UInt64($A452525352A6F7F5),
+      UInt64($763B3BEC3BC39A2F), UInt64($B7D6D675D6EAC29F),
+      UInt64($7DB3B3FAB3EF8715), UInt64($522929A42953F6F7),
+      UInt64($DDE3E3A1E3597CF8), UInt64($5E2F2FBC2F63E2DF),
+      UInt64($13848426844C356A), UInt64($A653535753AEF1F9),
+      UInt64($B9D1D169D1D2D0BB), UInt64($0000000000000000),
+      UInt64($C1EDED99ED2958B0), UInt64($40202080201BC09B),
+      UInt64($E3FCFCDDFCA13E7C), UInt64($79B1B1F2B1FF8B0D),
+      UInt64($B65B5B775BEEC199), UInt64($D46A6AB36A7D67CE),
+      UInt64($8DCBCB01CB028C03), UInt64($67BEBECEBE87A949),
+      UInt64($723939E439D39637), UInt64($944A4A334A66A755),
+      UInt64($984C4C2B4C56B37D), UInt64($B058587B58F6CB8D),
+      UInt64($85CFCF11CF229433), UInt64($BBD0D06DD0DAD6B7),
+      UInt64($C5EFEF91EF3954A8), UInt64($4FAAAA9EAA27D1B9),
+      UInt64($EDFBFBC1FB992C58), UInt64($86434317432E9139),
+      UInt64($9A4D4D2F4D5EB571), UInt64($663333CC3383AA4F),
+      UInt64($1185852285443366), UInt64($8A45450F451E8511),
+      UInt64($E9F9F9C9F9892040), UInt64($0402020802100C18),
+      UInt64($FE7F7FE77FD51932), UInt64($A050505B50B6FBED),
+      UInt64($783C3CF03CFB880B), UInt64($259F9F4A9F946FDE),
+      UInt64($4BA8A896A837DDA1), UInt64($A251515F51BEFDE1),
+      UInt64($5DA3A3BAA36FE7D5), UInt64($8040401B40369B2D),
+      UInt64($058F8F0A8F140F1E), UInt64($3F92927E92FC4182),
+      UInt64($219D9D429D8463C6), UInt64($703838E038DB903B),
+      UInt64($F1F5F5F9F5E90810), UInt64($63BCBCC6BC97A551),
+      UInt64($77B6B6EEB6C79929), UInt64($AFDADA45DA8AEACF),
+      UInt64($422121842113C697), UInt64($20101040108060C0),
+      UInt64($E5FFFFD1FFB93468), UInt64($FDF3F3E1F3D91C38),
+      UInt64($BFD2D265D2CADAAF), UInt64($81CDCD19CD32982B),
+      UInt64($180C0C300C602850), UInt64($2613134C13986AD4),
+      UInt64($C3ECEC9DEC215EBC), UInt64($BE5F5F675FCED9A9),
+      UInt64($3597976A97D45FBE), UInt64($8844440B4416831D),
+      UInt64($2E17175C17B872E4), UInt64($93C4C43DC47AAE47),
+      UInt64($55A7A7AAA74FFFE5), UInt64($FC7E7EE37EDD1F3E),
+      UInt64($7A3D3DF43DF38E07), UInt64($C864648B640D4386),
+      UInt64($BA5D5D6F5DDED5B1), UInt64($3219196419C856AC),
+      UInt64($E67373D773B53162), UInt64($C060609B602D5BB6),
+      UInt64($1981813281642B56), UInt64($9E4F4F274F4EB969),
+      UInt64($A3DCDC5DDCBAFEE7), UInt64($44222288220BCC83),
+      UInt64($542A2AA82A4BFCE3), UInt64($3B90907690EC4D9A),
+      UInt64($0B888816882C1D3A), UInt64($8C46460346068F05),
+      UInt64($C7EEEE95EE3152A4), UInt64($6BB8B8D6B8B7BD61),
+      UInt64($2814145014A078F0), UInt64($A7DEDE55DEAAF2FF),
+      UInt64($BC5E5E635EC6DFA5), UInt64($160B0B2C0B583A74),
+      UInt64($ADDBDB41DB82ECC3), UInt64($DBE0E0ADE04176EC),
+      UInt64($643232C8328BAC43), UInt64($743A3AE83ACB9C23),
+      UInt64($140A0A280A503C78), UInt64($9249493F497EAD41),
+      UInt64($0C06061806301428), UInt64($48242490243BD8AB),
+      UInt64($B85C5C6B5CD6D3BD), UInt64($9FC2C225C24ABA6F),
+      UInt64($BDD3D361D3C2DCA3), UInt64($43ACAC86AC17C591),
+      UInt64($C4626293623D57AE), UInt64($3991917291E44B96),
+      UInt64($3195956295C453A6), UInt64($D3E4E4BDE4616EDC),
+      UInt64($F27979FF79E50D1A), UInt64($D5E7E7B1E77964C8),
+      UInt64($8BC8C80DC81A8617), UInt64($6E3737DC37A3B27F),
+      UInt64($DA6D6DAF6D4575EA), UInt64($018D8D028D040306),
+      UInt64($B1D5D579D5F2C88B), UInt64($9C4E4E234E46BF65),
+      UInt64($49A9A992A93FDBAD), UInt64($D86C6CAB6C4D73E6),
+      UInt64($AC5656435686EFC5), UInt64($F3F4F4FDF4E10E1C),
+      UInt64($CFEAEA85EA114A94), UInt64($CA65658F6505458A),
+      UInt64($F47A7AF37AFD070E), UInt64($47AEAE8EAE07C989),
+      UInt64($1008082008403060), UInt64($6FBABADEBAA7B179),
+      UInt64($F07878FB78ED0B16), UInt64($4A2525942533DEA7),
+      UInt64($5C2E2EB82E6BE4D3), UInt64($381C1C701CE04890),
+      UInt64($57A6A6AEA647F9E9), UInt64($73B4B4E6B4D79531),
+      UInt64($97C6C635C66AA25F), UInt64($CBE8E88DE801468C),
+      UInt64($A1DDDD59DDB2F8EB), UInt64($E87474CB748D2346),
+      UInt64($3E1F1F7C1FF84284), UInt64($964B4B374B6EA159),
+      UInt64($61BDBDC2BD9FA35D), UInt64($0D8B8B1A8B34172E),
+      UInt64($0F8A8A1E8A3C1122), UInt64($E07070DB70AD3B76),
+      UInt64($7C3E3EF83EEB8413), UInt64($71B5B5E2B5DF933D),
+      UInt64($CC666683661D4F9E), UInt64($9048483B4876AB4D),
+      UInt64($0603030C03180A14), UInt64($F7F6F6F5F6F10204),
+      UInt64($1C0E0E380E702448), UInt64($C261619F61255DBA),
+      UInt64($6A3535D435B3BE67), UInt64($AE575747578EE9C9),
+      UInt64($69B9B9D2B9BFBB6D), UInt64($1786862E865C3972),
+      UInt64($99C1C129C152B07B), UInt64($3A1D1D741DE84E9C),
+      UInt64($279E9E4E9E9C69D2), UInt64($D9E1E1A9E14970E0),
+      UInt64($EBF8F8CDF881264C), UInt64($2B98985698AC7DFA),
+      UInt64($22111144118866CC), UInt64($D26969BF69656DDA),
+      UInt64($A9D9D949D992E0DB), UInt64($078E8E0E8E1C0912),
+      UInt64($3394946694CC55AA), UInt64($2D9B9B5A9BB477EE),
+      UInt64($3C1E1E781EF04488), UInt64($1587872A87543F7E),
+      UInt64($C9E9E989E9094080), UInt64($87CECE15CE2A923F),
+      UInt64($AA55554F559EE5D1), UInt64($502828A0285BF0FB),
+      UInt64($A5DFDF51DFA2F4F3), UInt64($038C8C068C0C050A),
+      UInt64($59A1A1B2A17FEBCD), UInt64($0989891289241B36),
+      UInt64($1A0D0D340D682E5C), UInt64($65BFBFCABF8FAF45),
+      UInt64($D7E6E6B5E67162C4), UInt64($8442421342269735),
+      UInt64($D06868BB686D6BD6), UInt64($8241411F413E9D21),
+      UInt64($2999995299A47BF6), UInt64($5A2D2DB42D73EEC7),
+      UInt64($1E0F0F3C0F782244), UInt64($7BB0B0F6B0F78D01),
+      UInt64($A854544B5496E3DD), UInt64($6DBBBBDABBAFB775),
+      UInt64($2C16165816B074E8));
+
+{$ENDREGION}
+    class function CalcTable(i: Int32): THashLibUInt64Array;
+
+    procedure InjectMsg(a_full_process: Boolean);
+
+    class constructor Grindahl512();
+
+  strict protected
+    procedure Finish(); override;
+    function GetResult(): THashLibByteArray; override;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TGrindahl512 }
+
+class function TGrindahl512.CalcTable(i: Int32): THashLibUInt64Array;
+var
+  j: Int32;
+begin
+  System.SetLength(result, 256);
+  j := 0;
+  while j < 256 do
+  begin
+    result[j] := TBits.RotateRight64(s_master_table[j], i * 8);
+    System.Inc(j);
+  end;
+end;
+
+constructor TGrindahl512.Create;
+begin
+  Inherited Create(64, 8);
+  System.SetLength(Fm_state, 13);
+  System.SetLength(Fm_temp, 13);
+end;
+
+procedure TGrindahl512.Finish;
+var
+  padding_size, i: Int32;
+  msg_length: UInt64;
+  pad: THashLibByteArray;
+begin
+  padding_size := 16 - Int32(Fm_processed_bytes and UInt32(7));
+  msg_length := (Fm_processed_bytes shr UInt64(3)) + 1;
+
+  System.SetLength(pad, padding_size);
+
+  pad[0] := $80;
+
+  msg_length := TConverters.be2me_64(msg_length);
+
+  TConverters.ReadUInt64AsBytesLE(msg_length, pad, padding_size - 8);
+
+  TransformBytes(pad, 0, padding_size - 8);
+
+  Fm_state[0] := TConverters.ReadBytesAsUInt64LE(PByte(pad), padding_size - 8);
+
+  Fm_state[0] := TConverters.be2me_64(Fm_state[0]);
+
+  InjectMsg(true);
+
+  i := 0;
+
+  while i < 8 do
+  begin
+    InjectMsg(true);
+    System.Inc(i);
+  end;
+
+end;
+
+function TGrindahl512.GetResult: THashLibByteArray;
+begin
+
+  System.SetLength(result, 8 * System.SizeOf(UInt64));
+
+  TConverters.be64_copy(PUInt64(Fm_state) + 5, 0, PByte(result), 0,
+    System.Length(result));
+
+end;
+
+class constructor TGrindahl512.Grindahl512;
+var
+  LowVal1, LowVal2: Int32;
+begin
+
+  System.SetLength(Fs_table_0, System.Length(s_master_table));
+
+{$IFDEF DELPHIXE2_UP}
+  LowVal1 := System.Low(s_master_table);
+  LowVal2 := System.Low(Fs_table_0);
+{$ELSE}
+  LowVal1 := 0;
+  LowVal2 := 0;
+{$ENDIF DELPHIXE2_UP}
+  System.Move(s_master_table[LowVal1], Fs_table_0[LowVal2],
+    System.SizeOf(s_master_table));
+
+  Fs_table_1 := CalcTable(1);
+  Fs_table_2 := CalcTable(2);
+  Fs_table_3 := CalcTable(3);
+  Fs_table_4 := CalcTable(4);
+  Fs_table_5 := CalcTable(5);
+  Fs_table_6 := CalcTable(6);
+  Fs_table_7 := CalcTable(7);
+
+end;
+
+procedure TGrindahl512.Initialize;
+begin
+
+  System.FillChar(Fm_state[0], System.Length(Fm_state) * System.SizeOf(UInt64),
+    UInt64(0));
+  System.FillChar(Fm_temp[0], System.Length(Fm_temp) * System.SizeOf(UInt64),
+    UInt64(0));
+
+  Inherited Initialize();
+
+end;
+
+procedure TGrindahl512.InjectMsg(a_full_process: Boolean);
+var
+  u: THashLibUInt64Array;
+begin
+
+  Fm_state[12] := Fm_state[12] xor $01;
+
+  if (a_full_process) then
+  begin
+    Fm_temp[0] := Fs_table_0[Byte(Fm_state[12] shr 56)] xor Fs_table_1
+      [Byte(Fm_state[11] shr 48)] xor Fs_table_2[Byte(Fm_state[10] shr 40)
+      ] xor Fs_table_3[Byte(Fm_state[9] shr 32)] xor Fs_table_4
+      [Byte(Fm_state[8] shr 24)] xor Fs_table_5[Byte(Fm_state[7] shr 16)
+      ] xor Fs_table_6[Byte(Fm_state[6] shr 8)] xor Fs_table_7
+      [Byte(Fm_state[5])];
+  end;
+
+  Fm_temp[1] := Fs_table_0[Byte(Fm_state[0] shr 56)] xor Fs_table_1
+    [Byte(Fm_state[12] shr 48)] xor Fs_table_2[Byte(Fm_state[11] shr 40)
+    ] xor Fs_table_3[Byte(Fm_state[10] shr 32)] xor Fs_table_4
+    [Byte(Fm_state[9] shr 24)] xor Fs_table_5[Byte(Fm_state[8] shr 16)
+    ] xor Fs_table_6[Byte(Fm_state[7] shr 8)] xor Fs_table_7[Byte(Fm_state[6])];
+
+  Fm_temp[2] := Fs_table_0[Byte(Fm_state[1] shr 56)] xor Fs_table_1
+    [Byte(Fm_state[0] shr 48)] xor Fs_table_2[Byte(Fm_state[12] shr 40)
+    ] xor Fs_table_3[Byte(Fm_state[11] shr 32)] xor Fs_table_4
+    [Byte(Fm_state[10] shr 24)] xor Fs_table_5[Byte(Fm_state[9] shr 16)
+    ] xor Fs_table_6[Byte(Fm_state[8] shr 8)] xor Fs_table_7[Byte(Fm_state[7])];
+
+  Fm_temp[3] := Fs_table_0[Byte(Fm_state[2] shr 56)] xor Fs_table_1
+    [Byte(Fm_state[1] shr 48)] xor Fs_table_2[Byte(Fm_state[0] shr 40)
+    ] xor Fs_table_3[Byte(Fm_state[12] shr 32)] xor Fs_table_4
+    [Byte(Fm_state[11] shr 24)] xor Fs_table_5[Byte(Fm_state[10] shr 16)
+    ] xor Fs_table_6[Byte(Fm_state[9] shr 8)] xor Fs_table_7[Byte(Fm_state[8])];
+
+  Fm_temp[4] := Fs_table_0[Byte(Fm_state[3] shr 56)] xor Fs_table_1
+    [Byte(Fm_state[2] shr 48)] xor Fs_table_2[Byte(Fm_state[1] shr 40)
+    ] xor Fs_table_3[Byte(Fm_state[0] shr 32)] xor Fs_table_4
+    [Byte(Fm_state[12] shr 24)] xor Fs_table_5[Byte(Fm_state[11] shr 16)
+    ] xor Fs_table_6[Byte(Fm_state[10] shr 8)] xor Fs_table_7
+    [Byte(Fm_state[9])];
+
+  Fm_temp[5] := Fs_table_0[Byte(Fm_state[4] shr 56)] xor Fs_table_1
+    [Byte(Fm_state[3] shr 48)] xor Fs_table_2[Byte(Fm_state[2] shr 40)
+    ] xor Fs_table_3[Byte(Fm_state[1] shr 32)] xor Fs_table_4
+    [Byte(Fm_state[0] shr 24)] xor Fs_table_5[Byte(Fm_state[12] shr 16)
+    ] xor Fs_table_6[Byte(Fm_state[11] shr 8)] xor Fs_table_7
+    [Byte(Fm_state[10])];
+
+  Fm_temp[6] := Fs_table_0[Byte(Fm_state[5] shr 56)] xor Fs_table_1
+    [Byte(Fm_state[4] shr 48)] xor Fs_table_2[Byte(Fm_state[3] shr 40)
+    ] xor Fs_table_3[Byte(Fm_state[2] shr 32)] xor Fs_table_4
+    [Byte(Fm_state[1] shr 24)] xor Fs_table_5[Byte(Fm_state[0] shr 16)
+    ] xor Fs_table_6[Byte(Fm_state[12] shr 8)] xor Fs_table_7
+    [Byte(Fm_state[11])];
+
+  Fm_temp[7] := Fs_table_0[Byte(Fm_state[6] shr 56)] xor Fs_table_1
+    [Byte(Fm_state[5] shr 48)] xor Fs_table_2[Byte(Fm_state[4] shr 40)
+    ] xor Fs_table_3[Byte(Fm_state[3] shr 32)] xor Fs_table_4
+    [Byte(Fm_state[2] shr 24)] xor Fs_table_5[Byte(Fm_state[1] shr 16)
+    ] xor Fs_table_6[Byte(Fm_state[0] shr 8)] xor Fs_table_7
+    [Byte(Fm_state[12])];
+
+  Fm_temp[8] := Fs_table_0[Byte(Fm_state[7] shr 56)] xor Fs_table_1
+    [Byte(Fm_state[6] shr 48)] xor Fs_table_2[Byte(Fm_state[5] shr 40)
+    ] xor Fs_table_3[Byte(Fm_state[4] shr 32)] xor Fs_table_4
+    [Byte(Fm_state[3] shr 24)] xor Fs_table_5[Byte(Fm_state[2] shr 16)
+    ] xor Fs_table_6[Byte(Fm_state[1] shr 8)] xor Fs_table_7[Byte(Fm_state[0])];
+
+  Fm_temp[9] := Fs_table_0[Byte(Fm_state[8] shr 56)] xor Fs_table_1
+    [Byte(Fm_state[7] shr 48)] xor Fs_table_2[Byte(Fm_state[6] shr 40)
+    ] xor Fs_table_3[Byte(Fm_state[5] shr 32)] xor Fs_table_4
+    [Byte(Fm_state[4] shr 24)] xor Fs_table_5[Byte(Fm_state[3] shr 16)
+    ] xor Fs_table_6[Byte(Fm_state[2] shr 8)] xor Fs_table_7[Byte(Fm_state[1])];
+
+  Fm_temp[10] := Fs_table_0[Byte(Fm_state[9] shr 56)] xor Fs_table_1
+    [Byte(Fm_state[8] shr 48)] xor Fs_table_2[Byte(Fm_state[7] shr 40)
+    ] xor Fs_table_3[Byte(Fm_state[6] shr 32)] xor Fs_table_4
+    [Byte(Fm_state[5] shr 24)] xor Fs_table_5[Byte(Fm_state[4] shr 16)
+    ] xor Fs_table_6[Byte(Fm_state[3] shr 8)] xor Fs_table_7[Byte(Fm_state[2])];
+
+  Fm_temp[11] := Fs_table_0[Byte(Fm_state[10] shr 56)] xor Fs_table_1
+    [Byte(Fm_state[9] shr 48)] xor Fs_table_2[Byte(Fm_state[8] shr 40)
+    ] xor Fs_table_3[Byte(Fm_state[7] shr 32)] xor Fs_table_4
+    [Byte(Fm_state[6] shr 24)] xor Fs_table_5[Byte(Fm_state[5] shr 16)
+    ] xor Fs_table_6[Byte(Fm_state[4] shr 8)] xor Fs_table_7[Byte(Fm_state[3])];
+
+  Fm_temp[12] := Fs_table_0[Byte(Fm_state[11] shr 56)] xor Fs_table_1
+    [Byte(Fm_state[10] shr 48)] xor Fs_table_2[Byte(Fm_state[9] shr 40)
+    ] xor Fs_table_3[Byte(Fm_state[8] shr 32)] xor Fs_table_4
+    [Byte(Fm_state[7] shr 24)] xor Fs_table_5[Byte(Fm_state[6] shr 16)
+    ] xor Fs_table_6[Byte(Fm_state[5] shr 8)] xor Fs_table_7[Byte(Fm_state[4])];
+
+  u := Fm_temp;
+  Fm_temp := Fm_state;
+  Fm_state := u;
+
+end;
+
+procedure TGrindahl512.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+begin
+
+  Fm_state[0] := TConverters.ReadBytesAsUInt64LE(a_data, a_index);
+
+  Fm_state[0] := TConverters.be2me_64(Fm_state[0]);
+
+  InjectMsg(false);
+
+end;
+
+end.

+ 209 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpHAS160.pas

@@ -0,0 +1,209 @@
+unit HlpHAS160;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpHashBuffer,
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpConverters,
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn;
+
+type
+  THAS160 = class sealed(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+  strict private
+
+    Fm_hash: THashLibUInt32Array;
+
+{$REGION 'Consts'}
+
+  const
+
+    s_rot: array [0 .. 19] of Int32 = (5, 11, 7, 15, 6, 13, 8, 14, 7, 12, 9, 11,
+      8, 15, 6, 12, 9, 14, 5, 13);
+
+    s_tor: array [0 .. 19] of Int32 = (27, 21, 25, 17, 26, 19, 24, 18, 25, 20,
+      23, 21, 24, 17, 26, 20, 23, 18, 27, 19);
+
+    s_index: array [0 .. 79] of Int32 = (18, 0, 1, 2, 3, 19, 4, 5, 6, 7, 16, 8,
+      9, 10, 11, 17, 12, 13, 14, 15, 18, 3, 6, 9, 12, 19, 15, 2, 5, 8, 16, 11,
+      14, 1, 4, 17, 7, 10, 13, 0, 18, 12, 5, 14, 7, 19, 0, 9, 2, 11, 16, 4, 13,
+      6, 15, 17, 8, 1, 10, 3, 18, 7, 2, 13, 8, 19, 3, 14, 9, 4, 16, 15, 10, 5,
+      0, 17, 11, 6, 1, 12);
+
+{$ENDREGION}
+  strict protected
+    procedure Finish(); override;
+    function GetResult(): THashLibByteArray; override;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+  end;
+
+implementation
+
+{ THAS160 }
+
+constructor THAS160.Create;
+begin
+  Inherited Create(20, 64);
+  System.SetLength(Fm_hash, 5);
+end;
+
+procedure THAS160.Finish;
+var
+  pad_index: Int32;
+  bits: UInt64;
+  pad: THashLibByteArray;
+begin
+  bits := Fm_processed_bytes * 8;
+  if (Fm_buffer.Pos < 56) then
+    pad_index := (56 - Fm_buffer.Pos)
+  else
+    pad_index := (120 - Fm_buffer.Pos);
+
+  System.SetLength(pad, pad_index + 8);
+
+  pad[0] := $80;
+
+  bits := TConverters.le2me_64(bits);
+
+  TConverters.ReadUInt64AsBytesLE(bits, pad, pad_index);
+
+  pad_index := pad_index + 8;
+
+  TransformBytes(pad, 0, pad_index);
+
+end;
+
+function THAS160.GetResult: THashLibByteArray;
+begin
+
+  System.SetLength(result, 5 * System.SizeOf(UInt32));
+
+  TConverters.le32_copy(PCardinal(Fm_hash), 0, PByte(result), 0,
+    System.Length(result));
+
+end;
+
+procedure THAS160.Initialize;
+begin
+  Fm_hash[0] := $67452301;
+  Fm_hash[1] := $EFCDAB89;
+  Fm_hash[2] := $98BADCFE;
+  Fm_hash[3] := $10325476;
+  Fm_hash[4] := $C3D2E1F0;
+
+  Inherited Initialize();
+end;
+
+procedure THAS160.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  A, B, C, D, E, T: UInt32;
+  r: Int32;
+  data: array [0 .. 19] of UInt32;
+begin
+  A := Fm_hash[0];
+  B := Fm_hash[1];
+  C := Fm_hash[2];
+  D := Fm_hash[3];
+  E := Fm_hash[4];
+
+  TConverters.le32_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+
+  data[16] := data[0] xor data[1] xor data[2] xor data[3];
+  data[17] := data[4] xor data[5] xor data[6] xor data[7];
+  data[18] := data[8] xor data[9] xor data[10] xor data[11];
+  data[19] := data[12] xor data[13] xor data[14] xor data[15];
+
+  r := 0;
+  while r < 20 do
+  begin
+    T := data[s_index[r]] + (A shl s_rot[r] or A shr s_tor[r]) +
+      ((B and C) or (not B and D)) + E;
+    E := D;
+    D := C;
+    C := B shl 10 or B shr 22;
+    B := A;
+    A := T;
+    System.Inc(r);
+  end;
+
+  data[16] := data[3] xor data[6] xor data[9] xor data[12];
+  data[17] := data[2] xor data[5] xor data[8] xor data[15];
+  data[18] := data[1] xor data[4] xor data[11] xor data[14];
+  data[19] := data[0] xor data[7] xor data[10] xor data[13];
+
+  r := 20;
+  while r < 40 do
+  begin
+    T := data[s_index[r]] + $5A827999 +
+      (A shl s_rot[r - 20] or A shr s_tor[r - 20]) + (B xor C xor D) + E;
+    E := D;
+    D := C;
+    C := B shl 17 or B shr 15;
+    B := A;
+    A := T;
+    System.Inc(r);
+  end;
+
+  data[16] := data[5] xor data[7] xor data[12] xor data[14];
+  data[17] := data[0] xor data[2] xor data[9] xor data[11];
+  data[18] := data[4] xor data[6] xor data[13] xor data[15];
+  data[19] := data[1] xor data[3] xor data[8] xor data[10];
+
+  r := 40;
+  while r < 60 do
+  begin
+    T := data[s_index[r]] + $6ED9EBA1 +
+      (A shl s_rot[r - 40] or A shr s_tor[r - 40]) + (C xor (B or not D)) + E;
+    E := D;
+    D := C;
+    C := B shl 25 or B shr 7;
+    B := A;
+    A := T;
+    System.Inc(r);
+  end;
+
+  data[16] := data[2] xor data[7] xor data[8] xor data[13];
+  data[17] := data[3] xor data[4] xor data[9] xor data[14];
+  data[18] := data[0] xor data[5] xor data[10] xor data[15];
+  data[19] := data[1] xor data[6] xor data[11] xor data[12];
+
+  r := 60;
+  while r < 80 do
+  begin
+    T := data[s_index[r]] + $8F1BBCDC +
+      (A shl s_rot[r - 60] or A shr s_tor[r - 60]) + (B xor C xor D) + E;
+    E := D;
+    D := C;
+    C := B shl 30 or B shr 2;
+    B := A;
+    A := T;
+    System.Inc(r);
+  end;
+
+  Fm_hash[0] := Fm_hash[0] + A;
+  Fm_hash[1] := Fm_hash[1] + B;
+  Fm_hash[2] := Fm_hash[2] + C;
+  Fm_hash[3] := Fm_hash[3] + D;
+  Fm_hash[4] := Fm_hash[4] + E;
+
+  System.FillChar(data, System.SizeOf(data), 0);
+
+end;
+
+end.

+ 2187 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpHaval.pas

@@ -0,0 +1,2187 @@
+unit HlpHaval;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpHashBuffer,
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpBits,
+  HlpHashSize,
+  HlpHashRounds,
+  HlpConverters,
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn;
+
+resourcestring
+  SInvalidHavalRound = 'Haval Round Must be 3, 4 or 5';
+  SInvalidHavalHashSize =
+    'Haval HashSize Must be Either 128 bit(16 byte), 160 bit(20 byte), 192 bit(24 byte), 224 bit(28 byte) or 256 bit(32 byte)';
+
+type
+  THaval = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+  strict private
+  const
+
+    HAVAL_VERSION = Int32(1);
+
+    procedure TailorDigestBits();
+
+  strict protected
+    Fm_rounds, FHashSize: Int32;
+    Fm_hash: THashLibUInt32Array;
+
+    constructor Create(a_rounds: THashRounds; a_hash_size: THashSize);
+
+    procedure Finish(); override;
+    function GetResult(): THashLibByteArray; override;
+
+  public
+    procedure Initialize(); override;
+  end;
+
+type
+
+  THaval3 = class abstract(THaval)
+
+  strict protected
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create(a_hash_size: THashSize);
+
+  end;
+
+type
+
+  THaval4 = class abstract(THaval)
+
+  strict protected
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create(a_hash_size: THashSize);
+
+  end;
+
+type
+
+  THaval5 = class abstract(THaval)
+
+  strict protected
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create(a_hash_size: THashSize);
+
+  end;
+
+type
+
+  THaval_3_128 = class sealed(THaval3)
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  THaval_4_128 = class sealed(THaval4)
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  THaval_5_128 = class sealed(THaval5)
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  THaval_3_160 = class sealed(THaval3)
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  THaval_4_160 = class sealed(THaval4)
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  THaval_5_160 = class sealed(THaval5)
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  THaval_3_192 = class sealed(THaval3)
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  THaval_4_192 = class sealed(THaval4)
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  THaval_5_192 = class sealed(THaval5)
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  THaval_3_224 = class sealed(THaval3)
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  THaval_4_224 = class sealed(THaval4)
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  THaval_5_224 = class sealed(THaval5)
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  THaval_3_256 = class sealed(THaval3)
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  THaval_4_256 = class sealed(THaval4)
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  THaval_5_256 = class sealed(THaval5)
+
+  public
+    constructor Create();
+
+  end;
+
+implementation
+
+{ THaval }
+
+constructor THaval.Create(a_rounds: THashRounds; a_hash_size: THashSize);
+begin
+  inherited Create(Int32(a_hash_size), 128);
+  FHashSize := HashSize;
+  System.SetLength(Fm_hash, 8);
+  Fm_rounds := Int32(a_rounds);
+
+end;
+
+procedure THaval.Finish;
+var
+  bits: UInt64;
+  padindex: Int32;
+  pad: THashLibByteArray;
+begin
+  bits := Fm_processed_bytes * 8;
+  if (Fm_buffer.Pos < 118) then
+    padindex := (118 - Fm_buffer.Pos)
+  else
+    padindex := (246 - Fm_buffer.Pos);
+  System.SetLength(pad, padindex + 10);
+
+  pad[0] := Byte($01);
+
+  pad[padindex] := Byte((Fm_rounds shl 3) or (HAVAL_VERSION and $07));
+  System.Inc(padindex);
+  pad[padindex] := Byte(FHashSize shl 1);
+  System.Inc(padindex);
+
+  bits := TConverters.le2me_64(bits);
+
+  TConverters.ReadUInt64AsBytesLE(bits, pad, padindex);
+
+  padindex := padindex + 8;
+
+  TransformBytes(pad, 0, padindex);
+
+end;
+
+function THaval.GetResult: THashLibByteArray;
+begin
+  TailorDigestBits();
+
+  System.SetLength(result, (FHashSize shr 2) * System.SizeOf(UInt32));
+
+  TConverters.le32_copy(PCardinal(Fm_hash), 0, PByte(result), 0,
+    System.Length(result));
+
+end;
+
+procedure THaval.Initialize;
+begin
+  Fm_hash[0] := $243F6A88;
+  Fm_hash[1] := $85A308D3;
+  Fm_hash[2] := $13198A2E;
+  Fm_hash[3] := $03707344;
+  Fm_hash[4] := $A4093822;
+  Fm_hash[5] := $299F31D0;
+  Fm_hash[6] := $082EFA98;
+  Fm_hash[7] := $EC4E6C89;
+
+  inherited Initialize();
+
+end;
+
+procedure THaval.TailorDigestBits;
+var
+  t: UInt32;
+begin
+
+  case FHashSize of
+
+    16:
+      begin
+        t := (Fm_hash[7] and $000000FF) or (Fm_hash[6] and $FF000000) or
+          (Fm_hash[5] and $00FF0000) or (Fm_hash[4] and $0000FF00);
+        Fm_hash[0] := Fm_hash[0] + TBits.RotateRight32(t, 8);
+        t := (Fm_hash[7] and $0000FF00) or (Fm_hash[6] and $000000FF) or
+          (Fm_hash[5] and $FF000000) or (Fm_hash[4] and $00FF0000);
+        Fm_hash[1] := Fm_hash[1] + TBits.RotateRight32(t, 16);
+        t := (Fm_hash[7] and $00FF0000) or (Fm_hash[6] and $0000FF00) or
+          (Fm_hash[5] and $000000FF) or (Fm_hash[4] and $FF000000);
+        Fm_hash[2] := Fm_hash[2] + TBits.RotateRight32(t, 24);
+        t := (Fm_hash[7] and $FF000000) or (Fm_hash[6] and $00FF0000) or
+          (Fm_hash[5] and $0000FF00) or (Fm_hash[4] and $000000FF);
+        Fm_hash[3] := Fm_hash[3] + t;
+      end;
+
+    20:
+      begin
+        t := UInt32(Fm_hash[7] and $3F) or UInt32(Fm_hash[6] and ($7F shl 25))
+          or UInt32(Fm_hash[5] and ($3F shl 19));
+        Fm_hash[0] := Fm_hash[0] + TBits.RotateRight32(t, 19);
+        t := UInt32(Fm_hash[7] and ($3F shl 6)) or UInt32(Fm_hash[6] and $3F) or
+          UInt32(Fm_hash[5] and ($7F shl 25));
+        Fm_hash[1] := Fm_hash[1] + TBits.RotateRight32(t, 25);
+        t := (Fm_hash[7] and ($7F shl 12)) or (Fm_hash[6] and ($3F shl 6)) or
+          (Fm_hash[5] and $3F);
+        Fm_hash[2] := Fm_hash[2] + t;
+        t := (Fm_hash[7] and ($3F shl 19)) or (Fm_hash[6] and ($7F shl 12)) or
+          (Fm_hash[5] and ($3F shl 6));
+        Fm_hash[3] := Fm_hash[3] + (t shr 6);
+        t := (Fm_hash[7] and (UInt32($7F) shl 25)) or
+          UInt32(Fm_hash[6] and ($3F shl 19)) or
+          UInt32(Fm_hash[5] and ($7F shl 12));
+        Fm_hash[4] := Fm_hash[4] + (t shr 12);
+      end;
+
+    24:
+      begin
+        t := UInt32(Fm_hash[7] and $1F) or UInt32(Fm_hash[6] and ($3F shl 26));
+        Fm_hash[0] := Fm_hash[0] + TBits.RotateRight32(t, 26);
+        t := (Fm_hash[7] and ($1F shl 5)) or (Fm_hash[6] and $1F);
+        Fm_hash[1] := Fm_hash[1] + t;
+        t := (Fm_hash[7] and ($3F shl 10)) or (Fm_hash[6] and ($1F shl 5));
+        Fm_hash[2] := Fm_hash[2] + (t shr 5);
+        t := (Fm_hash[7] and ($1F shl 16)) or (Fm_hash[6] and ($3F shl 10));
+        Fm_hash[3] := Fm_hash[3] + (t shr 10);
+        t := (Fm_hash[7] and ($1F shl 21)) or (Fm_hash[6] and ($1F shl 16));
+        Fm_hash[4] := Fm_hash[4] + (t shr 16);
+        t := UInt32(Fm_hash[7] and ($3F shl 26)) or
+          UInt32(Fm_hash[6] and ($1F shl 21));
+        Fm_hash[5] := Fm_hash[5] + (t shr 21);
+      end;
+
+    28:
+      begin
+        Fm_hash[0] := Fm_hash[0] + ((Fm_hash[7] shr 27) and $1F);
+        Fm_hash[1] := Fm_hash[1] + ((Fm_hash[7] shr 22) and $1F);
+        Fm_hash[2] := Fm_hash[2] + ((Fm_hash[7] shr 18) and $0F);
+        Fm_hash[3] := Fm_hash[3] + ((Fm_hash[7] shr 13) and $1F);
+        Fm_hash[4] := Fm_hash[4] + ((Fm_hash[7] shr 9) and $0F);
+        Fm_hash[5] := Fm_hash[5] + ((Fm_hash[7] shr 4) and $1F);
+        Fm_hash[6] := Fm_hash[6] + (Fm_hash[7] and $0F);
+      end;
+
+  end;
+
+end;
+
+{ THaval3 }
+
+constructor THaval3.Create(a_hash_size: THashSize);
+begin
+  inherited Create(THashRounds.hrRounds3, a_hash_size);
+end;
+
+procedure THaval3.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  a, b, c, d, e, f, g, h, t: UInt32;
+  temp: array [0 .. 31] of UInt32;
+begin
+
+  TConverters.le32_copy(a_data, a_index, @(temp[0]), 0, a_data_length);
+
+  a := Fm_hash[0];
+  b := Fm_hash[1];
+  c := Fm_hash[2];
+  d := Fm_hash[3];
+  e := Fm_hash[4];
+  f := Fm_hash[5];
+  g := Fm_hash[6];
+  h := Fm_hash[7];
+
+  t := c and (e xor d) xor g and a xor f and b xor e;
+  h := temp[0] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(h, 11);
+
+  t := b and (d xor c) xor f and h xor e and a xor d;
+  g := temp[1] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(g, 11);
+
+  t := a and (c xor b) xor e and g xor d and h xor c;
+  f := temp[2] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(f, 11);
+
+  t := h and (b xor a) xor d and f xor c and g xor b;
+  e := temp[3] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(e, 11);
+
+  t := g and (a xor h) xor c and e xor b and f xor a;
+  d := temp[4] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(d, 11);
+
+  t := f and (h xor g) xor b and d xor a and e xor h;
+  c := temp[5] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(c, 11);
+
+  t := e and (g xor f) xor a and c xor h and d xor g;
+  b := temp[6] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(b, 11);
+
+  t := d and (f xor e) xor h and b xor g and c xor f;
+  a := temp[7] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(a, 11);
+
+  t := c and (e xor d) xor g and a xor f and b xor e;
+  h := temp[8] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(h, 11);
+
+  t := b and (d xor c) xor f and h xor e and a xor d;
+  g := temp[9] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(g, 11);
+
+  t := a and (c xor b) xor e and g xor d and h xor c;
+  f := temp[10] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(f, 11);
+
+  t := h and (b xor a) xor d and f xor c and g xor b;
+  e := temp[11] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(e, 11);
+
+  t := g and (a xor h) xor c and e xor b and f xor a;
+  d := temp[12] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(d, 11);
+
+  t := f and (h xor g) xor b and d xor a and e xor h;
+  c := temp[13] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(c, 11);
+
+  t := e and (g xor f) xor a and c xor h and d xor g;
+  b := temp[14] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(b, 11);
+
+  t := d and (f xor e) xor h and b xor g and c xor f;
+  a := temp[15] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(a, 11);
+
+  t := c and (e xor d) xor g and a xor f and b xor e;
+  h := temp[16] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(h, 11);
+
+  t := b and (d xor c) xor f and h xor e and a xor d;
+  g := temp[17] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(g, 11);
+
+  t := a and (c xor b) xor e and g xor d and h xor c;
+  f := temp[18] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(f, 11);
+
+  t := h and (b xor a) xor d and f xor c and g xor b;
+  e := temp[19] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(e, 11);
+
+  t := g and (a xor h) xor c and e xor b and f xor a;
+  d := temp[20] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(d, 11);
+
+  t := f and (h xor g) xor b and d xor a and e xor h;
+  c := temp[21] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(c, 11);
+
+  t := e and (g xor f) xor a and c xor h and d xor g;
+  b := temp[22] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(b, 11);
+
+  t := d and (f xor e) xor h and b xor g and c xor f;
+  a := temp[23] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(a, 11);
+
+  t := c and (e xor d) xor g and a xor f and b xor e;
+  h := temp[24] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(h, 11);
+
+  t := b and (d xor c) xor f and h xor e and a xor d;
+  g := temp[25] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(g, 11);
+
+  t := a and (c xor b) xor e and g xor d and h xor c;
+  f := temp[26] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(f, 11);
+
+  t := h and (b xor a) xor d and f xor c and g xor b;
+  e := temp[27] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(e, 11);
+
+  t := g and (a xor h) xor c and e xor b and f xor a;
+  d := temp[28] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(d, 11);
+
+  t := f and (h xor g) xor b and d xor a and e xor h;
+  c := temp[29] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(c, 11);
+
+  t := e and (g xor f) xor a and c xor h and d xor g;
+  b := temp[30] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(b, 11);
+
+  t := d and (f xor e) xor h and b xor g and c xor f;
+  a := temp[31] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(a, 11);
+
+  t := f and (d and not a xor b and c xor e xor g) xor b and (d xor c)
+    xor a and c xor g;
+  h := temp[5] + $452821E6 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := e and (c and not h xor a and b xor d xor f) xor a and (c xor b)
+    xor h and b xor f;
+  g := temp[14] + $38D01377 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := d and (b and not g xor h and a xor c xor e) xor h and (b xor a)
+    xor g and a xor e;
+  f := temp[26] + $BE5466CF + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := c and (a and not f xor g and h xor b xor d) xor g and (a xor h)
+    xor f and h xor d;
+  e := temp[18] + $34E90C6C + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := b and (h and not e xor f and g xor a xor c) xor f and (h xor g)
+    xor e and g xor c;
+  d := temp[11] + $C0AC29B7 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := a and (g and not d xor e and f xor h xor b) xor e and (g xor f)
+    xor d and f xor b;
+  c := temp[28] + $C97C50DD + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := h and (f and not c xor d and e xor g xor a) xor d and (f xor e)
+    xor c and e xor a;
+  b := temp[7] + $3F84D5B5 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := g and (e and not b xor c and d xor f xor h) xor c and (e xor d)
+    xor b and d xor h;
+  a := temp[16] + $B5470917 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := f and (d and not a xor b and c xor e xor g) xor b and (d xor c)
+    xor a and c xor g;
+  h := temp[0] + $9216D5D9 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := e and (c and not h xor a and b xor d xor f) xor a and (c xor b)
+    xor h and b xor f;
+  g := temp[23] + $8979FB1B + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := d and (b and not g xor h and a xor c xor e) xor h and (b xor a)
+    xor g and a xor e;
+  f := temp[20] + $D1310BA6 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := c and (a and not f xor g and h xor b xor d) xor g and (a xor h)
+    xor f and h xor d;
+  e := temp[22] + $98DFB5AC + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := b and (h and not e xor f and g xor a xor c) xor f and (h xor g)
+    xor e and g xor c;
+  d := temp[1] + $2FFD72DB + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := a and (g and not d xor e and f xor h xor b) xor e and (g xor f)
+    xor d and f xor b;
+  c := temp[10] + $D01ADFB7 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := h and (f and not c xor d and e xor g xor a) xor d and (f xor e)
+    xor c and e xor a;
+  b := temp[4] + $B8E1AFED + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := g and (e and not b xor c and d xor f xor h) xor c and (e xor d)
+    xor b and d xor h;
+  a := temp[8] + $6A267E96 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := f and (d and not a xor b and c xor e xor g) xor b and (d xor c)
+    xor a and c xor g;
+  h := temp[30] + $BA7C9045 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := e and (c and not h xor a and b xor d xor f) xor a and (c xor b)
+    xor h and b xor f;
+  g := temp[3] + $F12C7F99 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := d and (b and not g xor h and a xor c xor e) xor h and (b xor a)
+    xor g and a xor e;
+  f := temp[21] + $24A19947 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := c and (a and not f xor g and h xor b xor d) xor g and (a xor h)
+    xor f and h xor d;
+  e := temp[9] + $B3916CF7 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := b and (h and not e xor f and g xor a xor c) xor f and (h xor g)
+    xor e and g xor c;
+  d := temp[17] + $0801F2E2 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := a and (g and not d xor e and f xor h xor b) xor e and (g xor f)
+    xor d and f xor b;
+  c := temp[24] + $858EFC16 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := h and (f and not c xor d and e xor g xor a) xor d and (f xor e)
+    xor c and e xor a;
+  b := temp[29] + $636920D8 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := g and (e and not b xor c and d xor f xor h) xor c and (e xor d)
+    xor b and d xor h;
+  a := temp[6] + $71574E69 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := f and (d and not a xor b and c xor e xor g) xor b and (d xor c)
+    xor a and c xor g;
+  h := temp[19] + $A458FEA3 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := e and (c and not h xor a and b xor d xor f) xor a and (c xor b)
+    xor h and b xor f;
+  g := temp[12] + $F4933D7E + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := d and (b and not g xor h and a xor c xor e) xor h and (b xor a)
+    xor g and a xor e;
+  f := temp[15] + $0D95748F + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := c and (a and not f xor g and h xor b xor d) xor g and (a xor h)
+    xor f and h xor d;
+  e := temp[13] + $728EB658 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := b and (h and not e xor f and g xor a xor c) xor f and (h xor g)
+    xor e and g xor c;
+  d := temp[2] + $718BCD58 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := a and (g and not d xor e and f xor h xor b) xor e and (g xor f)
+    xor d and f xor b;
+  c := temp[25] + $82154AEE + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := h and (f and not c xor d and e xor g xor a) xor d and (f xor e)
+    xor c and e xor a;
+  b := temp[31] + $7B54A41D + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := g and (e and not b xor c and d xor f xor h) xor c and (e xor d)
+    xor b and d xor h;
+  a := temp[27] + $C25A59B5 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := d and (f and e xor g xor a) xor f and c xor e and b xor a;
+  h := temp[19] + $9C30D539 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := c and (e and d xor f xor h) xor e and b xor d and a xor h;
+  g := temp[9] + $2AF26013 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := b and (d and c xor e xor g) xor d and a xor c and h xor g;
+  f := temp[4] + $C5D1B023 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := a and (c and b xor d xor f) xor c and h xor b and g xor f;
+  e := temp[20] + $286085F0 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := h and (b and a xor c xor e) xor b and g xor a and f xor e;
+  d := temp[28] + $CA417918 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := g and (a and h xor b xor d) xor a and f xor h and e xor d;
+  c := temp[17] + $B8DB38EF + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := f and (h and g xor a xor c) xor h and e xor g and d xor c;
+  b := temp[8] + $8E79DCB0 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := e and (g and f xor h xor b) xor g and d xor f and c xor b;
+  a := temp[22] + $603A180E + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := d and (f and e xor g xor a) xor f and c xor e and b xor a;
+  h := temp[29] + $6C9E0E8B + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := c and (e and d xor f xor h) xor e and b xor d and a xor h;
+  g := temp[14] + $B01E8A3E + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := b and (d and c xor e xor g) xor d and a xor c and h xor g;
+  f := temp[25] + $D71577C1 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := a and (c and b xor d xor f) xor c and h xor b and g xor f;
+  e := temp[12] + $BD314B27 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := h and (b and a xor c xor e) xor b and g xor a and f xor e;
+  d := temp[24] + $78AF2FDA + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := g and (a and h xor b xor d) xor a and f xor h and e xor d;
+  c := temp[30] + $55605C60 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := f and (h and g xor a xor c) xor h and e xor g and d xor c;
+  b := temp[16] + $E65525F3 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := e and (g and f xor h xor b) xor g and d xor f and c xor b;
+  a := temp[26] + $AA55AB94 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := d and (f and e xor g xor a) xor f and c xor e and b xor a;
+  h := temp[31] + $57489862 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := c and (e and d xor f xor h) xor e and b xor d and a xor h;
+  g := temp[15] + $63E81440 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := b and (d and c xor e xor g) xor d and a xor c and h xor g;
+  f := temp[7] + $55CA396A + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := a and (c and b xor d xor f) xor c and h xor b and g xor f;
+  e := temp[3] + $2AAB10B6 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := h and (b and a xor c xor e) xor b and g xor a and f xor e;
+  d := temp[1] + $B4CC5C34 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := g and (a and h xor b xor d) xor a and f xor h and e xor d;
+  c := temp[0] + $1141E8CE + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := f and (h and g xor a xor c) xor h and e xor g and d xor c;
+  b := temp[18] + $A15486AF + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := e and (g and f xor h xor b) xor g and d xor f and c xor b;
+  a := temp[27] + $7C72E993 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := d and (f and e xor g xor a) xor f and c xor e and b xor a;
+  h := temp[13] + $B3EE1411 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := c and (e and d xor f xor h) xor e and b xor d and a xor h;
+  g := temp[6] + $636FBC2A + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := b and (d and c xor e xor g) xor d and a xor c and h xor g;
+  f := temp[21] + $2BA9C55D + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := a and (c and b xor d xor f) xor c and h xor b and g xor f;
+  e := temp[10] + $741831F6 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := h and (b and a xor c xor e) xor b and g xor a and f xor e;
+  d := temp[23] + $CE5C3E16 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := g and (a and h xor b xor d) xor a and f xor h and e xor d;
+  c := temp[11] + $9B87931E + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := f and (h and g xor a xor c) xor h and e xor g and d xor c;
+  b := temp[5] + $AFD6BA33 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := e and (g and f xor h xor b) xor g and d xor f and c xor b;
+  a := temp[2] + $6C24CF5C + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  Fm_hash[0] := Fm_hash[0] + a;
+  Fm_hash[1] := Fm_hash[1] + b;
+  Fm_hash[2] := Fm_hash[2] + c;
+  Fm_hash[3] := Fm_hash[3] + d;
+  Fm_hash[4] := Fm_hash[4] + e;
+  Fm_hash[5] := Fm_hash[5] + f;
+  Fm_hash[6] := Fm_hash[6] + g;
+  Fm_hash[7] := Fm_hash[7] + h;
+
+  System.FillChar(temp, System.SizeOf(temp), 0);
+end;
+
+{ THaval4 }
+
+constructor THaval4.Create(a_hash_size: THashSize);
+begin
+  inherited Create(THashRounds.hrRounds4, a_hash_size);
+end;
+
+procedure THaval4.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  a, b, c, d, e, f, g, h, t: UInt32;
+  temp: array [0 .. 31] of UInt32;
+begin
+
+  TConverters.le32_copy(a_data, a_index, @(temp[0]), 0, a_data_length);
+
+  a := Fm_hash[0];
+  b := Fm_hash[1];
+  c := Fm_hash[2];
+  d := Fm_hash[3];
+  e := Fm_hash[4];
+  f := Fm_hash[5];
+  g := Fm_hash[6];
+  h := Fm_hash[7];
+
+  t := d and (a xor b) xor f and g xor e and c xor a;
+  h := temp[0] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(h, 11);
+
+  t := c and (h xor a) xor e and f xor d and b xor h;
+  g := temp[1] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(g, 11);
+
+  t := b and (g xor h) xor d and e xor c and a xor g;
+  f := temp[2] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(f, 11);
+
+  t := a and (f xor g) xor c and d xor b and h xor f;
+  e := temp[3] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(e, 11);
+
+  t := h and (e xor f) xor b and c xor a and g xor e;
+  d := temp[4] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(d, 11);
+
+  t := g and (d xor e) xor a and b xor h and f xor d;
+  c := temp[5] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(c, 11);
+
+  t := f and (c xor d) xor h and a xor g and e xor c;
+  b := temp[6] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(b, 11);
+
+  t := e and (b xor c) xor g and h xor f and d xor b;
+  a := temp[7] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(a, 11);
+
+  t := d and (a xor b) xor f and g xor e and c xor a;
+  h := temp[8] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(h, 11);
+
+  t := c and (h xor a) xor e and f xor d and b xor h;
+  g := temp[9] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(g, 11);
+
+  t := b and (g xor h) xor d and e xor c and a xor g;
+  f := temp[10] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(f, 11);
+
+  t := a and (f xor g) xor c and d xor b and h xor f;
+  e := temp[11] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(e, 11);
+
+  t := h and (e xor f) xor b and c xor a and g xor e;
+  d := temp[12] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(d, 11);
+
+  t := g and (d xor e) xor a and b xor h and f xor d;
+  c := temp[13] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(c, 11);
+
+  t := f and (c xor d) xor h and a xor g and e xor c;
+  b := temp[14] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(b, 11);
+
+  t := e and (b xor c) xor g and h xor f and d xor b;
+  a := temp[15] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(a, 11);
+
+  t := d and (a xor b) xor f and g xor e and c xor a;
+  h := temp[16] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(h, 11);
+
+  t := c and (h xor a) xor e and f xor d and b xor h;
+  g := temp[17] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(g, 11);
+
+  t := b and (g xor h) xor d and e xor c and a xor g;
+  f := temp[18] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(f, 11);
+
+  t := a and (f xor g) xor c and d xor b and h xor f;
+  e := temp[19] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(e, 11);
+
+  t := h and (e xor f) xor b and c xor a and g xor e;
+  d := temp[20] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(d, 11);
+
+  t := g and (d xor e) xor a and b xor h and f xor d;
+  c := temp[21] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(c, 11);
+
+  t := f and (c xor d) xor h and a xor g and e xor c;
+  b := temp[22] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(b, 11);
+
+  t := e and (b xor c) xor g and h xor f and d xor b;
+  a := temp[23] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(a, 11);
+
+  t := d and (a xor b) xor f and g xor e and c xor a;
+  h := temp[24] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(h, 11);
+
+  t := c and (h xor a) xor e and f xor d and b xor h;
+  g := temp[25] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(g, 11);
+
+  t := b and (g xor h) xor d and e xor c and a xor g;
+  f := temp[26] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(f, 11);
+
+  t := a and (f xor g) xor c and d xor b and h xor f;
+  e := temp[27] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(e, 11);
+
+  t := h and (e xor f) xor b and c xor a and g xor e;
+  d := temp[28] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(d, 11);
+
+  t := g and (d xor e) xor a and b xor h and f xor d;
+  c := temp[29] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(c, 11);
+
+  t := f and (c xor d) xor h and a xor g and e xor c;
+  b := temp[30] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(b, 11);
+
+  t := e and (b xor c) xor g and h xor f and d xor b;
+  a := temp[31] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(a, 11);
+
+  t := b and (g and not a xor c and f xor d xor e) xor c and (g xor f)
+    xor a and f xor e;
+  h := temp[5] + $452821E6 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := a and (f and not h xor b and e xor c xor d) xor b and (f xor e)
+    xor h and e xor d;
+  g := temp[14] + $38D01377 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := h and (e and not g xor a and d xor b xor c) xor a and (e xor d)
+    xor g and d xor c;
+  f := temp[26] + $BE5466CF + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := g and (d and not f xor h and c xor a xor b) xor h and (d xor c)
+    xor f and c xor b;
+  e := temp[18] + $34E90C6C + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := f and (c and not e xor g and b xor h xor a) xor g and (c xor b)
+    xor e and b xor a;
+  d := temp[11] + $C0AC29B7 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := e and (b and not d xor f and a xor g xor h) xor f and (b xor a)
+    xor d and a xor h;
+  c := temp[28] + $C97C50DD + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := d and (a and not c xor e and h xor f xor g) xor e and (a xor h)
+    xor c and h xor g;
+  b := temp[7] + $3F84D5B5 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := c and (h and not b xor d and g xor e xor f) xor d and (h xor g)
+    xor b and g xor f;
+  a := temp[16] + $B5470917 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := b and (g and not a xor c and f xor d xor e) xor c and (g xor f)
+    xor a and f xor e;
+  h := temp[0] + $9216D5D9 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := a and (f and not h xor b and e xor c xor d) xor b and (f xor e)
+    xor h and e xor d;
+  g := temp[23] + $8979FB1B + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := h and (e and not g xor a and d xor b xor c) xor a and (e xor d)
+    xor g and d xor c;
+  f := temp[20] + $D1310BA6 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := g and (d and not f xor h and c xor a xor b) xor h and (d xor c)
+    xor f and c xor b;
+  e := temp[22] + $98DFB5AC + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := f and (c and not e xor g and b xor h xor a) xor g and (c xor b)
+    xor e and b xor a;
+  d := temp[1] + $2FFD72DB + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := e and (b and not d xor f and a xor g xor h) xor f and (b xor a)
+    xor d and a xor h;
+  c := temp[10] + $D01ADFB7 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := d and (a and not c xor e and h xor f xor g) xor e and (a xor h)
+    xor c and h xor g;
+  b := temp[4] + $B8E1AFED + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := c and (h and not b xor d and g xor e xor f) xor d and (h xor g)
+    xor b and g xor f;
+  a := temp[8] + $6A267E96 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := b and (g and not a xor c and f xor d xor e) xor c and (g xor f)
+    xor a and f xor e;
+  h := temp[30] + $BA7C9045 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := a and (f and not h xor b and e xor c xor d) xor b and (f xor e)
+    xor h and e xor d;
+  g := temp[3] + $F12C7F99 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := h and (e and not g xor a and d xor b xor c) xor a and (e xor d)
+    xor g and d xor c;
+  f := temp[21] + $24A19947 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := g and (d and not f xor h and c xor a xor b) xor h and (d xor c)
+    xor f and c xor b;
+  e := temp[9] + $B3916CF7 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := f and (c and not e xor g and b xor h xor a) xor g and (c xor b)
+    xor e and b xor a;
+  d := temp[17] + $0801F2E2 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := e and (b and not d xor f and a xor g xor h) xor f and (b xor a)
+    xor d and a xor h;
+  c := temp[24] + $858EFC16 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := d and (a and not c xor e and h xor f xor g) xor e and (a xor h)
+    xor c and h xor g;
+  b := temp[29] + $636920D8 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := c and (h and not b xor d and g xor e xor f) xor d and (h xor g)
+    xor b and g xor f;
+  a := temp[6] + $71574E69 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := b and (g and not a xor c and f xor d xor e) xor c and (g xor f)
+    xor a and f xor e;
+  h := temp[19] + $A458FEA3 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := a and (f and not h xor b and e xor c xor d) xor b and (f xor e)
+    xor h and e xor d;
+  g := temp[12] + $F4933D7E + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := h and (e and not g xor a and d xor b xor c) xor a and (e xor d)
+    xor g and d xor c;
+  f := temp[15] + $0D95748F + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := g and (d and not f xor h and c xor a xor b) xor h and (d xor c)
+    xor f and c xor b;
+  e := temp[13] + $728EB658 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := f and (c and not e xor g and b xor h xor a) xor g and (c xor b)
+    xor e and b xor a;
+  d := temp[2] + $718BCD58 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := e and (b and not d xor f and a xor g xor h) xor f and (b xor a)
+    xor d and a xor h;
+  c := temp[25] + $82154AEE + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := d and (a and not c xor e and h xor f xor g) xor e and (a xor h)
+    xor c and h xor g;
+  b := temp[31] + $7B54A41D + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := c and (h and not b xor d and g xor e xor f) xor d and (h xor g)
+    xor b and g xor f;
+  a := temp[27] + $C25A59B5 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := g and (c and a xor b xor f) xor c and d xor a and e xor f;
+  h := temp[19] + $9C30D539 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := f and (b and h xor a xor e) xor b and c xor h and d xor e;
+  g := temp[9] + $2AF26013 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := e and (a and g xor h xor d) xor a and b xor g and c xor d;
+  f := temp[4] + $C5D1B023 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := d and (h and f xor g xor c) xor h and a xor f and b xor c;
+  e := temp[20] + $286085F0 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := c and (g and e xor f xor b) xor g and h xor e and a xor b;
+  d := temp[28] + $CA417918 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := b and (f and d xor e xor a) xor f and g xor d and h xor a;
+  c := temp[17] + $B8DB38EF + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := a and (e and c xor d xor h) xor e and f xor c and g xor h;
+  b := temp[8] + $8E79DCB0 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := h and (d and b xor c xor g) xor d and e xor b and f xor g;
+  a := temp[22] + $603A180E + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := g and (c and a xor b xor f) xor c and d xor a and e xor f;
+  h := temp[29] + $6C9E0E8B + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := f and (b and h xor a xor e) xor b and c xor h and d xor e;
+  g := temp[14] + $B01E8A3E + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := e and (a and g xor h xor d) xor a and b xor g and c xor d;
+  f := temp[25] + $D71577C1 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := d and (h and f xor g xor c) xor h and a xor f and b xor c;
+  e := temp[12] + $BD314B27 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := c and (g and e xor f xor b) xor g and h xor e and a xor b;
+  d := temp[24] + $78AF2FDA + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := b and (f and d xor e xor a) xor f and g xor d and h xor a;
+  c := temp[30] + $55605C60 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := a and (e and c xor d xor h) xor e and f xor c and g xor h;
+  b := temp[16] + $E65525F3 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := h and (d and b xor c xor g) xor d and e xor b and f xor g;
+  a := temp[26] + $AA55AB94 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := g and (c and a xor b xor f) xor c and d xor a and e xor f;
+  h := temp[31] + $57489862 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := f and (b and h xor a xor e) xor b and c xor h and d xor e;
+  g := temp[15] + $63E81440 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := e and (a and g xor h xor d) xor a and b xor g and c xor d;
+  f := temp[7] + $55CA396A + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := d and (h and f xor g xor c) xor h and a xor f and b xor c;
+  e := temp[3] + $2AAB10B6 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := c and (g and e xor f xor b) xor g and h xor e and a xor b;
+  d := temp[1] + $B4CC5C34 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := b and (f and d xor e xor a) xor f and g xor d and h xor a;
+  c := temp[0] + $1141E8CE + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := a and (e and c xor d xor h) xor e and f xor c and g xor h;
+  b := temp[18] + $A15486AF + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := h and (d and b xor c xor g) xor d and e xor b and f xor g;
+  a := temp[27] + $7C72E993 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := g and (c and a xor b xor f) xor c and d xor a and e xor f;
+  h := temp[13] + $B3EE1411 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := f and (b and h xor a xor e) xor b and c xor h and d xor e;
+  g := temp[6] + $636FBC2A + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := e and (a and g xor h xor d) xor a and b xor g and c xor d;
+  f := temp[21] + $2BA9C55D + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := d and (h and f xor g xor c) xor h and a xor f and b xor c;
+  e := temp[10] + $741831F6 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := c and (g and e xor f xor b) xor g and h xor e and a xor b;
+  d := temp[23] + $CE5C3E16 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := b and (f and d xor e xor a) xor f and g xor d and h xor a;
+  c := temp[11] + $9B87931E + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := a and (e and c xor d xor h) xor e and f xor c and g xor h;
+  b := temp[5] + $AFD6BA33 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := h and (d and b xor c xor g) xor d and e xor b and f xor g;
+  a := temp[2] + $6C24CF5C + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := a and (e and not c xor f and not g xor b xor g xor d) xor f and
+    (b and c xor e xor g) xor c and g xor d;
+  h := temp[24] + $7A325381 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := h and (d and not b xor e and not f xor a xor f xor c) xor e and
+    (a and b xor d xor f) xor b and f xor c;
+  g := temp[4] + $28958677 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := g and (c and not a xor d and not e xor h xor e xor b) xor d and
+    (h and a xor c xor e) xor a and e xor b;
+  f := temp[0] + $3B8F4898 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := f and (b and not h xor c and not d xor g xor d xor a) xor c and
+    (g and h xor b xor d) xor h and d xor a;
+  e := temp[14] + $6B4BB9AF + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := e and (a and not g xor b and not c xor f xor c xor h) xor b and
+    (f and g xor a xor c) xor g and c xor h;
+  d := temp[2] + $C4BFE81B + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := d and (h and not f xor a and not b xor e xor b xor g) xor a and
+    (e and f xor h xor b) xor f and b xor g;
+  c := temp[7] + $66282193 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := c and (g and not e xor h and not a xor d xor a xor f) xor h and
+    (d and e xor g xor a) xor e and a xor f;
+  b := temp[28] + $61D809CC + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := b and (f and not d xor g and not h xor c xor h xor e) xor g and
+    (c and d xor f xor h) xor d and h xor e;
+  a := temp[23] + $FB21A991 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := a and (e and not c xor f and not g xor b xor g xor d) xor f and
+    (b and c xor e xor g) xor c and g xor d;
+  h := temp[26] + $487CAC60 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := h and (d and not b xor e and not f xor a xor f xor c) xor e and
+    (a and b xor d xor f) xor b and f xor c;
+  g := temp[6] + $5DEC8032 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := g and (c and not a xor d and not e xor h xor e xor b) xor d and
+    (h and a xor c xor e) xor a and e xor b;
+  f := temp[30] + $EF845D5D + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := f and (b and not h xor c and not d xor g xor d xor a) xor c and
+    (g and h xor b xor d) xor h and d xor a;
+  e := temp[20] + $E98575B1 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := e and (a and not g xor b and not c xor f xor c xor h) xor b and
+    (f and g xor a xor c) xor g and c xor h;
+  d := temp[18] + $DC262302 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := d and (h and not f xor a and not b xor e xor b xor g) xor a and
+    (e and f xor h xor b) xor f and b xor g;
+  c := temp[25] + $EB651B88 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := c and (g and not e xor h and not a xor d xor a xor f) xor h and
+    (d and e xor g xor a) xor e and a xor f;
+  b := temp[19] + $23893E81 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := b and (f and not d xor g and not h xor c xor h xor e) xor g and
+    (c and d xor f xor h) xor d and h xor e;
+  a := temp[3] + $D396ACC5 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := a and (e and not c xor f and not g xor b xor g xor d) xor f and
+    (b and c xor e xor g) xor c and g xor d;
+  h := temp[22] + $0F6D6FF3 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := h and (d and not b xor e and not f xor a xor f xor c) xor e and
+    (a and b xor d xor f) xor b and f xor c;
+  g := temp[11] + $83F44239 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := g and (c and not a xor d and not e xor h xor e xor b) xor d and
+    (h and a xor c xor e) xor a and e xor b;
+  f := temp[31] + $2E0B4482 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := f and (b and not h xor c and not d xor g xor d xor a) xor c and
+    (g and h xor b xor d) xor h and d xor a;
+  e := temp[21] + $A4842004 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := e and (a and not g xor b and not c xor f xor c xor h) xor b and
+    (f and g xor a xor c) xor g and c xor h;
+  d := temp[8] + $69C8F04A + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := d and (h and not f xor a and not b xor e xor b xor g) xor a and
+    (e and f xor h xor b) xor f and b xor g;
+  c := temp[27] + $9E1F9B5E + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := c and (g and not e xor h and not a xor d xor a xor f) xor h and
+    (d and e xor g xor a) xor e and a xor f;
+  b := temp[12] + $21C66842 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := b and (f and not d xor g and not h xor c xor h xor e) xor g and
+    (c and d xor f xor h) xor d and h xor e;
+  a := temp[9] + $F6E96C9A + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := a and (e and not c xor f and not g xor b xor g xor d) xor f and
+    (b and c xor e xor g) xor c and g xor d;
+  h := temp[1] + $670C9C61 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := h and (d and not b xor e and not f xor a xor f xor c) xor e and
+    (a and b xor d xor f) xor b and f xor c;
+  g := temp[29] + $ABD388F0 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := g and (c and not a xor d and not e xor h xor e xor b) xor d and
+    (h and a xor c xor e) xor a and e xor b;
+  f := temp[5] + $6A51A0D2 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := f and (b and not h xor c and not d xor g xor d xor a) xor c and
+    (g and h xor b xor d) xor h and d xor a;
+  e := temp[15] + $D8542F68 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := e and (a and not g xor b and not c xor f xor c xor h) xor b and
+    (f and g xor a xor c) xor g and c xor h;
+  d := temp[17] + $960FA728 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := d and (h and not f xor a and not b xor e xor b xor g) xor a and
+    (e and f xor h xor b) xor f and b xor g;
+  c := temp[10] + $AB5133A3 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := c and (g and not e xor h and not a xor d xor a xor f) xor h and
+    (d and e xor g xor a) xor e and a xor f;
+  b := temp[16] + $6EEF0B6C + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := b and (f and not d xor g and not h xor c xor h xor e) xor g and
+    (c and d xor f xor h) xor d and h xor e;
+  a := temp[13] + $137A3BE4 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  Fm_hash[0] := Fm_hash[0] + a;
+  Fm_hash[1] := Fm_hash[1] + b;
+  Fm_hash[2] := Fm_hash[2] + c;
+  Fm_hash[3] := Fm_hash[3] + d;
+  Fm_hash[4] := Fm_hash[4] + e;
+  Fm_hash[5] := Fm_hash[5] + f;
+  Fm_hash[6] := Fm_hash[6] + g;
+  Fm_hash[7] := Fm_hash[7] + h;
+
+  System.FillChar(temp, System.SizeOf(temp), 0);
+
+end;
+
+{ THaval5 }
+
+constructor THaval5.Create(a_hash_size: THashSize);
+begin
+  inherited Create(THashRounds.hrRounds5, a_hash_size);
+end;
+
+procedure THaval5.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  a, b, c, d, e, f, g, h, t: UInt32;
+  temp: array [0 .. 31] of UInt32;
+begin
+
+  TConverters.le32_copy(a_data, a_index, @(temp[0]), 0, a_data_length);
+
+  a := Fm_hash[0];
+  b := Fm_hash[1];
+  c := Fm_hash[2];
+  d := Fm_hash[3];
+  e := Fm_hash[4];
+  f := Fm_hash[5];
+  g := Fm_hash[6];
+  h := Fm_hash[7];
+
+  t := c and (g xor b) xor f and e xor a and d xor g;
+  h := temp[0] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(h, 11);
+  t := b and (f xor a) xor e and d xor h and c xor f;
+  g := temp[1] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(g, 11);
+
+  t := a and (e xor h) xor d and c xor g and b xor e;
+  f := temp[2] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(f, 11);
+
+  t := h and (d xor g) xor c and b xor f and a xor d;
+  e := temp[3] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(e, 11);
+
+  t := g and (c xor f) xor b and a xor e and h xor c;
+  d := temp[4] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(d, 11);
+
+  t := f and (b xor e) xor a and h xor d and g xor b;
+  c := temp[5] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(c, 11);
+
+  t := e and (a xor d) xor h and g xor c and f xor a;
+  b := temp[6] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(b, 11);
+
+  t := d and (h xor c) xor g and f xor b and e xor h;
+  a := temp[7] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(a, 11);
+
+  t := c and (g xor b) xor f and e xor a and d xor g;
+  h := temp[8] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(h, 11);
+
+  t := b and (f xor a) xor e and d xor h and c xor f;
+  g := temp[9] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(g, 11);
+
+  t := a and (e xor h) xor d and c xor g and b xor e;
+  f := temp[10] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(f, 11);
+
+  t := h and (d xor g) xor c and b xor f and a xor d;
+  e := temp[11] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(e, 11);
+
+  t := g and (c xor f) xor b and a xor e and h xor c;
+  d := temp[12] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(d, 11);
+
+  t := f and (b xor e) xor a and h xor d and g xor b;
+  c := temp[13] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(c, 11);
+
+  t := e and (a xor d) xor h and g xor c and f xor a;
+  b := temp[14] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(b, 11);
+
+  t := d and (h xor c) xor g and f xor b and e xor h;
+  a := temp[15] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(a, 11);
+
+  t := c and (g xor b) xor f and e xor a and d xor g;
+  h := temp[16] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(h, 11);
+
+  t := b and (f xor a) xor e and d xor h and c xor f;
+  g := temp[17] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(g, 11);
+
+  t := a and (e xor h) xor d and c xor g and b xor e;
+  f := temp[18] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(f, 11);
+
+  t := h and (d xor g) xor c and b xor f and a xor d;
+  e := temp[19] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(e, 11);
+
+  t := g and (c xor f) xor b and a xor e and h xor c;
+  d := temp[20] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(d, 11);
+
+  t := f and (b xor e) xor a and h xor d and g xor b;
+  c := temp[21] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(c, 11);
+
+  t := e and (a xor d) xor h and g xor c and f xor a;
+  b := temp[22] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(b, 11);
+
+  t := d and (h xor c) xor g and f xor b and e xor h;
+  a := temp[23] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(a, 11);
+
+  t := c and (g xor b) xor f and e xor a and d xor g;
+  h := temp[24] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(h, 11);
+
+  t := b and (f xor a) xor e and d xor h and c xor f;
+  g := temp[25] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(g, 11);
+
+  t := a and (e xor h) xor d and c xor g and b xor e;
+  f := temp[26] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(f, 11);
+
+  t := h and (d xor g) xor c and b xor f and a xor d;
+  e := temp[27] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(e, 11);
+
+  t := g and (c xor f) xor b and a xor e and h xor c;
+  d := temp[28] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(d, 11);
+
+  t := f and (b xor e) xor a and h xor d and g xor b;
+  c := temp[29] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(c, 11);
+
+  t := e and (a xor d) xor h and g xor c and f xor a;
+  b := temp[30] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(b, 11);
+
+  t := d and (h xor c) xor g and f xor b and e xor h;
+  a := temp[31] + TBits.RotateRight32(t, 7) + TBits.RotateRight32(a, 11);
+
+  t := d and (e and not a xor b and c xor g xor f) xor b and (e xor c)
+    xor a and c xor f;
+  h := temp[5] + $452821E6 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := c and (d and not h xor a and b xor f xor e) xor a and (d xor b)
+    xor h and b xor e;
+  g := temp[14] + $38D01377 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := b and (c and not g xor h and a xor e xor d) xor h and (c xor a)
+    xor g and a xor d;
+  f := temp[26] + $BE5466CF + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := a and (b and not f xor g and h xor d xor c) xor g and (b xor h)
+    xor f and h xor c;
+  e := temp[18] + $34E90C6C + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := h and (a and not e xor f and g xor c xor b) xor f and (a xor g)
+    xor e and g xor b;
+  d := temp[11] + $C0AC29B7 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := g and (h and not d xor e and f xor b xor a) xor e and (h xor f)
+    xor d and f xor a;
+  c := temp[28] + $C97C50DD + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := f and (g and not c xor d and e xor a xor h) xor d and (g xor e)
+    xor c and e xor h;
+  b := temp[7] + $3F84D5B5 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := e and (f and not b xor c and d xor h xor g) xor c and (f xor d)
+    xor b and d xor g;
+  a := temp[16] + $B5470917 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := d and (e and not a xor b and c xor g xor f) xor b and (e xor c)
+    xor a and c xor f;
+  h := temp[0] + $9216D5D9 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := c and (d and not h xor a and b xor f xor e) xor a and (d xor b)
+    xor h and b xor e;
+  g := temp[23] + $8979FB1B + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := b and (c and not g xor h and a xor e xor d) xor h and (c xor a)
+    xor g and a xor d;
+  f := temp[20] + $D1310BA6 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := a and (b and not f xor g and h xor d xor c) xor g and (b xor h)
+    xor f and h xor c;
+  e := temp[22] + $98DFB5AC + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := h and (a and not e xor f and g xor c xor b) xor f and (a xor g)
+    xor e and g xor b;
+  d := temp[1] + $2FFD72DB + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := g and (h and not d xor e and f xor b xor a) xor e and (h xor f)
+    xor d and f xor a;
+  c := temp[10] + $D01ADFB7 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := f and (g and not c xor d and e xor a xor h) xor d and (g xor e)
+    xor c and e xor h;
+  b := temp[4] + $B8E1AFED + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := e and (f and not b xor c and d xor h xor g) xor c and (f xor d)
+    xor b and d xor g;
+  a := temp[8] + $6A267E96 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := d and (e and not a xor b and c xor g xor f) xor b and (e xor c)
+    xor a and c xor f;
+  h := temp[30] + $BA7C9045 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := c and (d and not h xor a and b xor f xor e) xor a and (d xor b)
+    xor h and b xor e;
+  g := temp[3] + $F12C7F99 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := b and (c and not g xor h and a xor e xor d) xor h and (c xor a)
+    xor g and a xor d;
+  f := temp[21] + $24A19947 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := a and (b and not f xor g and h xor d xor c) xor g and (b xor h)
+    xor f and h xor c;
+  e := temp[9] + $B3916CF7 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := h and (a and not e xor f and g xor c xor b) xor f and (a xor g)
+    xor e and g xor b;
+  d := temp[17] + $0801F2E2 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := g and (h and not d xor e and f xor b xor a) xor e and (h xor f)
+    xor d and f xor a;
+  c := temp[24] + $858EFC16 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := f and (g and not c xor d and e xor a xor h) xor d and (g xor e)
+    xor c and e xor h;
+  b := temp[29] + $636920D8 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := e and (f and not b xor c and d xor h xor g) xor c and (f xor d)
+    xor b and d xor g;
+  a := temp[6] + $71574E69 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := d and (e and not a xor b and c xor g xor f) xor b and (e xor c)
+    xor a and c xor f;
+  h := temp[19] + $A458FEA3 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := c and (d and not h xor a and b xor f xor e) xor a and (d xor b)
+    xor h and b xor e;
+  g := temp[12] + $F4933D7E + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := b and (c and not g xor h and a xor e xor d) xor h and (c xor a)
+    xor g and a xor d;
+  f := temp[15] + $0D95748F + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := a and (b and not f xor g and h xor d xor c) xor g and (b xor h)
+    xor f and h xor c;
+  e := temp[13] + $728EB658 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := h and (a and not e xor f and g xor c xor b) xor f and (a xor g)
+    xor e and g xor b;
+  d := temp[2] + $718BCD58 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := g and (h and not d xor e and f xor b xor a) xor e and (h xor f)
+    xor d and f xor a;
+  c := temp[25] + $82154AEE + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := f and (g and not c xor d and e xor a xor h) xor d and (g xor e)
+    xor c and e xor h;
+  b := temp[31] + $7B54A41D + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := e and (f and not b xor c and d xor h xor g) xor c and (f xor d)
+    xor b and d xor g;
+  a := temp[27] + $C25A59B5 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := e and (b and d xor c xor f) xor b and a xor d and g xor f;
+  h := temp[19] + $9C30D539 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := d and (a and c xor b xor e) xor a and h xor c and f xor e;
+  g := temp[9] + $2AF26013 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := c and (h and b xor a xor d) xor h and g xor b and e xor d;
+  f := temp[4] + $C5D1B023 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := b and (g and a xor h xor c) xor g and f xor a and d xor c;
+  e := temp[20] + $286085F0 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := a and (f and h xor g xor b) xor f and e xor h and c xor b;
+  d := temp[28] + $CA417918 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := h and (e and g xor f xor a) xor e and d xor g and b xor a;
+  c := temp[17] + $B8DB38EF + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := g and (d and f xor e xor h) xor d and c xor f and a xor h;
+  b := temp[8] + $8E79DCB0 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := f and (c and e xor d xor g) xor c and b xor e and h xor g;
+  a := temp[22] + $603A180E + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := e and (b and d xor c xor f) xor b and a xor d and g xor f;
+  h := temp[29] + $6C9E0E8B + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := d and (a and c xor b xor e) xor a and h xor c and f xor e;
+  g := temp[14] + $B01E8A3E + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := c and (h and b xor a xor d) xor h and g xor b and e xor d;
+  f := temp[25] + $D71577C1 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := b and (g and a xor h xor c) xor g and f xor a and d xor c;
+  e := temp[12] + $BD314B27 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := a and (f and h xor g xor b) xor f and e xor h and c xor b;
+  d := temp[24] + $78AF2FDA + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := h and (e and g xor f xor a) xor e and d xor g and b xor a;
+  c := temp[30] + $55605C60 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := g and (d and f xor e xor h) xor d and c xor f and a xor h;
+  b := temp[16] + $E65525F3 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := f and (c and e xor d xor g) xor c and b xor e and h xor g;
+  a := temp[26] + $AA55AB94 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := e and (b and d xor c xor f) xor b and a xor d and g xor f;
+  h := temp[31] + $57489862 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := d and (a and c xor b xor e) xor a and h xor c and f xor e;
+  g := temp[15] + $63E81440 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := c and (h and b xor a xor d) xor h and g xor b and e xor d;
+  f := temp[7] + $55CA396A + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := b and (g and a xor h xor c) xor g and f xor a and d xor c;
+  e := temp[3] + $2AAB10B6 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := a and (f and h xor g xor b) xor f and e xor h and c xor b;
+  d := temp[1] + $B4CC5C34 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := h and (e and g xor f xor a) xor e and d xor g and b xor a;
+  c := temp[0] + $1141E8CE + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := g and (d and f xor e xor h) xor d and c xor f and a xor h;
+  b := temp[18] + $A15486AF + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := f and (c and e xor d xor g) xor c and b xor e and h xor g;
+  a := temp[27] + $7C72E993 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := e and (b and d xor c xor f) xor b and a xor d and g xor f;
+  h := temp[13] + $B3EE1411 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := d and (a and c xor b xor e) xor a and h xor c and f xor e;
+  g := temp[6] + $636FBC2A + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := c and (h and b xor a xor d) xor h and g xor b and e xor d;
+  f := temp[21] + $2BA9C55D + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := b and (g and a xor h xor c) xor g and f xor a and d xor c;
+  e := temp[10] + $741831F6 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := a and (f and h xor g xor b) xor f and e xor h and c xor b;
+  d := temp[23] + $CE5C3E16 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := h and (e and g xor f xor a) xor e and d xor g and b xor a;
+  c := temp[11] + $9B87931E + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := g and (d and f xor e xor h) xor d and c xor f and a xor h;
+  b := temp[5] + $AFD6BA33 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := f and (c and e xor d xor g) xor c and b xor e and h xor g;
+  a := temp[2] + $6C24CF5C + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := d and (f and not a xor c and not b xor e xor b xor g) xor c and
+    (e and a xor f xor b) xor a and b xor g;
+  h := temp[24] + $7A325381 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := c and (e and not h xor b and not a xor d xor a xor f) xor b and
+    (d and h xor e xor a) xor h and a xor f;
+  g := temp[4] + $28958677 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := b and (d and not g xor a and not h xor c xor h xor e) xor a and
+    (c and g xor d xor h) xor g and h xor e;
+  f := temp[0] + $3B8F4898 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := a and (c and not f xor h and not g xor b xor g xor d) xor h and
+    (b and f xor c xor g) xor f and g xor d;
+  e := temp[14] + $6B4BB9AF + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := h and (b and not e xor g and not f xor a xor f xor c) xor g and
+    (a and e xor b xor f) xor e and f xor c;
+  d := temp[2] + $C4BFE81B + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := g and (a and not d xor f and not e xor h xor e xor b) xor f and
+    (h and d xor a xor e) xor d and e xor b;
+  c := temp[7] + $66282193 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := f and (h and not c xor e and not d xor g xor d xor a) xor e and
+    (g and c xor h xor d) xor c and d xor a;
+  b := temp[28] + $61D809CC + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := e and (g and not b xor d and not c xor f xor c xor h) xor d and
+    (f and b xor g xor c) xor b and c xor h;
+  a := temp[23] + $FB21A991 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := d and (f and not a xor c and not b xor e xor b xor g) xor c and
+    (e and a xor f xor b) xor a and b xor g;
+  h := temp[26] + $487CAC60 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := c and (e and not h xor b and not a xor d xor a xor f) xor b and
+    (d and h xor e xor a) xor h and a xor f;
+  g := temp[6] + $5DEC8032 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := b and (d and not g xor a and not h xor c xor h xor e) xor a and
+    (c and g xor d xor h) xor g and h xor e;
+  f := temp[30] + $EF845D5D + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := a and (c and not f xor h and not g xor b xor g xor d) xor h and
+    (b and f xor c xor g) xor f and g xor d;
+  e := temp[20] + $E98575B1 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := h and (b and not e xor g and not f xor a xor f xor c) xor g and
+    (a and e xor b xor f) xor e and f xor c;
+  d := temp[18] + $DC262302 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := g and (a and not d xor f and not e xor h xor e xor b) xor f and
+    (h and d xor a xor e) xor d and e xor b;
+  c := temp[25] + $EB651B88 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := f and (h and not c xor e and not d xor g xor d xor a) xor e and
+    (g and c xor h xor d) xor c and d xor a;
+  b := temp[19] + $23893E81 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := e and (g and not b xor d and not c xor f xor c xor h) xor d and
+    (f and b xor g xor c) xor b and c xor h;
+  a := temp[3] + $D396ACC5 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := d and (f and not a xor c and not b xor e xor b xor g) xor c and
+    (e and a xor f xor b) xor a and b xor g;
+  h := temp[22] + $0F6D6FF3 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := c and (e and not h xor b and not a xor d xor a xor f) xor b and
+    (d and h xor e xor a) xor h and a xor f;
+  g := temp[11] + $83F44239 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := b and (d and not g xor a and not h xor c xor h xor e) xor a and
+    (c and g xor d xor h) xor g and h xor e;
+  f := temp[31] + $2E0B4482 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := a and (c and not f xor h and not g xor b xor g xor d) xor h and
+    (b and f xor c xor g) xor f and g xor d;
+  e := temp[21] + $A4842004 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := h and (b and not e xor g and not f xor a xor f xor c) xor g and
+    (a and e xor b xor f) xor e and f xor c;
+  d := temp[8] + $69C8F04A + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := g and (a and not d xor f and not e xor h xor e xor b) xor f and
+    (h and d xor a xor e) xor d and e xor b;
+  c := temp[27] + $9E1F9B5E + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := f and (h and not c xor e and not d xor g xor d xor a) xor e and
+    (g and c xor h xor d) xor c and d xor a;
+  b := temp[12] + $21C66842 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := e and (g and not b xor d and not c xor f xor c xor h) xor d and
+    (f and b xor g xor c) xor b and c xor h;
+  a := temp[9] + $F6E96C9A + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := d and (f and not a xor c and not b xor e xor b xor g) xor c and
+    (e and a xor f xor b) xor a and b xor g;
+  h := temp[1] + $670C9C61 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := c and (e and not h xor b and not a xor d xor a xor f) xor b and
+    (d and h xor e xor a) xor h and a xor f;
+  g := temp[29] + $ABD388F0 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := b and (d and not g xor a and not h xor c xor h xor e) xor a and
+    (c and g xor d xor h) xor g and h xor e;
+  f := temp[5] + $6A51A0D2 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := a and (c and not f xor h and not g xor b xor g xor d) xor h and
+    (b and f xor c xor g) xor f and g xor d;
+  e := temp[15] + $D8542F68 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := h and (b and not e xor g and not f xor a xor f xor c) xor g and
+    (a and e xor b xor f) xor e and f xor c;
+  d := temp[17] + $960FA728 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := g and (a and not d xor f and not e xor h xor e xor b) xor f and
+    (h and d xor a xor e) xor d and e xor b;
+  c := temp[10] + $AB5133A3 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := f and (h and not c xor e and not d xor g xor d xor a) xor e and
+    (g and c xor h xor d) xor c and d xor a;
+  b := temp[16] + $6EEF0B6C + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := e and (g and not b xor d and not c xor f xor c xor h) xor d and
+    (f and b xor g xor c) xor b and c xor h;
+  a := temp[13] + $137A3BE4 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := b and (d and e and g xor not f) xor d and a xor e and f xor g and c;
+  h := temp[27] + $BA3BF050 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := a and (c and d and f xor not e) xor c and h xor d and e xor f and b;
+  g := temp[3] + $7EFB2A98 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := h and (b and c and e xor not d) xor b and g xor c and d xor e and a;
+  f := temp[21] + $A1F1651D + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := g and (a and b and d xor not c) xor a and f xor b and c xor d and h;
+  e := temp[26] + $39AF0176 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := f and (h and a and c xor not b) xor h and e xor a and b xor c and g;
+  d := temp[17] + $66CA593E + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := e and (g and h and b xor not a) xor g and d xor h and a xor b and f;
+  c := temp[11] + $82430E88 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := d and (f and g and a xor not h) xor f and c xor g and h xor a and e;
+  b := temp[20] + $8CEE8619 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := c and (e and f and h xor not g) xor e and b xor f and g xor h and d;
+  a := temp[29] + $456F9FB4 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := b and (d and e and g xor not f) xor d and a xor e and f xor g and c;
+  h := temp[19] + $7D84A5C3 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := a and (c and d and f xor not e) xor c and h xor d and e xor f and b;
+  g := temp[0] + $3B8B5EBE + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := h and (b and c and e xor not d) xor b and g xor c and d xor e and a;
+  f := temp[12] + $E06F75D8 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := g and (a and b and d xor not c) xor a and f xor b and c xor d and h;
+  e := temp[7] + $85C12073 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := f and (h and a and c xor not b) xor h and e xor a and b xor c and g;
+  d := temp[13] + $401A449F + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := e and (g and h and b xor not a) xor g and d xor h and a xor b and f;
+  c := temp[8] + $56C16AA6 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := d and (f and g and a xor not h) xor f and c xor g and h xor a and e;
+  b := temp[31] + $4ED3AA62 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := c and (e and f and h xor not g) xor e and b xor f and g xor h and d;
+  a := temp[10] + $363F7706 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := b and (d and e and g xor not f) xor d and a xor e and f xor g and c;
+  h := temp[5] + $1BFEDF72 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := a and (c and d and f xor not e) xor c and h xor d and e xor f and b;
+  g := temp[9] + $429B023D + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := h and (b and c and e xor not d) xor b and g xor c and d xor e and a;
+  f := temp[14] + $37D0D724 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := g and (a and b and d xor not c) xor a and f xor b and c xor d and h;
+  e := temp[30] + $D00A1248 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := f and (h and a and c xor not b) xor h and e xor a and b xor c and g;
+  d := temp[18] + $DB0FEAD3 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := e and (g and h and b xor not a) xor g and d xor h and a xor b and f;
+  c := temp[6] + $49F1C09B + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := d and (f and g and a xor not h) xor f and c xor g and h xor a and e;
+  b := temp[28] + $075372C9 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := c and (e and f and h xor not g) xor e and b xor f and g xor h and d;
+  a := temp[24] + $80991B7B + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  t := b and (d and e and g xor not f) xor d and a xor e and f xor g and c;
+  h := temp[2] + $25D479D8 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(h, 11);
+
+  t := a and (c and d and f xor not e) xor c and h xor d and e xor f and b;
+  g := temp[23] + $F6E8DEF7 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(g, 11);
+
+  t := h and (b and c and e xor not d) xor b and g xor c and d xor e and a;
+  f := temp[16] + $E3FE501A + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(f, 11);
+
+  t := g and (a and b and d xor not c) xor a and f xor b and c xor d and h;
+  e := temp[22] + $B6794C3B + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(e, 11);
+
+  t := f and (h and a and c xor not b) xor h and e xor a and b xor c and g;
+  d := temp[4] + $976CE0BD + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(d, 11);
+
+  t := e and (g and h and b xor not a) xor g and d xor h and a xor b and f;
+  c := temp[1] + $04C006BA + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(c, 11);
+
+  t := d and (f and g and a xor not h) xor f and c xor g and h xor a and e;
+  b := temp[25] + $C1A94FB6 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(b, 11);
+
+  t := c and (e and f and h xor not g) xor e and b xor f and g xor h and d;
+  a := temp[15] + $409F60C4 + TBits.RotateRight32(t, 7) +
+    TBits.RotateRight32(a, 11);
+
+  Fm_hash[0] := Fm_hash[0] + a;
+  Fm_hash[1] := Fm_hash[1] + b;
+  Fm_hash[2] := Fm_hash[2] + c;
+  Fm_hash[3] := Fm_hash[3] + d;
+  Fm_hash[4] := Fm_hash[4] + e;
+  Fm_hash[5] := Fm_hash[5] + f;
+  Fm_hash[6] := Fm_hash[6] + g;
+  Fm_hash[7] := Fm_hash[7] + h;
+
+  System.FillChar(temp, System.SizeOf(temp), 0);
+
+end;
+
+{ THaval_3_128 }
+
+constructor THaval_3_128.Create;
+begin
+  inherited Create(THashSize.hsHashSize128);
+end;
+
+{ THaval_4_128 }
+
+constructor THaval_4_128.Create;
+begin
+  inherited Create(THashSize.hsHashSize128);
+end;
+
+{ THaval_5_128 }
+
+constructor THaval_5_128.Create;
+begin
+  inherited Create(THashSize.hsHashSize128);
+end;
+
+{ THaval_3_160 }
+
+constructor THaval_3_160.Create;
+begin
+  inherited Create(THashSize.hsHashSize160);
+end;
+
+{ THaval_4_160 }
+
+constructor THaval_4_160.Create;
+begin
+  inherited Create(THashSize.hsHashSize160);
+end;
+
+{ THaval_5_160 }
+
+constructor THaval_5_160.Create;
+begin
+  inherited Create(THashSize.hsHashSize160);
+end;
+
+{ THaval_3_192 }
+
+constructor THaval_3_192.Create;
+begin
+  inherited Create(THashSize.hsHashSize192);
+end;
+
+{ THaval_4_192 }
+
+constructor THaval_4_192.Create;
+begin
+  inherited Create(THashSize.hsHashSize192);
+end;
+
+{ THaval_5_192 }
+
+constructor THaval_5_192.Create;
+begin
+  inherited Create(THashSize.hsHashSize192);
+end;
+
+{ THaval_3_224 }
+
+constructor THaval_3_224.Create;
+begin
+  inherited Create(THashSize.hsHashSize224);
+end;
+
+{ THaval_4_224 }
+
+constructor THaval_4_224.Create;
+begin
+  inherited Create(THashSize.hsHashSize224);
+end;
+
+{ THaval_5_224 }
+
+constructor THaval_5_224.Create;
+begin
+  inherited Create(THashSize.hsHashSize224);
+end;
+
+{ THaval_3_256 }
+
+constructor THaval_3_256.Create;
+begin
+  inherited Create(THashSize.hsHashSize256);
+end;
+
+{ THaval_4_256 }
+
+constructor THaval_4_256.Create;
+begin
+  inherited Create(THashSize.hsHashSize256);
+end;
+
+{ THaval_5_256 }
+
+constructor THaval_5_256.Create;
+begin
+  inherited Create(THashSize.hsHashSize256);
+
+end;
+
+end.

+ 170 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpMD2.pas

@@ -0,0 +1,170 @@
+unit HlpMD2;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpHashBuffer,
+{$ENDIF DELPHI}
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn;
+
+type
+  TMD2 = class sealed(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+  strict private
+    Fm_state, Fm_checksum: THashLibByteArray;
+
+{$REGION 'Consts'}
+
+  const
+
+    s_pi: array [0 .. 255] of Byte = (41, 46, 67, 201, 162, 216, 124, 1, 61, 54,
+      84, 161, 236, 240, 6, 19,
+
+      98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 76, 130, 202,
+
+      30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 138, 23, 229, 18,
+
+      190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 245, 142, 187,
+      47, 238, 122,
+
+      169, 104, 121, 145, 21, 178, 7, 63, 148, 194, 16, 137, 11, 34, 95, 33,
+
+      128, 127, 93, 154, 90, 144, 50, 39, 53, 62, 204, 231, 191, 247, 151, 3,
+
+      255, 25, 48, 179, 72, 165, 181, 209, 215, 94, 146, 42, 172, 86, 170, 198,
+
+      79, 184, 56, 210, 150, 164, 125, 182, 118, 252, 107, 226, 156,
+      116, 4, 241,
+
+      69, 157, 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2,
+
+      27, 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
+
+      85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, 234, 38,
+
+      44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, 129, 77, 82,
+
+      106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, 8, 12, 189, 177, 74,
+
+      120, 136, 149, 139, 227, 99, 232, 109, 233, 203, 213, 254, 59, 0, 29, 57,
+
+      242, 239, 183, 14, 102, 88, 208, 228, 166, 119, 114, 248, 235,
+      117, 75, 10,
+
+      49, 68, 80, 180, 143, 237, 31, 26, 219, 153, 141, 51, 159, 17, 131, 20);
+
+{$ENDREGION}
+  strict protected
+    procedure Finish(); override;
+    function GetResult(): THashLibByteArray; override;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TMD2 }
+
+constructor TMD2.Create;
+begin
+  Inherited Create(16, 16);
+  System.SetLength(Fm_state, 16);
+  System.SetLength(Fm_checksum, 16);
+
+end;
+
+procedure TMD2.Finish;
+var
+  padLen, i: Int32;
+  pad: THashLibByteArray;
+begin
+  padLen := 16 - Fm_buffer.Pos;
+  System.SetLength(pad, padLen);
+
+  i := 0;
+  while i < padLen do
+  begin
+    pad[i] := Byte(padLen);
+    System.Inc(i);
+  end;
+
+  TransformBytes(pad, 0, padLen);
+  TransformBytes(Fm_checksum, 0, 16);
+end;
+
+function TMD2.GetResult: THashLibByteArray;
+begin
+  result := System.Copy(Fm_state);
+end;
+
+procedure TMD2.Initialize;
+begin
+
+  System.FillChar(Fm_state[0], System.Length(Fm_state) *
+    System.SizeOf(Byte), Byte(0));
+
+  System.FillChar(Fm_checksum[0], System.Length(Fm_checksum) *
+    System.SizeOf(Byte), Byte(0));
+
+  Inherited Initialize();
+
+end;
+
+procedure TMD2.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  i, j: Int32;
+  t: UInt32;
+  temp: array [0 .. 47] of Byte;
+
+begin
+
+  System.Move(Fm_state[0], temp[0], a_data_length);
+
+  System.Move(a_data[a_index], temp[a_data_length], a_data_length);
+
+  for i := 0 to 15 do
+  begin
+    temp[i + 32] := Byte(Fm_state[i] xor a_data[i + a_index]);
+  end;
+
+  t := 0;
+
+  for i := 0 to 17 do
+  begin
+
+    for j := 0 to 47 do
+    begin
+      temp[j] := Byte(temp[j] xor s_pi[t]);
+      t := temp[j];
+    end;
+
+    t := Byte(t + UInt32(i));
+  end;
+
+  System.Move(temp[0], Fm_state[0], 16);
+
+  t := Fm_checksum[15];
+
+  for i := 0 to 15 do
+  begin
+
+    Fm_checksum[i] := Fm_checksum[i] xor (s_pi[a_data[i + a_index] xor t]);
+    t := Fm_checksum[i];
+  end;
+
+  System.FillChar(temp, System.SizeOf(temp), 0);
+
+end;
+
+end.

+ 161 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpMD4.pas

@@ -0,0 +1,161 @@
+unit HlpMD4;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpMDBase,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpBits,
+  HlpConverters,
+  HlpIHashInfo;
+
+type
+  TMD4 = class sealed(TMDBase, ITransformBlock)
+
+  strict protected
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create();
+
+  end;
+
+implementation
+
+{ TMD4 }
+
+constructor TMD4.Create;
+begin
+  Inherited Create(4, 16);
+end;
+
+procedure TMD4.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  a, b, c, d: UInt32;
+  data: array [0 .. 15] of UInt32;
+begin
+
+  TConverters.le32_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+
+  a := Fm_state[0];
+  b := Fm_state[1];
+  c := Fm_state[2];
+  d := Fm_state[3];
+
+  a := a + (data[0] + ((b and c) or ((not b) and d)));
+  a := TBits.RotateLeft32(a, 3);
+  d := d + (data[1] + ((a and b) or ((not a) and c)));
+  d := TBits.RotateLeft32(d, 7);
+  c := c + (data[2] + ((d and a) or ((not d) and b)));
+  c := TBits.RotateLeft32(c, 11);
+  b := b + (data[3] + ((c and d) or ((not c) and a)));
+  b := TBits.RotateLeft32(b, 19);
+  a := a + (data[4] + ((b and c) or ((not b) and d)));
+  a := TBits.RotateLeft32(a, 3);
+  d := d + (data[5] + ((a and b) or ((not a) and c)));
+  d := TBits.RotateLeft32(d, 7);
+  c := c + (data[6] + ((d and a) or ((not d) and b)));
+  c := TBits.RotateLeft32(c, 11);
+  b := b + (data[7] + ((c and d) or ((not c) and a)));
+  b := TBits.RotateLeft32(b, 19);
+  a := a + (data[8] + ((b and c) or ((not b) and d)));
+  a := TBits.RotateLeft32(a, 3);
+  d := d + (data[9] + ((a and b) or ((not a) and c)));
+  d := TBits.RotateLeft32(d, 7);
+  c := c + (data[10] + ((d and a) or ((not d) and b)));
+  c := TBits.RotateLeft32(c, 11);
+  b := b + (data[11] + ((c and d) or ((not c) and a)));
+  b := TBits.RotateLeft32(b, 19);
+  a := a + (data[12] + ((b and c) or ((not b) and d)));
+  a := TBits.RotateLeft32(a, 3);
+  d := d + (data[13] + ((a and b) or ((not a) and c)));
+  d := TBits.RotateLeft32(d, 7);
+  c := c + (data[14] + ((d and a) or ((not d) and b)));
+  c := TBits.RotateLeft32(c, 11);
+  b := b + (data[15] + ((c and d) or ((not c) and a)));
+  b := TBits.RotateLeft32(b, 19);
+
+  a := a + (data[0] + C2 + ((b and (c or d)) or (c and d)));
+  a := TBits.RotateLeft32(a, 3);
+  d := d + (data[4] + C2 + ((a and (b or c)) or (b and c)));
+  d := TBits.RotateLeft32(d, 5);
+  c := c + (data[8] + C2 + ((d and (a or b)) or (a and b)));
+  c := TBits.RotateLeft32(c, 9);
+  b := b + (data[12] + C2 + ((c and (d or a)) or (d and a)));
+  b := TBits.RotateLeft32(b, 13);
+  a := a + (data[1] + C2 + ((b and (c or d)) or (c and d)));
+  a := TBits.RotateLeft32(a, 3);
+  d := d + (data[5] + C2 + ((a and (b or c)) or (b and c)));
+  d := TBits.RotateLeft32(d, 5);
+  c := c + (data[9] + C2 + ((d and (a or b)) or (a and b)));
+  c := TBits.RotateLeft32(c, 9);
+  b := b + (data[13] + C2 + ((c and (d or a)) or (d and a)));
+  b := TBits.RotateLeft32(b, 13);
+  a := a + (data[2] + C2 + ((b and (c or d)) or (c and d)));
+  a := TBits.RotateLeft32(a, 3);
+  d := d + (data[6] + C2 + ((a and (b or c)) or (b and c)));
+  d := TBits.RotateLeft32(d, 5);
+  c := c + (data[10] + C2 + ((d and (a or b)) or (a and b)));
+  c := TBits.RotateLeft32(c, 9);
+  b := b + (data[14] + C2 + ((c and (d or a)) or (d and a)));
+  b := TBits.RotateLeft32(b, 13);
+  a := a + (data[3] + C2 + ((b and (c or d)) or (c and d)));
+  a := TBits.RotateLeft32(a, 3);
+  d := d + (data[7] + C2 + ((a and (b or c)) or (b and c)));
+  d := TBits.RotateLeft32(d, 5);
+  c := c + (data[11] + C2 + ((d and (a or b)) or (a and b)));
+  c := TBits.RotateLeft32(c, 9);
+  b := b + (data[15] + C2 + ((c and (d or a)) or (d and a)));
+  b := TBits.RotateLeft32(b, 13);
+
+  a := a + (data[0] + C4 + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 3);
+  d := d + (data[8] + C4 + (a xor b xor c));
+  d := TBits.RotateLeft32(d, 9);
+  c := c + (data[4] + C4 + (d xor a xor b));
+  c := TBits.RotateLeft32(c, 11);
+  b := b + (data[12] + C4 + (c xor d xor a));
+  b := TBits.RotateLeft32(b, 15);
+  a := a + (data[2] + C4 + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 3);
+  d := d + (data[10] + C4 + (a xor b xor c));
+  d := TBits.RotateLeft32(d, 9);
+  c := c + (data[6] + C4 + (d xor a xor b));
+  c := TBits.RotateLeft32(c, 11);
+  b := b + (data[14] + C4 + (c xor d xor a));
+  b := TBits.RotateLeft32(b, 15);
+  a := a + (data[1] + C4 + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 3);
+  d := d + (data[9] + C4 + (a xor b xor c));
+  d := TBits.RotateLeft32(d, 9);
+  c := c + (data[5] + C4 + (d xor a xor b));
+  c := TBits.RotateLeft32(c, 11);
+  b := b + (data[13] + C4 + (c xor d xor a));
+  b := TBits.RotateLeft32(b, 15);
+  a := a + (data[3] + C4 + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 3);
+  d := d + (data[11] + C4 + (a xor b xor c));
+  d := TBits.RotateLeft32(d, 9);
+  c := c + (data[7] + C4 + (d xor a xor b));
+  c := TBits.RotateLeft32(c, 11);
+  b := b + (data[15] + C4 + (c xor d xor a));
+  b := TBits.RotateLeft32(b, 15);
+
+  Fm_state[0] := Fm_state[0] + a;
+  Fm_state[1] := Fm_state[1] + b;
+  Fm_state[2] := Fm_state[2] + c;
+  Fm_state[3] := Fm_state[3] + d;
+
+  System.FillChar(data, System.SizeOf(data), 0);
+end;
+
+end.

+ 195 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpMD5.pas

@@ -0,0 +1,195 @@
+unit HlpMD5;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpBits,
+  HlpMDBase,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpConverters,
+  HlpIHashInfo;
+
+type
+  TMD5 = class sealed(TMDBase, ITransformBlock)
+
+  strict protected
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create();
+
+  end;
+
+implementation
+
+{ TMD5 }
+
+constructor TMD5.Create;
+begin
+  Inherited Create(4, 16);
+end;
+
+procedure TMD5.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  A, B, C, D: UInt32;
+  data: array [0 .. 15] of UInt32;
+begin
+
+  TConverters.le32_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+
+  A := Fm_state[0];
+  B := Fm_state[1];
+  C := Fm_state[2];
+  D := Fm_state[3];
+
+  A := data[0] + $D76AA478 + A + ((B and C) or (not B and D));
+  A := TBits.RotateLeft32(A, 7) + B;
+  D := data[1] + $E8C7B756 + D + ((A and B) or (not A and C));
+  D := TBits.RotateLeft32(D, 12) + A;
+  C := data[2] + $242070DB + C + ((D and A) or (not D and B));
+  C := TBits.RotateLeft32(C, 17) + D;
+  B := data[3] + $C1BDCEEE + B + ((C and D) or (not C and A));
+  B := TBits.RotateLeft32(B, 22) + C;
+  A := data[4] + $F57C0FAF + A + ((B and C) or (not B and D));
+  A := TBits.RotateLeft32(A, 7) + B;
+  D := data[5] + $4787C62A + D + ((A and B) or (not A and C));
+  D := TBits.RotateLeft32(D, 12) + A;
+  C := data[6] + $A8304613 + C + ((D and A) or (not D and B));
+  C := TBits.RotateLeft32(C, 17) + D;
+  B := data[7] + $FD469501 + B + ((C and D) or (not C and A));
+  B := TBits.RotateLeft32(B, 22) + C;
+  A := data[8] + $698098D8 + A + ((B and C) or (not B and D));
+  A := TBits.RotateLeft32(A, 7) + B;
+  D := data[9] + $8B44F7AF + D + ((A and B) or (not A and C));
+  D := TBits.RotateLeft32(D, 12) + A;
+  C := data[10] + $FFFF5BB1 + C + ((D and A) or (not D and B));
+  C := TBits.RotateLeft32(C, 17) + D;
+  B := data[11] + $895CD7BE + B + ((C and D) or (not C and A));
+  B := TBits.RotateLeft32(B, 22) + C;
+  A := data[12] + $6B901122 + A + ((B and C) or (not B and D));
+  A := TBits.RotateLeft32(A, 7) + B;
+  D := data[13] + $FD987193 + D + ((A and B) or (not A and C));
+  D := TBits.RotateLeft32(D, 12) + A;
+  C := data[14] + $A679438E + C + ((D and A) or (not D and B));
+  C := TBits.RotateLeft32(C, 17) + D;
+  B := data[15] + $49B40821 + B + ((C and D) or (not C and A));
+  B := TBits.RotateLeft32(B, 22) + C;
+
+  A := data[1] + $F61E2562 + A + ((B and D) or (C and not D));
+  A := TBits.RotateLeft32(A, 5) + B;
+  D := data[6] + $C040B340 + D + ((A and C) or (B and not C));
+  D := TBits.RotateLeft32(D, 9) + A;
+  C := data[11] + $265E5A51 + C + ((D and B) or (A and not B));
+  C := TBits.RotateLeft32(C, 14) + D;
+  B := data[0] + $E9B6C7AA + B + ((C and A) or (D and not A));
+  B := TBits.RotateLeft32(B, 20) + C;
+  A := data[5] + $D62F105D + A + ((B and D) or (C and not D));
+  A := TBits.RotateLeft32(A, 5) + B;
+  D := data[10] + $2441453 + D + ((A and C) or (B and not C));
+  D := TBits.RotateLeft32(D, 9) + A;
+  C := data[15] + $D8A1E681 + C + ((D and B) or (A and not B));
+  C := TBits.RotateLeft32(C, 14) + D;
+  B := data[4] + $E7D3FBC8 + B + ((C and A) or (D and not A));
+  B := TBits.RotateLeft32(B, 20) + C;
+  A := data[9] + $21E1CDE6 + A + ((B and D) or (C and not D));
+  A := TBits.RotateLeft32(A, 5) + B;
+  D := data[14] + $C33707D6 + D + ((A and C) or (B and not C));
+  D := TBits.RotateLeft32(D, 9) + A;
+  C := data[3] + $F4D50D87 + C + ((D and B) or (A and not B));
+  C := TBits.RotateLeft32(C, 14) + D;
+  B := data[8] + $455A14ED + B + ((C and A) or (D and not A));
+  B := TBits.RotateLeft32(B, 20) + C;
+  A := data[13] + $A9E3E905 + A + ((B and D) or (C and not D));
+  A := TBits.RotateLeft32(A, 5) + B;
+  D := data[2] + $FCEFA3F8 + D + ((A and C) or (B and not C));
+  D := TBits.RotateLeft32(D, 9) + A;
+  C := data[7] + $676F02D9 + C + ((D and B) or (A and not B));
+  C := TBits.RotateLeft32(C, 14) + D;
+  B := data[12] + $8D2A4C8A + B + ((C and A) or (D and not A));
+  B := TBits.RotateLeft32(B, 20) + C;
+
+  A := data[5] + $FFFA3942 + A + (B xor C xor D);
+  A := TBits.RotateLeft32(A, 4) + B;
+  D := data[8] + $8771F681 + D + (A xor B xor C);
+  D := TBits.RotateLeft32(D, 11) + A;
+  C := data[11] + $6D9D6122 + C + (D xor A xor B);
+  C := TBits.RotateLeft32(C, 16) + D;
+  B := data[14] + $FDE5380C + B + (C xor D xor A);
+  B := TBits.RotateLeft32(B, 23) + C;
+  A := data[1] + $A4BEEA44 + A + (B xor C xor D);
+  A := TBits.RotateLeft32(A, 4) + B;
+  D := data[4] + $4BDECFA9 + D + (A xor B xor C);
+  D := TBits.RotateLeft32(D, 11) + A;
+  C := data[7] + $F6BB4B60 + C + (D xor A xor B);
+  C := TBits.RotateLeft32(C, 16) + D;
+  B := data[10] + $BEBFBC70 + B + (C xor D xor A);
+  B := TBits.RotateLeft32(B, 23) + C;
+  A := data[13] + $289B7EC6 + A + (B xor C xor D);
+  A := TBits.RotateLeft32(A, 4) + B;
+  D := data[0] + $EAA127FA + D + (A xor B xor C);
+  D := TBits.RotateLeft32(D, 11) + A;
+  C := data[3] + $D4EF3085 + C + (D xor A xor B);
+  C := TBits.RotateLeft32(C, 16) + D;
+  B := data[6] + $4881D05 + B + (C xor D xor A);
+  B := TBits.RotateLeft32(B, 23) + C;
+  A := data[9] + $D9D4D039 + A + (B xor C xor D);
+  A := TBits.RotateLeft32(A, 4) + B;
+  D := data[12] + $E6DB99E5 + D + (A xor B xor C);
+  D := TBits.RotateLeft32(D, 11) + A;
+  C := data[15] + $1FA27CF8 + C + (D xor A xor B);
+  C := TBits.RotateLeft32(C, 16) + D;
+  B := data[2] + $C4AC5665 + B + (C xor D xor A);
+  B := TBits.RotateLeft32(B, 23) + C;
+
+  A := data[0] + $F4292244 + A + (C xor (B or not D));
+  A := TBits.RotateLeft32(A, 6) + B;
+  D := data[7] + $432AFF97 + D + (B xor (A or not C));
+  D := TBits.RotateLeft32(D, 10) + A;
+  C := data[14] + $AB9423A7 + C + (A xor (D or not B));
+  C := TBits.RotateLeft32(C, 15) + D;
+  B := data[5] + $FC93A039 + B + (D xor (C or not A));
+  B := TBits.RotateLeft32(B, 21) + C;
+  A := data[12] + $655B59C3 + A + (C xor (B or not D));
+  A := TBits.RotateLeft32(A, 6) + B;
+  D := data[3] + $8F0CCC92 + D + (B xor (A or not C));
+  D := TBits.RotateLeft32(D, 10) + A;
+  C := data[10] + $FFEFF47D + C + (A xor (D or not B));
+  C := TBits.RotateLeft32(C, 15) + D;
+  B := data[1] + $85845DD1 + B + (D xor (C or not A));
+  B := TBits.RotateLeft32(B, 21) + C;
+  A := data[8] + $6FA87E4F + A + (C xor (B or not D));
+  A := TBits.RotateLeft32(A, 6) + B;
+  D := data[15] + $FE2CE6E0 + D + (B xor (A or not C));
+  D := TBits.RotateLeft32(D, 10) + A;
+  C := data[6] + $A3014314 + C + (A xor (D or not B));
+  C := TBits.RotateLeft32(C, 15) + D;
+  B := data[13] + $4E0811A1 + B + (D xor (C or not A));
+  B := TBits.RotateLeft32(B, 21) + C;
+  A := data[4] + $F7537E82 + A + (C xor (B or not D));
+  A := TBits.RotateLeft32(A, 6) + B;
+  D := data[11] + $BD3AF235 + D + (B xor (A or not C));
+  D := TBits.RotateLeft32(D, 10) + A;
+  C := data[2] + $2AD7D2BB + C + (A xor (D or not B));
+  C := TBits.RotateLeft32(C, 15) + D;
+  B := data[9] + $EB86D391 + B + (D xor (C or not A));
+  B := TBits.RotateLeft32(B, 21) + C;
+
+  Fm_state[0] := Fm_state[0] + A;
+  Fm_state[1] := Fm_state[1] + B;
+  Fm_state[2] := Fm_state[2] + C;
+  Fm_state[3] := Fm_state[3] + D;
+
+  System.FillChar(data, System.SizeOf(data), 0);
+
+end;
+
+end.

+ 102 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpMDBase.pas

@@ -0,0 +1,102 @@
+unit HlpMDBase;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpHashBuffer,
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn,
+  HlpConverters;
+
+type
+  TMDBase = class abstract(TBlockHash, ICryptoNotBuildIn)
+
+  strict protected
+    Fm_state: THashLibUInt32Array;
+
+  const
+
+    C1 = UInt32($50A28BE6);
+    C2 = UInt32($5A827999);
+    C3 = UInt32($5C4DD124);
+    C4 = UInt32($6ED9EBA1);
+    C5 = UInt32($6D703EF3);
+    C6 = UInt32($8F1BBCDC);
+    C7 = UInt32($7A6D76E9);
+    C8 = UInt32($A953FD4E);
+
+    constructor Create(a_state_length, a_hash_size: Int32);
+
+    function GetResult(): THashLibByteArray; override;
+    procedure Finish(); override;
+
+  public
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TMDBase }
+
+constructor TMDBase.Create(a_state_length, a_hash_size: Int32);
+begin
+  Inherited Create(a_hash_size, 64);
+  System.SetLength(Fm_state, a_state_length);
+end;
+
+procedure TMDBase.Finish;
+var
+  bits: UInt64;
+  padindex: Int32;
+  pad: THashLibByteArray;
+begin
+  bits := Fm_processed_bytes * 8;
+  if (Fm_buffer.Pos < 56) then
+    padindex := 56 - Fm_buffer.Pos
+  else
+    padindex := 120 - Fm_buffer.Pos;
+  System.SetLength(pad, padindex + 8);
+
+  pad[0] := $80;
+
+  bits := TConverters.le2me_64(bits);
+
+  TConverters.ReadUInt64AsBytesLE(bits, pad, padindex);
+
+  padindex := padindex + 8;
+
+  TransformBytes(pad, 0, padindex);
+
+end;
+
+function TMDBase.GetResult: THashLibByteArray;
+begin
+
+  System.SetLength(result, System.Length(Fm_state) * System.SizeOf(UInt32));
+
+  TConverters.le32_copy(PCardinal(Fm_state), 0, PByte(result), 0,
+    System.Length(result));
+
+end;
+
+procedure TMDBase.Initialize;
+begin
+  Fm_state[0] := $67452301;
+  Fm_state[1] := $EFCDAB89;
+  Fm_state[2] := $98BADCFE;
+  Fm_state[3] := $10325476;
+  inherited Initialize();
+
+end;
+
+end.

+ 283 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpPanama.pas

@@ -0,0 +1,283 @@
+unit HlpPanama;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpBits,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpConverters,
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn;
+
+type
+  TPanama = class sealed(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+  strict private
+
+    Fm_state, Ftheta, Fgamma, Fpi: THashLibUInt32Array;
+
+    Fm_stages: THashLibMatrixUInt32Array;
+
+    Fm_tap: Int32;
+
+    procedure GPT(a_theta: PCardinal);
+
+  const
+
+  strict protected
+    procedure Finish(); override;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+    function GetResult(): THashLibByteArray; override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TPanama }
+
+constructor TPanama.Create;
+var
+  i: Int32;
+begin
+  Inherited Create(32, 32);
+  System.SetLength(Fm_state, 17);
+
+  System.SetLength(Fm_stages, 32);
+  i := 0;
+  while i <= System.High(Fm_stages) do
+  begin
+    System.SetLength(Fm_stages[i], 8);
+    System.Inc(i);
+  end;
+
+  System.SetLength(Ftheta, 17);
+
+  System.SetLength(Fgamma, 17);
+
+  System.SetLength(Fpi, 17);
+
+end;
+
+procedure TPanama.Finish;
+var
+  padding_size, i, tap4, tap16, tap25: Int32;
+  pad: THashLibByteArray;
+  theta: THashLibUInt32Array;
+  ptr_theta: PCardinal;
+begin
+
+  padding_size := 32 - ((Int32(Fm_processed_bytes)) and 31);
+
+  System.SetLength(pad, padding_size);
+
+  pad[0] := $01;
+  TransformBytes(pad, 0, padding_size);
+
+  System.SetLength(theta, 17);
+
+  ptr_theta := PCardinal(theta);
+
+  i := 0;
+  while i < 32 do
+  begin
+    tap4 := (Fm_tap + 4) and $1F;
+    tap16 := (Fm_tap + 16) and $1F;
+
+    Fm_tap := (Fm_tap - 1) and $1F;
+    tap25 := (Fm_tap + 25) and $1F;
+
+    GPT(ptr_theta);
+
+    Fm_stages[tap25, 0] := Fm_stages[tap25, 0] xor Fm_stages[Fm_tap, 2];
+    Fm_stages[tap25, 1] := Fm_stages[tap25, 1] xor Fm_stages[Fm_tap, 3];
+    Fm_stages[tap25, 2] := Fm_stages[tap25, 2] xor Fm_stages[Fm_tap, 4];
+    Fm_stages[tap25, 3] := Fm_stages[tap25, 3] xor Fm_stages[Fm_tap, 5];
+    Fm_stages[tap25, 4] := Fm_stages[tap25, 4] xor Fm_stages[Fm_tap, 6];
+    Fm_stages[tap25, 5] := Fm_stages[tap25, 5] xor Fm_stages[Fm_tap, 7];
+    Fm_stages[tap25, 6] := Fm_stages[tap25, 6] xor Fm_stages[Fm_tap, 0];
+    Fm_stages[tap25, 7] := Fm_stages[tap25, 7] xor Fm_stages[Fm_tap, 1];
+    Fm_stages[Fm_tap, 0] := Fm_stages[Fm_tap, 0] xor Fm_state[1];
+    Fm_stages[Fm_tap, 1] := Fm_stages[Fm_tap, 1] xor Fm_state[2];
+    Fm_stages[Fm_tap, 2] := Fm_stages[Fm_tap, 2] xor Fm_state[3];
+    Fm_stages[Fm_tap, 3] := Fm_stages[Fm_tap, 3] xor Fm_state[4];
+    Fm_stages[Fm_tap, 4] := Fm_stages[Fm_tap, 4] xor Fm_state[5];
+    Fm_stages[Fm_tap, 5] := Fm_stages[Fm_tap, 5] xor Fm_state[6];
+    Fm_stages[Fm_tap, 6] := Fm_stages[Fm_tap, 6] xor Fm_state[7];
+    Fm_stages[Fm_tap, 7] := Fm_stages[Fm_tap, 7] xor Fm_state[8];
+
+    Fm_state[0] := theta[0] xor $01;
+    Fm_state[1] := theta[1] xor Fm_stages[tap4, 0];
+    Fm_state[2] := theta[2] xor Fm_stages[tap4, 1];
+    Fm_state[3] := theta[3] xor Fm_stages[tap4, 2];
+    Fm_state[4] := theta[4] xor Fm_stages[tap4, 3];
+    Fm_state[5] := theta[5] xor Fm_stages[tap4, 4];
+    Fm_state[6] := theta[6] xor Fm_stages[tap4, 5];
+    Fm_state[7] := theta[7] xor Fm_stages[tap4, 6];
+    Fm_state[8] := theta[8] xor Fm_stages[tap4, 7];
+    Fm_state[9] := theta[9] xor Fm_stages[tap16, 0];
+    Fm_state[10] := theta[10] xor Fm_stages[tap16, 1];
+    Fm_state[11] := theta[11] xor Fm_stages[tap16, 2];
+    Fm_state[12] := theta[12] xor Fm_stages[tap16, 3];
+    Fm_state[13] := theta[13] xor Fm_stages[tap16, 4];
+    Fm_state[14] := theta[14] xor Fm_stages[tap16, 5];
+    Fm_state[15] := theta[15] xor Fm_stages[tap16, 6];
+    Fm_state[16] := theta[16] xor Fm_stages[tap16, 7];
+
+    System.Inc(i);
+  end;
+
+end;
+
+function TPanama.GetResult: THashLibByteArray;
+begin
+
+  System.SetLength(result, 8 * System.SizeOf(UInt32));
+
+  TConverters.le32_copy(PCardinal(Fm_state) + 9, 0, PByte(result), 0,
+    System.Length(result));
+
+end;
+
+procedure TPanama.GPT(a_theta: PCardinal);
+begin
+
+  Fgamma[0] := Fm_state[0] xor (Fm_state[1] or not Fm_state[2]);
+  Fgamma[1] := Fm_state[1] xor (Fm_state[2] or not Fm_state[3]);
+  Fgamma[2] := Fm_state[2] xor (Fm_state[3] or not Fm_state[4]);
+  Fgamma[3] := Fm_state[3] xor (Fm_state[4] or not Fm_state[5]);
+  Fgamma[4] := Fm_state[4] xor (Fm_state[5] or not Fm_state[6]);
+  Fgamma[5] := Fm_state[5] xor (Fm_state[6] or not Fm_state[7]);
+  Fgamma[6] := Fm_state[6] xor (Fm_state[7] or not Fm_state[8]);
+  Fgamma[7] := Fm_state[7] xor (Fm_state[8] or not Fm_state[9]);
+  Fgamma[8] := Fm_state[8] xor (Fm_state[9] or not Fm_state[10]);
+  Fgamma[9] := Fm_state[9] xor (Fm_state[10] or not Fm_state[11]);
+  Fgamma[10] := Fm_state[10] xor (Fm_state[11] or not Fm_state[12]);
+  Fgamma[11] := Fm_state[11] xor (Fm_state[12] or not Fm_state[13]);
+  Fgamma[12] := Fm_state[12] xor (Fm_state[13] or not Fm_state[14]);
+  Fgamma[13] := Fm_state[13] xor (Fm_state[14] or not Fm_state[15]);
+  Fgamma[14] := Fm_state[14] xor (Fm_state[15] or not Fm_state[16]);
+  Fgamma[15] := Fm_state[15] xor (Fm_state[16] or not Fm_state[0]);
+  Fgamma[16] := Fm_state[16] xor (Fm_state[0] or not Fm_state[1]);
+
+  Fpi[0] := Fgamma[0];
+  Fpi[1] := TBits.RotateLeft32(Fgamma[7], 1);
+  Fpi[2] := TBits.RotateLeft32(Fgamma[14], 3);
+  Fpi[3] := TBits.RotateLeft32(Fgamma[4], 6);
+  Fpi[4] := TBits.RotateLeft32(Fgamma[11], 10);
+  Fpi[5] := TBits.RotateLeft32(Fgamma[1], 15);
+  Fpi[6] := TBits.RotateLeft32(Fgamma[8], 21);
+  Fpi[7] := TBits.RotateLeft32(Fgamma[15], 28);
+  Fpi[8] := TBits.RotateLeft32(Fgamma[5], 4);
+  Fpi[9] := TBits.RotateLeft32(Fgamma[12], 13);
+  Fpi[10] := TBits.RotateLeft32(Fgamma[2], 23);
+  Fpi[11] := TBits.RotateLeft32(Fgamma[9], 2);
+  Fpi[12] := TBits.RotateLeft32(Fgamma[16], 14);
+  Fpi[13] := TBits.RotateLeft32(Fgamma[6], 27);
+  Fpi[14] := TBits.RotateLeft32(Fgamma[13], 9);
+  Fpi[15] := TBits.RotateLeft32(Fgamma[3], 24);
+  Fpi[16] := TBits.RotateLeft32(Fgamma[10], 8);
+
+  a_theta[0] := Fpi[0] xor Fpi[1] xor Fpi[4];
+  a_theta[1] := Fpi[1] xor Fpi[2] xor Fpi[5];
+  a_theta[2] := Fpi[2] xor Fpi[3] xor Fpi[6];
+  a_theta[3] := Fpi[3] xor Fpi[4] xor Fpi[7];
+  a_theta[4] := Fpi[4] xor Fpi[5] xor Fpi[8];
+  a_theta[5] := Fpi[5] xor Fpi[6] xor Fpi[9];
+  a_theta[6] := Fpi[6] xor Fpi[7] xor Fpi[10];
+  a_theta[7] := Fpi[7] xor Fpi[8] xor Fpi[11];
+  a_theta[8] := Fpi[8] xor Fpi[9] xor Fpi[12];
+  a_theta[9] := Fpi[9] xor Fpi[10] xor Fpi[13];
+  a_theta[10] := Fpi[10] xor Fpi[11] xor Fpi[14];
+  a_theta[11] := Fpi[11] xor Fpi[12] xor Fpi[15];
+  a_theta[12] := Fpi[12] xor Fpi[13] xor Fpi[16];
+  a_theta[13] := Fpi[13] xor Fpi[14] xor Fpi[0];
+  a_theta[14] := Fpi[14] xor Fpi[15] xor Fpi[1];
+  a_theta[15] := Fpi[15] xor Fpi[16] xor Fpi[2];
+  a_theta[16] := Fpi[16] xor Fpi[0] xor Fpi[3];
+
+end;
+
+procedure TPanama.Initialize;
+var
+  i: Int32;
+begin
+  System.FillChar(Fm_state[0], System.Length(Fm_state) * System.SizeOf(UInt32),
+    UInt32(0));
+
+  for i := System.Low(Fm_stages) to System.High(Fm_stages) do
+  begin
+    System.FillChar(Fm_stages[i, 0], System.Length(Fm_stages[i]) *
+      System.SizeOf(UInt32), UInt32(0));
+
+  end;
+
+  Inherited Initialize();
+
+end;
+
+procedure TPanama.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  work_buffer: array [0 .. 7] of UInt32;
+  tap16, tap25: Int32;
+begin
+
+  TConverters.le32_copy(a_data, a_index, @(work_buffer[0]), 0, a_data_length);
+
+  tap16 := (Fm_tap + 16) and $1F;
+
+  Fm_tap := (Fm_tap - 1) and $1F;
+  tap25 := (Fm_tap + 25) and $1F;
+
+  GPT(PCardinal(Ftheta));
+
+  Fm_stages[tap25, 0] := Fm_stages[tap25, 0] xor Fm_stages[Fm_tap, 2];
+  Fm_stages[tap25, 1] := Fm_stages[tap25, 1] xor Fm_stages[Fm_tap, 3];
+  Fm_stages[tap25, 2] := Fm_stages[tap25, 2] xor Fm_stages[Fm_tap, 4];
+  Fm_stages[tap25, 3] := Fm_stages[tap25, 3] xor Fm_stages[Fm_tap, 5];
+  Fm_stages[tap25, 4] := Fm_stages[tap25, 4] xor Fm_stages[Fm_tap, 6];
+  Fm_stages[tap25, 5] := Fm_stages[tap25, 5] xor Fm_stages[Fm_tap, 7];
+  Fm_stages[tap25, 6] := Fm_stages[tap25, 6] xor Fm_stages[Fm_tap, 0];
+  Fm_stages[tap25, 7] := Fm_stages[tap25, 7] xor Fm_stages[Fm_tap, 1];
+  Fm_stages[Fm_tap, 0] := Fm_stages[Fm_tap, 0] xor work_buffer[0];
+  Fm_stages[Fm_tap, 1] := Fm_stages[Fm_tap, 1] xor work_buffer[1];
+  Fm_stages[Fm_tap, 2] := Fm_stages[Fm_tap, 2] xor work_buffer[2];
+  Fm_stages[Fm_tap, 3] := Fm_stages[Fm_tap, 3] xor work_buffer[3];
+  Fm_stages[Fm_tap, 4] := Fm_stages[Fm_tap, 4] xor work_buffer[4];
+  Fm_stages[Fm_tap, 5] := Fm_stages[Fm_tap, 5] xor work_buffer[5];
+  Fm_stages[Fm_tap, 6] := Fm_stages[Fm_tap, 6] xor work_buffer[6];
+  Fm_stages[Fm_tap, 7] := Fm_stages[Fm_tap, 7] xor work_buffer[7];
+
+  Fm_state[0] := Ftheta[0] xor $01;
+  Fm_state[1] := Ftheta[1] xor work_buffer[0];
+  Fm_state[2] := Ftheta[2] xor work_buffer[1];
+  Fm_state[3] := Ftheta[3] xor work_buffer[2];
+  Fm_state[4] := Ftheta[4] xor work_buffer[3];
+  Fm_state[5] := Ftheta[5] xor work_buffer[4];
+  Fm_state[6] := Ftheta[6] xor work_buffer[5];
+  Fm_state[7] := Ftheta[7] xor work_buffer[6];
+  Fm_state[8] := Ftheta[8] xor work_buffer[7];
+  Fm_state[9] := Ftheta[9] xor Fm_stages[tap16, 0];
+  Fm_state[10] := Ftheta[10] xor Fm_stages[tap16, 1];
+  Fm_state[11] := Ftheta[11] xor Fm_stages[tap16, 2];
+  Fm_state[12] := Ftheta[12] xor Fm_stages[tap16, 3];
+  Fm_state[13] := Ftheta[13] xor Fm_stages[tap16, 4];
+  Fm_state[14] := Ftheta[14] xor Fm_stages[tap16, 5];
+  Fm_state[15] := Ftheta[15] xor Fm_stages[tap16, 6];
+  Fm_state[16] := Ftheta[16] xor Fm_stages[tap16, 7];
+
+  System.FillChar(work_buffer, System.SizeOf(work_buffer), 0);
+
+end;
+
+end.

+ 190 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpRIPEMD.pas

@@ -0,0 +1,190 @@
+unit HlpRIPEMD;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpBits,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpMDBase,
+  HlpConverters,
+  HlpIHashInfo;
+
+type
+  TRIPEMD = class sealed(TMDBase, ITransformBlock)
+
+  strict private
+    class function P1(a, b, c: UInt32): UInt32; static; inline;
+    class function P2(a, b, c: UInt32): UInt32; static; inline;
+    class function P3(a, b, c: UInt32): UInt32; static; inline;
+
+  strict protected
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create();
+
+  end;
+
+implementation
+
+{ TRIPEMD }
+
+constructor TRIPEMD.Create;
+begin
+  Inherited Create(4, 16);
+end;
+
+class function TRIPEMD.P1(a, b, c: UInt32): UInt32;
+begin
+  result := (a and b) or (not a and c);
+end;
+
+class function TRIPEMD.P2(a, b, c: UInt32): UInt32;
+begin
+  result := (a and b) or (a and c) or (b and c);
+end;
+
+class function TRIPEMD.P3(a, b, c: UInt32): UInt32;
+begin
+  result := a xor b xor c;
+end;
+
+procedure TRIPEMD.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  a, b, c, d, aa, bb, cc, dd: UInt32;
+  data: array [0 .. 15] of UInt32;
+begin
+
+  TConverters.le32_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+
+  a := Fm_state[0];
+  b := Fm_state[1];
+  c := Fm_state[2];
+  d := Fm_state[3];
+  aa := a;
+  bb := b;
+  cc := c;
+  dd := d;
+
+  a := TBits.RotateLeft32(P1(b, c, d) + a + data[0], 11);
+  d := TBits.RotateLeft32(P1(a, b, c) + d + data[1], 14);
+  c := TBits.RotateLeft32(P1(d, a, b) + c + data[2], 15);
+  b := TBits.RotateLeft32(P1(c, d, a) + b + data[3], 12);
+  a := TBits.RotateLeft32(P1(b, c, d) + a + data[4], 5);
+  d := TBits.RotateLeft32(P1(a, b, c) + d + data[5], 8);
+  c := TBits.RotateLeft32(P1(d, a, b) + c + data[6], 7);
+  b := TBits.RotateLeft32(P1(c, d, a) + b + data[7], 9);
+  a := TBits.RotateLeft32(P1(b, c, d) + a + data[8], 11);
+  d := TBits.RotateLeft32(P1(a, b, c) + d + data[9], 13);
+  c := TBits.RotateLeft32(P1(d, a, b) + c + data[10], 14);
+  b := TBits.RotateLeft32(P1(c, d, a) + b + data[11], 15);
+  a := TBits.RotateLeft32(P1(b, c, d) + a + data[12], 6);
+  d := TBits.RotateLeft32(P1(a, b, c) + d + data[13], 7);
+  c := TBits.RotateLeft32(P1(d, a, b) + c + data[14], 9);
+  b := TBits.RotateLeft32(P1(c, d, a) + b + data[15], 8);
+
+  a := TBits.RotateLeft32(P2(b, c, d) + a + data[7] + C2, 7);
+  d := TBits.RotateLeft32(P2(a, b, c) + d + data[4] + C2, 6);
+  c := TBits.RotateLeft32(P2(d, a, b) + c + data[13] + C2, 8);
+  b := TBits.RotateLeft32(P2(c, d, a) + b + data[1] + C2, 13);
+  a := TBits.RotateLeft32(P2(b, c, d) + a + data[10] + C2, 11);
+  d := TBits.RotateLeft32(P2(a, b, c) + d + data[6] + C2, 9);
+  c := TBits.RotateLeft32(P2(d, a, b) + c + data[15] + C2, 7);
+  b := TBits.RotateLeft32(P2(c, d, a) + b + data[3] + C2, 15);
+  a := TBits.RotateLeft32(P2(b, c, d) + a + data[12] + C2, 7);
+  d := TBits.RotateLeft32(P2(a, b, c) + d + data[0] + C2, 12);
+  c := TBits.RotateLeft32(P2(d, a, b) + c + data[9] + C2, 15);
+  b := TBits.RotateLeft32(P2(c, d, a) + b + data[5] + C2, 9);
+  a := TBits.RotateLeft32(P2(b, c, d) + a + data[14] + C2, 7);
+  d := TBits.RotateLeft32(P2(a, b, c) + d + data[2] + C2, 11);
+  c := TBits.RotateLeft32(P2(d, a, b) + c + data[11] + C2, 13);
+  b := TBits.RotateLeft32(P2(c, d, a) + b + data[8] + C2, 12);
+
+  a := TBits.RotateLeft32(P3(b, c, d) + a + data[3] + C4, 11);
+  d := TBits.RotateLeft32(P3(a, b, c) + d + data[10] + C4, 13);
+  c := TBits.RotateLeft32(P3(d, a, b) + c + data[2] + C4, 14);
+  b := TBits.RotateLeft32(P3(c, d, a) + b + data[4] + C4, 7);
+  a := TBits.RotateLeft32(P3(b, c, d) + a + data[9] + C4, 14);
+  d := TBits.RotateLeft32(P3(a, b, c) + d + data[15] + C4, 9);
+  c := TBits.RotateLeft32(P3(d, a, b) + c + data[8] + C4, 13);
+  b := TBits.RotateLeft32(P3(c, d, a) + b + data[1] + C4, 15);
+  a := TBits.RotateLeft32(P3(b, c, d) + a + data[14] + C4, 6);
+  d := TBits.RotateLeft32(P3(a, b, c) + d + data[7] + C4, 8);
+  c := TBits.RotateLeft32(P3(d, a, b) + c + data[0] + C4, 13);
+  b := TBits.RotateLeft32(P3(c, d, a) + b + data[6] + C4, 6);
+  a := TBits.RotateLeft32(P3(b, c, d) + a + data[11] + C4, 12);
+  d := TBits.RotateLeft32(P3(a, b, c) + d + data[13] + C4, 5);
+  c := TBits.RotateLeft32(P3(d, a, b) + c + data[5] + C4, 7);
+  b := TBits.RotateLeft32(P3(c, d, a) + b + data[12] + C4, 5);
+
+  aa := TBits.RotateLeft32(P1(bb, cc, dd) + aa + data[0] + C1, 11);
+  dd := TBits.RotateLeft32(P1(aa, bb, cc) + dd + data[1] + C1, 14);
+  cc := TBits.RotateLeft32(P1(dd, aa, bb) + cc + data[2] + C1, 15);
+  bb := TBits.RotateLeft32(P1(cc, dd, aa) + bb + data[3] + C1, 12);
+  aa := TBits.RotateLeft32(P1(bb, cc, dd) + aa + data[4] + C1, 5);
+  dd := TBits.RotateLeft32(P1(aa, bb, cc) + dd + data[5] + C1, 8);
+  cc := TBits.RotateLeft32(P1(dd, aa, bb) + cc + data[6] + C1, 7);
+  bb := TBits.RotateLeft32(P1(cc, dd, aa) + bb + data[7] + C1, 9);
+  aa := TBits.RotateLeft32(P1(bb, cc, dd) + aa + data[8] + C1, 11);
+  dd := TBits.RotateLeft32(P1(aa, bb, cc) + dd + data[9] + C1, 13);
+  cc := TBits.RotateLeft32(P1(dd, aa, bb) + cc + data[10] + C1, 14);
+  bb := TBits.RotateLeft32(P1(cc, dd, aa) + bb + data[11] + C1, 15);
+  aa := TBits.RotateLeft32(P1(bb, cc, dd) + aa + data[12] + C1, 6);
+  dd := TBits.RotateLeft32(P1(aa, bb, cc) + dd + data[13] + C1, 7);
+  cc := TBits.RotateLeft32(P1(dd, aa, bb) + cc + data[14] + C1, 9);
+  bb := TBits.RotateLeft32(P1(cc, dd, aa) + bb + data[15] + C1, 8);
+
+  aa := TBits.RotateLeft32(P2(bb, cc, dd) + aa + data[7], 7);
+  dd := TBits.RotateLeft32(P2(aa, bb, cc) + dd + data[4], 6);
+  cc := TBits.RotateLeft32(P2(dd, aa, bb) + cc + data[13], 8);
+  bb := TBits.RotateLeft32(P2(cc, dd, aa) + bb + data[1], 13);
+  aa := TBits.RotateLeft32(P2(bb, cc, dd) + aa + data[10], 11);
+  dd := TBits.RotateLeft32(P2(aa, bb, cc) + dd + data[6], 9);
+  cc := TBits.RotateLeft32(P2(dd, aa, bb) + cc + data[15], 7);
+  bb := TBits.RotateLeft32(P2(cc, dd, aa) + bb + data[3], 15);
+  aa := TBits.RotateLeft32(P2(bb, cc, dd) + aa + data[12], 7);
+  dd := TBits.RotateLeft32(P2(aa, bb, cc) + dd + data[0], 12);
+  cc := TBits.RotateLeft32(P2(dd, aa, bb) + cc + data[9], 15);
+  bb := TBits.RotateLeft32(P2(cc, dd, aa) + bb + data[5], 9);
+  aa := TBits.RotateLeft32(P2(bb, cc, dd) + aa + data[14], 7);
+  dd := TBits.RotateLeft32(P2(aa, bb, cc) + dd + data[2], 11);
+  cc := TBits.RotateLeft32(P2(dd, aa, bb) + cc + data[11], 13);
+  bb := TBits.RotateLeft32(P2(cc, dd, aa) + bb + data[8], 12);
+
+  aa := TBits.RotateLeft32(P3(bb, cc, dd) + aa + data[3] + C3, 11);
+  dd := TBits.RotateLeft32(P3(aa, bb, cc) + dd + data[10] + C3, 13);
+  cc := TBits.RotateLeft32(P3(dd, aa, bb) + cc + data[2] + C3, 14);
+  bb := TBits.RotateLeft32(P3(cc, dd, aa) + bb + data[4] + C3, 7);
+  aa := TBits.RotateLeft32(P3(bb, cc, dd) + aa + data[9] + C3, 14);
+  dd := TBits.RotateLeft32(P3(aa, bb, cc) + dd + data[15] + C3, 9);
+  cc := TBits.RotateLeft32(P3(dd, aa, bb) + cc + data[8] + C3, 13);
+  bb := TBits.RotateLeft32(P3(cc, dd, aa) + bb + data[1] + C3, 15);
+  aa := TBits.RotateLeft32(P3(bb, cc, dd) + aa + data[14] + C3, 6);
+  dd := TBits.RotateLeft32(P3(aa, bb, cc) + dd + data[7] + C3, 8);
+  cc := TBits.RotateLeft32(P3(dd, aa, bb) + cc + data[0] + C3, 13);
+  bb := TBits.RotateLeft32(P3(cc, dd, aa) + bb + data[6] + C3, 6);
+  aa := TBits.RotateLeft32(P3(bb, cc, dd) + aa + data[11] + C3, 12);
+  dd := TBits.RotateLeft32(P3(aa, bb, cc) + dd + data[13] + C3, 5);
+  cc := TBits.RotateLeft32(P3(dd, aa, bb) + cc + data[5] + C3, 7);
+  bb := TBits.RotateLeft32(P3(cc, dd, aa) + bb + data[12] + C3, 5);
+
+  cc := cc + Fm_state[0] + b;
+  Fm_state[0] := Fm_state[1] + c + dd;
+  Fm_state[1] := Fm_state[2] + d + aa;
+  Fm_state[2] := Fm_state[3] + a + bb;
+  Fm_state[3] := cc;
+
+  System.FillChar(data, System.SizeOf(data), 0);
+
+end;
+
+end.

+ 332 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpRIPEMD128.pas

@@ -0,0 +1,332 @@
+unit HlpRIPEMD128;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpMDBase,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpBits,
+  HlpConverters,
+  HlpIHashInfo;
+
+type
+  TRIPEMD128 = class sealed(TMDBase, ITransformBlock)
+
+  strict protected
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create();
+
+  end;
+
+implementation
+
+{ TRIPEMD128 }
+
+constructor TRIPEMD128.Create;
+begin
+  Inherited Create(4, 16);
+end;
+
+procedure TRIPEMD128.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  a, b, c, d, aa, bb, cc, dd: UInt32;
+  data: array [0 .. 15] of UInt32;
+begin
+
+  TConverters.le32_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+
+  a := Fm_state[0];
+  b := Fm_state[1];
+  c := Fm_state[2];
+  d := Fm_state[3];
+  aa := a;
+  bb := b;
+  cc := c;
+  dd := d;
+
+  a := a + (data[0] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 11);
+  d := d + (data[1] + (a xor b xor c));
+  d := TBits.RotateLeft32(d, 14);
+  c := c + (data[2] + (d xor a xor b));
+  c := TBits.RotateLeft32(c, 15);
+  b := b + (data[3] + (c xor d xor a));
+  b := TBits.RotateLeft32(b, 12);
+  a := a + (data[4] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 5);
+  d := d + (data[5] + (a xor b xor c));
+  d := TBits.RotateLeft32(d, 8);
+  c := c + (data[6] + (d xor a xor b));
+  c := TBits.RotateLeft32(c, 7);
+  b := b + (data[7] + (c xor d xor a));
+  b := TBits.RotateLeft32(b, 9);
+  a := a + (data[8] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 11);
+  d := d + (data[9] + (a xor b xor c));
+  d := TBits.RotateLeft32(d, 13);
+  c := c + (data[10] + (d xor a xor b));
+  c := TBits.RotateLeft32(c, 14);
+  b := b + (data[11] + (c xor d xor a));
+  b := TBits.RotateLeft32(b, 15);
+  a := a + (data[12] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 6);
+  d := d + (data[13] + (a xor b xor c));
+  d := TBits.RotateLeft32(d, 7);
+  c := c + (data[14] + (d xor a xor b));
+  c := TBits.RotateLeft32(c, 9);
+  b := b + (data[15] + (c xor d xor a));
+  b := TBits.RotateLeft32(b, 8);
+
+  a := a + (data[7] + C2 + ((b and c) or (not b and d)));
+  a := TBits.RotateLeft32(a, 7);
+  d := d + (data[4] + C2 + ((a and b) or (not a and c)));
+  d := TBits.RotateLeft32(d, 6);
+  c := c + (data[13] + C2 + ((d and a) or (not d and b)));
+  c := TBits.RotateLeft32(c, 8);
+  b := b + (data[1] + C2 + ((c and d) or (not c and a)));
+  b := TBits.RotateLeft32(b, 13);
+  a := a + (data[10] + C2 + ((b and c) or (not b and d)));
+  a := TBits.RotateLeft32(a, 11);
+  d := d + (data[6] + C2 + ((a and b) or (not a and c)));
+  d := TBits.RotateLeft32(d, 9);
+  c := c + (data[15] + C2 + ((d and a) or (not d and b)));
+  c := TBits.RotateLeft32(c, 7);
+  b := b + (data[3] + C2 + ((c and d) or (not c and a)));
+  b := TBits.RotateLeft32(b, 15);
+  a := a + (data[12] + C2 + ((b and c) or (not b and d)));
+  a := TBits.RotateLeft32(a, 7);
+  d := d + (data[0] + C2 + ((a and b) or (not a and c)));
+  d := TBits.RotateLeft32(d, 12);
+  c := c + (data[9] + C2 + ((d and a) or (not d and b)));
+  c := TBits.RotateLeft32(c, 15);
+  b := b + (data[5] + C2 + ((c and d) or (not c and a)));
+  b := TBits.RotateLeft32(b, 9);
+  a := a + (data[2] + C2 + ((b and c) or (not b and d)));
+  a := TBits.RotateLeft32(a, 11);
+  d := d + (data[14] + C2 + ((a and b) or (not a and c)));
+  d := TBits.RotateLeft32(d, 7);
+  c := c + (data[11] + C2 + ((d and a) or (not d and b)));
+  c := TBits.RotateLeft32(c, 13);
+  b := b + (data[8] + C2 + ((c and d) or (not c and a)));
+  b := TBits.RotateLeft32(b, 12);
+
+  a := a + (data[3] + C4 + ((b or not c) xor d));
+  a := TBits.RotateLeft32(a, 11);
+  d := d + (data[10] + C4 + ((a or not b) xor c));
+  d := TBits.RotateLeft32(d, 13);
+  c := c + (data[14] + C4 + ((d or not a) xor b));
+  c := TBits.RotateLeft32(c, 6);
+  b := b + (data[4] + C4 + ((c or not d) xor a));
+  b := TBits.RotateLeft32(b, 7);
+  a := a + (data[9] + C4 + ((b or not c) xor d));
+  a := TBits.RotateLeft32(a, 14);
+  d := d + (data[15] + C4 + ((a or not b) xor c));
+  d := TBits.RotateLeft32(d, 9);
+  c := c + (data[8] + C4 + ((d or not a) xor b));
+  c := TBits.RotateLeft32(c, 13);
+  b := b + (data[1] + C4 + ((c or not d) xor a));
+  b := TBits.RotateLeft32(b, 15);
+  a := a + (data[2] + C4 + ((b or not c) xor d));
+  a := TBits.RotateLeft32(a, 14);
+  d := d + (data[7] + C4 + ((a or not b) xor c));
+  d := TBits.RotateLeft32(d, 8);
+  c := c + (data[0] + C4 + ((d or not a) xor b));
+  c := TBits.RotateLeft32(c, 13);
+  b := b + (data[6] + C4 + ((c or not d) xor a));
+  b := TBits.RotateLeft32(b, 6);
+  a := a + (data[13] + C4 + ((b or not c) xor d));
+  a := TBits.RotateLeft32(a, 5);
+  d := d + (data[11] + C4 + ((a or not b) xor c));
+  d := TBits.RotateLeft32(d, 12);
+  c := c + (data[5] + C4 + ((d or not a) xor b));
+  c := TBits.RotateLeft32(c, 7);
+  b := b + (data[12] + C4 + ((c or not d) xor a));
+  b := TBits.RotateLeft32(b, 5);
+
+  a := a + (data[1] + C6 + ((b and d) or (c and not d)));
+  a := TBits.RotateLeft32(a, 11);
+  d := d + (data[9] + C6 + ((a and c) or (b and not c)));
+  d := TBits.RotateLeft32(d, 12);
+  c := c + (data[11] + C6 + ((d and b) or (a and not b)));
+  c := TBits.RotateLeft32(c, 14);
+  b := b + (data[10] + C6 + ((c and a) or (d and not a)));
+  b := TBits.RotateLeft32(b, 15);
+  a := a + (data[0] + C6 + ((b and d) or (c and not d)));
+  a := TBits.RotateLeft32(a, 14);
+  d := d + (data[8] + C6 + ((a and c) or (b and not c)));
+  d := TBits.RotateLeft32(d, 15);
+  c := c + (data[12] + C6 + ((d and b) or (a and not b)));
+  c := TBits.RotateLeft32(c, 9);
+  b := b + (data[4] + C6 + ((c and a) or (d and not a)));
+  b := TBits.RotateLeft32(b, 8);
+  a := a + (data[13] + C6 + ((b and d) or (c and not d)));
+  a := TBits.RotateLeft32(a, 9);
+  d := d + (data[3] + C6 + ((a and c) or (b and not c)));
+  d := TBits.RotateLeft32(d, 14);
+  c := c + (data[7] + C6 + ((d and b) or (a and not b)));
+  c := TBits.RotateLeft32(c, 5);
+  b := b + (data[15] + C6 + ((c and a) or (d and not a)));
+  b := TBits.RotateLeft32(b, 6);
+  a := a + (data[14] + C6 + ((b and d) or (c and not d)));
+  a := TBits.RotateLeft32(a, 8);
+  d := d + (data[5] + C6 + ((a and c) or (b and not c)));
+  d := TBits.RotateLeft32(d, 6);
+  c := c + (data[6] + C6 + ((d and b) or (a and not b)));
+  c := TBits.RotateLeft32(c, 5);
+  b := b + (data[2] + C6 + ((c and a) or (d and not a)));
+  b := TBits.RotateLeft32(b, 12);
+
+  aa := aa + (data[5] + C1 + ((bb and dd) or (cc and not dd)));
+  aa := TBits.RotateLeft32(aa, 8);
+  dd := dd + (data[14] + C1 + ((aa and cc) or (bb and not cc)));
+  dd := TBits.RotateLeft32(dd, 9);
+  cc := cc + (data[7] + C1 + ((dd and bb) or (aa and not bb)));
+  cc := TBits.RotateLeft32(cc, 9);
+  bb := bb + (data[0] + C1 + ((cc and aa) or (dd and not aa)));
+  bb := TBits.RotateLeft32(bb, 11);
+  aa := aa + (data[9] + C1 + ((bb and dd) or (cc and not dd)));
+  aa := TBits.RotateLeft32(aa, 13);
+  dd := dd + (data[2] + C1 + ((aa and cc) or (bb and not cc)));
+  dd := TBits.RotateLeft32(dd, 15);
+  cc := cc + (data[11] + C1 + ((dd and bb) or (aa and not bb)));
+  cc := TBits.RotateLeft32(cc, 15);
+  bb := bb + (data[4] + C1 + ((cc and aa) or (dd and not aa)));
+  bb := TBits.RotateLeft32(bb, 5);
+  aa := aa + (data[13] + C1 + ((bb and dd) or (cc and not dd)));
+  aa := TBits.RotateLeft32(aa, 7);
+  dd := dd + (data[6] + C1 + ((aa and cc) or (bb and not cc)));
+  dd := TBits.RotateLeft32(dd, 7);
+  cc := cc + (data[15] + C1 + ((dd and bb) or (aa and not bb)));
+  cc := TBits.RotateLeft32(cc, 8);
+  bb := bb + (data[8] + C1 + ((cc and aa) or (dd and not aa)));
+  bb := TBits.RotateLeft32(bb, 11);
+  aa := aa + (data[1] + C1 + ((bb and dd) or (cc and not dd)));
+  aa := TBits.RotateLeft32(aa, 14);
+  dd := dd + (data[10] + C1 + ((aa and cc) or (bb and not cc)));
+  dd := TBits.RotateLeft32(dd, 14);
+  cc := cc + (data[3] + C1 + ((dd and bb) or (aa and not bb)));
+  cc := TBits.RotateLeft32(cc, 12);
+  bb := bb + (data[12] + C1 + ((cc and aa) or (dd and not aa)));
+  bb := TBits.RotateLeft32(bb, 6);
+
+  aa := aa + (data[6] + C3 + ((bb or not cc) xor dd));
+  aa := TBits.RotateLeft32(aa, 9);
+  dd := dd + (data[11] + C3 + ((aa or not bb) xor cc));
+  dd := TBits.RotateLeft32(dd, 13);
+  cc := cc + (data[3] + C3 + ((dd or not aa) xor bb));
+  cc := TBits.RotateLeft32(cc, 15);
+  bb := bb + (data[7] + C3 + ((cc or not dd) xor aa));
+  bb := TBits.RotateLeft32(bb, 7);
+  aa := aa + (data[0] + C3 + ((bb or not cc) xor dd));
+  aa := TBits.RotateLeft32(aa, 12);
+  dd := dd + (data[13] + C3 + ((aa or not bb) xor cc));
+  dd := TBits.RotateLeft32(dd, 8);
+  cc := cc + (data[5] + C3 + ((dd or not aa) xor bb));
+  cc := TBits.RotateLeft32(cc, 9);
+  bb := bb + (data[10] + C3 + ((cc or not dd) xor aa));
+  bb := TBits.RotateLeft32(bb, 11);
+  aa := aa + (data[14] + C3 + ((bb or not cc) xor dd));
+  aa := TBits.RotateLeft32(aa, 7);
+  dd := dd + (data[15] + C3 + ((aa or not bb) xor cc));
+  dd := TBits.RotateLeft32(dd, 7);
+  cc := cc + (data[8] + C3 + ((dd or not aa) xor bb));
+  cc := TBits.RotateLeft32(cc, 12);
+  bb := bb + (data[12] + C3 + ((cc or not dd) xor aa));
+  bb := TBits.RotateLeft32(bb, 7);
+  aa := aa + (data[4] + C3 + ((bb or not cc) xor dd));
+  aa := TBits.RotateLeft32(aa, 6);
+  dd := dd + (data[9] + C3 + ((aa or not bb) xor cc));
+  dd := TBits.RotateLeft32(dd, 15);
+  cc := cc + (data[1] + C3 + ((dd or not aa) xor bb));
+  cc := TBits.RotateLeft32(cc, 13);
+  bb := bb + (data[2] + C3 + ((cc or not dd) xor aa));
+  bb := TBits.RotateLeft32(bb, 11);
+
+  aa := aa + (data[15] + C5 + ((bb and cc) or (not bb and dd)));
+  aa := TBits.RotateLeft32(aa, 9);
+  dd := dd + (data[5] + C5 + ((aa and bb) or (not aa and cc)));
+  dd := TBits.RotateLeft32(dd, 7);
+  cc := cc + (data[1] + C5 + ((dd and aa) or (not dd and bb)));
+  cc := TBits.RotateLeft32(cc, 15);
+  bb := bb + (data[3] + C5 + ((cc and dd) or (not cc and aa)));
+  bb := TBits.RotateLeft32(bb, 11);
+  aa := aa + (data[7] + C5 + ((bb and cc) or (not bb and dd)));
+  aa := TBits.RotateLeft32(aa, 8);
+  dd := dd + (data[14] + C5 + ((aa and bb) or (not aa and cc)));
+  dd := TBits.RotateLeft32(dd, 6);
+  cc := cc + (data[6] + C5 + ((dd and aa) or (not dd and bb)));
+  cc := TBits.RotateLeft32(cc, 6);
+  bb := bb + (data[9] + C5 + ((cc and dd) or (not cc and aa)));
+  bb := TBits.RotateLeft32(bb, 14);
+  aa := aa + (data[11] + C5 + ((bb and cc) or (not bb and dd)));
+  aa := TBits.RotateLeft32(aa, 12);
+  dd := dd + (data[8] + C5 + ((aa and bb) or (not aa and cc)));
+  dd := TBits.RotateLeft32(dd, 13);
+  cc := cc + (data[12] + C5 + ((dd and aa) or (not dd and bb)));
+  cc := TBits.RotateLeft32(cc, 5);
+  bb := bb + (data[2] + C5 + ((cc and dd) or (not cc and aa)));
+  bb := TBits.RotateLeft32(bb, 14);
+  aa := aa + (data[10] + C5 + ((bb and cc) or (not bb and dd)));
+  aa := TBits.RotateLeft32(aa, 13);
+  dd := dd + (data[0] + C5 + ((aa and bb) or (not aa and cc)));
+  dd := TBits.RotateLeft32(dd, 13);
+  cc := cc + (data[4] + C5 + ((dd and aa) or (not dd and bb)));
+  cc := TBits.RotateLeft32(cc, 7);
+  bb := bb + (data[13] + C5 + ((cc and dd) or (not cc and aa)));
+  bb := TBits.RotateLeft32(bb, 5);
+
+  aa := aa + (data[8] + (bb xor cc xor dd));
+  aa := TBits.RotateLeft32(aa, 15);
+  dd := dd + (data[6] + (aa xor bb xor cc));
+  dd := TBits.RotateLeft32(dd, 5);
+  cc := cc + (data[4] + (dd xor aa xor bb));
+  cc := TBits.RotateLeft32(cc, 8);
+  bb := bb + (data[1] + (cc xor dd xor aa));
+  bb := TBits.RotateLeft32(bb, 11);
+  aa := aa + (data[3] + (bb xor cc xor dd));
+  aa := TBits.RotateLeft32(aa, 14);
+  dd := dd + (data[11] + (aa xor bb xor cc));
+  dd := TBits.RotateLeft32(dd, 14);
+  cc := cc + (data[15] + (dd xor aa xor bb));
+  cc := TBits.RotateLeft32(cc, 6);
+  bb := bb + (data[0] + (cc xor dd xor aa));
+  bb := TBits.RotateLeft32(bb, 14);
+  aa := aa + (data[5] + (bb xor cc xor dd));
+  aa := TBits.RotateLeft32(aa, 6);
+  dd := dd + (data[12] + (aa xor bb xor cc));
+  dd := TBits.RotateLeft32(dd, 9);
+  cc := cc + (data[2] + (dd xor aa xor bb));
+  cc := TBits.RotateLeft32(cc, 12);
+  bb := bb + (data[13] + (cc xor dd xor aa));
+  bb := TBits.RotateLeft32(bb, 9);
+  aa := aa + (data[9] + (bb xor cc xor dd));
+  aa := TBits.RotateLeft32(aa, 12);
+  dd := dd + (data[7] + (aa xor bb xor cc));
+  dd := TBits.RotateLeft32(dd, 5);
+  cc := cc + (data[10] + (dd xor aa xor bb));
+  cc := TBits.RotateLeft32(cc, 15);
+  bb := bb + (data[14] + (cc xor dd xor aa));
+  bb := TBits.RotateLeft32(bb, 8);
+
+  dd := dd + c + Fm_state[1];
+  Fm_state[1] := Fm_state[2] + d + aa;
+  Fm_state[2] := Fm_state[3] + a + bb;
+  Fm_state[3] := Fm_state[0] + b + cc;
+  Fm_state[0] := dd;
+
+  System.FillChar(data, System.SizeOf(data), 0);
+
+end;
+
+end.

+ 570 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpRIPEMD160.pas

@@ -0,0 +1,570 @@
+unit HlpRIPEMD160;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpMDBase,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpBits,
+  HlpConverters,
+  HlpIHashInfo;
+
+type
+  TRIPEMD160 = class sealed(TMDBase, ITransformBlock)
+
+  strict protected
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TRIPEMD160 }
+
+constructor TRIPEMD160.Create;
+begin
+  Inherited Create(5, 20);
+end;
+
+procedure TRIPEMD160.Initialize;
+begin
+  Fm_state[4] := $C3D2E1F0;
+
+  Inherited Initialize();
+
+end;
+
+procedure TRIPEMD160.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  a, b, c, d, e, aa, bb, cc, dd, ee: UInt32;
+  data: array [0 .. 15] of UInt32;
+begin
+
+  TConverters.le32_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+
+  a := Fm_state[0];
+  b := Fm_state[1];
+  c := Fm_state[2];
+  d := Fm_state[3];
+  e := Fm_state[4];
+  aa := a;
+  bb := b;
+  cc := c;
+  dd := d;
+  ee := e;
+
+  a := a + (data[0] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 11) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[1] + (a xor b xor c));
+  e := TBits.RotateLeft32(e, 14) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[2] + (e xor a xor b));
+  d := TBits.RotateLeft32(d, 15) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[3] + (d xor e xor a));
+  c := TBits.RotateLeft32(c, 12) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[4] + (c xor d xor e));
+  b := TBits.RotateLeft32(b, 5) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[5] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 8) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[6] + (a xor b xor c));
+  e := TBits.RotateLeft32(e, 7) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[7] + (e xor a xor b));
+  d := TBits.RotateLeft32(d, 9) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[8] + (d xor e xor a));
+  c := TBits.RotateLeft32(c, 11) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[9] + (c xor d xor e));
+  b := TBits.RotateLeft32(b, 13) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[10] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 14) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[11] + (a xor b xor c));
+  e := TBits.RotateLeft32(e, 15) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[12] + (e xor a xor b));
+  d := TBits.RotateLeft32(d, 6) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[13] + (d xor e xor a));
+  c := TBits.RotateLeft32(c, 7) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[14] + (c xor d xor e));
+  b := TBits.RotateLeft32(b, 9) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[15] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 8) + e;
+  c := TBits.RotateLeft32(c, 10);
+
+  aa := aa + (data[5] + C1 + (bb xor (cc or not dd)));
+  aa := TBits.RotateLeft32(aa, 8) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[14] + C1 + (aa xor (bb or not cc)));
+  ee := TBits.RotateLeft32(ee, 9) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[7] + C1 + (ee xor (aa or not bb)));
+  dd := TBits.RotateLeft32(dd, 9) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[0] + C1 + (dd xor (ee or not aa)));
+  cc := TBits.RotateLeft32(cc, 11) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[9] + C1 + (cc xor (dd or not ee)));
+  bb := TBits.RotateLeft32(bb, 13) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[2] + C1 + (bb xor (cc or not dd)));
+  aa := TBits.RotateLeft32(aa, 15) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[11] + C1 + (aa xor (bb or not cc)));
+  ee := TBits.RotateLeft32(ee, 15) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[4] + C1 + (ee xor (aa or not bb)));
+  dd := TBits.RotateLeft32(dd, 5) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[13] + C1 + (dd xor (ee or not aa)));
+  cc := TBits.RotateLeft32(cc, 7) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[6] + C1 + (cc xor (dd or not ee)));
+  bb := TBits.RotateLeft32(bb, 7) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[15] + C1 + (bb xor (cc or not dd)));
+  aa := TBits.RotateLeft32(aa, 8) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[8] + C1 + (aa xor (bb or not cc)));
+  ee := TBits.RotateLeft32(ee, 11) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[1] + C1 + (ee xor (aa or not bb)));
+  dd := TBits.RotateLeft32(dd, 14) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[10] + C1 + (dd xor (ee or not aa)));
+  cc := TBits.RotateLeft32(cc, 14) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[3] + C1 + (cc xor (dd or not ee)));
+  bb := TBits.RotateLeft32(bb, 12) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[12] + C1 + (bb xor (cc or not dd)));
+  aa := TBits.RotateLeft32(aa, 6) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+
+  e := e + (data[7] + C2 + ((a and b) or (not a and c)));
+  e := TBits.RotateLeft32(e, 7) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[4] + C2 + ((e and a) or (not e and b)));
+  d := TBits.RotateLeft32(d, 6) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[13] + C2 + ((d and e) or (not d and a)));
+  c := TBits.RotateLeft32(c, 8) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[1] + C2 + ((c and d) or (not c and e)));
+  b := TBits.RotateLeft32(b, 13) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[10] + C2 + ((b and c) or (not b and d)));
+  a := TBits.RotateLeft32(a, 11) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[6] + C2 + ((a and b) or (not a and c)));
+  e := TBits.RotateLeft32(e, 9) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[15] + C2 + ((e and a) or (not e and b)));
+  d := TBits.RotateLeft32(d, 7) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[3] + C2 + ((d and e) or (not d and a)));
+  c := TBits.RotateLeft32(c, 15) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[12] + C2 + ((c and d) or (not c and e)));
+  b := TBits.RotateLeft32(b, 7) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[0] + C2 + ((b and c) or (not b and d)));
+  a := TBits.RotateLeft32(a, 12) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[9] + C2 + ((a and b) or (not a and c)));
+  e := TBits.RotateLeft32(e, 15) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[5] + C2 + ((e and a) or (not e and b)));
+  d := TBits.RotateLeft32(d, 9) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[2] + C2 + ((d and e) or (not d and a)));
+  c := TBits.RotateLeft32(c, 11) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[14] + C2 + ((c and d) or (not c and e)));
+  b := TBits.RotateLeft32(b, 7) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[11] + C2 + ((b and c) or (not b and d)));
+  a := TBits.RotateLeft32(a, 13) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[8] + C2 + ((a and b) or (not a and c)));
+  e := TBits.RotateLeft32(e, 12) + d;
+  b := TBits.RotateLeft32(b, 10);
+
+  ee := ee + (data[6] + C3 + ((aa and cc) or (bb and not cc)));
+  ee := TBits.RotateLeft32(ee, 9) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[11] + C3 + ((ee and bb) or (aa and not bb)));
+  dd := TBits.RotateLeft32(dd, 13) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[3] + C3 + ((dd and aa) or (ee and not aa)));
+  cc := TBits.RotateLeft32(cc, 15) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[7] + C3 + ((cc and ee) or (dd and not ee)));
+  bb := TBits.RotateLeft32(bb, 7) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[0] + C3 + ((bb and dd) or (cc and not dd)));
+  aa := TBits.RotateLeft32(aa, 12) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[13] + C3 + ((aa and cc) or (bb and not cc)));
+  ee := TBits.RotateLeft32(ee, 8) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[5] + C3 + ((ee and bb) or (aa and not bb)));
+  dd := TBits.RotateLeft32(dd, 9) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[10] + C3 + ((dd and aa) or (ee and not aa)));
+  cc := TBits.RotateLeft32(cc, 11) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[14] + C3 + ((cc and ee) or (dd and not ee)));
+  bb := TBits.RotateLeft32(bb, 7) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[15] + C3 + ((bb and dd) or (cc and not dd)));
+  aa := TBits.RotateLeft32(aa, 7) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[8] + C3 + ((aa and cc) or (bb and not cc)));
+  ee := TBits.RotateLeft32(ee, 12) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[12] + C3 + ((ee and bb) or (aa and not bb)));
+  dd := TBits.RotateLeft32(dd, 7) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[4] + C3 + ((dd and aa) or (ee and not aa)));
+  cc := TBits.RotateLeft32(cc, 6) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[9] + C3 + ((cc and ee) or (dd and not ee)));
+  bb := TBits.RotateLeft32(bb, 15) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[1] + C3 + ((bb and dd) or (cc and not dd)));
+  aa := TBits.RotateLeft32(aa, 13) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[2] + C3 + ((aa and cc) or (bb and not cc)));
+  ee := TBits.RotateLeft32(ee, 11) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+
+  d := d + (data[3] + C4 + ((e or not a) xor b));
+  d := TBits.RotateLeft32(d, 11) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[10] + C4 + ((d or not e) xor a));
+  c := TBits.RotateLeft32(c, 13) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[14] + C4 + ((c or not d) xor e));
+  b := TBits.RotateLeft32(b, 6) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[4] + C4 + ((b or not c) xor d));
+  a := TBits.RotateLeft32(a, 7) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[9] + C4 + ((a or not b) xor c));
+  e := TBits.RotateLeft32(e, 14) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[15] + C4 + ((e or not a) xor b));
+  d := TBits.RotateLeft32(d, 9) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[8] + C4 + ((d or not e) xor a));
+  c := TBits.RotateLeft32(c, 13) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[1] + C4 + ((c or not d) xor e));
+  b := TBits.RotateLeft32(b, 15) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[2] + C4 + ((b or not c) xor d));
+  a := TBits.RotateLeft32(a, 14) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[7] + C4 + ((a or not b) xor c));
+  e := TBits.RotateLeft32(e, 8) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[0] + C4 + ((e or not a) xor b));
+  d := TBits.RotateLeft32(d, 13) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[6] + C4 + ((d or not e) xor a));
+  c := TBits.RotateLeft32(c, 6) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[13] + C4 + ((c or not d) xor e));
+  b := TBits.RotateLeft32(b, 5) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[11] + C4 + ((b or not c) xor d));
+  a := TBits.RotateLeft32(a, 12) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[5] + C4 + ((a or not b) xor c));
+  e := TBits.RotateLeft32(e, 7) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[12] + C4 + ((e or not a) xor b));
+  d := TBits.RotateLeft32(d, 5) + c;
+  a := TBits.RotateLeft32(a, 10);
+
+  dd := dd + (data[15] + C5 + ((ee or not aa) xor bb));
+  dd := TBits.RotateLeft32(dd, 9) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[5] + C5 + ((dd or not ee) xor aa));
+  cc := TBits.RotateLeft32(cc, 7) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[1] + C5 + ((cc or not dd) xor ee));
+  bb := TBits.RotateLeft32(bb, 15) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[3] + C5 + ((bb or not cc) xor dd));
+  aa := TBits.RotateLeft32(aa, 11) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[7] + C5 + ((aa or not bb) xor cc));
+  ee := TBits.RotateLeft32(ee, 8) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[14] + C5 + ((ee or not aa) xor bb));
+  dd := TBits.RotateLeft32(dd, 6) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[6] + C5 + ((dd or not ee) xor aa));
+  cc := TBits.RotateLeft32(cc, 6) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[9] + C5 + ((cc or not dd) xor ee));
+  bb := TBits.RotateLeft32(bb, 14) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[11] + C5 + ((bb or not cc) xor dd));
+  aa := TBits.RotateLeft32(aa, 12) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[8] + C5 + ((aa or not bb) xor cc));
+  ee := TBits.RotateLeft32(ee, 13) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[12] + C5 + ((ee or not aa) xor bb));
+  dd := TBits.RotateLeft32(dd, 5) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[2] + C5 + ((dd or not ee) xor aa));
+  cc := TBits.RotateLeft32(cc, 14) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[10] + C5 + ((cc or not dd) xor ee));
+  bb := TBits.RotateLeft32(bb, 13) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[0] + C5 + ((bb or not cc) xor dd));
+  aa := TBits.RotateLeft32(aa, 13) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[4] + C5 + ((aa or not bb) xor cc));
+  ee := TBits.RotateLeft32(ee, 7) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[13] + C5 + ((ee or not aa) xor bb));
+  dd := TBits.RotateLeft32(dd, 5) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+
+  c := c + (data[1] + C6 + ((d and a) or (e and not a)));
+  c := TBits.RotateLeft32(c, 11) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[9] + C6 + ((c and e) or (d and not e)));
+  b := TBits.RotateLeft32(b, 12) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[11] + C6 + ((b and d) or (c and not d)));
+  a := TBits.RotateLeft32(a, 14) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[10] + C6 + ((a and c) or (b and not c)));
+  e := TBits.RotateLeft32(e, 15) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[0] + C6 + ((e and b) or (a and not b)));
+  d := TBits.RotateLeft32(d, 14) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[8] + C6 + ((d and a) or (e and not a)));
+  c := TBits.RotateLeft32(c, 15) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[12] + C6 + ((c and e) or (d and not e)));
+  b := TBits.RotateLeft32(b, 9) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[4] + C6 + ((b and d) or (c and not d)));
+  a := TBits.RotateLeft32(a, 8) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[13] + C6 + ((a and c) or (b and not c)));
+  e := TBits.RotateLeft32(e, 9) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[3] + C6 + ((e and b) or (a and not b)));
+  d := TBits.RotateLeft32(d, 14) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[7] + C6 + ((d and a) or (e and not a)));
+  c := TBits.RotateLeft32(c, 5) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[15] + C6 + ((c and e) or (d and not e)));
+  b := TBits.RotateLeft32(b, 6) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[14] + C6 + ((b and d) or (c and not d)));
+  a := TBits.RotateLeft32(a, 8) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[5] + C6 + ((a and c) or (b and not c)));
+  e := TBits.RotateLeft32(e, 6) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[6] + C6 + ((e and b) or (a and not b)));
+  d := TBits.RotateLeft32(d, 5) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[2] + C6 + ((d and a) or (e and not a)));
+  c := TBits.RotateLeft32(c, 12) + b;
+  e := TBits.RotateLeft32(e, 10);
+
+  cc := cc + (data[8] + C7 + ((dd and ee) or (not dd and aa)));
+  cc := TBits.RotateLeft32(cc, 15) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[6] + C7 + ((cc and dd) or (not cc and ee)));
+  bb := TBits.RotateLeft32(bb, 5) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[4] + C7 + ((bb and cc) or (not bb and dd)));
+  aa := TBits.RotateLeft32(aa, 8) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[1] + C7 + ((aa and bb) or (not aa and cc)));
+  ee := TBits.RotateLeft32(ee, 11) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[3] + C7 + ((ee and aa) or (not ee and bb)));
+  dd := TBits.RotateLeft32(dd, 14) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[11] + C7 + ((dd and ee) or (not dd and aa)));
+  cc := TBits.RotateLeft32(cc, 14) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[15] + C7 + ((cc and dd) or (not cc and ee)));
+  bb := TBits.RotateLeft32(bb, 6) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[0] + C7 + ((bb and cc) or (not bb and dd)));
+  aa := TBits.RotateLeft32(aa, 14) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[5] + C7 + ((aa and bb) or (not aa and cc)));
+  ee := TBits.RotateLeft32(ee, 6) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[12] + C7 + ((ee and aa) or (not ee and bb)));
+  dd := TBits.RotateLeft32(dd, 9) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[2] + C7 + ((dd and ee) or (not dd and aa)));
+  cc := TBits.RotateLeft32(cc, 12) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[13] + C7 + ((cc and dd) or (not cc and ee)));
+  bb := TBits.RotateLeft32(bb, 9) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[9] + C7 + ((bb and cc) or (not bb and dd)));
+  aa := TBits.RotateLeft32(aa, 12) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[7] + C7 + ((aa and bb) or (not aa and cc)));
+  ee := TBits.RotateLeft32(ee, 5) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[10] + C7 + ((ee and aa) or (not ee and bb)));
+  dd := TBits.RotateLeft32(dd, 15) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[14] + C7 + ((dd and ee) or (not dd and aa)));
+  cc := TBits.RotateLeft32(cc, 8) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+
+  b := b + (data[4] + C8 + (c xor (d or not e)));
+  b := TBits.RotateLeft32(b, 9) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[0] + C8 + (b xor (c or not d)));
+  a := TBits.RotateLeft32(a, 15) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[5] + C8 + (a xor (b or not c)));
+  e := TBits.RotateLeft32(e, 5) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[9] + C8 + (e xor (a or not b)));
+  d := TBits.RotateLeft32(d, 11) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[7] + C8 + (d xor (e or not a)));
+  c := TBits.RotateLeft32(c, 6) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[12] + C8 + (c xor (d or not e)));
+  b := TBits.RotateLeft32(b, 8) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[2] + C8 + (b xor (c or not d)));
+  a := TBits.RotateLeft32(a, 13) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[10] + C8 + (a xor (b or not c)));
+  e := TBits.RotateLeft32(e, 12) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[14] + C8 + (e xor (a or not b)));
+  d := TBits.RotateLeft32(d, 5) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[1] + C8 + (d xor (e or not a)));
+  c := TBits.RotateLeft32(c, 12) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[3] + C8 + (c xor (d or not e)));
+  b := TBits.RotateLeft32(b, 13) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[8] + C8 + (b xor (c or not d)));
+  a := TBits.RotateLeft32(a, 14) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[11] + C8 + (a xor (b or not c)));
+  e := TBits.RotateLeft32(e, 11) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[6] + C8 + (e xor (a or not b)));
+  d := TBits.RotateLeft32(d, 8) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[15] + C8 + (d xor (e or not a)));
+  c := TBits.RotateLeft32(c, 5) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[13] + C8 + (c xor (d or not e)));
+  b := TBits.RotateLeft32(b, 6) + a;
+  d := TBits.RotateLeft32(d, 10);
+
+  bb := bb + (data[12] + (cc xor dd xor ee));
+  bb := TBits.RotateLeft32(bb, 8) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[15] + (bb xor cc xor dd));
+  aa := TBits.RotateLeft32(aa, 5) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[10] + (aa xor bb xor cc));
+  ee := TBits.RotateLeft32(ee, 12) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[4] + (ee xor aa xor bb));
+  dd := TBits.RotateLeft32(dd, 9) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[1] + (dd xor ee xor aa));
+  cc := TBits.RotateLeft32(cc, 12) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[5] + (cc xor dd xor ee));
+  bb := TBits.RotateLeft32(bb, 5) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[8] + (bb xor cc xor dd));
+  aa := TBits.RotateLeft32(aa, 14) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[7] + (aa xor bb xor cc));
+  ee := TBits.RotateLeft32(ee, 6) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[6] + (ee xor aa xor bb));
+  dd := TBits.RotateLeft32(dd, 8) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[2] + (dd xor ee xor aa));
+  cc := TBits.RotateLeft32(cc, 13) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[13] + (cc xor dd xor ee));
+  bb := TBits.RotateLeft32(bb, 6) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[14] + (bb xor cc xor dd));
+  aa := TBits.RotateLeft32(aa, 5) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[0] + (aa xor bb xor cc));
+  ee := TBits.RotateLeft32(ee, 15) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[3] + (ee xor aa xor bb));
+  dd := TBits.RotateLeft32(dd, 13) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[9] + (dd xor ee xor aa));
+  cc := TBits.RotateLeft32(cc, 11) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[11] + (cc xor dd xor ee));
+  bb := TBits.RotateLeft32(bb, 11) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+
+  dd := dd + c + Fm_state[1];
+  Fm_state[1] := Fm_state[2] + d + ee;
+  Fm_state[2] := Fm_state[3] + e + aa;
+  Fm_state[3] := Fm_state[4] + a + bb;
+  Fm_state[4] := Fm_state[0] + b + cc;
+  Fm_state[0] := dd;
+
+  System.FillChar(data, System.SizeOf(data), 0);
+
+end;
+
+end.

+ 347 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpRIPEMD256.pas

@@ -0,0 +1,347 @@
+unit HlpRIPEMD256;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpMDBase,
+  HlpBits,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpConverters,
+  HlpIHashInfo;
+
+type
+  TRIPEMD256 = class sealed(TMDBase, ITransformBlock)
+
+  strict protected
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TRIPEMD256 }
+
+constructor TRIPEMD256.Create;
+begin
+  Inherited Create(8, 32);
+end;
+
+procedure TRIPEMD256.Initialize;
+begin
+  Fm_state[4] := $76543210;
+  Fm_state[5] := $FEDCBA98;
+  Fm_state[6] := $89ABCDEF;
+  Fm_state[7] := $01234567;
+
+  Inherited Initialize();
+
+end;
+
+procedure TRIPEMD256.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  a, b, c, d, aa, bb, cc, dd: UInt32;
+  data: array [0 .. 15] of UInt32;
+begin
+
+  TConverters.le32_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+
+  a := Fm_state[0];
+  b := Fm_state[1];
+  c := Fm_state[2];
+  d := Fm_state[3];
+  aa := Fm_state[4];
+  bb := Fm_state[5];
+  cc := Fm_state[6];
+  dd := Fm_state[7];
+
+  a := a + (data[0] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 11);
+  d := d + (data[1] + (a xor b xor c));
+  d := TBits.RotateLeft32(d, 14);
+  c := c + (data[2] + (d xor a xor b));
+  c := TBits.RotateLeft32(c, 15);
+  b := b + (data[3] + (c xor d xor a));
+  b := TBits.RotateLeft32(b, 12);
+  a := a + (data[4] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 5);
+  d := d + (data[5] + (a xor b xor c));
+  d := TBits.RotateLeft32(d, 8);
+  c := c + (data[6] + (d xor a xor b));
+  c := TBits.RotateLeft32(c, 7);
+  b := b + (data[7] + (c xor d xor a));
+  b := TBits.RotateLeft32(b, 9);
+  a := a + (data[8] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 11);
+  d := d + (data[9] + (a xor b xor c));
+  d := TBits.RotateLeft32(d, 13);
+  c := c + (data[10] + (d xor a xor b));
+  c := TBits.RotateLeft32(c, 14);
+  b := b + (data[11] + (c xor d xor a));
+  b := TBits.RotateLeft32(b, 15);
+  a := a + (data[12] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 6);
+  d := d + (data[13] + (a xor b xor c));
+  d := TBits.RotateLeft32(d, 7);
+  c := c + (data[14] + (d xor a xor b));
+  c := TBits.RotateLeft32(c, 9);
+  b := b + (data[15] + (c xor d xor a));
+  b := TBits.RotateLeft32(b, 8);
+
+  aa := aa + (data[5] + C1 + ((bb and dd) or (cc and not dd)));
+  aa := TBits.RotateLeft32(aa, 8);
+  dd := dd + (data[14] + C1 + ((aa and cc) or (bb and not cc)));
+  dd := TBits.RotateLeft32(dd, 9);
+  cc := cc + (data[7] + C1 + ((dd and bb) or (aa and not bb)));
+  cc := TBits.RotateLeft32(cc, 9);
+  bb := bb + (data[0] + C1 + ((cc and aa) or (dd and not aa)));
+  bb := TBits.RotateLeft32(bb, 11);
+  aa := aa + (data[9] + C1 + ((bb and dd) or (cc and not dd)));
+  aa := TBits.RotateLeft32(aa, 13);
+  dd := dd + (data[2] + C1 + ((aa and cc) or (bb and not cc)));
+  dd := TBits.RotateLeft32(dd, 15);
+  cc := cc + (data[11] + C1 + ((dd and bb) or (aa and not bb)));
+  cc := TBits.RotateLeft32(cc, 15);
+  bb := bb + (data[4] + C1 + ((cc and aa) or (dd and not aa)));
+  bb := TBits.RotateLeft32(bb, 5);
+  aa := aa + (data[13] + C1 + ((bb and dd) or (cc and not dd)));
+  aa := TBits.RotateLeft32(aa, 7);
+  dd := dd + (data[6] + C1 + ((aa and cc) or (bb and not cc)));
+  dd := TBits.RotateLeft32(dd, 7);
+  cc := cc + (data[15] + C1 + ((dd and bb) or (aa and not bb)));
+  cc := TBits.RotateLeft32(cc, 8);
+  bb := bb + (data[8] + C1 + ((cc and aa) or (dd and not aa)));
+  bb := TBits.RotateLeft32(bb, 11);
+  aa := aa + (data[1] + C1 + ((bb and dd) or (cc and not dd)));
+  aa := TBits.RotateLeft32(aa, 14);
+  dd := dd + (data[10] + C1 + ((aa and cc) or (bb and not cc)));
+  dd := TBits.RotateLeft32(dd, 14);
+  cc := cc + (data[3] + C1 + ((dd and bb) or (aa and not bb)));
+  cc := TBits.RotateLeft32(cc, 12);
+  bb := bb + (data[12] + C1 + ((cc and aa) or (dd and not aa)));
+  bb := TBits.RotateLeft32(bb, 6);
+
+  aa := aa + (data[7] + C2 + ((b and c) or (not b and d)));
+  aa := TBits.RotateLeft32(aa, 7);
+  d := d + (data[4] + C2 + ((aa and b) or (not aa and c)));
+  d := TBits.RotateLeft32(d, 6);
+  c := c + (data[13] + C2 + ((d and aa) or (not d and b)));
+  c := TBits.RotateLeft32(c, 8);
+  b := b + (data[1] + C2 + ((c and d) or (not c and aa)));
+  b := TBits.RotateLeft32(b, 13);
+  aa := aa + (data[10] + C2 + ((b and c) or (not b and d)));
+  aa := TBits.RotateLeft32(aa, 11);
+  d := d + (data[6] + C2 + ((aa and b) or (not aa and c)));
+  d := TBits.RotateLeft32(d, 9);
+  c := c + (data[15] + C2 + ((d and aa) or (not d and b)));
+  c := TBits.RotateLeft32(c, 7);
+  b := b + (data[3] + C2 + ((c and d) or (not c and aa)));
+  b := TBits.RotateLeft32(b, 15);
+  aa := aa + (data[12] + C2 + ((b and c) or (not b and d)));
+  aa := TBits.RotateLeft32(aa, 7);
+  d := d + (data[0] + C2 + ((aa and b) or (not aa and c)));
+  d := TBits.RotateLeft32(d, 12);
+  c := c + (data[9] + C2 + ((d and aa) or (not d and b)));
+  c := TBits.RotateLeft32(c, 15);
+  b := b + (data[5] + C2 + ((c and d) or (not c and aa)));
+  b := TBits.RotateLeft32(b, 9);
+  aa := aa + (data[2] + C2 + ((b and c) or (not b and d)));
+  aa := TBits.RotateLeft32(aa, 11);
+  d := d + (data[14] + C2 + ((aa and b) or (not aa and c)));
+  d := TBits.RotateLeft32(d, 7);
+  c := c + (data[11] + C2 + ((d and aa) or (not d and b)));
+  c := TBits.RotateLeft32(c, 13);
+  b := b + (data[8] + C2 + ((c and d) or (not c and aa)));
+  b := TBits.RotateLeft32(b, 12);
+
+  a := a + (data[6] + C3 + ((bb or not cc) xor dd));
+  a := TBits.RotateLeft32(a, 9);
+  dd := dd + (data[11] + C3 + ((a or not bb) xor cc));
+  dd := TBits.RotateLeft32(dd, 13);
+  cc := cc + (data[3] + C3 + ((dd or not a) xor bb));
+  cc := TBits.RotateLeft32(cc, 15);
+  bb := bb + (data[7] + C3 + ((cc or not dd) xor a));
+  bb := TBits.RotateLeft32(bb, 7);
+  a := a + (data[0] + C3 + ((bb or not cc) xor dd));
+  a := TBits.RotateLeft32(a, 12);
+  dd := dd + (data[13] + C3 + ((a or not bb) xor cc));
+  dd := TBits.RotateLeft32(dd, 8);
+  cc := cc + (data[5] + C3 + ((dd or not a) xor bb));
+  cc := TBits.RotateLeft32(cc, 9);
+  bb := bb + (data[10] + C3 + ((cc or not dd) xor a));
+  bb := TBits.RotateLeft32(bb, 11);
+  a := a + (data[14] + C3 + ((bb or not cc) xor dd));
+  a := TBits.RotateLeft32(a, 7);
+  dd := dd + (data[15] + C3 + ((a or not bb) xor cc));
+  dd := TBits.RotateLeft32(dd, 7);
+  cc := cc + (data[8] + C3 + ((dd or not a) xor bb));
+  cc := TBits.RotateLeft32(cc, 12);
+  bb := bb + (data[12] + C3 + ((cc or not dd) xor a));
+  bb := TBits.RotateLeft32(bb, 7);
+  a := a + (data[4] + C3 + ((bb or not cc) xor dd));
+  a := TBits.RotateLeft32(a, 6);
+  dd := dd + (data[9] + C3 + ((a or not bb) xor cc));
+  dd := TBits.RotateLeft32(dd, 15);
+  cc := cc + (data[1] + C3 + ((dd or not a) xor bb));
+  cc := TBits.RotateLeft32(cc, 13);
+  bb := bb + (data[2] + C3 + ((cc or not dd) xor a));
+  bb := TBits.RotateLeft32(bb, 11);
+
+  aa := aa + (data[3] + C4 + ((bb or not c) xor d));
+  aa := TBits.RotateLeft32(aa, 11);
+  d := d + (data[10] + C4 + ((aa or not bb) xor c));
+  d := TBits.RotateLeft32(d, 13);
+  c := c + (data[14] + C4 + ((d or not aa) xor bb));
+  c := TBits.RotateLeft32(c, 6);
+  bb := bb + (data[4] + C4 + ((c or not d) xor aa));
+  bb := TBits.RotateLeft32(bb, 7);
+  aa := aa + (data[9] + C4 + ((bb or not c) xor d));
+  aa := TBits.RotateLeft32(aa, 14);
+  d := d + (data[15] + C4 + ((aa or not bb) xor c));
+  d := TBits.RotateLeft32(d, 9);
+  c := c + (data[8] + C4 + ((d or not aa) xor bb));
+  c := TBits.RotateLeft32(c, 13);
+  bb := bb + (data[1] + C4 + ((c or not d) xor aa));
+  bb := TBits.RotateLeft32(bb, 15);
+  aa := aa + (data[2] + C4 + ((bb or not c) xor d));
+  aa := TBits.RotateLeft32(aa, 14);
+  d := d + (data[7] + C4 + ((aa or not bb) xor c));
+  d := TBits.RotateLeft32(d, 8);
+  c := c + (data[0] + C4 + ((d or not aa) xor bb));
+  c := TBits.RotateLeft32(c, 13);
+  bb := bb + (data[6] + C4 + ((c or not d) xor aa));
+  bb := TBits.RotateLeft32(bb, 6);
+  aa := aa + (data[13] + C4 + ((bb or not c) xor d));
+  aa := TBits.RotateLeft32(aa, 5);
+  d := d + (data[11] + C4 + ((aa or not bb) xor c));
+  d := TBits.RotateLeft32(d, 12);
+  c := c + (data[5] + C4 + ((d or not aa) xor bb));
+  c := TBits.RotateLeft32(c, 7);
+  bb := bb + (data[12] + C4 + ((c or not d) xor aa));
+  bb := TBits.RotateLeft32(bb, 5);
+
+  a := a + (data[15] + C5 + ((b and cc) or (not b and dd)));
+  a := TBits.RotateLeft32(a, 9);
+  dd := dd + (data[5] + C5 + ((a and b) or (not a and cc)));
+  dd := TBits.RotateLeft32(dd, 7);
+  cc := cc + (data[1] + C5 + ((dd and a) or (not dd and b)));
+  cc := TBits.RotateLeft32(cc, 15);
+  b := b + (data[3] + C5 + ((cc and dd) or (not cc and a)));
+  b := TBits.RotateLeft32(b, 11);
+  a := a + (data[7] + C5 + ((b and cc) or (not b and dd)));
+  a := TBits.RotateLeft32(a, 8);
+  dd := dd + (data[14] + C5 + ((a and b) or (not a and cc)));
+  dd := TBits.RotateLeft32(dd, 6);
+  cc := cc + (data[6] + C5 + ((dd and a) or (not dd and b)));
+  cc := TBits.RotateLeft32(cc, 6);
+  b := b + (data[9] + C5 + ((cc and dd) or (not cc and a)));
+  b := TBits.RotateLeft32(b, 14);
+  a := a + (data[11] + C5 + ((b and cc) or (not b and dd)));
+  a := TBits.RotateLeft32(a, 12);
+  dd := dd + (data[8] + C5 + ((a and b) or (not a and cc)));
+  dd := TBits.RotateLeft32(dd, 13);
+  cc := cc + (data[12] + C5 + ((dd and a) or (not dd and b)));
+  cc := TBits.RotateLeft32(cc, 5);
+  b := b + (data[2] + C5 + ((cc and dd) or (not cc and a)));
+  b := TBits.RotateLeft32(b, 14);
+  a := a + (data[10] + C5 + ((b and cc) or (not b and dd)));
+  a := TBits.RotateLeft32(a, 13);
+  dd := dd + (data[0] + C5 + ((a and b) or (not a and cc)));
+  dd := TBits.RotateLeft32(dd, 13);
+  cc := cc + (data[4] + C5 + ((dd and a) or (not dd and b)));
+  cc := TBits.RotateLeft32(cc, 7);
+  b := b + (data[13] + C5 + ((cc and dd) or (not cc and a)));
+  b := TBits.RotateLeft32(b, 5);
+
+  aa := aa + (data[1] + C6 + ((bb and d) or (cc and not d)));
+  aa := TBits.RotateLeft32(aa, 11);
+  d := d + (data[9] + C6 + ((aa and cc) or (bb and not cc)));
+  d := TBits.RotateLeft32(d, 12);
+  cc := cc + (data[11] + C6 + ((d and bb) or (aa and not bb)));
+  cc := TBits.RotateLeft32(cc, 14);
+  bb := bb + (data[10] + C6 + ((cc and aa) or (d and not aa)));
+  bb := TBits.RotateLeft32(bb, 15);
+  aa := aa + (data[0] + C6 + ((bb and d) or (cc and not d)));
+  aa := TBits.RotateLeft32(aa, 14);
+  d := d + (data[8] + C6 + ((aa and cc) or (bb and not cc)));
+  d := TBits.RotateLeft32(d, 15);
+  cc := cc + (data[12] + C6 + ((d and bb) or (aa and not bb)));
+  cc := TBits.RotateLeft32(cc, 9);
+  bb := bb + (data[4] + C6 + ((cc and aa) or (d and not aa)));
+  bb := TBits.RotateLeft32(bb, 8);
+  aa := aa + (data[13] + C6 + ((bb and d) or (cc and not d)));
+  aa := TBits.RotateLeft32(aa, 9);
+  d := d + (data[3] + C6 + ((aa and cc) or (bb and not cc)));
+  d := TBits.RotateLeft32(d, 14);
+  cc := cc + (data[7] + C6 + ((d and bb) or (aa and not bb)));
+  cc := TBits.RotateLeft32(cc, 5);
+  bb := bb + (data[15] + C6 + ((cc and aa) or (d and not aa)));
+  bb := TBits.RotateLeft32(bb, 6);
+  aa := aa + (data[14] + C6 + ((bb and d) or (cc and not d)));
+  aa := TBits.RotateLeft32(aa, 8);
+  d := d + (data[5] + C6 + ((aa and cc) or (bb and not cc)));
+  d := TBits.RotateLeft32(d, 6);
+  cc := cc + (data[6] + C6 + ((d and bb) or (aa and not bb)));
+  cc := TBits.RotateLeft32(cc, 5);
+  bb := bb + (data[2] + C6 + ((cc and aa) or (d and not aa)));
+  bb := TBits.RotateLeft32(bb, 12);
+
+  a := a + (data[8] + (b xor c xor dd));
+  a := TBits.RotateLeft32(a, 15);
+  dd := dd + (data[6] + (a xor b xor c));
+  dd := TBits.RotateLeft32(dd, 5);
+  c := c + (data[4] + (dd xor a xor b));
+  c := TBits.RotateLeft32(c, 8);
+  b := b + (data[1] + (c xor dd xor a));
+  b := TBits.RotateLeft32(b, 11);
+  a := a + (data[3] + (b xor c xor dd));
+  a := TBits.RotateLeft32(a, 14);
+  dd := dd + (data[11] + (a xor b xor c));
+  dd := TBits.RotateLeft32(dd, 14);
+  c := c + (data[15] + (dd xor a xor b));
+  c := TBits.RotateLeft32(c, 6);
+  b := b + (data[0] + (c xor dd xor a));
+  b := TBits.RotateLeft32(b, 14);
+  a := a + (data[5] + (b xor c xor dd));
+  a := TBits.RotateLeft32(a, 6);
+  dd := dd + (data[12] + (a xor b xor c));
+  dd := TBits.RotateLeft32(dd, 9);
+  c := c + (data[2] + (dd xor a xor b));
+  c := TBits.RotateLeft32(c, 12);
+  b := b + (data[13] + (c xor dd xor a));
+  b := TBits.RotateLeft32(b, 9);
+  a := a + (data[9] + (b xor c xor dd));
+  a := TBits.RotateLeft32(a, 12);
+  dd := dd + (data[7] + (a xor b xor c));
+  dd := TBits.RotateLeft32(dd, 5);
+  c := c + (data[10] + (dd xor a xor b));
+  c := TBits.RotateLeft32(c, 15);
+  b := b + (data[14] + (c xor dd xor a));
+  b := TBits.RotateLeft32(b, 8);
+
+  Fm_state[0] := Fm_state[0] + aa;
+  Fm_state[1] := Fm_state[1] + bb;
+  Fm_state[2] := Fm_state[2] + cc;
+  Fm_state[3] := Fm_state[3] + dd;
+  Fm_state[4] := Fm_state[4] + a;
+  Fm_state[5] := Fm_state[5] + b;
+  Fm_state[6] := Fm_state[6] + c;
+  Fm_state[7] := Fm_state[7] + d;
+
+  System.FillChar(data, System.SizeOf(data), 0);
+
+end;
+
+end.

+ 579 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpRIPEMD320.pas

@@ -0,0 +1,579 @@
+unit HlpRIPEMD320;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpMDBase,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpBits,
+  HlpConverters,
+  HlpIHashInfo;
+
+type
+  TRIPEMD320 = class sealed(TMDBase, ITransformBlock)
+
+  strict protected
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TRIPEMD320 }
+
+constructor TRIPEMD320.Create;
+begin
+  Inherited Create(10, 40);
+end;
+
+procedure TRIPEMD320.Initialize;
+begin
+  Fm_state[4] := $C3D2E1F0;
+  Fm_state[5] := $76543210;
+  Fm_state[6] := $FEDCBA98;
+  Fm_state[7] := $89ABCDEF;
+  Fm_state[8] := $01234567;
+  Fm_state[9] := $3C2D1E0F;
+
+  Inherited Initialize();
+
+end;
+
+procedure TRIPEMD320.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  a, b, c, d, e, aa, bb, cc, dd, ee: UInt32;
+  data: array [0 .. 15] of UInt32;
+begin
+
+  TConverters.le32_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+
+  a := Fm_state[0];
+  b := Fm_state[1];
+  c := Fm_state[2];
+  d := Fm_state[3];
+  e := Fm_state[4];
+  aa := Fm_state[5];
+  bb := Fm_state[6];
+  cc := Fm_state[7];
+  dd := Fm_state[8];
+  ee := Fm_state[9];
+
+  a := a + (data[0] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 11) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[1] + (a xor b xor c));
+  e := TBits.RotateLeft32(e, 14) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[2] + (e xor a xor b));
+  d := TBits.RotateLeft32(d, 15) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[3] + (d xor e xor a));
+  c := TBits.RotateLeft32(c, 12) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[4] + (c xor d xor e));
+  b := TBits.RotateLeft32(b, 5) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[5] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 8) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[6] + (a xor b xor c));
+  e := TBits.RotateLeft32(e, 7) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[7] + (e xor a xor b));
+  d := TBits.RotateLeft32(d, 9) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[8] + (d xor e xor a));
+  c := TBits.RotateLeft32(c, 11) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[9] + (c xor d xor e));
+  b := TBits.RotateLeft32(b, 13) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[10] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 14) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[11] + (a xor b xor c));
+  e := TBits.RotateLeft32(e, 15) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[12] + (e xor a xor b));
+  d := TBits.RotateLeft32(d, 6) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[13] + (d xor e xor a));
+  c := TBits.RotateLeft32(c, 7) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[14] + (c xor d xor e));
+  b := TBits.RotateLeft32(b, 9) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[15] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 8) + e;
+  c := TBits.RotateLeft32(c, 10);
+
+  aa := aa + (data[5] + C1 + (bb xor (cc or not dd)));
+  aa := TBits.RotateLeft32(aa, 8) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[14] + C1 + (aa xor (bb or not cc)));
+  ee := TBits.RotateLeft32(ee, 9) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[7] + C1 + (ee xor (aa or not bb)));
+  dd := TBits.RotateLeft32(dd, 9) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[0] + C1 + (dd xor (ee or not aa)));
+  cc := TBits.RotateLeft32(cc, 11) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[9] + C1 + (cc xor (dd or not ee)));
+  bb := TBits.RotateLeft32(bb, 13) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[2] + C1 + (bb xor (cc or not dd)));
+  aa := TBits.RotateLeft32(aa, 15) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[11] + C1 + (aa xor (bb or not cc)));
+  ee := TBits.RotateLeft32(ee, 15) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[4] + C1 + (ee xor (aa or not bb)));
+  dd := TBits.RotateLeft32(dd, 5) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[13] + C1 + (dd xor (ee or not aa)));
+  cc := TBits.RotateLeft32(cc, 7) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[6] + C1 + (cc xor (dd or not ee)));
+  bb := TBits.RotateLeft32(bb, 7) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[15] + C1 + (bb xor (cc or not dd)));
+  aa := TBits.RotateLeft32(aa, 8) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[8] + C1 + (aa xor (bb or not cc)));
+  ee := TBits.RotateLeft32(ee, 11) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[1] + C1 + (ee xor (aa or not bb)));
+  dd := TBits.RotateLeft32(dd, 14) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[10] + C1 + (dd xor (ee or not aa)));
+  cc := TBits.RotateLeft32(cc, 14) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[3] + C1 + (cc xor (dd or not ee)));
+  bb := TBits.RotateLeft32(bb, 12) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[12] + C1 + (bb xor (cc or not dd)));
+  aa := TBits.RotateLeft32(aa, 6) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+
+  e := e + (data[7] + C2 + ((aa and b) or (not aa and c)));
+  e := TBits.RotateLeft32(e, 7) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[4] + C2 + ((e and aa) or (not e and b)));
+  d := TBits.RotateLeft32(d, 6) + c;
+  aa := TBits.RotateLeft32(aa, 10);
+  c := c + (data[13] + C2 + ((d and e) or (not d and aa)));
+  c := TBits.RotateLeft32(c, 8) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[1] + C2 + ((c and d) or (not c and e)));
+  b := TBits.RotateLeft32(b, 13) + aa;
+  d := TBits.RotateLeft32(d, 10);
+  aa := aa + (data[10] + C2 + ((b and c) or (not b and d)));
+  aa := TBits.RotateLeft32(aa, 11) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[6] + C2 + ((aa and b) or (not aa and c)));
+  e := TBits.RotateLeft32(e, 9) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[15] + C2 + ((e and aa) or (not e and b)));
+  d := TBits.RotateLeft32(d, 7) + c;
+  aa := TBits.RotateLeft32(aa, 10);
+  c := c + (data[3] + C2 + ((d and e) or (not d and aa)));
+  c := TBits.RotateLeft32(c, 15) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[12] + C2 + ((c and d) or (not c and e)));
+  b := TBits.RotateLeft32(b, 7) + aa;
+  d := TBits.RotateLeft32(d, 10);
+  aa := aa + (data[0] + C2 + ((b and c) or (not b and d)));
+  aa := TBits.RotateLeft32(aa, 12) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[9] + C2 + ((aa and b) or (not aa and c)));
+  e := TBits.RotateLeft32(e, 15) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[5] + C2 + ((e and aa) or (not e and b)));
+  d := TBits.RotateLeft32(d, 9) + c;
+  aa := TBits.RotateLeft32(aa, 10);
+  c := c + (data[2] + C2 + ((d and e) or (not d and aa)));
+  c := TBits.RotateLeft32(c, 11) + b;
+  e := TBits.RotateLeft32(e, 10);
+  b := b + (data[14] + C2 + ((c and d) or (not c and e)));
+  b := TBits.RotateLeft32(b, 7) + aa;
+  d := TBits.RotateLeft32(d, 10);
+  aa := aa + (data[11] + C2 + ((b and c) or (not b and d)));
+  aa := TBits.RotateLeft32(aa, 13) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[8] + C2 + ((aa and b) or (not aa and c)));
+  e := TBits.RotateLeft32(e, 12) + d;
+  b := TBits.RotateLeft32(b, 10);
+
+  ee := ee + (data[6] + C3 + ((a and cc) or (bb and not cc)));
+  ee := TBits.RotateLeft32(ee, 9) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[11] + C3 + ((ee and bb) or (a and not bb)));
+  dd := TBits.RotateLeft32(dd, 13) + cc;
+  a := TBits.RotateLeft32(a, 10);
+  cc := cc + (data[3] + C3 + ((dd and a) or (ee and not a)));
+  cc := TBits.RotateLeft32(cc, 15) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[7] + C3 + ((cc and ee) or (dd and not ee)));
+  bb := TBits.RotateLeft32(bb, 7) + a;
+  dd := TBits.RotateLeft32(dd, 10);
+  a := a + (data[0] + C3 + ((bb and dd) or (cc and not dd)));
+  a := TBits.RotateLeft32(a, 12) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[13] + C3 + ((a and cc) or (bb and not cc)));
+  ee := TBits.RotateLeft32(ee, 8) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[5] + C3 + ((ee and bb) or (a and not bb)));
+  dd := TBits.RotateLeft32(dd, 9) + cc;
+  a := TBits.RotateLeft32(a, 10);
+  cc := cc + (data[10] + C3 + ((dd and a) or (ee and not a)));
+  cc := TBits.RotateLeft32(cc, 11) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[14] + C3 + ((cc and ee) or (dd and not ee)));
+  bb := TBits.RotateLeft32(bb, 7) + a;
+  dd := TBits.RotateLeft32(dd, 10);
+  a := a + (data[15] + C3 + ((bb and dd) or (cc and not dd)));
+  a := TBits.RotateLeft32(a, 7) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[8] + C3 + ((a and cc) or (bb and not cc)));
+  ee := TBits.RotateLeft32(ee, 12) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[12] + C3 + ((ee and bb) or (a and not bb)));
+  dd := TBits.RotateLeft32(dd, 7) + cc;
+  a := TBits.RotateLeft32(a, 10);
+  cc := cc + (data[4] + C3 + ((dd and a) or (ee and not a)));
+  cc := TBits.RotateLeft32(cc, 6) + bb;
+  ee := TBits.RotateLeft32(ee, 10);
+  bb := bb + (data[9] + C3 + ((cc and ee) or (dd and not ee)));
+  bb := TBits.RotateLeft32(bb, 15) + a;
+  dd := TBits.RotateLeft32(dd, 10);
+  a := a + (data[1] + C3 + ((bb and dd) or (cc and not dd)));
+  a := TBits.RotateLeft32(a, 13) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[2] + C3 + ((a and cc) or (bb and not cc)));
+  ee := TBits.RotateLeft32(ee, 11) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+
+  d := d + (data[3] + C4 + ((e or not aa) xor bb));
+  d := TBits.RotateLeft32(d, 11) + c;
+  aa := TBits.RotateLeft32(aa, 10);
+  c := c + (data[10] + C4 + ((d or not e) xor aa));
+  c := TBits.RotateLeft32(c, 13) + bb;
+  e := TBits.RotateLeft32(e, 10);
+  bb := bb + (data[14] + C4 + ((c or not d) xor e));
+  bb := TBits.RotateLeft32(bb, 6) + aa;
+  d := TBits.RotateLeft32(d, 10);
+  aa := aa + (data[4] + C4 + ((bb or not c) xor d));
+  aa := TBits.RotateLeft32(aa, 7) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[9] + C4 + ((aa or not bb) xor c));
+  e := TBits.RotateLeft32(e, 14) + d;
+  bb := TBits.RotateLeft32(bb, 10);
+  d := d + (data[15] + C4 + ((e or not aa) xor bb));
+  d := TBits.RotateLeft32(d, 9) + c;
+  aa := TBits.RotateLeft32(aa, 10);
+  c := c + (data[8] + C4 + ((d or not e) xor aa));
+  c := TBits.RotateLeft32(c, 13) + bb;
+  e := TBits.RotateLeft32(e, 10);
+  bb := bb + (data[1] + C4 + ((c or not d) xor e));
+  bb := TBits.RotateLeft32(bb, 15) + aa;
+  d := TBits.RotateLeft32(d, 10);
+  aa := aa + (data[2] + C4 + ((bb or not c) xor d));
+  aa := TBits.RotateLeft32(aa, 14) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[7] + C4 + ((aa or not bb) xor c));
+  e := TBits.RotateLeft32(e, 8) + d;
+  bb := TBits.RotateLeft32(bb, 10);
+  d := d + (data[0] + C4 + ((e or not aa) xor bb));
+  d := TBits.RotateLeft32(d, 13) + c;
+  aa := TBits.RotateLeft32(aa, 10);
+  c := c + (data[6] + C4 + ((d or not e) xor aa));
+  c := TBits.RotateLeft32(c, 6) + bb;
+  e := TBits.RotateLeft32(e, 10);
+  bb := bb + (data[13] + C4 + ((c or not d) xor e));
+  bb := TBits.RotateLeft32(bb, 5) + aa;
+  d := TBits.RotateLeft32(d, 10);
+  aa := aa + (data[11] + C4 + ((bb or not c) xor d));
+  aa := TBits.RotateLeft32(aa, 12) + e;
+  c := TBits.RotateLeft32(c, 10);
+  e := e + (data[5] + C4 + ((aa or not bb) xor c));
+  e := TBits.RotateLeft32(e, 7) + d;
+  bb := TBits.RotateLeft32(bb, 10);
+  d := d + (data[12] + C4 + ((e or not aa) xor bb));
+  d := TBits.RotateLeft32(d, 5) + c;
+  aa := TBits.RotateLeft32(aa, 10);
+
+  dd := dd + (data[15] + C5 + ((ee or not a) xor b));
+  dd := TBits.RotateLeft32(dd, 9) + cc;
+  a := TBits.RotateLeft32(a, 10);
+  cc := cc + (data[5] + C5 + ((dd or not ee) xor a));
+  cc := TBits.RotateLeft32(cc, 7) + b;
+  ee := TBits.RotateLeft32(ee, 10);
+  b := b + (data[1] + C5 + ((cc or not dd) xor ee));
+  b := TBits.RotateLeft32(b, 15) + a;
+  dd := TBits.RotateLeft32(dd, 10);
+  a := a + (data[3] + C5 + ((b or not cc) xor dd));
+  a := TBits.RotateLeft32(a, 11) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[7] + C5 + ((a or not b) xor cc));
+  ee := TBits.RotateLeft32(ee, 8) + dd;
+  b := TBits.RotateLeft32(b, 10);
+  dd := dd + (data[14] + C5 + ((ee or not a) xor b));
+  dd := TBits.RotateLeft32(dd, 6) + cc;
+  a := TBits.RotateLeft32(a, 10);
+  cc := cc + (data[6] + C5 + ((dd or not ee) xor a));
+  cc := TBits.RotateLeft32(cc, 6) + b;
+  ee := TBits.RotateLeft32(ee, 10);
+  b := b + (data[9] + C5 + ((cc or not dd) xor ee));
+  b := TBits.RotateLeft32(b, 14) + a;
+  dd := TBits.RotateLeft32(dd, 10);
+  a := a + (data[11] + C5 + ((b or not cc) xor dd));
+  a := TBits.RotateLeft32(a, 12) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[8] + C5 + ((a or not b) xor cc));
+  ee := TBits.RotateLeft32(ee, 13) + dd;
+  b := TBits.RotateLeft32(b, 10);
+  dd := dd + (data[12] + C5 + ((ee or not a) xor b));
+  dd := TBits.RotateLeft32(dd, 5) + cc;
+  a := TBits.RotateLeft32(a, 10);
+  cc := cc + (data[2] + C5 + ((dd or not ee) xor a));
+  cc := TBits.RotateLeft32(cc, 14) + b;
+  ee := TBits.RotateLeft32(ee, 10);
+  b := b + (data[10] + C5 + ((cc or not dd) xor ee));
+  b := TBits.RotateLeft32(b, 13) + a;
+  dd := TBits.RotateLeft32(dd, 10);
+  a := a + (data[0] + C5 + ((b or not cc) xor dd));
+  a := TBits.RotateLeft32(a, 13) + ee;
+  cc := TBits.RotateLeft32(cc, 10);
+  ee := ee + (data[4] + C5 + ((a or not b) xor cc));
+  ee := TBits.RotateLeft32(ee, 7) + dd;
+  b := TBits.RotateLeft32(b, 10);
+  dd := dd + (data[13] + C5 + ((ee or not a) xor b));
+  dd := TBits.RotateLeft32(dd, 5) + cc;
+  a := TBits.RotateLeft32(a, 10);
+
+  cc := cc + (data[1] + C6 + ((d and aa) or (e and not aa)));
+  cc := TBits.RotateLeft32(cc, 11) + bb;
+  e := TBits.RotateLeft32(e, 10);
+  bb := bb + (data[9] + C6 + ((cc and e) or (d and not e)));
+  bb := TBits.RotateLeft32(bb, 12) + aa;
+  d := TBits.RotateLeft32(d, 10);
+  aa := aa + (data[11] + C6 + ((bb and d) or (cc and not d)));
+  aa := TBits.RotateLeft32(aa, 14) + e;
+  cc := TBits.RotateLeft32(cc, 10);
+  e := e + (data[10] + C6 + ((aa and cc) or (bb and not cc)));
+  e := TBits.RotateLeft32(e, 15) + d;
+  bb := TBits.RotateLeft32(bb, 10);
+  d := d + (data[0] + C6 + ((e and bb) or (aa and not bb)));
+  d := TBits.RotateLeft32(d, 14) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[8] + C6 + ((d and aa) or (e and not aa)));
+  cc := TBits.RotateLeft32(cc, 15) + bb;
+  e := TBits.RotateLeft32(e, 10);
+  bb := bb + (data[12] + C6 + ((cc and e) or (d and not e)));
+  bb := TBits.RotateLeft32(bb, 9) + aa;
+  d := TBits.RotateLeft32(d, 10);
+  aa := aa + (data[4] + C6 + ((bb and d) or (cc and not d)));
+  aa := TBits.RotateLeft32(aa, 8) + e;
+  cc := TBits.RotateLeft32(cc, 10);
+  e := e + (data[13] + C6 + ((aa and cc) or (bb and not cc)));
+  e := TBits.RotateLeft32(e, 9) + d;
+  bb := TBits.RotateLeft32(bb, 10);
+  d := d + (data[3] + C6 + ((e and bb) or (aa and not bb)));
+  d := TBits.RotateLeft32(d, 14) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[7] + C6 + ((d and aa) or (e and not aa)));
+  cc := TBits.RotateLeft32(cc, 5) + bb;
+  e := TBits.RotateLeft32(e, 10);
+  bb := bb + (data[15] + C6 + ((cc and e) or (d and not e)));
+  bb := TBits.RotateLeft32(bb, 6) + aa;
+  d := TBits.RotateLeft32(d, 10);
+  aa := aa + (data[14] + C6 + ((bb and d) or (cc and not d)));
+  aa := TBits.RotateLeft32(aa, 8) + e;
+  cc := TBits.RotateLeft32(cc, 10);
+  e := e + (data[5] + C6 + ((aa and cc) or (bb and not cc)));
+  e := TBits.RotateLeft32(e, 6) + d;
+  bb := TBits.RotateLeft32(bb, 10);
+  d := d + (data[6] + C6 + ((e and bb) or (aa and not bb)));
+  d := TBits.RotateLeft32(d, 5) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[2] + C6 + ((d and aa) or (e and not aa)));
+  cc := TBits.RotateLeft32(cc, 12) + bb;
+  e := TBits.RotateLeft32(e, 10);
+
+  c := c + (data[8] + C7 + ((dd and ee) or (not dd and a)));
+  c := TBits.RotateLeft32(c, 15) + b;
+  ee := TBits.RotateLeft32(ee, 10);
+  b := b + (data[6] + C7 + ((c and dd) or (not c and ee)));
+  b := TBits.RotateLeft32(b, 5) + a;
+  dd := TBits.RotateLeft32(dd, 10);
+  a := a + (data[4] + C7 + ((b and c) or (not b and dd)));
+  a := TBits.RotateLeft32(a, 8) + ee;
+  c := TBits.RotateLeft32(c, 10);
+  ee := ee + (data[1] + C7 + ((a and b) or (not a and c)));
+  ee := TBits.RotateLeft32(ee, 11) + dd;
+  b := TBits.RotateLeft32(b, 10);
+  dd := dd + (data[3] + C7 + ((ee and a) or (not ee and b)));
+  dd := TBits.RotateLeft32(dd, 14) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[11] + C7 + ((dd and ee) or (not dd and a)));
+  c := TBits.RotateLeft32(c, 14) + b;
+  ee := TBits.RotateLeft32(ee, 10);
+  b := b + (data[15] + C7 + ((c and dd) or (not c and ee)));
+  b := TBits.RotateLeft32(b, 6) + a;
+  dd := TBits.RotateLeft32(dd, 10);
+  a := a + (data[0] + C7 + ((b and c) or (not b and dd)));
+  a := TBits.RotateLeft32(a, 14) + ee;
+  c := TBits.RotateLeft32(c, 10);
+  ee := ee + (data[5] + C7 + ((a and b) or (not a and c)));
+  ee := TBits.RotateLeft32(ee, 6) + dd;
+  b := TBits.RotateLeft32(b, 10);
+  dd := dd + (data[12] + C7 + ((ee and a) or (not ee and b)));
+  dd := TBits.RotateLeft32(dd, 9) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[2] + C7 + ((dd and ee) or (not dd and a)));
+  c := TBits.RotateLeft32(c, 12) + b;
+  ee := TBits.RotateLeft32(ee, 10);
+  b := b + (data[13] + C7 + ((c and dd) or (not c and ee)));
+  b := TBits.RotateLeft32(b, 9) + a;
+  dd := TBits.RotateLeft32(dd, 10);
+  a := a + (data[9] + C7 + ((b and c) or (not b and dd)));
+  a := TBits.RotateLeft32(a, 12) + ee;
+  c := TBits.RotateLeft32(c, 10);
+  ee := ee + (data[7] + C7 + ((a and b) or (not a and c)));
+  ee := TBits.RotateLeft32(ee, 5) + dd;
+  b := TBits.RotateLeft32(b, 10);
+  dd := dd + (data[10] + C7 + ((ee and a) or (not ee and b)));
+  dd := TBits.RotateLeft32(dd, 15) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[14] + C7 + ((dd and ee) or (not dd and a)));
+  c := TBits.RotateLeft32(c, 8) + b;
+  ee := TBits.RotateLeft32(ee, 10);
+
+  bb := bb + (data[4] + C8 + (cc xor (dd or not e)));
+  bb := TBits.RotateLeft32(bb, 9) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[0] + C8 + (bb xor (cc or not dd)));
+  aa := TBits.RotateLeft32(aa, 15) + e;
+  cc := TBits.RotateLeft32(cc, 10);
+  e := e + (data[5] + C8 + (aa xor (bb or not cc)));
+  e := TBits.RotateLeft32(e, 5) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[9] + C8 + (e xor (aa or not bb)));
+  dd := TBits.RotateLeft32(dd, 11) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[7] + C8 + (dd xor (e or not aa)));
+  cc := TBits.RotateLeft32(cc, 6) + bb;
+  e := TBits.RotateLeft32(e, 10);
+  bb := bb + (data[12] + C8 + (cc xor (dd or not e)));
+  bb := TBits.RotateLeft32(bb, 8) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[2] + C8 + (bb xor (cc or not dd)));
+  aa := TBits.RotateLeft32(aa, 13) + e;
+  cc := TBits.RotateLeft32(cc, 10);
+  e := e + (data[10] + C8 + (aa xor (bb or not cc)));
+  e := TBits.RotateLeft32(e, 12) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[14] + C8 + (e xor (aa or not bb)));
+  dd := TBits.RotateLeft32(dd, 5) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[1] + C8 + (dd xor (e or not aa)));
+  cc := TBits.RotateLeft32(cc, 12) + bb;
+  e := TBits.RotateLeft32(e, 10);
+  bb := bb + (data[3] + C8 + (cc xor (dd or not e)));
+  bb := TBits.RotateLeft32(bb, 13) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+  aa := aa + (data[8] + C8 + (bb xor (cc or not dd)));
+  aa := TBits.RotateLeft32(aa, 14) + e;
+  cc := TBits.RotateLeft32(cc, 10);
+  e := e + (data[11] + C8 + (aa xor (bb or not cc)));
+  e := TBits.RotateLeft32(e, 11) + dd;
+  bb := TBits.RotateLeft32(bb, 10);
+  dd := dd + (data[6] + C8 + (e xor (aa or not bb)));
+  dd := TBits.RotateLeft32(dd, 8) + cc;
+  aa := TBits.RotateLeft32(aa, 10);
+  cc := cc + (data[15] + C8 + (dd xor (e or not aa)));
+  cc := TBits.RotateLeft32(cc, 5) + bb;
+  e := TBits.RotateLeft32(e, 10);
+  bb := bb + (data[13] + C8 + (cc xor (dd or not e)));
+  bb := TBits.RotateLeft32(bb, 6) + aa;
+  dd := TBits.RotateLeft32(dd, 10);
+
+  b := b + (data[12] + (c xor d xor ee));
+  b := TBits.RotateLeft32(b, 8) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[15] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 5) + ee;
+  c := TBits.RotateLeft32(c, 10);
+  ee := ee + (data[10] + (a xor b xor c));
+  ee := TBits.RotateLeft32(ee, 12) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[4] + (ee xor a xor b));
+  d := TBits.RotateLeft32(d, 9) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[1] + (d xor ee xor a));
+  c := TBits.RotateLeft32(c, 12) + b;
+  ee := TBits.RotateLeft32(ee, 10);
+  b := b + (data[5] + (c xor d xor ee));
+  b := TBits.RotateLeft32(b, 5) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[8] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 14) + ee;
+  c := TBits.RotateLeft32(c, 10);
+  ee := ee + (data[7] + (a xor b xor c));
+  ee := TBits.RotateLeft32(ee, 6) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[6] + (ee xor a xor b));
+  d := TBits.RotateLeft32(d, 8) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[2] + (d xor ee xor a));
+  c := TBits.RotateLeft32(c, 13) + b;
+  ee := TBits.RotateLeft32(ee, 10);
+  b := b + (data[13] + (c xor d xor ee));
+  b := TBits.RotateLeft32(b, 6) + a;
+  d := TBits.RotateLeft32(d, 10);
+  a := a + (data[14] + (b xor c xor d));
+  a := TBits.RotateLeft32(a, 5) + ee;
+  c := TBits.RotateLeft32(c, 10);
+  ee := ee + (data[0] + (a xor b xor c));
+  ee := TBits.RotateLeft32(ee, 15) + d;
+  b := TBits.RotateLeft32(b, 10);
+  d := d + (data[3] + (ee xor a xor b));
+  d := TBits.RotateLeft32(d, 13) + c;
+  a := TBits.RotateLeft32(a, 10);
+  c := c + (data[9] + (d xor ee xor a));
+  c := TBits.RotateLeft32(c, 11) + b;
+  ee := TBits.RotateLeft32(ee, 10);
+  b := b + (data[11] + (c xor d xor ee));
+  b := TBits.RotateLeft32(b, 11) + a;
+  d := TBits.RotateLeft32(d, 10);
+
+  Fm_state[0] := Fm_state[0] + aa;
+  Fm_state[1] := Fm_state[1] + bb;
+  Fm_state[2] := Fm_state[2] + cc;
+  Fm_state[3] := Fm_state[3] + dd;
+  Fm_state[4] := Fm_state[4] + ee;
+  Fm_state[5] := Fm_state[5] + a;
+  Fm_state[6] := Fm_state[6] + b;
+  Fm_state[7] := Fm_state[7] + c;
+  Fm_state[8] := Fm_state[8] + d;
+  Fm_state[9] := Fm_state[9] + e;
+
+  System.FillChar(data, System.SizeOf(data), 0);
+
+end;
+
+end.

+ 213 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpRadioGatun32.pas

@@ -0,0 +1,213 @@
+unit HlpRadioGatun32;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpBits,
+  HlpConverters,
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn;
+
+type
+  TRadioGatun32 = class sealed(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+  strict private
+
+    Fm_mill: THashLibUInt32Array;
+
+    Fm_belt: THashLibMatrixUInt32Array;
+
+    procedure RoundFunction();
+
+  strict protected
+    procedure Finish(); override;
+    function GetResult(): THashLibByteArray; override;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TRadioGatun32 }
+
+constructor TRadioGatun32.Create;
+var
+  i: Int32;
+begin
+
+  Inherited Create(32, 12);
+  System.SetLength(Fm_mill, 19);
+
+  System.SetLength(Fm_belt, 13);
+  i := 0;
+  while i < 13 do
+  begin
+    System.SetLength(Fm_belt[i], 3);
+
+    System.Inc(i);
+  end;
+
+end;
+
+procedure TRadioGatun32.Finish;
+var
+  padding_size, i: Int32;
+  pad: THashLibByteArray;
+begin
+  padding_size := 12 - ((Int32(Fm_processed_bytes)) mod 12);
+
+  System.SetLength(pad, padding_size);
+  pad[0] := $01;
+  TransformBytes(pad, 0, padding_size);
+  i := 0;
+  while i < 16 do
+  begin
+    RoundFunction();
+    System.Inc(i);
+  end;
+
+end;
+
+function TRadioGatun32.GetResult: THashLibByteArray;
+var
+  tempRes: THashLibUInt32Array;
+  i: Int32;
+begin
+  System.SetLength(tempRes, 8);
+
+  System.SetLength(result, System.Length(tempRes) * System.SizeOf(UInt32));
+
+  i := 0;
+
+  while i < 4 do
+  begin
+    RoundFunction();
+
+    System.Move(Fm_mill[1], tempRes[i * 2], 2 * System.SizeOf(UInt32));
+    System.Inc(i);
+  end;
+
+  TConverters.le32_copy(PCardinal(tempRes), 0, PByte(result), 0,
+    System.Length(result));
+
+end;
+
+procedure TRadioGatun32.Initialize;
+var
+  i: Int32;
+begin
+
+  System.FillChar(Fm_mill[0], System.Length(Fm_mill) * System.SizeOf(UInt32),
+    UInt32(0));
+
+  i := 0;
+  while i < 13 do
+  begin
+
+    System.FillChar(Fm_belt[i][0], System.Length(Fm_belt[i]) *
+      System.SizeOf(UInt32), UInt32(0));
+    System.Inc(i);
+  end;
+
+  Inherited Initialize();
+
+end;
+
+procedure TRadioGatun32.RoundFunction;
+var
+  q: THashLibUInt32Array;
+  a: array [0 .. 18] of UInt32;
+  i: Int32;
+begin
+
+  q := Fm_belt[12];
+  i := 12;
+  while i > 0 do
+  begin
+    Fm_belt[i] := Fm_belt[i - 1];
+    System.Dec(i);
+  end;
+
+  Fm_belt[0] := q;
+
+  i := 0;
+  while i < 12 do
+  begin
+    Fm_belt[i + 1][i mod 3] := Fm_belt[i + 1][i mod 3] xor Fm_mill[i + 1];
+    System.Inc(i);
+  end;
+
+  i := 0;
+  while i < 19 do
+  begin
+    a[i] := Fm_mill[i] xor (Fm_mill[(i + 1) mod 19] or
+      not Fm_mill[(i + 2) mod 19]);
+    System.Inc(i);
+  end;
+
+  i := 0;
+  while i < 19 do
+  begin
+    Fm_mill[i] := TBits.RotateRight32(a[(7 * i) mod 19], (i * (i + 1)) shr 1);
+    System.Inc(i);
+  end;
+
+  i := 0;
+  while i < 19 do
+  begin
+    a[i] := Fm_mill[i] xor Fm_mill[(i + 1) mod 19] xor Fm_mill[(i + 4) mod 19];
+    System.Inc(i);
+  end;
+
+  a[0] := a[0] xor 1;
+
+  i := 0;
+  while i < 19 do
+  begin
+    Fm_mill[i] := a[i];
+    System.Inc(i);
+  end;
+
+  i := 0;
+  while i < 3 do
+  begin
+    Fm_mill[i + 13] := Fm_mill[i + 13] xor q[i];
+    System.Inc(i);
+  end;
+
+end;
+
+procedure TRadioGatun32.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  data: array [0 .. 2] of UInt32;
+  i: Int32;
+begin
+  TConverters.le32_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+
+  i := 0;
+  while i < 3 do
+  begin
+    Fm_mill[i + 16] := Fm_mill[i + 16] xor data[i];
+    Fm_belt[0][i] := Fm_belt[0][i] xor data[i];
+
+    System.Inc(i);
+  end;
+
+  RoundFunction();
+
+  System.FillChar(data, System.SizeOf(data), 0);
+end;
+
+end.

+ 211 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpRadioGatun64.pas

@@ -0,0 +1,211 @@
+unit HlpRadioGatun64;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpBits,
+  HlpConverters,
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn;
+
+type
+  TRadioGatun64 = class sealed(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+  strict private
+
+    Fm_mill: THashLibUInt64Array;
+
+    Fm_belt: THashLibMatrixUInt64Array;
+
+    procedure RoundFunction();
+
+  strict protected
+    procedure Finish(); override;
+    function GetResult(): THashLibByteArray; override;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TRadioGatun64 }
+
+constructor TRadioGatun64.Create;
+var
+  i: Int32;
+begin
+
+  Inherited Create(32, 24);
+  System.SetLength(Fm_mill, 19);
+
+  System.SetLength(Fm_belt, 13);
+  i := 0;
+  while i < 13 do
+  begin
+    System.SetLength(Fm_belt[i], 3);
+
+    System.Inc(i);
+  end;
+
+end;
+
+procedure TRadioGatun64.Finish;
+var
+  padding_size, i: Int32;
+  pad: THashLibByteArray;
+begin
+  padding_size := 24 - ((Int32(Fm_processed_bytes)) mod 24);
+
+  System.SetLength(pad, padding_size);
+  pad[0] := $01;
+  TransformBytes(pad, 0, padding_size);
+  i := 0;
+  while i < 16 do
+  begin
+    RoundFunction();
+    System.Inc(i);
+  end;
+
+end;
+
+function TRadioGatun64.GetResult: THashLibByteArray;
+var
+  tempRes: THashLibUInt64Array;
+  i: Int32;
+begin
+  System.SetLength(tempRes, 4);
+
+  System.SetLength(result, System.Length(tempRes) * System.SizeOf(UInt64));
+  i := 0;
+
+  while i < 2 do
+  begin
+    RoundFunction();
+
+    System.Move(Fm_mill[1], tempRes[i * 2], 2 * System.SizeOf(UInt64));
+    System.Inc(i);
+  end;
+
+  TConverters.le64_copy(PCardinal(tempRes), 0, PByte(result), 0,
+    System.Length(result));
+end;
+
+procedure TRadioGatun64.Initialize;
+var
+  i: Int32;
+begin
+
+  System.FillChar(Fm_mill[0], System.Length(Fm_mill) * System.SizeOf(UInt64),
+    UInt64(0));
+
+  i := 0;
+  while i < 13 do
+  begin
+
+    System.FillChar(Fm_belt[i][0], System.Length(Fm_belt[i]) *
+      System.SizeOf(UInt64), UInt64(0));
+    System.Inc(i);
+  end;
+
+  Inherited Initialize();
+
+end;
+
+procedure TRadioGatun64.RoundFunction;
+var
+  q: THashLibUInt64Array;
+  a: array [0 .. 18] of UInt64;
+  i: Int32;
+begin
+
+  q := Fm_belt[12];
+  i := 12;
+  while i > 0 do
+  begin
+    Fm_belt[i] := Fm_belt[i - 1];
+    System.Dec(i);
+  end;
+
+  Fm_belt[0] := q;
+
+  i := 0;
+  while i < 12 do
+  begin
+    Fm_belt[i + 1][i mod 3] := Fm_belt[i + 1][i mod 3] xor Fm_mill[i + 1];
+    System.Inc(i);
+  end;
+
+  i := 0;
+  while i < 19 do
+  begin
+    a[i] := Fm_mill[i] xor (Fm_mill[(i + 1) mod 19] or
+      not Fm_mill[(i + 2) mod 19]);
+    System.Inc(i);
+  end;
+
+  i := 0;
+  while i < 19 do
+  begin
+    Fm_mill[i] := TBits.RotateRight64(a[(7 * i) mod 19], (i * (i + 1)) shr 1);
+    System.Inc(i);
+  end;
+
+  i := 0;
+  while i < 19 do
+  begin
+    a[i] := Fm_mill[i] xor Fm_mill[(i + 1) mod 19] xor Fm_mill[(i + 4) mod 19];
+    System.Inc(i);
+  end;
+
+  a[0] := a[0] xor 1;
+
+  i := 0;
+  while i < 19 do
+  begin
+    Fm_mill[i] := a[i];
+    System.Inc(i);
+  end;
+
+  i := 0;
+  while i < 3 do
+  begin
+    Fm_mill[i + 13] := Fm_mill[i + 13] xor q[i];
+    System.Inc(i);
+  end;
+
+end;
+
+procedure TRadioGatun64.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  data: array [0 .. 2] of UInt64;
+  i: Int32;
+begin
+
+  TConverters.le64_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+  i := 0;
+  while i < 3 do
+  begin
+    Fm_mill[i + 16] := Fm_mill[i + 16] xor data[i];
+    Fm_belt[0][i] := Fm_belt[0][i] xor data[i];
+
+    System.Inc(i);
+  end;
+
+  RoundFunction();
+
+  System.FillChar(data, System.SizeOf(data), 0);
+end;
+
+end.

+ 566 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA0.pas

@@ -0,0 +1,566 @@
+unit HlpSHA0;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpBits,
+{$IFDEF DELPHI}
+  HlpHashBuffer,
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpHashLibTypes,
+  HlpConverters,
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn;
+
+type
+  TSHA0 = class(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+  strict protected
+
+    Fm_state: THashLibUInt32Array;
+
+{$REGION 'Consts'}
+
+  const
+
+    C1 = UInt32($5A827999);
+    C2 = UInt32($6ED9EBA1);
+    C3 = UInt32($8F1BBCDC);
+    C4 = UInt32($CA62C1D6);
+
+{$ENDREGION}
+    procedure Finish(); override;
+    procedure Expand(a_data: PCardinal); virtual;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+    function GetResult(): THashLibByteArray; override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TSHA0 }
+
+constructor TSHA0.Create;
+begin
+  Inherited Create(20, 64);
+  System.SetLength(Fm_state, 5);
+end;
+
+procedure TSHA0.Expand(a_data: PCardinal);
+{$IFNDEF USE_UNROLLED_VARIANT}
+var
+  j: Int32;
+{$ENDIF USE_UNROLLED_VARIANT}
+begin
+
+{$IFDEF USE_UNROLLED_VARIANT}
+  a_data[16] := ((a_data[16 - 3] xor a_data[16 - 8]) xor a_data[16 - 14])
+    xor a_data[0];
+  a_data[17] := ((a_data[17 - 3] xor a_data[17 - 8]) xor a_data[17 - 14])
+    xor a_data[17 - 16];
+  a_data[18] := ((a_data[18 - 3] xor a_data[18 - 8]) xor a_data[18 - 14])
+    xor a_data[18 - 16];
+  a_data[19] := ((a_data[19 - 3] xor a_data[19 - 8]) xor a_data[19 - 14])
+    xor a_data[19 - 16];
+  a_data[20] := ((a_data[20 - 3] xor a_data[20 - 8]) xor a_data[20 - 14])
+    xor a_data[20 - 16];
+  a_data[21] := ((a_data[21 - 3] xor a_data[21 - 8]) xor a_data[21 - 14])
+    xor a_data[21 - 16];
+  a_data[22] := ((a_data[22 - 3] xor a_data[22 - 8]) xor a_data[22 - 14])
+    xor a_data[22 - 16];
+  a_data[23] := ((a_data[23 - 3] xor a_data[23 - 8]) xor a_data[23 - 14])
+    xor a_data[23 - 16];
+  a_data[24] := ((a_data[24 - 3] xor a_data[24 - 8]) xor a_data[24 - 14])
+    xor a_data[24 - 16];
+  a_data[25] := ((a_data[25 - 3] xor a_data[25 - 8]) xor a_data[25 - 14])
+    xor a_data[25 - 16];
+  a_data[26] := ((a_data[26 - 3] xor a_data[26 - 8]) xor a_data[26 - 14])
+    xor a_data[26 - 16];
+  a_data[27] := ((a_data[27 - 3] xor a_data[27 - 8]) xor a_data[27 - 14])
+    xor a_data[27 - 16];
+  a_data[28] := ((a_data[28 - 3] xor a_data[28 - 8]) xor a_data[28 - 14])
+    xor a_data[28 - 16];
+  a_data[29] := ((a_data[29 - 3] xor a_data[29 - 8]) xor a_data[29 - 14])
+    xor a_data[29 - 16];
+  a_data[30] := ((a_data[30 - 3] xor a_data[30 - 8]) xor a_data[30 - 14])
+    xor a_data[30 - 16];
+  a_data[31] := ((a_data[31 - 3] xor a_data[31 - 8]) xor a_data[31 - 14])
+    xor a_data[31 - 16];
+  a_data[32] := ((a_data[32 - 3] xor a_data[32 - 8]) xor a_data[32 - 14])
+    xor a_data[32 - 16];
+  a_data[33] := ((a_data[33 - 3] xor a_data[33 - 8]) xor a_data[33 - 14])
+    xor a_data[33 - 16];
+  a_data[34] := ((a_data[34 - 3] xor a_data[34 - 8]) xor a_data[34 - 14])
+    xor a_data[34 - 16];
+  a_data[35] := ((a_data[35 - 3] xor a_data[35 - 8]) xor a_data[35 - 14])
+    xor a_data[35 - 16];
+  a_data[36] := ((a_data[36 - 3] xor a_data[36 - 8]) xor a_data[36 - 14])
+    xor a_data[36 - 16];
+  a_data[37] := ((a_data[37 - 3] xor a_data[37 - 8]) xor a_data[37 - 14])
+    xor a_data[37 - 16];
+  a_data[38] := ((a_data[38 - 3] xor a_data[38 - 8]) xor a_data[38 - 14])
+    xor a_data[38 - 16];
+  a_data[39] := ((a_data[39 - 3] xor a_data[39 - 8]) xor a_data[39 - 14])
+    xor a_data[39 - 16];
+  a_data[40] := ((a_data[40 - 3] xor a_data[40 - 8]) xor a_data[40 - 14])
+    xor a_data[40 - 16];
+  a_data[41] := ((a_data[41 - 3] xor a_data[41 - 8]) xor a_data[41 - 14])
+    xor a_data[41 - 16];
+  a_data[42] := ((a_data[42 - 3] xor a_data[42 - 8]) xor a_data[42 - 14])
+    xor a_data[42 - 16];
+  a_data[43] := ((a_data[43 - 3] xor a_data[43 - 8]) xor a_data[43 - 14])
+    xor a_data[43 - 16];
+  a_data[44] := ((a_data[44 - 3] xor a_data[44 - 8]) xor a_data[44 - 14])
+    xor a_data[44 - 16];
+  a_data[45] := ((a_data[45 - 3] xor a_data[45 - 8]) xor a_data[45 - 14])
+    xor a_data[45 - 16];
+  a_data[46] := ((a_data[46 - 3] xor a_data[46 - 8]) xor a_data[46 - 14])
+    xor a_data[46 - 16];
+  a_data[47] := ((a_data[47 - 3] xor a_data[47 - 8]) xor a_data[47 - 14])
+    xor a_data[47 - 16];
+  a_data[48] := ((a_data[48 - 3] xor a_data[48 - 8]) xor a_data[48 - 14])
+    xor a_data[48 - 16];
+  a_data[49] := ((a_data[49 - 3] xor a_data[49 - 8]) xor a_data[49 - 14])
+    xor a_data[49 - 16];
+  a_data[50] := ((a_data[50 - 3] xor a_data[50 - 8]) xor a_data[50 - 14])
+    xor a_data[50 - 16];
+  a_data[51] := ((a_data[51 - 3] xor a_data[51 - 8]) xor a_data[51 - 14])
+    xor a_data[51 - 16];
+  a_data[52] := ((a_data[52 - 3] xor a_data[52 - 8]) xor a_data[52 - 14])
+    xor a_data[52 - 16];
+  a_data[53] := ((a_data[53 - 3] xor a_data[53 - 8]) xor a_data[53 - 14])
+    xor a_data[53 - 16];
+  a_data[54] := ((a_data[54 - 3] xor a_data[54 - 8]) xor a_data[54 - 14])
+    xor a_data[54 - 16];
+  a_data[55] := ((a_data[55 - 3] xor a_data[55 - 8]) xor a_data[55 - 14])
+    xor a_data[55 - 16];
+  a_data[56] := ((a_data[56 - 3] xor a_data[56 - 8]) xor a_data[56 - 14])
+    xor a_data[56 - 16];
+  a_data[57] := ((a_data[57 - 3] xor a_data[57 - 8]) xor a_data[57 - 14])
+    xor a_data[57 - 16];
+  a_data[58] := ((a_data[58 - 3] xor a_data[58 - 8]) xor a_data[58 - 14])
+    xor a_data[58 - 16];
+  a_data[59] := ((a_data[59 - 3] xor a_data[59 - 8]) xor a_data[59 - 14])
+    xor a_data[59 - 16];
+  a_data[60] := ((a_data[60 - 3] xor a_data[60 - 8]) xor a_data[60 - 14])
+    xor a_data[60 - 16];
+  a_data[61] := ((a_data[61 - 3] xor a_data[61 - 8]) xor a_data[61 - 14])
+    xor a_data[61 - 16];
+  a_data[62] := ((a_data[62 - 3] xor a_data[62 - 8]) xor a_data[62 - 14])
+    xor a_data[62 - 16];
+  a_data[63] := ((a_data[63 - 3] xor a_data[63 - 8]) xor a_data[63 - 14])
+    xor a_data[63 - 16];
+  a_data[64] := ((a_data[64 - 3] xor a_data[64 - 8]) xor a_data[64 - 14])
+    xor a_data[64 - 16];
+  a_data[65] := ((a_data[65 - 3] xor a_data[65 - 8]) xor a_data[65 - 14])
+    xor a_data[65 - 16];
+  a_data[66] := ((a_data[66 - 3] xor a_data[66 - 8]) xor a_data[66 - 14])
+    xor a_data[66 - 16];
+  a_data[67] := ((a_data[67 - 3] xor a_data[67 - 8]) xor a_data[67 - 14])
+    xor a_data[67 - 16];
+  a_data[68] := ((a_data[68 - 3] xor a_data[68 - 8]) xor a_data[68 - 14])
+    xor a_data[68 - 16];
+  a_data[69] := ((a_data[69 - 3] xor a_data[69 - 8]) xor a_data[69 - 14])
+    xor a_data[69 - 16];
+  a_data[70] := ((a_data[70 - 3] xor a_data[70 - 8]) xor a_data[70 - 14])
+    xor a_data[70 - 16];
+  a_data[71] := ((a_data[71 - 3] xor a_data[71 - 8]) xor a_data[71 - 14])
+    xor a_data[71 - 16];
+  a_data[72] := ((a_data[72 - 3] xor a_data[72 - 8]) xor a_data[72 - 14])
+    xor a_data[72 - 16];
+  a_data[73] := ((a_data[73 - 3] xor a_data[73 - 8]) xor a_data[73 - 14])
+    xor a_data[73 - 16];
+  a_data[74] := ((a_data[74 - 3] xor a_data[74 - 8]) xor a_data[74 - 14])
+    xor a_data[74 - 16];
+  a_data[75] := ((a_data[75 - 3] xor a_data[75 - 8]) xor a_data[75 - 14])
+    xor a_data[75 - 16];
+  a_data[76] := ((a_data[76 - 3] xor a_data[76 - 8]) xor a_data[76 - 14])
+    xor a_data[76 - 16];
+  a_data[77] := ((a_data[77 - 3] xor a_data[77 - 8]) xor a_data[77 - 14])
+    xor a_data[77 - 16];
+  a_data[78] := ((a_data[78 - 3] xor a_data[78 - 8]) xor a_data[78 - 14])
+    xor a_data[78 - 16];
+  a_data[79] := ((a_data[79 - 3] xor a_data[79 - 8]) xor a_data[79 - 14])
+    xor a_data[79 - 16];
+
+{$ELSE}
+  for j := 16 to 79 do
+  begin
+    a_data[j] := ((a_data[j - 3] xor a_data[j - 8]) xor a_data[j - 14])
+      xor a_data[j - 16];
+  end;
+{$ENDIF USE_UNROLLED_VARIANT}
+end;
+
+procedure TSHA0.Finish;
+var
+  bits: UInt64;
+  padindex: Int32;
+  pad: THashLibByteArray;
+begin
+  bits := Fm_processed_bytes * 8;
+  if (Fm_buffer.Pos < 56) then
+
+    padindex := (56 - Fm_buffer.Pos)
+  else
+    padindex := (120 - Fm_buffer.Pos);
+
+  System.SetLength(pad, padindex + 8);
+
+  pad[0] := $80;
+
+  bits := TConverters.be2me_64(bits);
+
+  TConverters.ReadUInt64AsBytesLE(bits, pad, padindex);
+
+  padindex := padindex + 8;
+
+  TransformBytes(pad, 0, padindex);
+
+end;
+
+function TSHA0.GetResult: THashLibByteArray;
+begin
+
+  System.SetLength(result, 5 * System.SizeOf(UInt32));
+  TConverters.be32_copy(PCardinal(Fm_state), 0, PByte(result), 0,
+    System.Length(result));
+
+end;
+
+procedure TSHA0.Initialize;
+begin
+
+  Fm_state[0] := $67452301;
+  Fm_state[1] := $EFCDAB89;
+  Fm_state[2] := $98BADCFE;
+  Fm_state[3] := $10325476;
+  Fm_state[4] := $C3D2E1F0;
+
+  Inherited Initialize();
+
+end;
+
+procedure TSHA0.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  A, B, C, D, E: UInt32;
+  data: array [0 .. 79] of UInt32;
+  ptr_data: PCardinal;
+begin
+
+  ptr_data := @(data[0]);
+
+  TConverters.be32_copy(a_data, a_index, ptr_data, 0, a_data_length);
+
+  Expand(ptr_data);
+
+  A := Fm_state[0];
+  B := Fm_state[1];
+  C := Fm_state[2];
+  D := Fm_state[3];
+  E := Fm_state[4];
+
+  E := (data[0] + C1 + TBits.RotateLeft32(A, 5) +
+    (D xor (B and (C xor D)))) + E;
+
+  B := TBits.RotateLeft32(B, 30);
+  D := (data[1] + C1 + TBits.RotateLeft32(E, 5) +
+    (C xor (A and (B xor C)))) + D;
+
+  A := TBits.RotateLeft32(A, 30);
+  C := (data[2] + C1 + TBits.RotateLeft32(D, 5) +
+    (B xor (E and (A xor B)))) + C;
+
+  E := TBits.RotateLeft32(E, 30);
+  B := (data[3] + C1 + TBits.RotateLeft32(C, 5) +
+    (A xor (D and (E xor A)))) + B;
+
+  D := TBits.RotateLeft32(D, 30);
+  A := (data[4] + C1 + TBits.RotateLeft32(B, 5) +
+    (E xor (C and (D xor E)))) + A;
+
+  C := TBits.RotateLeft32(C, 30);
+  E := (data[5] + C1 + TBits.RotateLeft32(A, 5) +
+    (D xor (B and (C xor D)))) + E;
+
+  B := TBits.RotateLeft32(B, 30);
+  D := (data[6] + C1 + TBits.RotateLeft32(E, 5) +
+    (C xor (A and (B xor C)))) + D;
+
+  A := TBits.RotateLeft32(A, 30);
+  C := (data[7] + C1 + TBits.RotateLeft32(D, 5) +
+    (B xor (E and (A xor B)))) + C;
+
+  E := TBits.RotateLeft32(E, 30);
+  B := (data[8] + C1 + TBits.RotateLeft32(C, 5) +
+    (A xor (D and (E xor A)))) + B;
+
+  D := TBits.RotateLeft32(D, 30);
+  A := (data[9] + C1 + TBits.RotateLeft32(B, 5) +
+    (E xor (C and (D xor E)))) + A;
+
+  C := TBits.RotateLeft32(C, 30);
+  E := (data[10] + C1 + TBits.RotateLeft32(A, 5) +
+    (D xor (B and (C xor D)))) + E;
+
+  B := TBits.RotateLeft32(B, 30);
+  D := (data[11] + C1 + TBits.RotateLeft32(E, 5) +
+    (C xor (A and (B xor C)))) + D;
+
+  A := TBits.RotateLeft32(A, 30);
+  C := (data[12] + C1 + TBits.RotateLeft32(D, 5) +
+    (B xor (E and (A xor B)))) + C;
+
+  E := TBits.RotateLeft32(E, 30);
+  B := (data[13] + C1 + TBits.RotateLeft32(C, 5) +
+    (A xor (D and (E xor A)))) + B;
+
+  D := TBits.RotateLeft32(D, 30);
+  A := (data[14] + C1 + TBits.RotateLeft32(B, 5) +
+    (E xor (C and (D xor E)))) + A;
+
+  C := TBits.RotateLeft32(C, 30);
+  E := (data[15] + C1 + TBits.RotateLeft32(A, 5) +
+    (D xor (B and (C xor D)))) + E;
+
+  B := TBits.RotateLeft32(B, 30);
+  D := (data[16] + C1 + TBits.RotateLeft32(E, 5) +
+    (C xor (A and (B xor C)))) + D;
+
+  A := TBits.RotateLeft32(A, 30);
+  C := (data[17] + C1 + TBits.RotateLeft32(D, 5) +
+    (B xor (E and (A xor B)))) + C;
+
+  E := TBits.RotateLeft32(E, 30);
+  B := (data[18] + C1 + TBits.RotateLeft32(C, 5) +
+    (A xor (D and (E xor A)))) + B;
+
+  D := TBits.RotateLeft32(D, 30);
+  A := (data[19] + C1 + TBits.RotateLeft32(B, 5) +
+    (E xor (C and (D xor E)))) + A;
+
+  C := TBits.RotateLeft32(C, 30);
+  E := (data[20] + C2 + TBits.RotateLeft32(A, 5) + (B xor C xor D)) + E;
+
+  B := TBits.RotateLeft32(B, 30);
+  D := (data[21] + C2 + TBits.RotateLeft32(E, 5) + (A xor B xor C)) + D;
+
+  A := TBits.RotateLeft32(A, 30);
+  C := (data[22] + C2 + TBits.RotateLeft32(D, 5) + (E xor A xor B)) + C;
+
+  E := TBits.RotateLeft32(E, 30);
+  B := (data[23] + C2 + TBits.RotateLeft32(C, 5) + (D xor E xor A)) + B;
+
+  D := TBits.RotateLeft32(D, 30);
+  A := (data[24] + C2 + TBits.RotateLeft32(B, 5) + (C xor D xor E)) + A;
+
+  C := TBits.RotateLeft32(C, 30);
+  E := (data[25] + C2 + TBits.RotateLeft32(A, 5) + (B xor C xor D)) + E;
+
+  B := TBits.RotateLeft32(B, 30);
+  D := (data[26] + C2 + TBits.RotateLeft32(E, 5) + (A xor B xor C)) + D;
+
+  A := TBits.RotateLeft32(A, 30);
+  C := (data[27] + C2 + TBits.RotateLeft32(D, 5) + (E xor A xor B)) + C;
+
+  E := TBits.RotateLeft32(E, 30);
+  B := (data[28] + C2 + TBits.RotateLeft32(C, 5) + (D xor E xor A)) + B;
+
+  D := TBits.RotateLeft32(D, 30);
+  A := (data[29] + C2 + TBits.RotateLeft32(B, 5) + (C xor D xor E)) + A;
+
+  C := TBits.RotateLeft32(C, 30);
+  E := (data[30] + C2 + TBits.RotateLeft32(A, 5) + (B xor C xor D)) + E;
+
+  B := TBits.RotateLeft32(B, 30);
+  D := (data[31] + C2 + TBits.RotateLeft32(E, 5) + (A xor B xor C)) + D;
+
+  A := TBits.RotateLeft32(A, 30);
+  C := (data[32] + C2 + TBits.RotateLeft32(D, 5) + (E xor A xor B)) + C;
+
+  E := TBits.RotateLeft32(E, 30);
+  B := (data[33] + C2 + TBits.RotateLeft32(C, 5) + (D xor E xor A)) + B;
+
+  D := TBits.RotateLeft32(D, 30);
+  A := (data[34] + C2 + TBits.RotateLeft32(B, 5) + (C xor D xor E)) + A;
+
+  C := TBits.RotateLeft32(C, 30);
+  E := (data[35] + C2 + TBits.RotateLeft32(A, 5) + (B xor C xor D)) + E;
+
+  B := TBits.RotateLeft32(B, 30);
+  D := (data[36] + C2 + TBits.RotateLeft32(E, 5) + (A xor B xor C)) + D;
+
+  A := TBits.RotateLeft32(A, 30);
+  C := (data[37] + C2 + TBits.RotateLeft32(D, 5) + (E xor A xor B)) + C;
+
+  E := TBits.RotateLeft32(E, 30);
+  B := (data[38] + C2 + TBits.RotateLeft32(C, 5) + (D xor E xor A)) + B;
+
+  D := TBits.RotateLeft32(D, 30);
+  A := (data[39] + C2 + TBits.RotateLeft32(B, 5) + (C xor D xor E)) + A;
+
+  C := TBits.RotateLeft32(C, 30);
+  E := (data[40] + C3 + TBits.RotateLeft32(A, 5) +
+    ((B and C) or (D and (B or C)))) + E;
+
+  B := TBits.RotateLeft32(B, 30);
+  D := (data[41] + C3 + TBits.RotateLeft32(E, 5) +
+    ((A and B) or (C and (A or B)))) + D;
+
+  A := TBits.RotateLeft32(A, 30);
+  C := (data[42] + C3 + TBits.RotateLeft32(D, 5) +
+    ((E and A) or (B and (E or A)))) + C;
+
+  E := TBits.RotateLeft32(E, 30);
+  B := (data[43] + C3 + TBits.RotateLeft32(C, 5) +
+    ((D and E) or (A and (D or E)))) + B;
+
+  D := TBits.RotateLeft32(D, 30);
+  A := (data[44] + C3 + TBits.RotateLeft32(B, 5) +
+    ((C and D) or (E and (C or D)))) + A;
+
+  C := TBits.RotateLeft32(C, 30);
+  E := (data[45] + C3 + TBits.RotateLeft32(A, 5) +
+    ((B and C) or (D and (B or C)))) + E;
+
+  B := TBits.RotateLeft32(B, 30);
+  D := (data[46] + C3 + TBits.RotateLeft32(E, 5) +
+    ((A and B) or (C and (A or B)))) + D;
+
+  A := TBits.RotateLeft32(A, 30);
+  C := (data[47] + C3 + TBits.RotateLeft32(D, 5) +
+    ((E and A) or (B and (E or A)))) + C;
+
+  E := TBits.RotateLeft32(E, 30);
+  B := (data[48] + C3 + TBits.RotateLeft32(C, 5) +
+    ((D and E) or (A and (D or E)))) + B;
+
+  D := TBits.RotateLeft32(D, 30);
+  A := (data[49] + C3 + TBits.RotateLeft32(B, 5) +
+    ((C and D) or (E and (C or D)))) + A;
+
+  C := TBits.RotateLeft32(C, 30);
+  E := (data[50] + C3 + TBits.RotateLeft32(A, 5) +
+    ((B and C) or (D and (B or C)))) + E;
+
+  B := TBits.RotateLeft32(B, 30);
+  D := (data[51] + C3 + TBits.RotateLeft32(E, 5) +
+    ((A and B) or (C and (A or B)))) + D;
+
+  A := TBits.RotateLeft32(A, 30);
+  C := (data[52] + C3 + TBits.RotateLeft32(D, 5) +
+    ((E and A) or (B and (E or A)))) + C;
+
+  E := TBits.RotateLeft32(E, 30);
+  B := (data[53] + C3 + TBits.RotateLeft32(C, 5) +
+    ((D and E) or (A and (D or E)))) + B;
+
+  D := TBits.RotateLeft32(D, 30);
+  A := (data[54] + C3 + TBits.RotateLeft32(B, 5) +
+    ((C and D) or (E and (C or D)))) + A;
+
+  C := TBits.RotateLeft32(C, 30);
+  E := (data[55] + C3 + TBits.RotateLeft32(A, 5) +
+    ((B and C) or (D and (B or C)))) + E;
+
+  B := TBits.RotateLeft32(B, 30);
+  D := (data[56] + C3 + TBits.RotateLeft32(E, 5) +
+    ((A and B) or (C and (A or B)))) + D;
+
+  A := TBits.RotateLeft32(A, 30);
+  C := (data[57] + C3 + TBits.RotateLeft32(D, 5) +
+    ((E and A) or (B and (E or A)))) + C;
+
+  E := TBits.RotateLeft32(E, 30);
+  B := (data[58] + C3 + TBits.RotateLeft32(C, 5) +
+    ((D and E) or (A and (D or E)))) + B;
+
+  D := TBits.RotateLeft32(D, 30);
+  A := (data[59] + C3 + TBits.RotateLeft32(B, 5) +
+    ((C and D) or (E and (C or D)))) + A;
+
+  C := TBits.RotateLeft32(C, 30);
+  E := (data[60] + C4 + TBits.RotateLeft32(A, 5) + (B xor C xor D)) + E;
+
+  B := TBits.RotateLeft32(B, 30);
+  D := (data[61] + C4 + TBits.RotateLeft32(E, 5) + (A xor B xor C)) + D;
+
+  A := TBits.RotateLeft32(A, 30);
+  C := (data[62] + C4 + TBits.RotateLeft32(D, 5) + (E xor A xor B)) + C;
+
+  E := TBits.RotateLeft32(E, 30);
+  B := (data[63] + C4 + TBits.RotateLeft32(C, 5) + (D xor E xor A)) + B;
+
+  D := TBits.RotateLeft32(D, 30);
+  A := (data[64] + C4 + TBits.RotateLeft32(B, 5) + (C xor D xor E)) + A;
+
+  C := TBits.RotateLeft32(C, 30);
+  E := (data[65] + C4 + TBits.RotateLeft32(A, 5) + (B xor C xor D)) + E;
+
+  B := TBits.RotateLeft32(B, 30);
+  D := (data[66] + C4 + TBits.RotateLeft32(E, 5) + (A xor B xor C)) + D;
+
+  A := TBits.RotateLeft32(A, 30);
+  C := (data[67] + C4 + TBits.RotateLeft32(D, 5) + (E xor A xor B)) + C;
+
+  E := TBits.RotateLeft32(E, 30);
+  B := (data[68] + C4 + TBits.RotateLeft32(C, 5) + (D xor E xor A)) + B;
+
+  D := TBits.RotateLeft32(D, 30);
+  A := (data[69] + C4 + TBits.RotateLeft32(B, 5) + (C xor D xor E)) + A;
+
+  C := TBits.RotateLeft32(C, 30);
+  E := (data[70] + C4 + TBits.RotateLeft32(A, 5) + (B xor C xor D)) + E;
+
+  B := TBits.RotateLeft32(B, 30);
+  D := (data[71] + C4 + TBits.RotateLeft32(E, 5) + (A xor B xor C)) + D;
+
+  A := TBits.RotateLeft32(A, 30);
+  C := (data[72] + C4 + TBits.RotateLeft32(D, 5) + (E xor A xor B)) + C;
+
+  E := TBits.RotateLeft32(E, 30);
+  B := (data[73] + C4 + TBits.RotateLeft32(C, 5) + (D xor E xor A)) + B;
+
+  D := TBits.RotateLeft32(D, 30);
+  A := (data[74] + C4 + TBits.RotateLeft32(B, 5) + (C xor D xor E)) + A;
+
+  C := TBits.RotateLeft32(C, 30);
+  E := (data[75] + C4 + TBits.RotateLeft32(A, 5) + (B xor C xor D)) + E;
+
+  B := TBits.RotateLeft32(B, 30);
+  D := (data[76] + C4 + TBits.RotateLeft32(E, 5) + (A xor B xor C)) + D;
+
+  A := TBits.RotateLeft32(A, 30);
+  C := (data[77] + C4 + TBits.RotateLeft32(D, 5) + (E xor A xor B)) + C;
+
+  E := TBits.RotateLeft32(E, 30);
+  B := (data[78] + C4 + TBits.RotateLeft32(C, 5) + (D xor E xor A)) + B;
+
+  D := TBits.RotateLeft32(D, 30);
+  A := (data[79] + C4 + TBits.RotateLeft32(B, 5) + (C xor D xor E)) + A;
+
+  C := TBits.RotateLeft32(C, 30);
+
+  Fm_state[0] := Fm_state[0] + A;
+  Fm_state[1] := Fm_state[1] + B;
+  Fm_state[2] := Fm_state[2] + C;
+  Fm_state[3] := Fm_state[3] + D;
+  Fm_state[4] := Fm_state[4] + E;
+
+  System.FillChar(data, System.SizeOf(data), 0);
+
+end;
+
+end.

+ 245 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA1.pas

@@ -0,0 +1,245 @@
+unit HlpSHA1;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+
+  HlpBits,
+  HlpSHA0;
+
+type
+  TSHA1 = class sealed(TSHA0)
+
+  strict protected
+    procedure Expand(a_data: PCardinal); override;
+
+  public
+    // Not really needed because there is an Intristic default constructor always
+    // called for classes if none is defined by the developer but I just put it
+    // for readability reasons.
+    constructor Create();
+
+  end;
+
+implementation
+
+{ TSHA1 }
+
+constructor TSHA1.Create;
+begin
+  Inherited Create();
+end;
+
+procedure TSHA1.Expand(a_data: PCardinal);
+var
+{$IFNDEF USE_UNROLLED_VARIANT}
+  i: Int32;
+{$ENDIF USE_UNROLLED_VARIANT}
+  T: UInt32;
+begin
+
+{$IFDEF USE_UNROLLED_VARIANT}
+  T := a_data[16 - 3] xor a_data[16 - 8] xor a_data[16 - 14] xor a_data[0];
+  a_data[16] := TBits.RotateLeft32(T, 1);
+  T := a_data[17 - 3] xor a_data[17 - 8] xor a_data[17 - 14] xor a_data
+    [17 - 16];
+  a_data[17] := TBits.RotateLeft32(T, 1);
+  T := a_data[18 - 3] xor a_data[18 - 8] xor a_data[18 - 14] xor a_data
+    [18 - 16];
+  a_data[18] := TBits.RotateLeft32(T, 1);
+  T := a_data[19 - 3] xor a_data[19 - 8] xor a_data[19 - 14] xor a_data
+    [19 - 16];
+  a_data[19] := TBits.RotateLeft32(T, 1);
+  T := a_data[20 - 3] xor a_data[20 - 8] xor a_data[20 - 14] xor a_data
+    [20 - 16];
+  a_data[20] := TBits.RotateLeft32(T, 1);
+  T := a_data[21 - 3] xor a_data[21 - 8] xor a_data[21 - 14] xor a_data
+    [21 - 16];
+  a_data[21] := TBits.RotateLeft32(T, 1);
+  T := a_data[22 - 3] xor a_data[22 - 8] xor a_data[22 - 14] xor a_data
+    [22 - 16];
+  a_data[22] := TBits.RotateLeft32(T, 1);
+  T := a_data[23 - 3] xor a_data[23 - 8] xor a_data[23 - 14] xor a_data
+    [23 - 16];
+  a_data[23] := TBits.RotateLeft32(T, 1);
+  T := a_data[24 - 3] xor a_data[24 - 8] xor a_data[24 - 14] xor a_data
+    [24 - 16];
+  a_data[24] := TBits.RotateLeft32(T, 1);
+  T := a_data[25 - 3] xor a_data[25 - 8] xor a_data[25 - 14] xor a_data
+    [25 - 16];
+  a_data[25] := TBits.RotateLeft32(T, 1);
+  T := a_data[26 - 3] xor a_data[26 - 8] xor a_data[26 - 14] xor a_data
+    [26 - 16];
+  a_data[26] := TBits.RotateLeft32(T, 1);
+  T := a_data[27 - 3] xor a_data[27 - 8] xor a_data[27 - 14] xor a_data
+    [27 - 16];
+  a_data[27] := TBits.RotateLeft32(T, 1);
+  T := a_data[28 - 3] xor a_data[28 - 8] xor a_data[28 - 14] xor a_data
+    [28 - 16];
+  a_data[28] := TBits.RotateLeft32(T, 1);
+  T := a_data[29 - 3] xor a_data[29 - 8] xor a_data[29 - 14] xor a_data
+    [29 - 16];
+  a_data[29] := TBits.RotateLeft32(T, 1);
+  T := a_data[30 - 3] xor a_data[30 - 8] xor a_data[30 - 14] xor a_data
+    [30 - 16];
+  a_data[30] := TBits.RotateLeft32(T, 1);
+  T := a_data[31 - 3] xor a_data[31 - 8] xor a_data[31 - 14] xor a_data
+    [31 - 16];
+  a_data[31] := TBits.RotateLeft32(T, 1);
+  T := a_data[32 - 3] xor a_data[32 - 8] xor a_data[32 - 14] xor a_data
+    [32 - 16];
+  a_data[32] := TBits.RotateLeft32(T, 1);
+  T := a_data[33 - 3] xor a_data[33 - 8] xor a_data[33 - 14] xor a_data
+    [33 - 16];
+  a_data[33] := TBits.RotateLeft32(T, 1);
+  T := a_data[34 - 3] xor a_data[34 - 8] xor a_data[34 - 14] xor a_data
+    [34 - 16];
+  a_data[34] := TBits.RotateLeft32(T, 1);
+  T := a_data[35 - 3] xor a_data[35 - 8] xor a_data[35 - 14] xor a_data
+    [35 - 16];
+  a_data[35] := TBits.RotateLeft32(T, 1);
+  T := a_data[36 - 3] xor a_data[36 - 8] xor a_data[36 - 14] xor a_data
+    [36 - 16];
+  a_data[36] := TBits.RotateLeft32(T, 1);
+  T := a_data[37 - 3] xor a_data[37 - 8] xor a_data[37 - 14] xor a_data
+    [37 - 16];
+  a_data[37] := TBits.RotateLeft32(T, 1);
+  T := a_data[38 - 3] xor a_data[38 - 8] xor a_data[38 - 14] xor a_data
+    [38 - 16];
+  a_data[38] := TBits.RotateLeft32(T, 1);
+  T := a_data[39 - 3] xor a_data[39 - 8] xor a_data[39 - 14] xor a_data
+    [39 - 16];
+  a_data[39] := TBits.RotateLeft32(T, 1);
+  T := a_data[40 - 3] xor a_data[40 - 8] xor a_data[40 - 14] xor a_data
+    [40 - 16];
+  a_data[40] := TBits.RotateLeft32(T, 1);
+  T := a_data[41 - 3] xor a_data[41 - 8] xor a_data[41 - 14] xor a_data
+    [41 - 16];
+  a_data[41] := TBits.RotateLeft32(T, 1);
+  T := a_data[42 - 3] xor a_data[42 - 8] xor a_data[42 - 14] xor a_data
+    [42 - 16];
+  a_data[42] := TBits.RotateLeft32(T, 1);
+  T := a_data[43 - 3] xor a_data[43 - 8] xor a_data[43 - 14] xor a_data
+    [43 - 16];
+  a_data[43] := TBits.RotateLeft32(T, 1);
+  T := a_data[44 - 3] xor a_data[44 - 8] xor a_data[44 - 14] xor a_data
+    [44 - 16];
+  a_data[44] := TBits.RotateLeft32(T, 1);
+  T := a_data[45 - 3] xor a_data[45 - 8] xor a_data[45 - 14] xor a_data
+    [45 - 16];
+  a_data[45] := TBits.RotateLeft32(T, 1);
+  T := a_data[46 - 3] xor a_data[46 - 8] xor a_data[46 - 14] xor a_data
+    [46 - 16];
+  a_data[46] := TBits.RotateLeft32(T, 1);
+  T := a_data[47 - 3] xor a_data[47 - 8] xor a_data[47 - 14] xor a_data
+    [47 - 16];
+  a_data[47] := TBits.RotateLeft32(T, 1);
+  T := a_data[48 - 3] xor a_data[48 - 8] xor a_data[48 - 14] xor a_data
+    [48 - 16];
+  a_data[48] := TBits.RotateLeft32(T, 1);
+  T := a_data[49 - 3] xor a_data[49 - 8] xor a_data[49 - 14] xor a_data
+    [49 - 16];
+  a_data[49] := TBits.RotateLeft32(T, 1);
+  T := a_data[50 - 3] xor a_data[50 - 8] xor a_data[50 - 14] xor a_data
+    [50 - 16];
+  a_data[50] := TBits.RotateLeft32(T, 1);
+  T := a_data[51 - 3] xor a_data[51 - 8] xor a_data[51 - 14] xor a_data
+    [51 - 16];
+  a_data[51] := TBits.RotateLeft32(T, 1);
+  T := a_data[52 - 3] xor a_data[52 - 8] xor a_data[52 - 14] xor a_data
+    [52 - 16];
+  a_data[52] := TBits.RotateLeft32(T, 1);
+  T := a_data[53 - 3] xor a_data[53 - 8] xor a_data[53 - 14] xor a_data
+    [53 - 16];
+  a_data[53] := TBits.RotateLeft32(T, 1);
+  T := a_data[54 - 3] xor a_data[54 - 8] xor a_data[54 - 14] xor a_data
+    [54 - 16];
+  a_data[54] := TBits.RotateLeft32(T, 1);
+  T := a_data[55 - 3] xor a_data[55 - 8] xor a_data[55 - 14] xor a_data
+    [55 - 16];
+  a_data[55] := TBits.RotateLeft32(T, 1);
+  T := a_data[56 - 3] xor a_data[56 - 8] xor a_data[56 - 14] xor a_data
+    [56 - 16];
+  a_data[56] := TBits.RotateLeft32(T, 1);
+  T := a_data[57 - 3] xor a_data[57 - 8] xor a_data[57 - 14] xor a_data
+    [57 - 16];
+  a_data[57] := TBits.RotateLeft32(T, 1);
+  T := a_data[58 - 3] xor a_data[58 - 8] xor a_data[58 - 14] xor a_data
+    [58 - 16];
+  a_data[58] := TBits.RotateLeft32(T, 1);
+  T := a_data[59 - 3] xor a_data[59 - 8] xor a_data[59 - 14] xor a_data
+    [59 - 16];
+  a_data[59] := TBits.RotateLeft32(T, 1);
+  T := a_data[60 - 3] xor a_data[60 - 8] xor a_data[60 - 14] xor a_data
+    [60 - 16];
+  a_data[60] := TBits.RotateLeft32(T, 1);
+  T := a_data[61 - 3] xor a_data[61 - 8] xor a_data[61 - 14] xor a_data
+    [61 - 16];
+  a_data[61] := TBits.RotateLeft32(T, 1);
+  T := a_data[62 - 3] xor a_data[62 - 8] xor a_data[62 - 14] xor a_data
+    [62 - 16];
+  a_data[62] := TBits.RotateLeft32(T, 1);
+  T := a_data[63 - 3] xor a_data[63 - 8] xor a_data[63 - 14] xor a_data
+    [63 - 16];
+  a_data[63] := TBits.RotateLeft32(T, 1);
+  T := a_data[64 - 3] xor a_data[64 - 8] xor a_data[64 - 14] xor a_data
+    [64 - 16];
+  a_data[64] := TBits.RotateLeft32(T, 1);
+  T := a_data[65 - 3] xor a_data[65 - 8] xor a_data[65 - 14] xor a_data
+    [65 - 16];
+  a_data[65] := TBits.RotateLeft32(T, 1);
+  T := a_data[66 - 3] xor a_data[66 - 8] xor a_data[66 - 14] xor a_data
+    [66 - 16];
+  a_data[66] := TBits.RotateLeft32(T, 1);
+  T := a_data[67 - 3] xor a_data[67 - 8] xor a_data[67 - 14] xor a_data
+    [67 - 16];
+  a_data[67] := TBits.RotateLeft32(T, 1);
+  T := a_data[68 - 3] xor a_data[68 - 8] xor a_data[68 - 14] xor a_data
+    [68 - 16];
+  a_data[68] := TBits.RotateLeft32(T, 1);
+  T := a_data[69 - 3] xor a_data[69 - 8] xor a_data[69 - 14] xor a_data
+    [69 - 16];
+  a_data[69] := TBits.RotateLeft32(T, 1);
+  T := a_data[70 - 3] xor a_data[70 - 8] xor a_data[70 - 14] xor a_data
+    [70 - 16];
+  a_data[70] := TBits.RotateLeft32(T, 1);
+  T := a_data[71 - 3] xor a_data[71 - 8] xor a_data[71 - 14] xor a_data
+    [71 - 16];
+  a_data[71] := TBits.RotateLeft32(T, 1);
+  T := a_data[72 - 3] xor a_data[72 - 8] xor a_data[72 - 14] xor a_data
+    [72 - 16];
+  a_data[72] := TBits.RotateLeft32(T, 1);
+  T := a_data[73 - 3] xor a_data[73 - 8] xor a_data[73 - 14] xor a_data
+    [73 - 16];
+  a_data[73] := TBits.RotateLeft32(T, 1);
+  T := a_data[74 - 3] xor a_data[74 - 8] xor a_data[74 - 14] xor a_data
+    [74 - 16];
+  a_data[74] := TBits.RotateLeft32(T, 1);
+  T := a_data[75 - 3] xor a_data[75 - 8] xor a_data[75 - 14] xor a_data
+    [75 - 16];
+  a_data[75] := TBits.RotateLeft32(T, 1);
+  T := a_data[76 - 3] xor a_data[76 - 8] xor a_data[76 - 14] xor a_data
+    [76 - 16];
+  a_data[76] := TBits.RotateLeft32(T, 1);
+  T := a_data[77 - 3] xor a_data[77 - 8] xor a_data[77 - 14] xor a_data
+    [77 - 16];
+  a_data[77] := TBits.RotateLeft32(T, 1);
+  T := a_data[78 - 3] xor a_data[78 - 8] xor a_data[78 - 14] xor a_data
+    [78 - 16];
+  a_data[78] := TBits.RotateLeft32(T, 1);
+  T := a_data[79 - 3] xor a_data[79 - 8] xor a_data[79 - 14] xor a_data
+    [79 - 16];
+  a_data[79] := TBits.RotateLeft32(T, 1);
+
+{$ELSE}
+  for i := 16 to 79 do
+  begin
+    T := a_data[i - 3] xor a_data[i - 8] xor a_data[i - 14] xor a_data[i - 16];
+    a_data[i] := TBits.RotateLeft32(T, 1);
+  end;
+{$ENDIF USE_UNROLLED_VARIANT}
+end;
+
+end.

+ 61 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA2_224.pas

@@ -0,0 +1,61 @@
+unit HlpSHA2_224;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpSHA2_256Base,
+  HlpConverters;
+
+type
+  TSHA2_224 = class sealed(TSHA2_256Base)
+
+  strict protected
+    function GetResult(): THashLibByteArray; override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TSHA2_224 }
+
+constructor TSHA2_224.Create;
+begin
+  Inherited Create(28);
+end;
+
+function TSHA2_224.GetResult: THashLibByteArray;
+begin
+  System.SetLength(result, 7 * System.SizeOf(UInt32));
+  TConverters.be32_copy(PCardinal(Fm_state), 0, PByte(result), 0,
+    System.Length(result));
+end;
+
+procedure TSHA2_224.Initialize;
+begin
+  Fm_state[0] := $C1059ED8;
+  Fm_state[1] := $367CD507;
+  Fm_state[2] := $3070DD17;
+  Fm_state[3] := $F70E5939;
+  Fm_state[4] := $FFC00B31;
+  Fm_state[5] := $68581511;
+  Fm_state[6] := $64F98FA7;
+  Fm_state[7] := $BEFA4FA4;
+
+  Inherited Initialize();
+
+end;
+
+end.

+ 63 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA2_256.pas

@@ -0,0 +1,63 @@
+unit HlpSHA2_256;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpSHA2_256Base,
+  HlpConverters;
+
+type
+  TSHA2_256 = class sealed(TSHA2_256Base)
+
+  strict protected
+    function GetResult(): THashLibByteArray; override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TSHA2_256 }
+
+constructor TSHA2_256.Create;
+begin
+  Inherited Create(32);
+end;
+
+function TSHA2_256.GetResult: THashLibByteArray;
+begin
+
+  System.SetLength(result, 8 * System.SizeOf(UInt32));
+  TConverters.be32_copy(PCardinal(Fm_state), 0, PByte(result), 0,
+    System.Length(result));
+
+end;
+
+procedure TSHA2_256.Initialize;
+begin
+  Fm_state[0] := $6A09E667;
+  Fm_state[1] := $BB67AE85;
+  Fm_state[2] := $3C6EF372;
+  Fm_state[3] := $A54FF53A;
+  Fm_state[4] := $510E527F;
+  Fm_state[5] := $9B05688C;
+  Fm_state[6] := $1F83D9AB;
+  Fm_state[7] := $5BE0CD19;
+
+  Inherited Initialize();
+
+end;
+
+end.

+ 948 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA2_256Base.pas

@@ -0,0 +1,948 @@
+unit HlpSHA2_256Base;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpHashBuffer,
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpBits,
+  HlpConverters,
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn;
+
+type
+  TSHA2_256Base = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+{$IFNDEF USE_UNROLLED_VARIANT}
+{$REGION 'Consts'}
+  const
+
+    s_K: array [0 .. 63] of UInt32 = ($428A2F98, $71374491, $B5C0FBCF,
+      $E9B5DBA5, $3956C25B, $59F111F1, $923F82A4, $AB1C5ED5, $D807AA98,
+      $12835B01, $243185BE, $550C7DC3, $72BE5D74, $80DEB1FE, $9BDC06A7,
+      $C19BF174, $E49B69C1, $EFBE4786, $0FC19DC6, $240CA1CC, $2DE92C6F,
+      $4A7484AA, $5CB0A9DC, $76F988DA, $983E5152, $A831C66D, $B00327C8,
+      $BF597FC7, $C6E00BF3, $D5A79147, $06CA6351, $14292967, $27B70A85,
+      $2E1B2138, $4D2C6DFC, $53380D13, $650A7354, $766A0ABB, $81C2C92E,
+      $92722C85, $A2BFE8A1, $A81A664B, $C24B8B70, $C76C51A3, $D192E819,
+      $D6990624, $F40E3585, $106AA070, $19A4C116, $1E376C08, $2748774C,
+      $34B0BCB5, $391C0CB3, $4ED8AA4A, $5B9CCA4F, $682E6FF3, $748F82EE,
+      $78A5636F, $84C87814, $8CC70208, $90BEFFFA, $A4506CEB, $BEF9A3F7,
+      $C67178F2);
+
+{$ENDREGION}
+{$ENDIF USE_UNROLLED_VARIANT}
+  strict protected
+    Fm_state: THashLibUInt32Array;
+
+    constructor Create(a_hash_size: Int32);
+
+    procedure Finish(); override;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  end;
+
+implementation
+
+{ TSHA2_256Base }
+
+constructor TSHA2_256Base.Create(a_hash_size: Int32);
+begin
+  Inherited Create(a_hash_size, 64);
+  System.SetLength(Fm_state, 8);
+end;
+
+procedure TSHA2_256Base.Finish;
+var
+  bits: UInt64;
+  padindex: Int32;
+  pad: THashLibByteArray;
+begin
+  bits := Fm_processed_bytes * 8;
+  if (Fm_buffer.Pos < 56) then
+
+    padindex := (56 - Fm_buffer.Pos)
+  else
+    padindex := (120 - Fm_buffer.Pos);
+  System.SetLength(pad, padindex + 8);
+  pad[0] := $80;
+
+  bits := TConverters.be2me_64(bits);
+
+  TConverters.ReadUInt64AsBytesLE(bits, pad, padindex);
+
+  padindex := padindex + 8;
+
+  TransformBytes(pad, 0, padindex);
+
+end;
+
+procedure TSHA2_256Base.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  A, B, C, D, E, F, G, H, T, T2: UInt32;
+{$IFNDEF USE_UNROLLED_VARIANT}
+  r: Int32;
+{$ENDIF USE_UNROLLED_VARIANT}
+  data: array [0 .. 63] of UInt32;
+begin
+
+  TConverters.be32_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+
+  A := Fm_state[0];
+  B := Fm_state[1];
+  C := Fm_state[2];
+  D := Fm_state[3];
+  E := Fm_state[4];
+  F := Fm_state[5];
+  G := Fm_state[6];
+  H := Fm_state[7];
+
+  // Step 1
+
+{$IFDEF USE_UNROLLED_VARIANT}
+  T := data[14];
+  T2 := data[1];
+  data[16] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[9] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[0];
+
+  T := data[15];
+  T2 := data[2];
+  data[17] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[10] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[1];
+
+  T := data[16];
+  T2 := data[3];
+  data[18] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[11] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[2];
+
+  T := data[17];
+  T2 := data[4];
+  data[19] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[12] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[3];
+
+  T := data[18];
+  T2 := data[5];
+  data[20] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[13] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[4];
+
+  T := data[19];
+  T2 := data[6];
+  data[21] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[14] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[5];
+
+  T := data[20];
+  T2 := data[7];
+  data[22] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[15] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[6];
+
+  T := data[21];
+  T2 := data[8];
+  data[23] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[16] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[7];
+
+  T := data[22];
+  T2 := data[9];
+  data[24] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[17] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[8];
+
+  T := data[23];
+  T2 := data[10];
+  data[25] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[18] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[9];
+
+  T := data[24];
+  T2 := data[11];
+  data[26] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[19] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[10];
+
+  T := data[25];
+  T2 := data[12];
+  data[27] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[20] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[11];
+
+  T := data[26];
+  T2 := data[13];
+  data[28] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[21] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[12];
+
+  T := data[27];
+  T2 := data[14];
+  data[29] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[22] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[13];
+
+  T := data[28];
+  T2 := data[15];
+  data[30] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[23] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[14];
+
+  T := data[29];
+  T2 := data[16];
+  data[31] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[24] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[15];
+
+  T := data[30];
+  T2 := data[17];
+  data[32] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[25] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[16];
+
+  T := data[31];
+  T2 := data[18];
+  data[33] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[26] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[17];
+
+  T := data[32];
+  T2 := data[19];
+  data[34] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[27] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[18];
+
+  T := data[33];
+  T2 := data[20];
+  data[35] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[28] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[19];
+
+  T := data[34];
+  T2 := data[21];
+  data[36] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[29] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[20];
+
+  T := data[35];
+  T2 := data[22];
+  data[37] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[30] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[21];
+
+  T := data[36];
+  T2 := data[23];
+  data[38] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[31] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[22];
+
+  T := data[37];
+  T2 := data[24];
+  data[39] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[32] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[23];
+
+  T := data[38];
+  T2 := data[25];
+  data[40] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[33] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[24];
+
+  T := data[39];
+  T2 := data[26];
+  data[41] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[34] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[25];
+
+  T := data[40];
+  T2 := data[27];
+  data[42] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[35] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[26];
+
+  T := data[41];
+  T2 := data[28];
+  data[43] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[36] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[27];
+
+  T := data[42];
+  T2 := data[29];
+  data[44] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[37] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[28];
+
+  T := data[43];
+  T2 := data[30];
+  data[45] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[38] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[29];
+
+  T := data[44];
+  T2 := data[31];
+  data[46] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[39] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[30];
+
+  T := data[45];
+  T2 := data[32];
+  data[47] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[40] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[31];
+
+  T := data[46];
+  T2 := data[33];
+  data[48] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[41] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[32];
+
+  T := data[47];
+  T2 := data[34];
+  data[49] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[42] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[33];
+
+  T := data[48];
+  T2 := data[35];
+  data[50] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[43] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[34];
+
+  T := data[49];
+  T2 := data[36];
+  data[51] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[44] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[35];
+
+  T := data[50];
+  T2 := data[37];
+  data[52] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[45] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[36];
+
+  T := data[51];
+  T2 := data[38];
+  data[53] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[46] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[37];
+
+  T := data[52];
+  T2 := data[39];
+  data[54] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[47] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[38];
+
+  T := data[53];
+  T2 := data[40];
+  data[55] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[48] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[39];
+
+  T := data[54];
+  T2 := data[41];
+  data[56] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[49] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[40];
+
+  T := data[55];
+  T2 := data[42];
+  data[57] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[50] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[41];
+
+  T := data[56];
+  T2 := data[43];
+  data[58] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[51] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[42];
+
+  T := data[57];
+  T2 := data[44];
+  data[59] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[52] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[43];
+
+  T := data[58];
+  T2 := data[45];
+  data[60] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[53] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[44];
+
+  T := data[59];
+  T2 := data[46];
+  data[61] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[54] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[45];
+
+  T := data[60];
+  T2 := data[47];
+  data[62] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[55] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[46];
+
+  T := data[61];
+  T2 := data[48];
+  data[63] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+    xor (T shr 10)) + data[56] +
+    ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+    xor (T2 shr 3)) + data[47];
+
+  // Step 2
+
+  T := H + ((TBits.RotateRight32(E, 6)) xor (TBits.RotateRight32(E, 11))
+    xor (TBits.RotateRight32(E, 25))) + ((E and F) xor (not E and G)) +
+    $428A2F98 + data[0];
+  T2 := ((TBits.RotateRight32(A, 2)) xor (TBits.RotateRight32(A, 13))
+    xor ((A shr 22) xor (A shl 10))) + ((A and B) xor (A and C) xor (B and C));
+  H := T + T2;
+  D := D + T;
+  T := G + ((TBits.RotateRight32(D, 6)) xor (TBits.RotateRight32(D, 11))
+    xor (TBits.RotateRight32(D, 25))) + ((D and E) xor (not D and F)) +
+    $71374491 + data[1];
+  T2 := ((TBits.RotateRight32(H, 2)) xor (TBits.RotateRight32(H, 13))
+    xor ((H shr 22) xor (H shl 10))) + ((H and A) xor (H and B) xor (A and B));
+  G := T + T2;
+  C := C + T;
+  T := F + ((TBits.RotateRight32(C, 6)) xor (TBits.RotateRight32(C, 11))
+    xor (TBits.RotateRight32(C, 25))) + ((C and D) xor (not C and E)) +
+    $B5C0FBCF + data[2];
+  T2 := ((TBits.RotateRight32(G, 2)) xor (TBits.RotateRight32(G, 13))
+    xor ((G shr 22) xor (G shl 10))) + ((G and H) xor (G and A) xor (H and A));
+  F := T + T2;
+  B := B + T;
+  T := E + ((TBits.RotateRight32(B, 6)) xor (TBits.RotateRight32(B, 11))
+    xor (TBits.RotateRight32(B, 25))) + ((B and C) xor (not B and D)) +
+    $E9B5DBA5 + data[3];
+  T2 := ((TBits.RotateRight32(F, 2)) xor (TBits.RotateRight32(F, 13))
+    xor ((F shr 22) xor (F shl 10))) + ((F and G) xor (F and H) xor (G and H));
+  E := T + T2;
+  A := A + T;
+  T := D + ((TBits.RotateRight32(A, 6)) xor (TBits.RotateRight32(A, 11))
+    xor (TBits.RotateRight32(A, 25))) + ((A and B) xor (not A and C)) +
+    $3956C25B + data[4];
+  T2 := ((TBits.RotateRight32(E, 2)) xor (TBits.RotateRight32(E, 13))
+    xor ((E shr 22) xor (E shl 10))) + ((E and F) xor (E and G) xor (F and G));
+  D := T + T2;
+  H := H + T;
+  T := C + ((TBits.RotateRight32(H, 6)) xor (TBits.RotateRight32(H, 11))
+    xor (TBits.RotateRight32(H, 25))) + ((H and A) xor (not H and B)) +
+    $59F111F1 + data[5];
+  T2 := ((TBits.RotateRight32(D, 2)) xor (TBits.RotateRight32(D, 13))
+    xor ((D shr 22) xor (D shl 10))) + ((D and E) xor (D and F) xor (E and F));
+  C := T + T2;
+  G := G + T;
+  T := B + ((TBits.RotateRight32(G, 6)) xor (TBits.RotateRight32(G, 11))
+    xor (TBits.RotateRight32(G, 25))) + ((G and H) xor (not G and A)) +
+    $923F82A4 + data[6];
+  T2 := ((TBits.RotateRight32(C, 2)) xor (TBits.RotateRight32(C, 13))
+    xor ((C shr 22) xor (C shl 10))) + ((C and D) xor (C and E) xor (D and E));
+  B := T + T2;
+  F := F + T;
+  T := A + ((TBits.RotateRight32(F, 6)) xor (TBits.RotateRight32(F, 11))
+    xor (TBits.RotateRight32(F, 25))) + ((F and G) xor (not F and H)) +
+    $AB1C5ED5 + data[7];
+  T2 := ((TBits.RotateRight32(B, 2)) xor (TBits.RotateRight32(B, 13))
+    xor ((B shr 22) xor (B shl 10))) + ((B and C) xor (B and D) xor (C and D));
+  A := T + T2;
+  E := E + T;
+  T := H + ((TBits.RotateRight32(E, 6)) xor (TBits.RotateRight32(E, 11))
+    xor (TBits.RotateRight32(E, 25))) + ((E and F) xor (not E and G)) +
+    $D807AA98 + data[8];
+  T2 := ((TBits.RotateRight32(A, 2)) xor (TBits.RotateRight32(A, 13))
+    xor ((A shr 22) xor (A shl 10))) + ((A and B) xor (A and C) xor (B and C));
+  H := T + T2;
+  D := D + T;
+  T := G + ((TBits.RotateRight32(D, 6)) xor (TBits.RotateRight32(D, 11))
+    xor (TBits.RotateRight32(D, 25))) + ((D and E) xor (not D and F)) +
+    $12835B01 + data[9];
+  T2 := ((TBits.RotateRight32(H, 2)) xor (TBits.RotateRight32(H, 13))
+    xor ((H shr 22) xor (H shl 10))) + ((H and A) xor (H and B) xor (A and B));
+  G := T + T2;
+  C := C + T;
+  T := F + ((TBits.RotateRight32(C, 6)) xor (TBits.RotateRight32(C, 11))
+    xor (TBits.RotateRight32(C, 25))) + ((C and D) xor (not C and E)) +
+    $243185BE + data[10];
+  T2 := ((TBits.RotateRight32(G, 2)) xor (TBits.RotateRight32(G, 13))
+    xor ((G shr 22) xor (G shl 10))) + ((G and H) xor (G and A) xor (H and A));
+  F := T + T2;
+  B := B + T;
+  T := E + ((TBits.RotateRight32(B, 6)) xor (TBits.RotateRight32(B, 11))
+    xor (TBits.RotateRight32(B, 25))) + ((B and C) xor (not B and D)) +
+    $550C7DC3 + data[11];
+  T2 := ((TBits.RotateRight32(F, 2)) xor (TBits.RotateRight32(F, 13))
+    xor ((F shr 22) xor (F shl 10))) + ((F and G) xor (F and H) xor (G and H));
+  E := T + T2;
+  A := A + T;
+  T := D + ((TBits.RotateRight32(A, 6)) xor (TBits.RotateRight32(A, 11))
+    xor (TBits.RotateRight32(A, 25))) + ((A and B) xor (not A and C)) +
+    $72BE5D74 + data[12];
+  T2 := ((TBits.RotateRight32(E, 2)) xor (TBits.RotateRight32(E, 13))
+    xor ((E shr 22) xor (E shl 10))) + ((E and F) xor (E and G) xor (F and G));
+  D := T + T2;
+  H := H + T;
+  T := C + ((TBits.RotateRight32(H, 6)) xor (TBits.RotateRight32(H, 11))
+    xor (TBits.RotateRight32(H, 25))) + ((H and A) xor (not H and B)) +
+    $80DEB1FE + data[13];
+  T2 := ((TBits.RotateRight32(D, 2)) xor (TBits.RotateRight32(D, 13))
+    xor ((D shr 22) xor (D shl 10))) + ((D and E) xor (D and F) xor (E and F));
+  C := T + T2;
+  G := G + T;
+  T := B + ((TBits.RotateRight32(G, 6)) xor (TBits.RotateRight32(G, 11))
+    xor (TBits.RotateRight32(G, 25))) + ((G and H) xor (not G and A)) +
+    $9BDC06A7 + data[14];
+  T2 := ((TBits.RotateRight32(C, 2)) xor (TBits.RotateRight32(C, 13))
+    xor ((C shr 22) xor (C shl 10))) + ((C and D) xor (C and E) xor (D and E));
+  B := T + T2;
+  F := F + T;
+  T := A + ((TBits.RotateRight32(F, 6)) xor (TBits.RotateRight32(F, 11))
+    xor (TBits.RotateRight32(F, 25))) + ((F and G) xor (not F and H)) +
+    $C19BF174 + data[15];
+  T2 := ((TBits.RotateRight32(B, 2)) xor (TBits.RotateRight32(B, 13))
+    xor ((B shr 22) xor (B shl 10))) + ((B and C) xor (B and D) xor (C and D));
+  A := T + T2;
+  E := E + T;
+  T := H + ((TBits.RotateRight32(E, 6)) xor (TBits.RotateRight32(E, 11))
+    xor (TBits.RotateRight32(E, 25))) + ((E and F) xor (not E and G)) +
+    $E49B69C1 + data[16];
+  T2 := ((TBits.RotateRight32(A, 2)) xor (TBits.RotateRight32(A, 13))
+    xor ((A shr 22) xor (A shl 10))) + ((A and B) xor (A and C) xor (B and C));
+  H := T + T2;
+  D := D + T;
+  T := G + ((TBits.RotateRight32(D, 6)) xor (TBits.RotateRight32(D, 11))
+    xor (TBits.RotateRight32(D, 25))) + ((D and E) xor (not D and F)) +
+    $EFBE4786 + data[17];
+  T2 := ((TBits.RotateRight32(H, 2)) xor (TBits.RotateRight32(H, 13))
+    xor ((H shr 22) xor (H shl 10))) + ((H and A) xor (H and B) xor (A and B));
+  G := T + T2;
+  C := C + T;
+  T := F + ((TBits.RotateRight32(C, 6)) xor (TBits.RotateRight32(C, 11))
+    xor (TBits.RotateRight32(C, 25))) + ((C and D) xor (not C and E)) +
+    $0FC19DC6 + data[18];
+  T2 := ((TBits.RotateRight32(G, 2)) xor (TBits.RotateRight32(G, 13))
+    xor ((G shr 22) xor (G shl 10))) + ((G and H) xor (G and A) xor (H and A));
+  F := T + T2;
+  B := B + T;
+  T := E + ((TBits.RotateRight32(B, 6)) xor (TBits.RotateRight32(B, 11))
+    xor (TBits.RotateRight32(B, 25))) + ((B and C) xor (not B and D)) +
+    $240CA1CC + data[19];
+  T2 := ((TBits.RotateRight32(F, 2)) xor (TBits.RotateRight32(F, 13))
+    xor ((F shr 22) xor (F shl 10))) + ((F and G) xor (F and H) xor (G and H));
+  E := T + T2;
+  A := A + T;
+  T := D + ((TBits.RotateRight32(A, 6)) xor (TBits.RotateRight32(A, 11))
+    xor (TBits.RotateRight32(A, 25))) + ((A and B) xor (not A and C)) +
+    $2DE92C6F + data[20];
+  T2 := ((TBits.RotateRight32(E, 2)) xor (TBits.RotateRight32(E, 13))
+    xor ((E shr 22) xor (E shl 10))) + ((E and F) xor (E and G) xor (F and G));
+  D := T + T2;
+  H := H + T;
+  T := C + ((TBits.RotateRight32(H, 6)) xor (TBits.RotateRight32(H, 11))
+    xor (TBits.RotateRight32(H, 25))) + ((H and A) xor (not H and B)) +
+    $4A7484AA + data[21];
+  T2 := ((TBits.RotateRight32(D, 2)) xor (TBits.RotateRight32(D, 13))
+    xor ((D shr 22) xor (D shl 10))) + ((D and E) xor (D and F) xor (E and F));
+  C := T + T2;
+  G := G + T;
+  T := B + ((TBits.RotateRight32(G, 6)) xor (TBits.RotateRight32(G, 11))
+    xor (TBits.RotateRight32(G, 25))) + ((G and H) xor (not G and A)) +
+    $5CB0A9DC + data[22];
+  T2 := ((TBits.RotateRight32(C, 2)) xor (TBits.RotateRight32(C, 13))
+    xor ((C shr 22) xor (C shl 10))) + ((C and D) xor (C and E) xor (D and E));
+  B := T + T2;
+  F := F + T;
+  T := A + ((TBits.RotateRight32(F, 6)) xor (TBits.RotateRight32(F, 11))
+    xor (TBits.RotateRight32(F, 25))) + ((F and G) xor (not F and H)) +
+    $76F988DA + data[23];
+  T2 := ((TBits.RotateRight32(B, 2)) xor (TBits.RotateRight32(B, 13))
+    xor ((B shr 22) xor (B shl 10))) + ((B and C) xor (B and D) xor (C and D));
+  A := T + T2;
+  E := E + T;
+  T := H + ((TBits.RotateRight32(E, 6)) xor (TBits.RotateRight32(E, 11))
+    xor (TBits.RotateRight32(E, 25))) + ((E and F) xor (not E and G)) +
+    $983E5152 + data[24];
+  T2 := ((TBits.RotateRight32(A, 2)) xor (TBits.RotateRight32(A, 13))
+    xor ((A shr 22) xor (A shl 10))) + ((A and B) xor (A and C) xor (B and C));
+  H := T + T2;
+  D := D + T;
+  T := G + ((TBits.RotateRight32(D, 6)) xor (TBits.RotateRight32(D, 11))
+    xor (TBits.RotateRight32(D, 25))) + ((D and E) xor (not D and F)) +
+    $A831C66D + data[25];
+  T2 := ((TBits.RotateRight32(H, 2)) xor (TBits.RotateRight32(H, 13))
+    xor ((H shr 22) xor (H shl 10))) + ((H and A) xor (H and B) xor (A and B));
+  G := T + T2;
+  C := C + T;
+  T := F + ((TBits.RotateRight32(C, 6)) xor (TBits.RotateRight32(C, 11))
+    xor (TBits.RotateRight32(C, 25))) + ((C and D) xor (not C and E)) +
+    $B00327C8 + data[26];
+  T2 := ((TBits.RotateRight32(G, 2)) xor (TBits.RotateRight32(G, 13))
+    xor ((G shr 22) xor (G shl 10))) + ((G and H) xor (G and A) xor (H and A));
+  F := T + T2;
+  B := B + T;
+  T := E + ((TBits.RotateRight32(B, 6)) xor (TBits.RotateRight32(B, 11))
+    xor (TBits.RotateRight32(B, 25))) + ((B and C) xor (not B and D)) +
+    $BF597FC7 + data[27];
+  T2 := ((TBits.RotateRight32(F, 2)) xor (TBits.RotateRight32(F, 13))
+    xor ((F shr 22) xor (F shl 10))) + ((F and G) xor (F and H) xor (G and H));
+  E := T + T2;
+  A := A + T;
+  T := D + ((TBits.RotateRight32(A, 6)) xor (TBits.RotateRight32(A, 11))
+    xor (TBits.RotateRight32(A, 25))) + ((A and B) xor (not A and C)) +
+    $C6E00BF3 + data[28];
+  T2 := ((TBits.RotateRight32(E, 2)) xor (TBits.RotateRight32(E, 13))
+    xor ((E shr 22) xor (E shl 10))) + ((E and F) xor (E and G) xor (F and G));
+  D := T + T2;
+  H := H + T;
+  T := C + ((TBits.RotateRight32(H, 6)) xor (TBits.RotateRight32(H, 11))
+    xor (TBits.RotateRight32(H, 25))) + ((H and A) xor (not H and B)) +
+    $D5A79147 + data[29];
+  T2 := ((TBits.RotateRight32(D, 2)) xor (TBits.RotateRight32(D, 13))
+    xor ((D shr 22) xor (D shl 10))) + ((D and E) xor (D and F) xor (E and F));
+  C := T + T2;
+  G := G + T;
+  T := B + ((TBits.RotateRight32(G, 6)) xor (TBits.RotateRight32(G, 11))
+    xor (TBits.RotateRight32(G, 25))) + ((G and H) xor (not G and A)) +
+    $06CA6351 + data[30];
+  T2 := ((TBits.RotateRight32(C, 2)) xor (TBits.RotateRight32(C, 13))
+    xor ((C shr 22) xor (C shl 10))) + ((C and D) xor (C and E) xor (D and E));
+  B := T + T2;
+  F := F + T;
+  T := A + ((TBits.RotateRight32(F, 6)) xor (TBits.RotateRight32(F, 11))
+    xor (TBits.RotateRight32(F, 25))) + ((F and G) xor (not F and H)) +
+    $14292967 + data[31];
+  T2 := ((TBits.RotateRight32(B, 2)) xor (TBits.RotateRight32(B, 13))
+    xor ((B shr 22) xor (B shl 10))) + ((B and C) xor (B and D) xor (C and D));
+  A := T + T2;
+  E := E + T;
+  T := H + ((TBits.RotateRight32(E, 6)) xor (TBits.RotateRight32(E, 11))
+    xor (TBits.RotateRight32(E, 25))) + ((E and F) xor (not E and G)) +
+    $27B70A85 + data[32];
+  T2 := ((TBits.RotateRight32(A, 2)) xor (TBits.RotateRight32(A, 13))
+    xor ((A shr 22) xor (A shl 10))) + ((A and B) xor (A and C) xor (B and C));
+  H := T + T2;
+  D := D + T;
+  T := G + ((TBits.RotateRight32(D, 6)) xor (TBits.RotateRight32(D, 11))
+    xor (TBits.RotateRight32(D, 25))) + ((D and E) xor (not D and F)) +
+    $2E1B2138 + data[33];
+  T2 := ((TBits.RotateRight32(H, 2)) xor (TBits.RotateRight32(H, 13))
+    xor ((H shr 22) xor (H shl 10))) + ((H and A) xor (H and B) xor (A and B));
+  G := T + T2;
+  C := C + T;
+  T := F + ((TBits.RotateRight32(C, 6)) xor (TBits.RotateRight32(C, 11))
+    xor (TBits.RotateRight32(C, 25))) + ((C and D) xor (not C and E)) +
+    $4D2C6DFC + data[34];
+  T2 := ((TBits.RotateRight32(G, 2)) xor (TBits.RotateRight32(G, 13))
+    xor ((G shr 22) xor (G shl 10))) + ((G and H) xor (G and A) xor (H and A));
+  F := T + T2;
+  B := B + T;
+  T := E + ((TBits.RotateRight32(B, 6)) xor (TBits.RotateRight32(B, 11))
+    xor (TBits.RotateRight32(B, 25))) + ((B and C) xor (not B and D)) +
+    $53380D13 + data[35];
+  T2 := ((TBits.RotateRight32(F, 2)) xor (TBits.RotateRight32(F, 13))
+    xor ((F shr 22) xor (F shl 10))) + ((F and G) xor (F and H) xor (G and H));
+  E := T + T2;
+  A := A + T;
+  T := D + ((TBits.RotateRight32(A, 6)) xor (TBits.RotateRight32(A, 11))
+    xor (TBits.RotateRight32(A, 25))) + ((A and B) xor (not A and C)) +
+    $650A7354 + data[36];
+  T2 := ((TBits.RotateRight32(E, 2)) xor (TBits.RotateRight32(E, 13))
+    xor ((E shr 22) xor (E shl 10))) + ((E and F) xor (E and G) xor (F and G));
+  D := T + T2;
+  H := H + T;
+  T := C + ((TBits.RotateRight32(H, 6)) xor (TBits.RotateRight32(H, 11))
+    xor (TBits.RotateRight32(H, 25))) + ((H and A) xor (not H and B)) +
+    $766A0ABB + data[37];
+  T2 := ((TBits.RotateRight32(D, 2)) xor (TBits.RotateRight32(D, 13))
+    xor ((D shr 22) xor (D shl 10))) + ((D and E) xor (D and F) xor (E and F));
+  C := T + T2;
+  G := G + T;
+  T := B + ((TBits.RotateRight32(G, 6)) xor (TBits.RotateRight32(G, 11))
+    xor (TBits.RotateRight32(G, 25))) + ((G and H) xor (not G and A)) +
+    $81C2C92E + data[38];
+  T2 := ((TBits.RotateRight32(C, 2)) xor (TBits.RotateRight32(C, 13))
+    xor ((C shr 22) xor (C shl 10))) + ((C and D) xor (C and E) xor (D and E));
+  B := T + T2;
+  F := F + T;
+  T := A + ((TBits.RotateRight32(F, 6)) xor (TBits.RotateRight32(F, 11))
+    xor (TBits.RotateRight32(F, 25))) + ((F and G) xor (not F and H)) +
+    $92722C85 + data[39];
+  T2 := ((TBits.RotateRight32(B, 2)) xor (TBits.RotateRight32(B, 13))
+    xor ((B shr 22) xor (B shl 10))) + ((B and C) xor (B and D) xor (C and D));
+  A := T + T2;
+  E := E + T;
+  T := H + ((TBits.RotateRight32(E, 6)) xor (TBits.RotateRight32(E, 11))
+    xor (TBits.RotateRight32(E, 25))) + ((E and F) xor (not E and G)) +
+    $A2BFE8A1 + data[40];
+  T2 := ((TBits.RotateRight32(A, 2)) xor (TBits.RotateRight32(A, 13))
+    xor ((A shr 22) xor (A shl 10))) + ((A and B) xor (A and C) xor (B and C));
+  H := T + T2;
+  D := D + T;
+  T := G + ((TBits.RotateRight32(D, 6)) xor (TBits.RotateRight32(D, 11))
+    xor (TBits.RotateRight32(D, 25))) + ((D and E) xor (not D and F)) +
+    $A81A664B + data[41];
+  T2 := ((TBits.RotateRight32(H, 2)) xor (TBits.RotateRight32(H, 13))
+    xor ((H shr 22) xor (H shl 10))) + ((H and A) xor (H and B) xor (A and B));
+  G := T + T2;
+  C := C + T;
+  T := F + ((TBits.RotateRight32(C, 6)) xor (TBits.RotateRight32(C, 11))
+    xor (TBits.RotateRight32(C, 25))) + ((C and D) xor (not C and E)) +
+    $C24B8B70 + data[42];
+  T2 := ((TBits.RotateRight32(G, 2)) xor (TBits.RotateRight32(G, 13))
+    xor ((G shr 22) xor (G shl 10))) + ((G and H) xor (G and A) xor (H and A));
+  F := T + T2;
+  B := B + T;
+  T := E + ((TBits.RotateRight32(B, 6)) xor (TBits.RotateRight32(B, 11))
+    xor (TBits.RotateRight32(B, 25))) + ((B and C) xor (not B and D)) +
+    $C76C51A3 + data[43];
+  T2 := ((TBits.RotateRight32(F, 2)) xor (TBits.RotateRight32(F, 13))
+    xor ((F shr 22) xor (F shl 10))) + ((F and G) xor (F and H) xor (G and H));
+  E := T + T2;
+  A := A + T;
+  T := D + ((TBits.RotateRight32(A, 6)) xor (TBits.RotateRight32(A, 11))
+    xor (TBits.RotateRight32(A, 25))) + ((A and B) xor (not A and C)) +
+    $D192E819 + data[44];
+  T2 := ((TBits.RotateRight32(E, 2)) xor (TBits.RotateRight32(E, 13))
+    xor ((E shr 22) xor (E shl 10))) + ((E and F) xor (E and G) xor (F and G));
+  D := T + T2;
+  H := H + T;
+  T := C + ((TBits.RotateRight32(H, 6)) xor (TBits.RotateRight32(H, 11))
+    xor (TBits.RotateRight32(H, 25))) + ((H and A) xor (not H and B)) +
+    $D6990624 + data[45];
+  T2 := ((TBits.RotateRight32(D, 2)) xor (TBits.RotateRight32(D, 13))
+    xor ((D shr 22) xor (D shl 10))) + ((D and E) xor (D and F) xor (E and F));
+  C := T + T2;
+  G := G + T;
+  T := B + ((TBits.RotateRight32(G, 6)) xor (TBits.RotateRight32(G, 11))
+    xor (TBits.RotateRight32(G, 25))) + ((G and H) xor (not G and A)) +
+    $F40E3585 + data[46];
+  T2 := ((TBits.RotateRight32(C, 2)) xor (TBits.RotateRight32(C, 13))
+    xor ((C shr 22) xor (C shl 10))) + ((C and D) xor (C and E) xor (D and E));
+  B := T + T2;
+  F := F + T;
+  T := A + ((TBits.RotateRight32(F, 6)) xor (TBits.RotateRight32(F, 11))
+    xor (TBits.RotateRight32(F, 25))) + ((F and G) xor (not F and H)) +
+    $106AA070 + data[47];
+  T2 := ((TBits.RotateRight32(B, 2)) xor (TBits.RotateRight32(B, 13))
+    xor ((B shr 22) xor (B shl 10))) + ((B and C) xor (B and D) xor (C and D));
+  A := T + T2;
+  E := E + T;
+  T := H + ((TBits.RotateRight32(E, 6)) xor (TBits.RotateRight32(E, 11))
+    xor (TBits.RotateRight32(E, 25))) + ((E and F) xor (not E and G)) +
+    $19A4C116 + data[48];
+  T2 := ((TBits.RotateRight32(A, 2)) xor (TBits.RotateRight32(A, 13))
+    xor ((A shr 22) xor (A shl 10))) + ((A and B) xor (A and C) xor (B and C));
+  H := T + T2;
+  D := D + T;
+  T := G + ((TBits.RotateRight32(D, 6)) xor (TBits.RotateRight32(D, 11))
+    xor (TBits.RotateRight32(D, 25))) + ((D and E) xor (not D and F)) +
+    $1E376C08 + data[49];
+  T2 := ((TBits.RotateRight32(H, 2)) xor (TBits.RotateRight32(H, 13))
+    xor ((H shr 22) xor (H shl 10))) + ((H and A) xor (H and B) xor (A and B));
+  G := T + T2;
+  C := C + T;
+  T := F + ((TBits.RotateRight32(C, 6)) xor (TBits.RotateRight32(C, 11))
+    xor (TBits.RotateRight32(C, 25))) + ((C and D) xor (not C and E)) +
+    $2748774C + data[50];
+  T2 := ((TBits.RotateRight32(G, 2)) xor (TBits.RotateRight32(G, 13))
+    xor ((G shr 22) xor (G shl 10))) + ((G and H) xor (G and A) xor (H and A));
+  F := T + T2;
+  B := B + T;
+  T := E + ((TBits.RotateRight32(B, 6)) xor (TBits.RotateRight32(B, 11))
+    xor (TBits.RotateRight32(B, 25))) + ((B and C) xor (not B and D)) +
+    $34B0BCB5 + data[51];
+  T2 := ((TBits.RotateRight32(F, 2)) xor (TBits.RotateRight32(F, 13))
+    xor ((F shr 22) xor (F shl 10))) + ((F and G) xor (F and H) xor (G and H));
+  E := T + T2;
+  A := A + T;
+  T := D + ((TBits.RotateRight32(A, 6)) xor (TBits.RotateRight32(A, 11))
+    xor (TBits.RotateRight32(A, 25))) + ((A and B) xor (not A and C)) +
+    $391C0CB3 + data[52];
+  T2 := ((TBits.RotateRight32(E, 2)) xor (TBits.RotateRight32(E, 13))
+    xor ((E shr 22) xor (E shl 10))) + ((E and F) xor (E and G) xor (F and G));
+  D := T + T2;
+  H := H + T;
+  T := C + ((TBits.RotateRight32(H, 6)) xor (TBits.RotateRight32(H, 11))
+    xor (TBits.RotateRight32(H, 25))) + ((H and A) xor (not H and B)) +
+    $4ED8AA4A + data[53];
+  T2 := ((TBits.RotateRight32(D, 2)) xor (TBits.RotateRight32(D, 13))
+    xor ((D shr 22) xor (D shl 10))) + ((D and E) xor (D and F) xor (E and F));
+  C := T + T2;
+  G := G + T;
+  T := B + ((TBits.RotateRight32(G, 6)) xor (TBits.RotateRight32(G, 11))
+    xor (TBits.RotateRight32(G, 25))) + ((G and H) xor (not G and A)) +
+    $5B9CCA4F + data[54];
+  T2 := ((TBits.RotateRight32(C, 2)) xor (TBits.RotateRight32(C, 13))
+    xor ((C shr 22) xor (C shl 10))) + ((C and D) xor (C and E) xor (D and E));
+  B := T + T2;
+  F := F + T;
+  T := A + ((TBits.RotateRight32(F, 6)) xor (TBits.RotateRight32(F, 11))
+    xor (TBits.RotateRight32(F, 25))) + ((F and G) xor (not F and H)) +
+    $682E6FF3 + data[55];
+  T2 := ((TBits.RotateRight32(B, 2)) xor (TBits.RotateRight32(B, 13))
+    xor ((B shr 22) xor (B shl 10))) + ((B and C) xor (B and D) xor (C and D));
+  A := T + T2;
+  E := E + T;
+  T := H + ((TBits.RotateRight32(E, 6)) xor (TBits.RotateRight32(E, 11))
+    xor (TBits.RotateRight32(E, 25))) + ((E and F) xor (not E and G)) +
+    $748F82EE + data[56];
+  T2 := ((TBits.RotateRight32(A, 2)) xor (TBits.RotateRight32(A, 13))
+    xor ((A shr 22) xor (A shl 10))) + ((A and B) xor (A and C) xor (B and C));
+  H := T + T2;
+  D := D + T;
+  T := G + ((TBits.RotateRight32(D, 6)) xor (TBits.RotateRight32(D, 11))
+    xor (TBits.RotateRight32(D, 25))) + ((D and E) xor (not D and F)) +
+    $78A5636F + data[57];
+  T2 := ((TBits.RotateRight32(H, 2)) xor (TBits.RotateRight32(H, 13))
+    xor ((H shr 22) xor (H shl 10))) + ((H and A) xor (H and B) xor (A and B));
+  G := T + T2;
+  C := C + T;
+  T := F + ((TBits.RotateRight32(C, 6)) xor (TBits.RotateRight32(C, 11))
+    xor (TBits.RotateRight32(C, 25))) + ((C and D) xor (not C and E)) +
+    $84C87814 + data[58];
+  T2 := ((TBits.RotateRight32(G, 2)) xor (TBits.RotateRight32(G, 13))
+    xor ((G shr 22) xor (G shl 10))) + ((G and H) xor (G and A) xor (H and A));
+  F := T + T2;
+  B := B + T;
+  T := E + ((TBits.RotateRight32(B, 6)) xor (TBits.RotateRight32(B, 11))
+    xor (TBits.RotateRight32(B, 25))) + ((B and C) xor (not B and D)) +
+    $8CC70208 + data[59];
+  T2 := ((TBits.RotateRight32(F, 2)) xor (TBits.RotateRight32(F, 13))
+    xor ((F shr 22) xor (F shl 10))) + ((F and G) xor (F and H) xor (G and H));
+  E := T + T2;
+  A := A + T;
+  T := D + ((TBits.RotateRight32(A, 6)) xor (TBits.RotateRight32(A, 11))
+    xor (TBits.RotateRight32(A, 25))) + ((A and B) xor (not A and C)) +
+    $90BEFFFA + data[60];
+  T2 := ((TBits.RotateRight32(E, 2)) xor (TBits.RotateRight32(E, 13))
+    xor ((E shr 22) xor (E shl 10))) + ((E and F) xor (E and G) xor (F and G));
+  D := T + T2;
+  H := H + T;
+  T := C + ((TBits.RotateRight32(H, 6)) xor (TBits.RotateRight32(H, 11))
+    xor (TBits.RotateRight32(H, 25))) + ((H and A) xor (not H and B)) +
+    $A4506CEB + data[61];
+  T2 := ((TBits.RotateRight32(D, 2)) xor (TBits.RotateRight32(D, 13))
+    xor ((D shr 22) xor (D shl 10))) + ((D and E) xor (D and F) xor (E and F));
+  C := T + T2;
+  G := G + T;
+  T := B + ((TBits.RotateRight32(G, 6)) xor (TBits.RotateRight32(G, 11))
+    xor (TBits.RotateRight32(G, 25))) + ((G and H) xor (not G and A)) +
+    $BEF9A3F7 + data[62];
+  T2 := ((TBits.RotateRight32(C, 2)) xor (TBits.RotateRight32(C, 13))
+    xor ((C shr 22) xor (C shl 10))) + ((C and D) xor (C and E) xor (D and E));
+  B := T + T2;
+  F := F + T;
+  T := A + ((TBits.RotateRight32(F, 6)) xor (TBits.RotateRight32(F, 11))
+    xor (TBits.RotateRight32(F, 25))) + ((F and G) xor (not F and H)) +
+    $C67178F2 + data[63];
+  T2 := ((TBits.RotateRight32(B, 2)) xor (TBits.RotateRight32(B, 13))
+    xor ((B shr 22) xor (B shl 10))) + ((B and C) xor (B and D) xor (C and D));
+  A := T + T2;
+  E := E + T;
+
+{$ELSE}
+  // Step 1
+  for r := 16 to 63 do
+  begin
+    T := data[r - 2];
+    T2 := data[r - 15];
+    data[r] := ((TBits.RotateRight32(T, 17)) xor (TBits.RotateRight32(T, 19))
+      xor (T shr 10)) + data[r - 7] +
+      ((TBits.RotateRight32(T2, 7)) xor (TBits.RotateRight32(T2, 18))
+      xor (T2 shr 3)) + data[r - 16];
+  end;
+
+  // Step 2
+
+  for r := 0 to 63 do
+  begin
+
+    T := s_K[r] + data[r] + H +
+      ((TBits.RotateRight32(E, 6)) xor (TBits.RotateRight32(E, 11))
+      xor (TBits.RotateRight32(E, 25))) + ((E and F) xor (not E and G));
+    T2 := ((TBits.RotateRight32(A, 2)) xor (TBits.RotateRight32(A, 13))
+      xor (TBits.RotateRight32(A, 22))) +
+      ((A and B) xor (A and C) xor (B and C));
+
+    H := G;
+    G := F;
+    F := E;
+    E := D + T;
+    D := C;
+    C := B;
+    B := A;
+    A := T + T2;
+  end;
+
+{$ENDIF USE_UNROLLED_VARIANT}
+  Fm_state[0] := Fm_state[0] + A;
+  Fm_state[1] := Fm_state[1] + B;
+  Fm_state[2] := Fm_state[2] + C;
+  Fm_state[3] := Fm_state[3] + D;
+  Fm_state[4] := Fm_state[4] + E;
+  Fm_state[5] := Fm_state[5] + F;
+  Fm_state[6] := Fm_state[6] + G;
+  Fm_state[7] := Fm_state[7] + H;
+
+  System.FillChar(data, System.SizeOf(data), 0);
+
+end;
+
+end.

+ 64 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA2_384.pas

@@ -0,0 +1,64 @@
+unit HlpSHA2_384;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpSHA2_512Base,
+  HlpConverters;
+
+type
+  TSHA2_384 = class sealed(TSHA2_512Base)
+
+  strict protected
+    function GetResult(): THashLibByteArray; override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TSHA2_384 }
+
+constructor TSHA2_384.Create;
+begin
+  Inherited Create(48);
+end;
+
+function TSHA2_384.GetResult: THashLibByteArray;
+begin
+
+  System.SetLength(result, 6 * System.SizeOf(UInt64));
+  TConverters.be64_copy(PUInt64(Fm_state), 0, PByte(result), 0,
+    System.Length(result));
+
+end;
+
+procedure TSHA2_384.Initialize;
+begin
+
+  Fm_state[0] := UInt64($CBBB9D5DC1059ED8);
+  Fm_state[1] := $629A292A367CD507;
+  Fm_state[2] := UInt64($9159015A3070DD17);
+  Fm_state[3] := $152FECD8F70E5939;
+  Fm_state[4] := $67332667FFC00B31;
+  Fm_state[5] := UInt64($8EB44A8768581511);
+  Fm_state[6] := UInt64($DB0C2E0D64F98FA7);
+  Fm_state[7] := $47B5481DBEFA4FA4;
+
+  Inherited Initialize();
+
+end;
+
+end.

+ 63 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA2_512.pas

@@ -0,0 +1,63 @@
+unit HlpSHA2_512;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpSHA2_512Base,
+  HlpConverters;
+
+type
+  TSHA2_512 = class sealed(TSHA2_512Base)
+
+  strict protected
+    function GetResult(): THashLibByteArray; override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TSHA2_512 }
+
+constructor TSHA2_512.Create;
+begin
+  Inherited Create(64);
+end;
+
+function TSHA2_512.GetResult: THashLibByteArray;
+begin
+
+  System.SetLength(result, 8 * System.SizeOf(UInt64));
+  TConverters.be64_copy(PUInt64(Fm_state), 0, PByte(result), 0,
+    System.Length(result));
+end;
+
+procedure TSHA2_512.Initialize;
+begin
+
+  Fm_state[0] := $6A09E667F3BCC908;
+  Fm_state[1] := UInt64($BB67AE8584CAA73B);
+  Fm_state[2] := $3C6EF372FE94F82B;
+  Fm_state[3] := UInt64($A54FF53A5F1D36F1);
+  Fm_state[4] := $510E527FADE682D1;
+  Fm_state[5] := UInt64($9B05688C2B3E6C1F);
+  Fm_state[6] := $1F83D9ABFB41BD6B;
+  Fm_state[7] := $5BE0CD19137E2179;
+
+  Inherited Initialize();
+
+end;
+
+end.

+ 1303 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA2_512Base.pas

@@ -0,0 +1,1303 @@
+unit HlpSHA2_512Base;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpHashBuffer,
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpBits,
+  HlpConverters,
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn;
+
+type
+  TSHA2_512Base = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+{$IFNDEF USE_UNROLLED_VARIANT}
+{$REGION 'Consts'}
+  const
+
+    s_K: array [0 .. 79] of UInt64 = ($428A2F98D728AE22, $7137449123EF65CD,
+      $B5C0FBCFEC4D3B2F, $E9B5DBA58189DBBC, $3956C25BF348B538,
+      $59F111F1B605D019, $923F82A4AF194F9B, $AB1C5ED5DA6D8118,
+      $D807AA98A3030242, $12835B0145706FBE, $243185BE4EE4B28C,
+      $550C7DC3D5FFB4E2, $72BE5D74F27B896F, $80DEB1FE3B1696B1,
+      $9BDC06A725C71235, $C19BF174CF692694, $E49B69C19EF14AD2,
+      $EFBE4786384F25E3, $0FC19DC68B8CD5B5, $240CA1CC77AC9C65,
+      $2DE92C6F592B0275, $4A7484AA6EA6E483, $5CB0A9DCBD41FBD4,
+      $76F988DA831153B5, $983E5152EE66DFAB, $A831C66D2DB43210,
+      $B00327C898FB213F, $BF597FC7BEEF0EE4, $C6E00BF33DA88FC2,
+      $D5A79147930AA725, $06CA6351E003826F, $142929670A0E6E70,
+      $27B70A8546D22FFC, $2E1B21385C26C926, $4D2C6DFC5AC42AED,
+      $53380D139D95B3DF, $650A73548BAF63DE, $766A0ABB3C77B2A8,
+      $81C2C92E47EDAEE6, $92722C851482353B, $A2BFE8A14CF10364,
+      $A81A664BBC423001, $C24B8B70D0F89791, $C76C51A30654BE30,
+      $D192E819D6EF5218, $D69906245565A910, $F40E35855771202A,
+      $106AA07032BBD1B8, $19A4C116B8D2D0C8, $1E376C085141AB53,
+      $2748774CDF8EEB99, $34B0BCB5E19B48A8, $391C0CB3C5C95A63,
+      $4ED8AA4AE3418ACB, $5B9CCA4F7763E373, $682E6FF3D6B2B8A3,
+      $748F82EE5DEFB2FC, $78A5636F43172F60, $84C87814A1F0AB72,
+      $8CC702081A6439EC, $90BEFFFA23631E28, $A4506CEBDE82BDE9,
+      $BEF9A3F7B2C67915, $C67178F2E372532B, $CA273ECEEA26619C,
+      $D186B8C721C0C207, $EADA7DD6CDE0EB1E, $F57D4F7FEE6ED178,
+      $06F067AA72176FBA, $0A637DC5A2C898A6, $113F9804BEF90DAE,
+      $1B710B35131C471B, $28DB77F523047D84, $32CAAB7B40C72493,
+      $3C9EBE0A15C9BEBC, $431D67C49C100D4C, $4CC5D4BECB3E42B6,
+      $597F299CFC657E2A, $5FCB6FAB3AD6FAEC, $6C44198C4A475817);
+
+{$ENDREGION}
+{$ENDIF USE_UNROLLED_VARIANT}
+  strict protected
+    Fm_state: THashLibUInt64Array;
+
+    constructor Create(a_hash_size: Int32);
+
+    procedure Finish(); override;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+  end;
+
+implementation
+
+{ TSHA2_512Base }
+
+constructor TSHA2_512Base.Create(a_hash_size: Int32);
+begin
+  Inherited Create(a_hash_size, 128);
+  System.SetLength(Fm_state, 8);
+end;
+
+procedure TSHA2_512Base.Finish;
+var
+  lowBits, hiBits: UInt64;
+  padindex: Int32;
+  pad: THashLibByteArray;
+begin
+  lowBits := Fm_processed_bytes shl 3;
+  hiBits := Fm_processed_bytes shr 61;
+
+  if (Fm_buffer.Pos < 112) then
+
+    padindex := (111 - Fm_buffer.Pos)
+  else
+    padindex := (239 - Fm_buffer.Pos);
+
+  System.Inc(padindex);
+  System.SetLength(pad, padindex + 16);
+  pad[0] := $80;
+
+  hiBits := TConverters.be2me_64(hiBits);
+
+  TConverters.ReadUInt64AsBytesLE(hiBits, pad, padindex);
+
+  padindex := padindex + 8;
+
+  lowBits := TConverters.be2me_64(lowBits);
+
+  TConverters.ReadUInt64AsBytesLE(lowBits, pad, padindex);
+
+  padindex := padindex + 8;
+
+  TransformBytes(pad, 0, padindex);
+
+end;
+
+procedure TSHA2_512Base.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+{$IFNDEF USE_UNROLLED_VARIANT}
+  i, t: Int32;
+{$ENDIF USE_UNROLLED_VARIANT}
+  T0, T1, a, b, c, d, e, f, g, h: UInt64;
+  data: array [0 .. 79] of UInt64;
+begin
+
+  TConverters.be64_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+
+  // Step 1
+
+{$IFDEF USE_UNROLLED_VARIANT}
+  T0 := data[16 - 15];
+  T1 := data[16 - 2];
+  data[16] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[16 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[0];
+  T0 := data[17 - 15];
+  T1 := data[17 - 2];
+  data[17] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[17 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[17 - 16];
+  T0 := data[18 - 15];
+  T1 := data[18 - 2];
+  data[18] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[18 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[18 - 16];
+  T0 := data[19 - 15];
+  T1 := data[19 - 2];
+  data[19] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[19 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[19 - 16];
+  T0 := data[20 - 15];
+  T1 := data[20 - 2];
+  data[20] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[20 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[20 - 16];
+  T0 := data[21 - 15];
+  T1 := data[21 - 2];
+  data[21] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[21 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[21 - 16];
+  T0 := data[22 - 15];
+  T1 := data[22 - 2];
+  data[22] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[22 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[22 - 16];
+  T0 := data[23 - 15];
+  T1 := data[23 - 2];
+  data[23] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[23 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[23 - 16];
+  T0 := data[24 - 15];
+  T1 := data[24 - 2];
+  data[24] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[24 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[24 - 16];
+  T0 := data[25 - 15];
+  T1 := data[25 - 2];
+  data[25] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[25 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[25 - 16];
+  T0 := data[26 - 15];
+  T1 := data[26 - 2];
+  data[26] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[26 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[26 - 16];
+  T0 := data[27 - 15];
+  T1 := data[27 - 2];
+  data[27] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[27 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[27 - 16];
+  T0 := data[28 - 15];
+  T1 := data[28 - 2];
+  data[28] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[28 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[28 - 16];
+  T0 := data[29 - 15];
+  T1 := data[29 - 2];
+  data[29] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[29 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[29 - 16];
+  T0 := data[30 - 15];
+  T1 := data[30 - 2];
+  data[30] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[30 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[30 - 16];
+  T0 := data[31 - 15];
+  T1 := data[31 - 2];
+  data[31] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[31 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[31 - 16];
+  T0 := data[32 - 15];
+  T1 := data[32 - 2];
+  data[32] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[32 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[32 - 16];
+  T0 := data[33 - 15];
+  T1 := data[33 - 2];
+  data[33] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[33 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[33 - 16];
+  T0 := data[34 - 15];
+  T1 := data[34 - 2];
+  data[34] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[34 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[34 - 16];
+  T0 := data[35 - 15];
+  T1 := data[35 - 2];
+  data[35] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[35 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[35 - 16];
+  T0 := data[36 - 15];
+  T1 := data[36 - 2];
+  data[36] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[36 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[36 - 16];
+  T0 := data[37 - 15];
+  T1 := data[37 - 2];
+  data[37] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[37 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[37 - 16];
+  T0 := data[38 - 15];
+  T1 := data[38 - 2];
+  data[38] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[38 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[38 - 16];
+  T0 := data[39 - 15];
+  T1 := data[39 - 2];
+  data[39] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[39 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[39 - 16];
+  T0 := data[40 - 15];
+  T1 := data[40 - 2];
+  data[40] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[40 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[40 - 16];
+  T0 := data[41 - 15];
+  T1 := data[41 - 2];
+  data[41] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[41 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[41 - 16];
+  T0 := data[42 - 15];
+  T1 := data[42 - 2];
+  data[42] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[42 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[42 - 16];
+  T0 := data[43 - 15];
+  T1 := data[43 - 2];
+  data[43] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[43 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[43 - 16];
+  T0 := data[44 - 15];
+  T1 := data[44 - 2];
+  data[44] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[44 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[44 - 16];
+  T0 := data[45 - 15];
+  T1 := data[45 - 2];
+  data[45] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[45 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[45 - 16];
+  T0 := data[46 - 15];
+  T1 := data[46 - 2];
+  data[46] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[46 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[46 - 16];
+  T0 := data[47 - 15];
+  T1 := data[47 - 2];
+  data[47] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[47 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[47 - 16];
+  T0 := data[48 - 15];
+  T1 := data[48 - 2];
+  data[48] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[48 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[48 - 16];
+  T0 := data[49 - 15];
+  T1 := data[49 - 2];
+  data[49] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[49 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[49 - 16];
+  T0 := data[50 - 15];
+  T1 := data[50 - 2];
+  data[50] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[50 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[50 - 16];
+  T0 := data[51 - 15];
+  T1 := data[51 - 2];
+  data[51] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[51 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[51 - 16];
+  T0 := data[52 - 15];
+  T1 := data[52 - 2];
+  data[52] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[52 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[52 - 16];
+  T0 := data[53 - 15];
+  T1 := data[53 - 2];
+  data[53] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[53 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[53 - 16];
+  T0 := data[54 - 15];
+  T1 := data[54 - 2];
+  data[54] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[54 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[54 - 16];
+  T0 := data[55 - 15];
+  T1 := data[55 - 2];
+  data[55] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[55 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[55 - 16];
+  T0 := data[56 - 15];
+  T1 := data[56 - 2];
+  data[56] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[56 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[56 - 16];
+  T0 := data[57 - 15];
+  T1 := data[57 - 2];
+  data[57] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[57 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[57 - 16];
+  T0 := data[58 - 15];
+  T1 := data[58 - 2];
+  data[58] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[58 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[58 - 16];
+  T0 := data[59 - 15];
+  T1 := data[59 - 2];
+  data[59] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[59 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[59 - 16];
+  T0 := data[60 - 15];
+  T1 := data[60 - 2];
+  data[60] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[60 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[60 - 16];
+  T0 := data[61 - 15];
+  T1 := data[61 - 2];
+  data[61] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[61 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[61 - 16];
+  T0 := data[62 - 15];
+  T1 := data[62 - 2];
+  data[62] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[62 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[62 - 16];
+  T0 := data[63 - 15];
+  T1 := data[63 - 2];
+  data[63] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[63 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[63 - 16];
+  T0 := data[64 - 15];
+  T1 := data[64 - 2];
+  data[64] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[64 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[64 - 16];
+  T0 := data[65 - 15];
+  T1 := data[65 - 2];
+  data[65] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[65 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[65 - 16];
+  T0 := data[66 - 15];
+  T1 := data[66 - 2];
+  data[66] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[66 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[66 - 16];
+  T0 := data[67 - 15];
+  T1 := data[67 - 2];
+  data[67] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[67 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[67 - 16];
+  T0 := data[68 - 15];
+  T1 := data[68 - 2];
+  data[68] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[68 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[68 - 16];
+  T0 := data[69 - 15];
+  T1 := data[69 - 2];
+  data[69] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[69 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[69 - 16];
+  T0 := data[70 - 15];
+  T1 := data[70 - 2];
+  data[70] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[70 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[70 - 16];
+  T0 := data[71 - 15];
+  T1 := data[71 - 2];
+  data[71] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[71 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[71 - 16];
+  T0 := data[72 - 15];
+  T1 := data[72 - 2];
+  data[72] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[72 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[72 - 16];
+  T0 := data[73 - 15];
+  T1 := data[73 - 2];
+  data[73] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[73 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[73 - 16];
+  T0 := data[74 - 15];
+  T1 := data[74 - 2];
+  data[74] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[74 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[74 - 16];
+  T0 := data[75 - 15];
+  T1 := data[75 - 2];
+  data[75] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[75 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[75 - 16];
+  T0 := data[76 - 15];
+  T1 := data[76 - 2];
+  data[76] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[76 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[76 - 16];
+  T0 := data[77 - 15];
+  T1 := data[77 - 2];
+  data[77] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[77 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[77 - 16];
+  T0 := data[78 - 15];
+  T1 := data[78 - 2];
+  data[78] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[78 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[78 - 16];
+  T0 := data[79 - 15];
+  T1 := data[79 - 2];
+  data[79] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+    xor (T1 shr 6)) + data[79 - 7] +
+    ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+    xor (T0 shr 7)) + data[79 - 16];
+
+  a := Fm_state[0];
+  b := Fm_state[1];
+  c := Fm_state[2];
+  d := Fm_state[3];
+  e := Fm_state[4];
+  f := Fm_state[5];
+  g := Fm_state[6];
+  h := Fm_state[7];
+
+  // Step 2
+
+  // R0
+  h := h + ($428A2F98D728AE22 + data[0] + ((TBits.RotateLeft64(e, 50))
+    xor (TBits.RotateLeft64(e, 46)) xor (TBits.RotateLeft64(e, 23))) +
+    ((e and f) xor (not e and g)));
+
+  d := d + h;
+  h := h + (((TBits.RotateLeft64(a, 36)) xor (TBits.RotateLeft64(a, 30))
+    xor (TBits.RotateLeft64(a, 25))) + ((a and b) xor (a and c) xor (b and c)));
+
+  g := g + ($7137449123EF65CD + data[1] + ((TBits.RotateLeft64(d, 50))
+    xor (TBits.RotateLeft64(d, 46)) xor (TBits.RotateLeft64(d, 23))) +
+    ((d and e) xor (not d and f)));
+
+  c := c + g;
+  g := g + (((TBits.RotateLeft64(h, 36)) xor (TBits.RotateLeft64(h, 30))
+    xor (TBits.RotateLeft64(h, 25))) + ((h and a) xor (h and b) xor (a and b)));
+
+  f := f + ($B5C0FBCFEC4D3B2F + data[2] + ((TBits.RotateLeft64(c, 50))
+    xor (TBits.RotateLeft64(c, 46)) xor (TBits.RotateLeft64(c, 23))) +
+    ((c and d) xor (not c and e)));
+
+  b := b + f;
+  f := f + (((TBits.RotateLeft64(g, 36)) xor (TBits.RotateLeft64(g, 30))
+    xor (TBits.RotateLeft64(g, 25))) + ((g and h) xor (g and a) xor (h and a)));
+
+  e := e + ($E9B5DBA58189DBBC + data[3] + ((TBits.RotateLeft64(b, 50))
+    xor (TBits.RotateLeft64(b, 46)) xor (TBits.RotateLeft64(b, 23))) +
+    ((b and c) xor (not b and d)));
+
+  a := a + e;
+  e := e + (((TBits.RotateLeft64(f, 36)) xor (TBits.RotateLeft64(f, 30))
+    xor (TBits.RotateLeft64(f, 25))) + ((f and g) xor (f and h) xor (g and h)));
+
+  d := d + ($3956C25BF348B538 + data[4] + ((TBits.RotateLeft64(a, 50))
+    xor (TBits.RotateLeft64(a, 46)) xor (TBits.RotateLeft64(a, 23))) +
+    ((a and b) xor (not a and c)));
+
+  h := h + d;
+  d := d + (((TBits.RotateLeft64(e, 36)) xor (TBits.RotateLeft64(e, 30))
+    xor (TBits.RotateLeft64(e, 25))) + ((e and f) xor (e and g) xor (f and g)));
+
+  c := c + ($59F111F1B605D019 + data[5] + ((TBits.RotateLeft64(h, 50))
+    xor (TBits.RotateLeft64(h, 46)) xor (TBits.RotateLeft64(h, 23))) +
+    ((h and a) xor (not h and b)));
+
+  g := g + c;
+  c := c + (((TBits.RotateLeft64(d, 36)) xor (TBits.RotateLeft64(d, 30))
+    xor (TBits.RotateLeft64(d, 25))) + ((d and e) xor (d and f) xor (e and f)));
+
+  b := b + ($923F82A4AF194F9B + data[6] + ((TBits.RotateLeft64(g, 50))
+    xor (TBits.RotateLeft64(g, 46)) xor (TBits.RotateLeft64(g, 23))) +
+    ((g and h) xor (not g and a)));
+
+  f := f + b;
+  b := b + (((TBits.RotateLeft64(c, 36)) xor (TBits.RotateLeft64(c, 30))
+    xor (TBits.RotateLeft64(c, 25))) + ((c and d) xor (c and e) xor (d and e)));
+
+  a := a + ($AB1C5ED5DA6D8118 + data[7] + ((TBits.RotateLeft64(f, 50))
+    xor (TBits.RotateLeft64(f, 46)) xor (TBits.RotateLeft64(f, 23))) +
+    ((f and g) xor (not f and h)));
+
+  e := e + a;
+  a := a + (((TBits.RotateLeft64(b, 36)) xor (TBits.RotateLeft64(b, 30))
+    xor (TBits.RotateLeft64(b, 25))) + ((b and c) xor (b and d) xor (c and d)));
+
+  // R1
+  h := h + ($D807AA98A3030242 + data[8] + ((TBits.RotateLeft64(e, 50))
+    xor (TBits.RotateLeft64(e, 46)) xor (TBits.RotateLeft64(e, 23))) +
+    ((e and f) xor (not e and g)));
+
+  d := d + h;
+  h := h + (((TBits.RotateLeft64(a, 36)) xor (TBits.RotateLeft64(a, 30))
+    xor (TBits.RotateLeft64(a, 25))) + ((a and b) xor (a and c) xor (b and c)));
+
+  g := g + ($12835B0145706FBE + data[9] + ((TBits.RotateLeft64(d, 50))
+    xor (TBits.RotateLeft64(d, 46)) xor (TBits.RotateLeft64(d, 23))) +
+    ((d and e) xor (not d and f)));
+
+  c := c + g;
+  g := g + (((TBits.RotateLeft64(h, 36)) xor (TBits.RotateLeft64(h, 30))
+    xor (TBits.RotateLeft64(h, 25))) + ((h and a) xor (h and b) xor (a and b)));
+
+  f := f + ($243185BE4EE4B28C + data[10] + ((TBits.RotateLeft64(c, 50))
+    xor (TBits.RotateLeft64(c, 46)) xor (TBits.RotateLeft64(c, 23))) +
+    ((c and d) xor (not c and e)));
+
+  b := b + f;
+  f := f + (((TBits.RotateLeft64(g, 36)) xor (TBits.RotateLeft64(g, 30))
+    xor (TBits.RotateLeft64(g, 25))) + ((g and h) xor (g and a) xor (h and a)));
+
+  e := e + ($550C7DC3D5FFB4E2 + data[11] + ((TBits.RotateLeft64(b, 50))
+    xor (TBits.RotateLeft64(b, 46)) xor (TBits.RotateLeft64(b, 23))) +
+    ((b and c) xor (not b and d)));
+
+  a := a + e;
+  e := e + (((TBits.RotateLeft64(f, 36)) xor (TBits.RotateLeft64(f, 30))
+    xor (TBits.RotateLeft64(f, 25))) + ((f and g) xor (f and h) xor (g and h)));
+
+  d := d + ($72BE5D74F27B896F + data[12] + ((TBits.RotateLeft64(a, 50))
+    xor (TBits.RotateLeft64(a, 46)) xor (TBits.RotateLeft64(a, 23))) +
+    ((a and b) xor (not a and c)));
+
+  h := h + d;
+  d := d + (((TBits.RotateLeft64(e, 36)) xor (TBits.RotateLeft64(e, 30))
+    xor (TBits.RotateLeft64(e, 25))) + ((e and f) xor (e and g) xor (f and g)));
+
+  c := c + ($80DEB1FE3B1696B1 + data[13] + ((TBits.RotateLeft64(h, 50))
+    xor (TBits.RotateLeft64(h, 46)) xor (TBits.RotateLeft64(h, 23))) +
+    ((h and a) xor (not h and b)));
+
+  g := g + c;
+  c := c + (((TBits.RotateLeft64(d, 36)) xor (TBits.RotateLeft64(d, 30))
+    xor (TBits.RotateLeft64(d, 25))) + ((d and e) xor (d and f) xor (e and f)));
+
+  b := b + ($9BDC06A725C71235 + data[14] + ((TBits.RotateLeft64(g, 50))
+    xor (TBits.RotateLeft64(g, 46)) xor (TBits.RotateLeft64(g, 23))) +
+    ((g and h) xor (not g and a)));
+
+  f := f + b;
+  b := b + (((TBits.RotateLeft64(c, 36)) xor (TBits.RotateLeft64(c, 30))
+    xor (TBits.RotateLeft64(c, 25))) + ((c and d) xor (c and e) xor (d and e)));
+
+  a := a + ($C19BF174CF692694 + data[15] + ((TBits.RotateLeft64(f, 50))
+    xor (TBits.RotateLeft64(f, 46)) xor (TBits.RotateLeft64(f, 23))) +
+    ((f and g) xor (not f and h)));
+
+  e := e + a;
+  a := a + (((TBits.RotateLeft64(b, 36)) xor (TBits.RotateLeft64(b, 30))
+    xor (TBits.RotateLeft64(b, 25))) + ((b and c) xor (b and d) xor (c and d)));
+
+  // R2
+
+  h := h + ($E49B69C19EF14AD2 + data[16] + ((TBits.RotateLeft64(e, 50))
+    xor (TBits.RotateLeft64(e, 46)) xor (TBits.RotateLeft64(e, 23))) +
+    ((e and f) xor (not e and g)));
+
+  d := d + h;
+  h := h + (((TBits.RotateLeft64(a, 36)) xor (TBits.RotateLeft64(a, 30))
+    xor (TBits.RotateLeft64(a, 25))) + ((a and b) xor (a and c) xor (b and c)));
+
+  g := g + ($EFBE4786384F25E3 + data[17] + ((TBits.RotateLeft64(d, 50))
+    xor (TBits.RotateLeft64(d, 46)) xor (TBits.RotateLeft64(d, 23))) +
+    ((d and e) xor (not d and f)));
+
+  c := c + g;
+  g := g + (((TBits.RotateLeft64(h, 36)) xor (TBits.RotateLeft64(h, 30))
+    xor (TBits.RotateLeft64(h, 25))) + ((h and a) xor (h and b) xor (a and b)));
+
+  f := f + ($0FC19DC68B8CD5B5 + data[18] + ((TBits.RotateLeft64(c, 50))
+    xor (TBits.RotateLeft64(c, 46)) xor (TBits.RotateLeft64(c, 23))) +
+    ((c and d) xor (not c and e)));
+
+  b := b + f;
+  f := f + (((TBits.RotateLeft64(g, 36)) xor (TBits.RotateLeft64(g, 30))
+    xor (TBits.RotateLeft64(g, 25))) + ((g and h) xor (g and a) xor (h and a)));
+
+  e := e + ($240CA1CC77AC9C65 + data[19] + ((TBits.RotateLeft64(b, 50))
+    xor (TBits.RotateLeft64(b, 46)) xor (TBits.RotateLeft64(b, 23))) +
+    ((b and c) xor (not b and d)));
+
+  a := a + e;
+  e := e + (((TBits.RotateLeft64(f, 36)) xor (TBits.RotateLeft64(f, 30))
+    xor (TBits.RotateLeft64(f, 25))) + ((f and g) xor (f and h) xor (g and h)));
+
+  d := d + ($2DE92C6F592B0275 + data[20] + ((TBits.RotateLeft64(a, 50))
+    xor (TBits.RotateLeft64(a, 46)) xor (TBits.RotateLeft64(a, 23))) +
+    ((a and b) xor (not a and c)));
+
+  h := h + d;
+  d := d + (((TBits.RotateLeft64(e, 36)) xor (TBits.RotateLeft64(e, 30))
+    xor (TBits.RotateLeft64(e, 25))) + ((e and f) xor (e and g) xor (f and g)));
+
+  c := c + ($4A7484AA6EA6E483 + data[21] + ((TBits.RotateLeft64(h, 50))
+    xor (TBits.RotateLeft64(h, 46)) xor (TBits.RotateLeft64(h, 23))) +
+    ((h and a) xor (not h and b)));
+
+  g := g + c;
+  c := c + (((TBits.RotateLeft64(d, 36)) xor (TBits.RotateLeft64(d, 30))
+    xor (TBits.RotateLeft64(d, 25))) + ((d and e) xor (d and f) xor (e and f)));
+
+  b := b + ($5CB0A9DCBD41FBD4 + data[22] + ((TBits.RotateLeft64(g, 50))
+    xor (TBits.RotateLeft64(g, 46)) xor (TBits.RotateLeft64(g, 23))) +
+    ((g and h) xor (not g and a)));
+
+  f := f + b;
+  b := b + (((TBits.RotateLeft64(c, 36)) xor (TBits.RotateLeft64(c, 30))
+    xor (TBits.RotateLeft64(c, 25))) + ((c and d) xor (c and e) xor (d and e)));
+
+  a := a + ($76F988DA831153B5 + data[23] + ((TBits.RotateLeft64(f, 50))
+    xor (TBits.RotateLeft64(f, 46)) xor (TBits.RotateLeft64(f, 23))) +
+    ((f and g) xor (not f and h)));
+
+  e := e + a;
+  a := a + (((TBits.RotateLeft64(b, 36)) xor (TBits.RotateLeft64(b, 30))
+    xor (TBits.RotateLeft64(b, 25))) + ((b and c) xor (b and d) xor (c and d)));
+
+  // R3
+
+  h := h + ($983E5152EE66DFAB + data[24] + ((TBits.RotateLeft64(e, 50))
+    xor (TBits.RotateLeft64(e, 46)) xor (TBits.RotateLeft64(e, 23))) +
+    ((e and f) xor (not e and g)));
+
+  d := d + h;
+  h := h + (((TBits.RotateLeft64(a, 36)) xor (TBits.RotateLeft64(a, 30))
+    xor (TBits.RotateLeft64(a, 25))) + ((a and b) xor (a and c) xor (b and c)));
+
+  g := g + ($A831C66D2DB43210 + data[25] + ((TBits.RotateLeft64(d, 50))
+    xor (TBits.RotateLeft64(d, 46)) xor (TBits.RotateLeft64(d, 23))) +
+    ((d and e) xor (not d and f)));
+
+  c := c + g;
+  g := g + (((TBits.RotateLeft64(h, 36)) xor (TBits.RotateLeft64(h, 30))
+    xor (TBits.RotateLeft64(h, 25))) + ((h and a) xor (h and b) xor (a and b)));
+
+  f := f + ($B00327C898FB213F + data[26] + ((TBits.RotateLeft64(c, 50))
+    xor (TBits.RotateLeft64(c, 46)) xor (TBits.RotateLeft64(c, 23))) +
+    ((c and d) xor (not c and e)));
+
+  b := b + f;
+  f := f + (((TBits.RotateLeft64(g, 36)) xor (TBits.RotateLeft64(g, 30))
+    xor (TBits.RotateLeft64(g, 25))) + ((g and h) xor (g and a) xor (h and a)));
+
+  e := e + ($BF597FC7BEEF0EE4 + data[27] + ((TBits.RotateLeft64(b, 50))
+    xor (TBits.RotateLeft64(b, 46)) xor (TBits.RotateLeft64(b, 23))) +
+    ((b and c) xor (not b and d)));
+
+  a := a + e;
+  e := e + (((TBits.RotateLeft64(f, 36)) xor (TBits.RotateLeft64(f, 30))
+    xor (TBits.RotateLeft64(f, 25))) + ((f and g) xor (f and h) xor (g and h)));
+
+  d := d + ($C6E00BF33DA88FC2 + data[28] + ((TBits.RotateLeft64(a, 50))
+    xor (TBits.RotateLeft64(a, 46)) xor (TBits.RotateLeft64(a, 23))) +
+    ((a and b) xor (not a and c)));
+
+  h := h + d;
+  d := d + (((TBits.RotateLeft64(e, 36)) xor (TBits.RotateLeft64(e, 30))
+    xor (TBits.RotateLeft64(e, 25))) + ((e and f) xor (e and g) xor (f and g)));
+
+  c := c + ($D5A79147930AA725 + data[29] + ((TBits.RotateLeft64(h, 50))
+    xor (TBits.RotateLeft64(h, 46)) xor (TBits.RotateLeft64(h, 23))) +
+    ((h and a) xor (not h and b)));
+
+  g := g + c;
+  c := c + (((TBits.RotateLeft64(d, 36)) xor (TBits.RotateLeft64(d, 30))
+    xor (TBits.RotateLeft64(d, 25))) + ((d and e) xor (d and f) xor (e and f)));
+
+  b := b + ($06CA6351E003826F + data[30] + ((TBits.RotateLeft64(g, 50))
+    xor (TBits.RotateLeft64(g, 46)) xor (TBits.RotateLeft64(g, 23))) +
+    ((g and h) xor (not g and a)));
+
+  f := f + b;
+  b := b + (((TBits.RotateLeft64(c, 36)) xor (TBits.RotateLeft64(c, 30))
+    xor (TBits.RotateLeft64(c, 25))) + ((c and d) xor (c and e) xor (d and e)));
+
+  a := a + ($142929670A0E6E70 + data[31] + ((TBits.RotateLeft64(f, 50))
+    xor (TBits.RotateLeft64(f, 46)) xor (TBits.RotateLeft64(f, 23))) +
+    ((f and g) xor (not f and h)));
+
+  e := e + a;
+  a := a + (((TBits.RotateLeft64(b, 36)) xor (TBits.RotateLeft64(b, 30))
+    xor (TBits.RotateLeft64(b, 25))) + ((b and c) xor (b and d) xor (c and d)));
+
+  // R4
+
+  h := h + ($27B70A8546D22FFC + data[32] + ((TBits.RotateLeft64(e, 50))
+    xor (TBits.RotateLeft64(e, 46)) xor (TBits.RotateLeft64(e, 23))) +
+    ((e and f) xor (not e and g)));
+
+  d := d + h;
+  h := h + (((TBits.RotateLeft64(a, 36)) xor (TBits.RotateLeft64(a, 30))
+    xor (TBits.RotateLeft64(a, 25))) + ((a and b) xor (a and c) xor (b and c)));
+
+  g := g + ($2E1B21385C26C926 + data[33] + ((TBits.RotateLeft64(d, 50))
+    xor (TBits.RotateLeft64(d, 46)) xor (TBits.RotateLeft64(d, 23))) +
+    ((d and e) xor (not d and f)));
+
+  c := c + g;
+  g := g + (((TBits.RotateLeft64(h, 36)) xor (TBits.RotateLeft64(h, 30))
+    xor (TBits.RotateLeft64(h, 25))) + ((h and a) xor (h and b) xor (a and b)));
+
+  f := f + ($4D2C6DFC5AC42AED + data[34] + ((TBits.RotateLeft64(c, 50))
+    xor (TBits.RotateLeft64(c, 46)) xor (TBits.RotateLeft64(c, 23))) +
+    ((c and d) xor (not c and e)));
+
+  b := b + f;
+  f := f + (((TBits.RotateLeft64(g, 36)) xor (TBits.RotateLeft64(g, 30))
+    xor (TBits.RotateLeft64(g, 25))) + ((g and h) xor (g and a) xor (h and a)));
+
+  e := e + ($53380D139D95B3DF + data[35] + ((TBits.RotateLeft64(b, 50))
+    xor (TBits.RotateLeft64(b, 46)) xor (TBits.RotateLeft64(b, 23))) +
+    ((b and c) xor (not b and d)));
+
+  a := a + e;
+  e := e + (((TBits.RotateLeft64(f, 36)) xor (TBits.RotateLeft64(f, 30))
+    xor (TBits.RotateLeft64(f, 25))) + ((f and g) xor (f and h) xor (g and h)));
+
+  d := d + ($650A73548BAF63DE + data[36] + ((TBits.RotateLeft64(a, 50))
+    xor (TBits.RotateLeft64(a, 46)) xor (TBits.RotateLeft64(a, 23))) +
+    ((a and b) xor (not a and c)));
+
+  h := h + d;
+  d := d + (((TBits.RotateLeft64(e, 36)) xor (TBits.RotateLeft64(e, 30))
+    xor (TBits.RotateLeft64(e, 25))) + ((e and f) xor (e and g) xor (f and g)));
+
+  c := c + ($766A0ABB3C77B2A8 + data[37] + ((TBits.RotateLeft64(h, 50))
+    xor (TBits.RotateLeft64(h, 46)) xor (TBits.RotateLeft64(h, 23))) +
+    ((h and a) xor (not h and b)));
+
+  g := g + c;
+  c := c + (((TBits.RotateLeft64(d, 36)) xor (TBits.RotateLeft64(d, 30))
+    xor (TBits.RotateLeft64(d, 25))) + ((d and e) xor (d and f) xor (e and f)));
+
+  b := b + ($81C2C92E47EDAEE6 + data[38] + ((TBits.RotateLeft64(g, 50))
+    xor (TBits.RotateLeft64(g, 46)) xor (TBits.RotateLeft64(g, 23))) +
+    ((g and h) xor (not g and a)));
+
+  f := f + b;
+  b := b + (((TBits.RotateLeft64(c, 36)) xor (TBits.RotateLeft64(c, 30))
+    xor (TBits.RotateLeft64(c, 25))) + ((c and d) xor (c and e) xor (d and e)));
+
+  a := a + ($92722C851482353B + data[39] + ((TBits.RotateLeft64(f, 50))
+    xor (TBits.RotateLeft64(f, 46)) xor (TBits.RotateLeft64(f, 23))) +
+    ((f and g) xor (not f and h)));
+
+  e := e + a;
+  a := a + (((TBits.RotateLeft64(b, 36)) xor (TBits.RotateLeft64(b, 30))
+    xor (TBits.RotateLeft64(b, 25))) + ((b and c) xor (b and d) xor (c and d)));
+
+  // R5
+
+  h := h + ($A2BFE8A14CF10364 + data[40] + ((TBits.RotateLeft64(e, 50))
+    xor (TBits.RotateLeft64(e, 46)) xor (TBits.RotateLeft64(e, 23))) +
+    ((e and f) xor (not e and g)));
+
+  d := d + h;
+  h := h + (((TBits.RotateLeft64(a, 36)) xor (TBits.RotateLeft64(a, 30))
+    xor (TBits.RotateLeft64(a, 25))) + ((a and b) xor (a and c) xor (b and c)));
+
+  g := g + ($A81A664BBC423001 + data[41] + ((TBits.RotateLeft64(d, 50))
+    xor (TBits.RotateLeft64(d, 46)) xor (TBits.RotateLeft64(d, 23))) +
+    ((d and e) xor (not d and f)));
+
+  c := c + g;
+  g := g + (((TBits.RotateLeft64(h, 36)) xor (TBits.RotateLeft64(h, 30))
+    xor (TBits.RotateLeft64(h, 25))) + ((h and a) xor (h and b) xor (a and b)));
+
+  f := f + ($C24B8B70D0F89791 + data[42] + ((TBits.RotateLeft64(c, 50))
+    xor (TBits.RotateLeft64(c, 46)) xor (TBits.RotateLeft64(c, 23))) +
+    ((c and d) xor (not c and e)));
+
+  b := b + f;
+  f := f + (((TBits.RotateLeft64(g, 36)) xor (TBits.RotateLeft64(g, 30))
+    xor (TBits.RotateLeft64(g, 25))) + ((g and h) xor (g and a) xor (h and a)));
+
+  e := e + ($C76C51A30654BE30 + data[43] + ((TBits.RotateLeft64(b, 50))
+    xor (TBits.RotateLeft64(b, 46)) xor (TBits.RotateLeft64(b, 23))) +
+    ((b and c) xor (not b and d)));
+
+  a := a + e;
+  e := e + (((TBits.RotateLeft64(f, 36)) xor (TBits.RotateLeft64(f, 30))
+    xor (TBits.RotateLeft64(f, 25))) + ((f and g) xor (f and h) xor (g and h)));
+
+  d := d + ($D192E819D6EF5218 + data[44] + ((TBits.RotateLeft64(a, 50))
+    xor (TBits.RotateLeft64(a, 46)) xor (TBits.RotateLeft64(a, 23))) +
+    ((a and b) xor (not a and c)));
+
+  h := h + d;
+  d := d + (((TBits.RotateLeft64(e, 36)) xor (TBits.RotateLeft64(e, 30))
+    xor (TBits.RotateLeft64(e, 25))) + ((e and f) xor (e and g) xor (f and g)));
+
+  c := c + ($D69906245565A910 + data[45] + ((TBits.RotateLeft64(h, 50))
+    xor (TBits.RotateLeft64(h, 46)) xor (TBits.RotateLeft64(h, 23))) +
+    ((h and a) xor (not h and b)));
+
+  g := g + c;
+  c := c + (((TBits.RotateLeft64(d, 36)) xor (TBits.RotateLeft64(d, 30))
+    xor (TBits.RotateLeft64(d, 25))) + ((d and e) xor (d and f) xor (e and f)));
+
+  b := b + ($F40E35855771202A + data[46] + ((TBits.RotateLeft64(g, 50))
+    xor (TBits.RotateLeft64(g, 46)) xor (TBits.RotateLeft64(g, 23))) +
+    ((g and h) xor (not g and a)));
+
+  f := f + b;
+  b := b + (((TBits.RotateLeft64(c, 36)) xor (TBits.RotateLeft64(c, 30))
+    xor (TBits.RotateLeft64(c, 25))) + ((c and d) xor (c and e) xor (d and e)));
+
+  a := a + ($106AA07032BBD1B8 + data[47] + ((TBits.RotateLeft64(f, 50))
+    xor (TBits.RotateLeft64(f, 46)) xor (TBits.RotateLeft64(f, 23))) +
+    ((f and g) xor (not f and h)));
+
+  e := e + a;
+  a := a + (((TBits.RotateLeft64(b, 36)) xor (TBits.RotateLeft64(b, 30))
+    xor (TBits.RotateLeft64(b, 25))) + ((b and c) xor (b and d) xor (c and d)));
+
+  // R6
+
+  h := h + ($19A4C116B8D2D0C8 + data[48] + ((TBits.RotateLeft64(e, 50))
+    xor (TBits.RotateLeft64(e, 46)) xor (TBits.RotateLeft64(e, 23))) +
+    ((e and f) xor (not e and g)));
+
+  d := d + h;
+  h := h + (((TBits.RotateLeft64(a, 36)) xor (TBits.RotateLeft64(a, 30))
+    xor (TBits.RotateLeft64(a, 25))) + ((a and b) xor (a and c) xor (b and c)));
+
+  g := g + ($1E376C085141AB53 + data[49] + ((TBits.RotateLeft64(d, 50))
+    xor (TBits.RotateLeft64(d, 46)) xor (TBits.RotateLeft64(d, 23))) +
+    ((d and e) xor (not d and f)));
+
+  c := c + g;
+  g := g + (((TBits.RotateLeft64(h, 36)) xor (TBits.RotateLeft64(h, 30))
+    xor (TBits.RotateLeft64(h, 25))) + ((h and a) xor (h and b) xor (a and b)));
+
+  f := f + ($2748774CDF8EEB99 + data[50] + ((TBits.RotateLeft64(c, 50))
+    xor (TBits.RotateLeft64(c, 46)) xor (TBits.RotateLeft64(c, 23))) +
+    ((c and d) xor (not c and e)));
+
+  b := b + f;
+  f := f + (((TBits.RotateLeft64(g, 36)) xor (TBits.RotateLeft64(g, 30))
+    xor (TBits.RotateLeft64(g, 25))) + ((g and h) xor (g and a) xor (h and a)));
+
+  e := e + ($34B0BCB5E19B48A8 + data[51] + ((TBits.RotateLeft64(b, 50))
+    xor (TBits.RotateLeft64(b, 46)) xor (TBits.RotateLeft64(b, 23))) +
+    ((b and c) xor (not b and d)));
+
+  a := a + e;
+  e := e + (((TBits.RotateLeft64(f, 36)) xor (TBits.RotateLeft64(f, 30))
+    xor (TBits.RotateLeft64(f, 25))) + ((f and g) xor (f and h) xor (g and h)));
+
+  d := d + ($391C0CB3C5C95A63 + data[52] + ((TBits.RotateLeft64(a, 50))
+    xor (TBits.RotateLeft64(a, 46)) xor (TBits.RotateLeft64(a, 23))) +
+    ((a and b) xor (not a and c)));
+
+  h := h + d;
+  d := d + (((TBits.RotateLeft64(e, 36)) xor (TBits.RotateLeft64(e, 30))
+    xor (TBits.RotateLeft64(e, 25))) + ((e and f) xor (e and g) xor (f and g)));
+
+  c := c + ($4ED8AA4AE3418ACB + data[53] + ((TBits.RotateLeft64(h, 50))
+    xor (TBits.RotateLeft64(h, 46)) xor (TBits.RotateLeft64(h, 23))) +
+    ((h and a) xor (not h and b)));
+
+  g := g + c;
+  c := c + (((TBits.RotateLeft64(d, 36)) xor (TBits.RotateLeft64(d, 30))
+    xor (TBits.RotateLeft64(d, 25))) + ((d and e) xor (d and f) xor (e and f)));
+
+  b := b + ($5B9CCA4F7763E373 + data[54] + ((TBits.RotateLeft64(g, 50))
+    xor (TBits.RotateLeft64(g, 46)) xor (TBits.RotateLeft64(g, 23))) +
+    ((g and h) xor (not g and a)));
+
+  f := f + b;
+  b := b + (((TBits.RotateLeft64(c, 36)) xor (TBits.RotateLeft64(c, 30))
+    xor (TBits.RotateLeft64(c, 25))) + ((c and d) xor (c and e) xor (d and e)));
+
+  a := a + ($682E6FF3D6B2B8A3 + data[55] + ((TBits.RotateLeft64(f, 50))
+    xor (TBits.RotateLeft64(f, 46)) xor (TBits.RotateLeft64(f, 23))) +
+    ((f and g) xor (not f and h)));
+
+  e := e + a;
+  a := a + (((TBits.RotateLeft64(b, 36)) xor (TBits.RotateLeft64(b, 30))
+    xor (TBits.RotateLeft64(b, 25))) + ((b and c) xor (b and d) xor (c and d)));
+
+  // R7
+
+  h := h + ($748F82EE5DEFB2FC + data[56] + ((TBits.RotateLeft64(e, 50))
+    xor (TBits.RotateLeft64(e, 46)) xor (TBits.RotateLeft64(e, 23))) +
+    ((e and f) xor (not e and g)));
+
+  d := d + h;
+  h := h + (((TBits.RotateLeft64(a, 36)) xor (TBits.RotateLeft64(a, 30))
+    xor (TBits.RotateLeft64(a, 25))) + ((a and b) xor (a and c) xor (b and c)));
+
+  g := g + ($78A5636F43172F60 + data[57] + ((TBits.RotateLeft64(d, 50))
+    xor (TBits.RotateLeft64(d, 46)) xor (TBits.RotateLeft64(d, 23))) +
+    ((d and e) xor (not d and f)));
+
+  c := c + g;
+  g := g + (((TBits.RotateLeft64(h, 36)) xor (TBits.RotateLeft64(h, 30))
+    xor (TBits.RotateLeft64(h, 25))) + ((h and a) xor (h and b) xor (a and b)));
+
+  f := f + ($84C87814A1F0AB72 + data[58] + ((TBits.RotateLeft64(c, 50))
+    xor (TBits.RotateLeft64(c, 46)) xor (TBits.RotateLeft64(c, 23))) +
+    ((c and d) xor (not c and e)));
+
+  b := b + f;
+  f := f + (((TBits.RotateLeft64(g, 36)) xor (TBits.RotateLeft64(g, 30))
+    xor (TBits.RotateLeft64(g, 25))) + ((g and h) xor (g and a) xor (h and a)));
+
+  e := e + ($8CC702081A6439EC + data[59] + ((TBits.RotateLeft64(b, 50))
+    xor (TBits.RotateLeft64(b, 46)) xor (TBits.RotateLeft64(b, 23))) +
+    ((b and c) xor (not b and d)));
+
+  a := a + e;
+  e := e + (((TBits.RotateLeft64(f, 36)) xor (TBits.RotateLeft64(f, 30))
+    xor (TBits.RotateLeft64(f, 25))) + ((f and g) xor (f and h) xor (g and h)));
+
+  d := d + ($90BEFFFA23631E28 + data[60] + ((TBits.RotateLeft64(a, 50))
+    xor (TBits.RotateLeft64(a, 46)) xor (TBits.RotateLeft64(a, 23))) +
+    ((a and b) xor (not a and c)));
+
+  h := h + d;
+  d := d + (((TBits.RotateLeft64(e, 36)) xor (TBits.RotateLeft64(e, 30))
+    xor (TBits.RotateLeft64(e, 25))) + ((e and f) xor (e and g) xor (f and g)));
+
+  c := c + ($A4506CEBDE82BDE9 + data[61] + ((TBits.RotateLeft64(h, 50))
+    xor (TBits.RotateLeft64(h, 46)) xor (TBits.RotateLeft64(h, 23))) +
+    ((h and a) xor (not h and b)));
+
+  g := g + c;
+  c := c + (((TBits.RotateLeft64(d, 36)) xor (TBits.RotateLeft64(d, 30))
+    xor (TBits.RotateLeft64(d, 25))) + ((d and e) xor (d and f) xor (e and f)));
+
+  b := b + ($BEF9A3F7B2C67915 + data[62] + ((TBits.RotateLeft64(g, 50))
+    xor (TBits.RotateLeft64(g, 46)) xor (TBits.RotateLeft64(g, 23))) +
+    ((g and h) xor (not g and a)));
+
+  f := f + b;
+  b := b + (((TBits.RotateLeft64(c, 36)) xor (TBits.RotateLeft64(c, 30))
+    xor (TBits.RotateLeft64(c, 25))) + ((c and d) xor (c and e) xor (d and e)));
+
+  a := a + ($C67178F2E372532B + data[63] + ((TBits.RotateLeft64(f, 50))
+    xor (TBits.RotateLeft64(f, 46)) xor (TBits.RotateLeft64(f, 23))) +
+    ((f and g) xor (not f and h)));
+
+  e := e + a;
+  a := a + (((TBits.RotateLeft64(b, 36)) xor (TBits.RotateLeft64(b, 30))
+    xor (TBits.RotateLeft64(b, 25))) + ((b and c) xor (b and d) xor (c and d)));
+
+  // R8
+
+  h := h + ($CA273ECEEA26619C + data[64] + ((TBits.RotateLeft64(e, 50))
+    xor (TBits.RotateLeft64(e, 46)) xor (TBits.RotateLeft64(e, 23))) +
+    ((e and f) xor (not e and g)));
+
+  d := d + h;
+  h := h + (((TBits.RotateLeft64(a, 36)) xor (TBits.RotateLeft64(a, 30))
+    xor (TBits.RotateLeft64(a, 25))) + ((a and b) xor (a and c) xor (b and c)));
+
+  g := g + ($D186B8C721C0C207 + data[65] + ((TBits.RotateLeft64(d, 50))
+    xor (TBits.RotateLeft64(d, 46)) xor (TBits.RotateLeft64(d, 23))) +
+    ((d and e) xor (not d and f)));
+
+  c := c + g;
+  g := g + (((TBits.RotateLeft64(h, 36)) xor (TBits.RotateLeft64(h, 30))
+    xor (TBits.RotateLeft64(h, 25))) + ((h and a) xor (h and b) xor (a and b)));
+
+  f := f + ($EADA7DD6CDE0EB1E + data[66] + ((TBits.RotateLeft64(c, 50))
+    xor (TBits.RotateLeft64(c, 46)) xor (TBits.RotateLeft64(c, 23))) +
+    ((c and d) xor (not c and e)));
+
+  b := b + f;
+  f := f + (((TBits.RotateLeft64(g, 36)) xor (TBits.RotateLeft64(g, 30))
+    xor (TBits.RotateLeft64(g, 25))) + ((g and h) xor (g and a) xor (h and a)));
+
+  e := e + ($F57D4F7FEE6ED178 + data[67] + ((TBits.RotateLeft64(b, 50))
+    xor (TBits.RotateLeft64(b, 46)) xor (TBits.RotateLeft64(b, 23))) +
+    ((b and c) xor (not b and d)));
+
+  a := a + e;
+  e := e + (((TBits.RotateLeft64(f, 36)) xor (TBits.RotateLeft64(f, 30))
+    xor (TBits.RotateLeft64(f, 25))) + ((f and g) xor (f and h) xor (g and h)));
+
+  d := d + ($06F067AA72176FBA + data[68] + ((TBits.RotateLeft64(a, 50))
+    xor (TBits.RotateLeft64(a, 46)) xor (TBits.RotateLeft64(a, 23))) +
+    ((a and b) xor (not a and c)));
+
+  h := h + d;
+  d := d + (((TBits.RotateLeft64(e, 36)) xor (TBits.RotateLeft64(e, 30))
+    xor (TBits.RotateLeft64(e, 25))) + ((e and f) xor (e and g) xor (f and g)));
+
+  c := c + ($0A637DC5A2C898A6 + data[69] + ((TBits.RotateLeft64(h, 50))
+    xor (TBits.RotateLeft64(h, 46)) xor (TBits.RotateLeft64(h, 23))) +
+    ((h and a) xor (not h and b)));
+
+  g := g + c;
+  c := c + (((TBits.RotateLeft64(d, 36)) xor (TBits.RotateLeft64(d, 30))
+    xor (TBits.RotateLeft64(d, 25))) + ((d and e) xor (d and f) xor (e and f)));
+
+  b := b + ($113F9804BEF90DAE + data[70] + ((TBits.RotateLeft64(g, 50))
+    xor (TBits.RotateLeft64(g, 46)) xor (TBits.RotateLeft64(g, 23))) +
+    ((g and h) xor (not g and a)));
+
+  f := f + b;
+  b := b + (((TBits.RotateLeft64(c, 36)) xor (TBits.RotateLeft64(c, 30))
+    xor (TBits.RotateLeft64(c, 25))) + ((c and d) xor (c and e) xor (d and e)));
+
+  a := a + ($1B710B35131C471B + data[71] + ((TBits.RotateLeft64(f, 50))
+    xor (TBits.RotateLeft64(f, 46)) xor (TBits.RotateLeft64(f, 23))) +
+    ((f and g) xor (not f and h)));
+
+  e := e + a;
+  a := a + (((TBits.RotateLeft64(b, 36)) xor (TBits.RotateLeft64(b, 30))
+    xor (TBits.RotateLeft64(b, 25))) + ((b and c) xor (b and d) xor (c and d)));
+
+  // R9
+
+  h := h + ($28DB77F523047D84 + data[72] + ((TBits.RotateLeft64(e, 50))
+    xor (TBits.RotateLeft64(e, 46)) xor (TBits.RotateLeft64(e, 23))) +
+    ((e and f) xor (not e and g)));
+
+  d := d + h;
+  h := h + (((TBits.RotateLeft64(a, 36)) xor (TBits.RotateLeft64(a, 30))
+    xor (TBits.RotateLeft64(a, 25))) + ((a and b) xor (a and c) xor (b and c)));
+
+  g := g + ($32CAAB7B40C72493 + data[73] + ((TBits.RotateLeft64(d, 50))
+    xor (TBits.RotateLeft64(d, 46)) xor (TBits.RotateLeft64(d, 23))) +
+    ((d and e) xor (not d and f)));
+
+  c := c + g;
+  g := g + (((TBits.RotateLeft64(h, 36)) xor (TBits.RotateLeft64(h, 30))
+    xor (TBits.RotateLeft64(h, 25))) + ((h and a) xor (h and b) xor (a and b)));
+
+  f := f + ($3C9EBE0A15C9BEBC + data[74] + ((TBits.RotateLeft64(c, 50))
+    xor (TBits.RotateLeft64(c, 46)) xor (TBits.RotateLeft64(c, 23))) +
+    ((c and d) xor (not c and e)));
+
+  b := b + f;
+  f := f + (((TBits.RotateLeft64(g, 36)) xor (TBits.RotateLeft64(g, 30))
+    xor (TBits.RotateLeft64(g, 25))) + ((g and h) xor (g and a) xor (h and a)));
+
+  e := e + ($431D67C49C100D4C + data[75] + ((TBits.RotateLeft64(b, 50))
+    xor (TBits.RotateLeft64(b, 46)) xor (TBits.RotateLeft64(b, 23))) +
+    ((b and c) xor (not b and d)));
+
+  a := a + e;
+  e := e + (((TBits.RotateLeft64(f, 36)) xor (TBits.RotateLeft64(f, 30))
+    xor (TBits.RotateLeft64(f, 25))) + ((f and g) xor (f and h) xor (g and h)));
+
+  d := d + ($4CC5D4BECB3E42B6 + data[76] + ((TBits.RotateLeft64(a, 50))
+    xor (TBits.RotateLeft64(a, 46)) xor (TBits.RotateLeft64(a, 23))) +
+    ((a and b) xor (not a and c)));
+
+  h := h + d;
+  d := d + (((TBits.RotateLeft64(e, 36)) xor (TBits.RotateLeft64(e, 30))
+    xor (TBits.RotateLeft64(e, 25))) + ((e and f) xor (e and g) xor (f and g)));
+
+  c := c + ($597F299CFC657E2A + data[77] + ((TBits.RotateLeft64(h, 50))
+    xor (TBits.RotateLeft64(h, 46)) xor (TBits.RotateLeft64(h, 23))) +
+    ((h and a) xor (not h and b)));
+
+  g := g + c;
+  c := c + (((TBits.RotateLeft64(d, 36)) xor (TBits.RotateLeft64(d, 30))
+    xor (TBits.RotateLeft64(d, 25))) + ((d and e) xor (d and f) xor (e and f)));
+
+  b := b + ($5FCB6FAB3AD6FAEC + data[78] + ((TBits.RotateLeft64(g, 50))
+    xor (TBits.RotateLeft64(g, 46)) xor (TBits.RotateLeft64(g, 23))) +
+    ((g and h) xor (not g and a)));
+
+  f := f + b;
+  b := b + (((TBits.RotateLeft64(c, 36)) xor (TBits.RotateLeft64(c, 30))
+    xor (TBits.RotateLeft64(c, 25))) + ((c and d) xor (c and e) xor (d and e)));
+
+  a := a + ($6C44198C4A475817 + data[79] + ((TBits.RotateLeft64(f, 50))
+    xor (TBits.RotateLeft64(f, 46)) xor (TBits.RotateLeft64(f, 23))) +
+    ((f and g) xor (not f and h)));
+
+  e := e + a;
+  a := a + (((TBits.RotateLeft64(b, 36)) xor (TBits.RotateLeft64(b, 30))
+    xor (TBits.RotateLeft64(b, 25))) + ((b and c) xor (b and d) xor (c and d)));
+
+{$ELSE}
+  a := Fm_state[0];
+  b := Fm_state[1];
+  c := Fm_state[2];
+  d := Fm_state[3];
+  e := Fm_state[4];
+  f := Fm_state[5];
+  g := Fm_state[6];
+  h := Fm_state[7];
+
+  // Step 1
+
+  for i := 16 to 79 do
+  begin
+    T0 := data[i - 15];
+    T1 := data[i - 2];
+    data[i] := ((TBits.RotateLeft64(T1, 45)) xor (TBits.RotateLeft64(T1, 3))
+      xor (T1 shr 6)) + data[i - 7] +
+      ((TBits.RotateLeft64(T0, 63)) xor (TBits.RotateLeft64(T0, 56))
+      xor (T0 shr 7)) + data[i - 16];
+  end;
+
+
+  // Step 2
+
+  t := 0;
+  i := 0;
+
+  while i <= 9 do
+
+  begin
+
+    h := h + (s_K[t] + data[t] + ((TBits.RotateLeft64(e, 50))
+      xor (TBits.RotateLeft64(e, 46)) xor (TBits.RotateLeft64(e, 23))) +
+      ((e and f) xor (not e and g)));
+    System.Inc(t);
+    d := d + h;
+    h := h + (((TBits.RotateLeft64(a, 36)) xor (TBits.RotateLeft64(a, 30))
+      xor (TBits.RotateLeft64(a, 25))) + ((a and b) xor (a and c)
+      xor (b and c)));
+
+    g := g + (s_K[t] + data[t] + ((TBits.RotateLeft64(d, 50))
+      xor (TBits.RotateLeft64(d, 46)) xor (TBits.RotateLeft64(d, 23))) +
+      ((d and e) xor (not d and f)));
+    System.Inc(t);
+    c := c + g;
+    g := g + (((TBits.RotateLeft64(h, 36)) xor (TBits.RotateLeft64(h, 30))
+      xor (TBits.RotateLeft64(h, 25))) + ((h and a) xor (h and b)
+      xor (a and b)));
+
+    f := f + (s_K[t] + data[t] + ((TBits.RotateLeft64(c, 50))
+      xor (TBits.RotateLeft64(c, 46)) xor (TBits.RotateLeft64(c, 23))) +
+      ((c and d) xor (not c and e)));
+    System.Inc(t);
+    b := b + f;
+    f := f + (((TBits.RotateLeft64(g, 36)) xor (TBits.RotateLeft64(g, 30))
+      xor (TBits.RotateLeft64(g, 25))) + ((g and h) xor (g and a)
+      xor (h and a)));
+
+    e := e + (s_K[t] + data[t] + ((TBits.RotateLeft64(b, 50))
+      xor (TBits.RotateLeft64(b, 46)) xor (TBits.RotateLeft64(b, 23))) +
+      ((b and c) xor (not b and d)));
+    System.Inc(t);
+    a := a + e;
+    e := e + (((TBits.RotateLeft64(f, 36)) xor (TBits.RotateLeft64(f, 30))
+      xor (TBits.RotateLeft64(f, 25))) + ((f and g) xor (f and h)
+      xor (g and h)));
+
+    d := d + (s_K[t] + data[t] + ((TBits.RotateLeft64(a, 50))
+      xor (TBits.RotateLeft64(a, 46)) xor (TBits.RotateLeft64(a, 23))) +
+      ((a and b) xor (not a and c)));
+    System.Inc(t);
+    h := h + d;
+    d := d + (((TBits.RotateLeft64(e, 36)) xor (TBits.RotateLeft64(e, 30))
+      xor (TBits.RotateLeft64(e, 25))) + ((e and f) xor (e and g)
+      xor (f and g)));
+
+    c := c + (s_K[t] + data[t] + ((TBits.RotateLeft64(h, 50))
+      xor (TBits.RotateLeft64(h, 46)) xor (TBits.RotateLeft64(h, 23))) +
+      ((h and a) xor (not h and b)));
+    System.Inc(t);
+    g := g + c;
+    c := c + (((TBits.RotateLeft64(d, 36)) xor (TBits.RotateLeft64(d, 30))
+      xor (TBits.RotateLeft64(d, 25))) + ((d and e) xor (d and f)
+      xor (e and f)));
+
+    b := b + (s_K[t] + data[t] + ((TBits.RotateLeft64(g, 50))
+      xor (TBits.RotateLeft64(g, 46)) xor (TBits.RotateLeft64(g, 23))) +
+      ((g and h) xor (not g and a)));
+    System.Inc(t);
+    f := f + b;
+    b := b + (((TBits.RotateLeft64(c, 36)) xor (TBits.RotateLeft64(c, 30))
+      xor (TBits.RotateLeft64(c, 25))) + ((c and d) xor (c and e)
+      xor (d and e)));
+
+    a := a + (s_K[t] + data[t] + ((TBits.RotateLeft64(f, 50))
+      xor (TBits.RotateLeft64(f, 46)) xor (TBits.RotateLeft64(f, 23))) +
+      ((f and g) xor (not f and h)));
+    System.Inc(t);
+    e := e + a;
+    a := a + (((TBits.RotateLeft64(b, 36)) xor (TBits.RotateLeft64(b, 30))
+      xor (TBits.RotateLeft64(b, 25))) + ((b and c) xor (b and d)
+      xor (c and d)));
+
+    System.Inc(i);
+  end;
+
+{$ENDIF USE_UNROLLED_VARIANT}
+  Fm_state[0] := Fm_state[0] + a;
+  Fm_state[1] := Fm_state[1] + b;
+  Fm_state[2] := Fm_state[2] + c;
+  Fm_state[3] := Fm_state[3] + d;
+  Fm_state[4] := Fm_state[4] + e;
+  Fm_state[5] := Fm_state[5] + f;
+  Fm_state[6] := Fm_state[6] + g;
+  Fm_state[7] := Fm_state[7] + h;
+
+  System.FillChar(data, System.SizeOf(data), 0);
+
+end;
+
+end.

+ 65 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA2_512_224.pas

@@ -0,0 +1,65 @@
+unit HlpSHA2_512_224;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpSHA2_512Base,
+  HlpConverters;
+
+type
+  TSHA2_512_224 = class sealed(TSHA2_512Base)
+
+  strict protected
+    function GetResult(): THashLibByteArray; override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TSHA2_512_224 }
+
+constructor TSHA2_512_224.Create;
+begin
+  Inherited Create(28);
+end;
+
+function TSHA2_512_224.GetResult: THashLibByteArray;
+begin
+
+  System.SetLength(result, 4 * System.SizeOf(UInt64));
+  TConverters.be64_copy(PUInt64(Fm_state), 0, PByte(result), 0,
+    System.Length(result));
+  System.SetLength(result, HashSize * System.SizeOf(Byte));
+
+end;
+
+procedure TSHA2_512_224.Initialize;
+begin
+
+  Fm_state[0] := UInt64($8C3D37C819544DA2);
+  Fm_state[1] := $73E1996689DCD4D6;
+  Fm_state[2] := $1DFAB7AE32FF9C82;
+  Fm_state[3] := $679DD514582F9FCF;
+  Fm_state[4] := $0F6D2B697BD44DA8;
+  Fm_state[5] := $77E36F7304C48942;
+  Fm_state[6] := $3F9D85A86A1D36C8;
+  Fm_state[7] := $1112E6AD91D692A1;
+
+  Inherited Initialize();
+
+end;
+
+end.

+ 64 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA2_512_256.pas

@@ -0,0 +1,64 @@
+unit HlpSHA2_512_256;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpSHA2_512Base,
+  HlpConverters;
+
+type
+  TSHA2_512_256 = class sealed(TSHA2_512Base)
+
+  strict protected
+    function GetResult(): THashLibByteArray; override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TSHA2_512_256 }
+
+constructor TSHA2_512_256.Create;
+begin
+  Inherited Create(32);
+end;
+
+function TSHA2_512_256.GetResult: THashLibByteArray;
+begin
+
+  System.SetLength(result, 4 * System.SizeOf(UInt64));
+  TConverters.be64_copy(PUInt64(Fm_state), 0, PByte(result), 0,
+    System.Length(result));
+
+end;
+
+procedure TSHA2_512_256.Initialize;
+begin
+
+  Fm_state[0] := $22312194FC2BF72C;
+  Fm_state[1] := UInt64($9F555FA3C84C64C2);
+  Fm_state[2] := $2393B86B6F53B151;
+  Fm_state[3] := UInt64($963877195940EABD);
+  Fm_state[4] := UInt64($96283EE2A88EFFE3);
+  Fm_state[5] := UInt64($BE5E1E2553863992);
+  Fm_state[6] := $2B0199FC2C85B8AA;
+  Fm_state[7] := $0EB72DDC81C52CA2;
+
+  Inherited Initialize();
+
+end;
+
+end.

+ 2814 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSHA3.pas

@@ -0,0 +1,2814 @@
+unit HlpSHA3;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpBits,
+{$IFDEF DELPHI}
+  HlpHashBuffer,
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn,
+  HlpConverters,
+  HlpHashSize,
+  HlpHashLibTypes;
+
+type
+  TSHA3 = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+  strict private
+    Fm_state: THashLibUInt64Array;
+
+  strict protected
+
+    FHashSize, FBlockSize: Int32;
+
+    (*
+      {$REGION 'Consts'}
+
+      const
+
+      RC: array [0 .. 23] of UInt64 = ($0000000000000001, $0000000000008082,
+      $800000000000808A, $8000000080008000, $000000000000808B,
+      $0000000080000001, $8000000080008081, $8000000000008009,
+      $000000000000008A, $0000000000000088, $0000000080008009,
+      $000000008000000A, $000000008000808B, $800000000000008B,
+      $8000000000008089, $8000000000008003, $8000000000008002,
+      $8000000000000080, $000000000000800A, $800000008000000A,
+      $8000000080008081, $8000000000008080, $0000000080000001,
+      $8000000080008008);
+
+      {$ENDREGION}
+    *)
+    constructor Create(a_hash_size: THashSize);
+
+    procedure Finish(); override;
+    function GetResult(): THashLibByteArray; override;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    procedure Initialize; override;
+
+  end;
+
+type
+
+  TSHA3_224 = class sealed(TSHA3)
+
+  public
+
+    constructor Create();
+  end;
+
+type
+
+  TSHA3_256 = class sealed(TSHA3)
+
+  public
+
+    constructor Create();
+  end;
+
+type
+
+  TSHA3_384 = class sealed(TSHA3)
+
+  public
+
+    constructor Create();
+  end;
+
+type
+
+  TSHA3_512 = class sealed(TSHA3)
+
+  public
+
+    constructor Create();
+  end;
+
+implementation
+
+{ TSHA3 }
+
+constructor TSHA3.Create(a_hash_size: THashSize);
+begin
+  Inherited Create(Int32(a_hash_size), 200 - (Int32(a_hash_size) * 2));
+
+  FHashSize := HashSize;
+  FBlockSize := BlockSize;
+
+  System.SetLength(Fm_state, 25);
+
+end;
+
+procedure TSHA3.Finish;
+var
+  buffer_pos: Int32;
+  block: THashLibByteArray;
+begin
+  buffer_pos := Fm_buffer.Pos;
+  block := Fm_buffer.GetBytesZeroPadded();
+
+  block[buffer_pos] := $6;
+  block[FBlockSize - 1] := block[FBlockSize - 1] xor $80;
+
+  TransformBlock(PByte(block), System.Length(block), 0);
+
+  Fm_state[1] := not Fm_state[1];
+  Fm_state[2] := not Fm_state[2];
+  Fm_state[8] := not Fm_state[8];
+  Fm_state[12] := not Fm_state[12];
+  Fm_state[17] := not Fm_state[17];
+
+end;
+
+function TSHA3.GetResult: THashLibByteArray;
+begin
+
+  System.SetLength(result, FHashSize);
+
+  TConverters.le64_copy(PUInt64(Fm_state), 0, PByte(result), 0,
+    System.Length(result));
+
+end;
+
+procedure TSHA3.Initialize;
+begin
+
+  System.FillChar(Fm_state[0], System.Length(Fm_state) * System.SizeOf(UInt64),
+    UInt64(0));
+
+  Fm_state[1] := System.High(UInt64);
+  Fm_state[2] := System.High(UInt64);
+  Fm_state[8] := System.High(UInt64);
+  Fm_state[12] := System.High(UInt64);
+  Fm_state[17] := System.High(UInt64);
+  Fm_state[20] := System.High(UInt64);
+
+  Inherited Initialize();
+
+end;
+
+procedure TSHA3.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  Aba, Abe, Abi, Abo, Abu, Aga, Age, Agi, Ago, Agu, Aka, Ake, Aki, Ako, Aku,
+    Ama, Ame, Ami, Amo, Amu, Asa, Ase, Asi, Aso, Asu, Bba, Bbe, Bbi, Bbo, Bbu,
+    Bga, Bge, Bgi, Bgo, Bgu, Bka, Bke, Bki, Bko, Bku, Bma, Bme, Bmi, Bmo, Bmu,
+    Bsa, Bse, Bsi, Bso, Bsu, Ca, Ce, Ci, Co, Cu, Da, De, Di, &Do, Du, Eba, Ebe,
+    Ebi, Ebo, Ebu, Ega, Ege, Egi, Ego, Egu, Eka, Eke, Eki, Eko, Eku, Ema, Eme,
+    Emi, Emo, Emu, Esa, Ese, Esi, Eso, Esu: UInt64;
+  data: array [0 .. 17] of UInt64;
+  j: Int32;
+begin
+  TConverters.le64_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+
+  j := 0;
+
+  while j < (FBlockSize shr 3) do
+  begin
+    Fm_state[j] := Fm_state[j] xor data[j];
+    System.Inc(j);
+  end;
+
+  Aba := Fm_state[0];
+  Abe := Fm_state[1];
+  Abi := Fm_state[2];
+  Abo := Fm_state[3];
+  Abu := Fm_state[4];
+  Aga := Fm_state[5];
+  Age := Fm_state[6];
+  Agi := Fm_state[7];
+  Ago := Fm_state[8];
+  Agu := Fm_state[9];
+  Aka := Fm_state[10];
+  Ake := Fm_state[11];
+  Aki := Fm_state[12];
+  Ako := Fm_state[13];
+  Aku := Fm_state[14];
+  Ama := Fm_state[15];
+  Ame := Fm_state[16];
+  Ami := Fm_state[17];
+  Amo := Fm_state[18];
+  Amu := Fm_state[19];
+  Asa := Fm_state[20];
+  Ase := Fm_state[21];
+  Asi := Fm_state[22];
+  Aso := Fm_state[23];
+  Asu := Fm_state[24];
+
+  Ca := Aba xor Aga xor Aka xor Ama xor Asa;
+  Ce := Abe xor Age xor Ake xor Ame xor Ase;
+  Ci := Abi xor Agi xor Aki xor Ami xor Asi;
+  Co := Abo xor Ago xor Ako xor Amo xor Aso;
+  Cu := Abu xor Agu xor Aku xor Amu xor Asu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Aba := Aba xor Da;
+  Bba := Aba;
+  Age := Age xor De;
+  Bbe := TBits.RotateLeft64(Age, 44);
+  Aki := Aki xor Di;
+  Bbi := TBits.RotateLeft64(Aki, 43);
+  Amo := Amo xor &Do;
+  Bbo := TBits.RotateLeft64(Amo, 21);
+  Asu := Asu xor Du;
+  Bbu := TBits.RotateLeft64(Asu, 14);
+  Eba := Bba xor (Bbe or Bbi);
+  // Eba := Eba xor RC[0];
+  Eba := Eba xor $0000000000000001;
+  Ca := Eba;
+  Ebe := Bbe xor (not Bbi or Bbo);
+  Ce := Ebe;
+  Ebi := Bbi xor (Bbo and Bbu);
+  Ci := Ebi;
+  Ebo := Bbo xor (Bbu or Bba);
+  Co := Ebo;
+  Ebu := Bbu xor (Bba and Bbe);
+  Cu := Ebu;
+  Abo := Abo xor &Do;
+  Bga := TBits.RotateLeft64(Abo, 28);
+  Agu := Agu xor Du;
+  Bge := TBits.RotateLeft64(Agu, 20);
+  Aka := Aka xor Da;
+  Bgi := TBits.RotateLeft64(Aka, 3);
+  Ame := Ame xor De;
+  Bgo := TBits.RotateLeft64(Ame, 45);
+  Asi := Asi xor Di;
+  Bgu := TBits.RotateLeft64(Asi, 61);
+  Ega := Bga xor (Bge or Bgi);
+  Ca := Ca xor Ega;
+  Ege := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Ege;
+  Egi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Egi;
+  Ego := Bgo xor (Bgu or Bga);
+  Co := Co xor Ego;
+  Egu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Egu;
+  Abe := Abe xor De;
+  Bka := TBits.RotateLeft64(Abe, 1);
+  Agi := Agi xor Di;
+  Bke := TBits.RotateLeft64(Agi, 6);
+  Ako := Ako xor &Do;
+  Bki := TBits.RotateLeft64(Ako, 25);
+  Amu := Amu xor Du;
+  Bko := TBits.RotateLeft64(Amu, 8);
+  Asa := Asa xor Da;
+  Bku := TBits.RotateLeft64(Asa, 18);
+  Eka := Bka xor (Bke or Bki);
+  Ca := Ca xor Eka;
+  Eke := Bke xor (Bki and Bko);
+  Ce := Ce xor Eke;
+  Eki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Eki;
+  Eko := (not Bko) xor (Bku or Bka);
+  Co := Co xor Eko;
+  Eku := Bku xor (Bka and Bke);
+  Cu := Cu xor Eku;
+  Abu := Abu xor Du;
+  Bma := TBits.RotateLeft64(Abu, 27);
+  Aga := Aga xor Da;
+  Bme := TBits.RotateLeft64(Aga, 36);
+  Ake := Ake xor De;
+  Bmi := TBits.RotateLeft64(Ake, 10);
+  Ami := Ami xor Di;
+  Bmo := TBits.RotateLeft64(Ami, 15);
+  Aso := Aso xor &Do;
+  Bmu := TBits.RotateLeft64(Aso, 56);
+  Ema := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ema;
+  Eme := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Eme;
+  Emi := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Emi;
+  Emo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Emo;
+  Emu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Emu;
+  Abi := Abi xor Di;
+  Bsa := TBits.RotateLeft64(Abi, 62);
+  Ago := Ago xor &Do;
+  Bse := TBits.RotateLeft64(Ago, 55);
+  Aku := Aku xor Du;
+  Bsi := TBits.RotateLeft64(Aku, 39);
+  Ama := Ama xor Da;
+  Bso := TBits.RotateLeft64(Ama, 41);
+  Ase := Ase xor De;
+  Bsu := TBits.RotateLeft64(Ase, 2);
+  Esa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Esa;
+  Ese := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ese;
+  Esi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Esi;
+  Eso := Bso xor (Bsu or Bsa);
+  Co := Co xor Eso;
+  Esu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Esu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Eba := Eba xor Da;
+  Bba := Eba;
+  Ege := Ege xor De;
+  Bbe := TBits.RotateLeft64(Ege, 44);
+  Eki := Eki xor Di;
+  Bbi := TBits.RotateLeft64(Eki, 43);
+  Emo := Emo xor &Do;
+  Bbo := TBits.RotateLeft64(Emo, 21);
+  Esu := Esu xor Du;
+  Bbu := TBits.RotateLeft64(Esu, 14);
+  Aba := Bba xor (Bbe or Bbi);
+  // Aba := Aba xor RC[1];
+  Aba := Aba xor $0000000000008082;
+  Ca := Aba;
+  Abe := Bbe xor (not Bbi or Bbo);
+  Ce := Abe;
+  Abi := Bbi xor (Bbo and Bbu);
+  Ci := Abi;
+  Abo := Bbo xor (Bbu or Bba);
+  Co := Abo;
+  Abu := Bbu xor (Bba and Bbe);
+  Cu := Abu;
+  Ebo := Ebo xor &Do;
+  Bga := TBits.RotateLeft64(Ebo, 28);
+  Egu := Egu xor Du;
+  Bge := TBits.RotateLeft64(Egu, 20);
+  Eka := Eka xor Da;
+  Bgi := TBits.RotateLeft64(Eka, 3);
+  Eme := Eme xor De;
+  Bgo := TBits.RotateLeft64(Eme, 45);
+  Esi := Esi xor Di;
+  Bgu := TBits.RotateLeft64(Esi, 61);
+  Aga := Bga xor (Bge or Bgi);
+  Ca := Ca xor Aga;
+  Age := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Age;
+  Agi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Agi;
+  Ago := Bgo xor (Bgu or Bga);
+  Co := Co xor Ago;
+  Agu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Agu;
+  Ebe := Ebe xor De;
+  Bka := TBits.RotateLeft64(Ebe, 1);
+  Egi := Egi xor Di;
+  Bke := TBits.RotateLeft64(Egi, 6);
+  Eko := Eko xor &Do;
+  Bki := TBits.RotateLeft64(Eko, 25);
+  Emu := Emu xor Du;
+  Bko := TBits.RotateLeft64(Emu, 8);
+  Esa := Esa xor Da;
+  Bku := TBits.RotateLeft64(Esa, 18);
+  Aka := Bka xor (Bke or Bki);
+  Ca := Ca xor Aka;
+  Ake := Bke xor (Bki and Bko);
+  Ce := Ce xor Ake;
+  Aki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Aki;
+  Ako := (not Bko) xor (Bku or Bka);
+  Co := Co xor Ako;
+  Aku := Bku xor (Bka and Bke);
+  Cu := Cu xor Aku;
+  Ebu := Ebu xor Du;
+  Bma := TBits.RotateLeft64(Ebu, 27);
+  Ega := Ega xor Da;
+  Bme := TBits.RotateLeft64(Ega, 36);
+  Eke := Eke xor De;
+  Bmi := TBits.RotateLeft64(Eke, 10);
+  Emi := Emi xor Di;
+  Bmo := TBits.RotateLeft64(Emi, 15);
+  Eso := Eso xor &Do;
+  Bmu := TBits.RotateLeft64(Eso, 56);
+  Ama := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ama;
+  Ame := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Ame;
+  Ami := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Ami;
+  Amo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Amo;
+  Amu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Amu;
+  Ebi := Ebi xor Di;
+  Bsa := TBits.RotateLeft64(Ebi, 62);
+  Ego := Ego xor &Do;
+  Bse := TBits.RotateLeft64(Ego, 55);
+  Eku := Eku xor Du;
+  Bsi := TBits.RotateLeft64(Eku, 39);
+  Ema := Ema xor Da;
+  Bso := TBits.RotateLeft64(Ema, 41);
+  Ese := Ese xor De;
+  Bsu := TBits.RotateLeft64(Ese, 2);
+  Asa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Asa;
+  Ase := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ase;
+  Asi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Asi;
+  Aso := Bso xor (Bsu or Bsa);
+  Co := Co xor Aso;
+  Asu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Asu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Aba := Aba xor Da;
+  Bba := Aba;
+  Age := Age xor De;
+  Bbe := TBits.RotateLeft64(Age, 44);
+  Aki := Aki xor Di;
+  Bbi := TBits.RotateLeft64(Aki, 43);
+  Amo := Amo xor &Do;
+  Bbo := TBits.RotateLeft64(Amo, 21);
+  Asu := Asu xor Du;
+  Bbu := TBits.RotateLeft64(Asu, 14);
+  Eba := Bba xor (Bbe or Bbi);
+  // Eba := Eba xor RC[2];
+  Eba := Eba xor $800000000000808A;
+  Ca := Eba;
+  Ebe := Bbe xor (not Bbi or Bbo);
+  Ce := Ebe;
+  Ebi := Bbi xor (Bbo and Bbu);
+  Ci := Ebi;
+  Ebo := Bbo xor (Bbu or Bba);
+  Co := Ebo;
+  Ebu := Bbu xor (Bba and Bbe);
+  Cu := Ebu;
+  Abo := Abo xor &Do;
+  Bga := TBits.RotateLeft64(Abo, 28);
+  Agu := Agu xor Du;
+  Bge := TBits.RotateLeft64(Agu, 20);
+  Aka := Aka xor Da;
+  Bgi := TBits.RotateLeft64(Aka, 3);
+  Ame := Ame xor De;
+  Bgo := TBits.RotateLeft64(Ame, 45);
+  Asi := Asi xor Di;
+  Bgu := TBits.RotateLeft64(Asi, 61);
+  Ega := Bga xor (Bge or Bgi);
+  Ca := Ca xor Ega;
+  Ege := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Ege;
+  Egi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Egi;
+  Ego := Bgo xor (Bgu or Bga);
+  Co := Co xor Ego;
+  Egu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Egu;
+  Abe := Abe xor De;
+  Bka := TBits.RotateLeft64(Abe, 1);
+  Agi := Agi xor Di;
+  Bke := TBits.RotateLeft64(Agi, 6);
+  Ako := Ako xor &Do;
+  Bki := TBits.RotateLeft64(Ako, 25);
+  Amu := Amu xor Du;
+  Bko := TBits.RotateLeft64(Amu, 8);
+  Asa := Asa xor Da;
+  Bku := TBits.RotateLeft64(Asa, 18);
+  Eka := Bka xor (Bke or Bki);
+  Ca := Ca xor Eka;
+  Eke := Bke xor (Bki and Bko);
+  Ce := Ce xor Eke;
+  Eki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Eki;
+  Eko := (not Bko) xor (Bku or Bka);
+  Co := Co xor Eko;
+  Eku := Bku xor (Bka and Bke);
+  Cu := Cu xor Eku;
+  Abu := Abu xor Du;
+  Bma := TBits.RotateLeft64(Abu, 27);
+  Aga := Aga xor Da;
+  Bme := TBits.RotateLeft64(Aga, 36);
+  Ake := Ake xor De;
+  Bmi := TBits.RotateLeft64(Ake, 10);
+  Ami := Ami xor Di;
+  Bmo := TBits.RotateLeft64(Ami, 15);
+  Aso := Aso xor &Do;
+  Bmu := TBits.RotateLeft64(Aso, 56);
+  Ema := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ema;
+  Eme := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Eme;
+  Emi := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Emi;
+  Emo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Emo;
+  Emu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Emu;
+  Abi := Abi xor Di;
+  Bsa := TBits.RotateLeft64(Abi, 62);
+  Ago := Ago xor &Do;
+  Bse := TBits.RotateLeft64(Ago, 55);
+  Aku := Aku xor Du;
+  Bsi := TBits.RotateLeft64(Aku, 39);
+  Ama := Ama xor Da;
+  Bso := TBits.RotateLeft64(Ama, 41);
+  Ase := Ase xor De;
+  Bsu := TBits.RotateLeft64(Ase, 2);
+  Esa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Esa;
+  Ese := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ese;
+  Esi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Esi;
+  Eso := Bso xor (Bsu or Bsa);
+  Co := Co xor Eso;
+  Esu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Esu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Eba := Eba xor Da;
+  Bba := Eba;
+  Ege := Ege xor De;
+  Bbe := TBits.RotateLeft64(Ege, 44);
+  Eki := Eki xor Di;
+  Bbi := TBits.RotateLeft64(Eki, 43);
+  Emo := Emo xor &Do;
+  Bbo := TBits.RotateLeft64(Emo, 21);
+  Esu := Esu xor Du;
+  Bbu := TBits.RotateLeft64(Esu, 14);
+  Aba := Bba xor (Bbe or Bbi);
+  // Aba := Aba xor RC[3];
+  Aba := Aba xor $8000000080008000;
+  Ca := Aba;
+  Abe := Bbe xor (not Bbi or Bbo);
+  Ce := Abe;
+  Abi := Bbi xor (Bbo and Bbu);
+  Ci := Abi;
+  Abo := Bbo xor (Bbu or Bba);
+  Co := Abo;
+  Abu := Bbu xor (Bba and Bbe);
+  Cu := Abu;
+  Ebo := Ebo xor &Do;
+  Bga := TBits.RotateLeft64(Ebo, 28);
+  Egu := Egu xor Du;
+  Bge := TBits.RotateLeft64(Egu, 20);
+  Eka := Eka xor Da;
+  Bgi := TBits.RotateLeft64(Eka, 3);
+  Eme := Eme xor De;
+  Bgo := TBits.RotateLeft64(Eme, 45);
+  Esi := Esi xor Di;
+  Bgu := TBits.RotateLeft64(Esi, 61);
+  Aga := Bga xor (Bge or Bgi);
+  Ca := Ca xor Aga;
+  Age := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Age;
+  Agi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Agi;
+  Ago := Bgo xor (Bgu or Bga);
+  Co := Co xor Ago;
+  Agu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Agu;
+  Ebe := Ebe xor De;
+  Bka := TBits.RotateLeft64(Ebe, 1);
+  Egi := Egi xor Di;
+  Bke := TBits.RotateLeft64(Egi, 6);
+  Eko := Eko xor &Do;
+  Bki := TBits.RotateLeft64(Eko, 25);
+  Emu := Emu xor Du;
+  Bko := TBits.RotateLeft64(Emu, 8);
+  Esa := Esa xor Da;
+  Bku := TBits.RotateLeft64(Esa, 18);
+  Aka := Bka xor (Bke or Bki);
+  Ca := Ca xor Aka;
+  Ake := Bke xor (Bki and Bko);
+  Ce := Ce xor Ake;
+  Aki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Aki;
+  Ako := (not Bko) xor (Bku or Bka);
+  Co := Co xor Ako;
+  Aku := Bku xor (Bka and Bke);
+  Cu := Cu xor Aku;
+  Ebu := Ebu xor Du;
+  Bma := TBits.RotateLeft64(Ebu, 27);
+  Ega := Ega xor Da;
+  Bme := TBits.RotateLeft64(Ega, 36);
+  Eke := Eke xor De;
+  Bmi := TBits.RotateLeft64(Eke, 10);
+  Emi := Emi xor Di;
+  Bmo := TBits.RotateLeft64(Emi, 15);
+  Eso := Eso xor &Do;
+  Bmu := TBits.RotateLeft64(Eso, 56);
+  Ama := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ama;
+  Ame := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Ame;
+  Ami := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Ami;
+  Amo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Amo;
+  Amu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Amu;
+  Ebi := Ebi xor Di;
+  Bsa := TBits.RotateLeft64(Ebi, 62);
+  Ego := Ego xor &Do;
+  Bse := TBits.RotateLeft64(Ego, 55);
+  Eku := Eku xor Du;
+  Bsi := TBits.RotateLeft64(Eku, 39);
+  Ema := Ema xor Da;
+  Bso := TBits.RotateLeft64(Ema, 41);
+  Ese := Ese xor De;
+  Bsu := TBits.RotateLeft64(Ese, 2);
+  Asa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Asa;
+  Ase := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ase;
+  Asi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Asi;
+  Aso := Bso xor (Bsu or Bsa);
+  Co := Co xor Aso;
+  Asu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Asu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Aba := Aba xor Da;
+  Bba := Aba;
+  Age := Age xor De;
+  Bbe := TBits.RotateLeft64(Age, 44);
+  Aki := Aki xor Di;
+  Bbi := TBits.RotateLeft64(Aki, 43);
+  Amo := Amo xor &Do;
+  Bbo := TBits.RotateLeft64(Amo, 21);
+  Asu := Asu xor Du;
+  Bbu := TBits.RotateLeft64(Asu, 14);
+  Eba := Bba xor (Bbe or Bbi);
+  // Eba := Eba xor RC[4];
+  Eba := Eba xor $000000000000808B;
+  Ca := Eba;
+  Ebe := Bbe xor (not Bbi or Bbo);
+  Ce := Ebe;
+  Ebi := Bbi xor (Bbo and Bbu);
+  Ci := Ebi;
+  Ebo := Bbo xor (Bbu or Bba);
+  Co := Ebo;
+  Ebu := Bbu xor (Bba and Bbe);
+  Cu := Ebu;
+  Abo := Abo xor &Do;
+  Bga := TBits.RotateLeft64(Abo, 28);
+  Agu := Agu xor Du;
+  Bge := TBits.RotateLeft64(Agu, 20);
+  Aka := Aka xor Da;
+  Bgi := TBits.RotateLeft64(Aka, 3);
+  Ame := Ame xor De;
+  Bgo := TBits.RotateLeft64(Ame, 45);
+  Asi := Asi xor Di;
+  Bgu := TBits.RotateLeft64(Asi, 61);
+  Ega := Bga xor (Bge or Bgi);
+  Ca := Ca xor Ega;
+  Ege := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Ege;
+  Egi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Egi;
+  Ego := Bgo xor (Bgu or Bga);
+  Co := Co xor Ego;
+  Egu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Egu;
+  Abe := Abe xor De;
+  Bka := TBits.RotateLeft64(Abe, 1);
+  Agi := Agi xor Di;
+  Bke := TBits.RotateLeft64(Agi, 6);
+  Ako := Ako xor &Do;
+  Bki := TBits.RotateLeft64(Ako, 25);
+  Amu := Amu xor Du;
+  Bko := TBits.RotateLeft64(Amu, 8);
+  Asa := Asa xor Da;
+  Bku := TBits.RotateLeft64(Asa, 18);
+  Eka := Bka xor (Bke or Bki);
+  Ca := Ca xor Eka;
+  Eke := Bke xor (Bki and Bko);
+  Ce := Ce xor Eke;
+  Eki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Eki;
+  Eko := (not Bko) xor (Bku or Bka);
+  Co := Co xor Eko;
+  Eku := Bku xor (Bka and Bke);
+  Cu := Cu xor Eku;
+  Abu := Abu xor Du;
+  Bma := TBits.RotateLeft64(Abu, 27);
+  Aga := Aga xor Da;
+  Bme := TBits.RotateLeft64(Aga, 36);
+  Ake := Ake xor De;
+  Bmi := TBits.RotateLeft64(Ake, 10);
+  Ami := Ami xor Di;
+  Bmo := TBits.RotateLeft64(Ami, 15);
+  Aso := Aso xor &Do;
+  Bmu := TBits.RotateLeft64(Aso, 56);
+  Ema := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ema;
+  Eme := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Eme;
+  Emi := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Emi;
+  Emo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Emo;
+  Emu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Emu;
+  Abi := Abi xor Di;
+  Bsa := TBits.RotateLeft64(Abi, 62);
+  Ago := Ago xor &Do;
+  Bse := TBits.RotateLeft64(Ago, 55);
+  Aku := Aku xor Du;
+  Bsi := TBits.RotateLeft64(Aku, 39);
+  Ama := Ama xor Da;
+  Bso := TBits.RotateLeft64(Ama, 41);
+  Ase := Ase xor De;
+  Bsu := TBits.RotateLeft64(Ase, 2);
+  Esa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Esa;
+  Ese := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ese;
+  Esi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Esi;
+  Eso := Bso xor (Bsu or Bsa);
+  Co := Co xor Eso;
+  Esu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Esu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Eba := Eba xor Da;
+  Bba := Eba;
+  Ege := Ege xor De;
+  Bbe := TBits.RotateLeft64(Ege, 44);
+  Eki := Eki xor Di;
+  Bbi := TBits.RotateLeft64(Eki, 43);
+  Emo := Emo xor &Do;
+  Bbo := TBits.RotateLeft64(Emo, 21);
+  Esu := Esu xor Du;
+  Bbu := TBits.RotateLeft64(Esu, 14);
+  Aba := Bba xor (Bbe or Bbi);
+  // Aba := Aba xor RC[5];
+  Aba := Aba xor $0000000080000001;
+  Ca := Aba;
+  Abe := Bbe xor (not Bbi or Bbo);
+  Ce := Abe;
+  Abi := Bbi xor (Bbo and Bbu);
+  Ci := Abi;
+  Abo := Bbo xor (Bbu or Bba);
+  Co := Abo;
+  Abu := Bbu xor (Bba and Bbe);
+  Cu := Abu;
+  Ebo := Ebo xor &Do;
+  Bga := TBits.RotateLeft64(Ebo, 28);
+  Egu := Egu xor Du;
+  Bge := TBits.RotateLeft64(Egu, 20);
+  Eka := Eka xor Da;
+  Bgi := TBits.RotateLeft64(Eka, 3);
+  Eme := Eme xor De;
+  Bgo := TBits.RotateLeft64(Eme, 45);
+  Esi := Esi xor Di;
+  Bgu := TBits.RotateLeft64(Esi, 61);
+  Aga := Bga xor (Bge or Bgi);
+  Ca := Ca xor Aga;
+  Age := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Age;
+  Agi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Agi;
+  Ago := Bgo xor (Bgu or Bga);
+  Co := Co xor Ago;
+  Agu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Agu;
+  Ebe := Ebe xor De;
+  Bka := TBits.RotateLeft64(Ebe, 1);
+  Egi := Egi xor Di;
+  Bke := TBits.RotateLeft64(Egi, 6);
+  Eko := Eko xor &Do;
+  Bki := TBits.RotateLeft64(Eko, 25);
+  Emu := Emu xor Du;
+  Bko := TBits.RotateLeft64(Emu, 8);
+  Esa := Esa xor Da;
+  Bku := TBits.RotateLeft64(Esa, 18);
+  Aka := Bka xor (Bke or Bki);
+  Ca := Ca xor Aka;
+  Ake := Bke xor (Bki and Bko);
+  Ce := Ce xor Ake;
+  Aki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Aki;
+  Ako := (not Bko) xor (Bku or Bka);
+  Co := Co xor Ako;
+  Aku := Bku xor (Bka and Bke);
+  Cu := Cu xor Aku;
+  Ebu := Ebu xor Du;
+  Bma := TBits.RotateLeft64(Ebu, 27);
+  Ega := Ega xor Da;
+  Bme := TBits.RotateLeft64(Ega, 36);
+  Eke := Eke xor De;
+  Bmi := TBits.RotateLeft64(Eke, 10);
+  Emi := Emi xor Di;
+  Bmo := TBits.RotateLeft64(Emi, 15);
+  Eso := Eso xor &Do;
+  Bmu := TBits.RotateLeft64(Eso, 56);
+  Ama := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ama;
+  Ame := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Ame;
+  Ami := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Ami;
+  Amo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Amo;
+  Amu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Amu;
+  Ebi := Ebi xor Di;
+  Bsa := TBits.RotateLeft64(Ebi, 62);
+  Ego := Ego xor &Do;
+  Bse := TBits.RotateLeft64(Ego, 55);
+  Eku := Eku xor Du;
+  Bsi := TBits.RotateLeft64(Eku, 39);
+  Ema := Ema xor Da;
+  Bso := TBits.RotateLeft64(Ema, 41);
+  Ese := Ese xor De;
+  Bsu := TBits.RotateLeft64(Ese, 2);
+  Asa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Asa;
+  Ase := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ase;
+  Asi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Asi;
+  Aso := Bso xor (Bsu or Bsa);
+  Co := Co xor Aso;
+  Asu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Asu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Aba := Aba xor Da;
+  Bba := Aba;
+  Age := Age xor De;
+  Bbe := TBits.RotateLeft64(Age, 44);
+  Aki := Aki xor Di;
+  Bbi := TBits.RotateLeft64(Aki, 43);
+  Amo := Amo xor &Do;
+  Bbo := TBits.RotateLeft64(Amo, 21);
+  Asu := Asu xor Du;
+  Bbu := TBits.RotateLeft64(Asu, 14);
+  Eba := Bba xor (Bbe or Bbi);
+  // Eba := Eba xor RC[6];
+  Eba := Eba xor $8000000080008081;
+  Ca := Eba;
+  Ebe := Bbe xor (not Bbi or Bbo);
+  Ce := Ebe;
+  Ebi := Bbi xor (Bbo and Bbu);
+  Ci := Ebi;
+  Ebo := Bbo xor (Bbu or Bba);
+  Co := Ebo;
+  Ebu := Bbu xor (Bba and Bbe);
+  Cu := Ebu;
+  Abo := Abo xor &Do;
+  Bga := TBits.RotateLeft64(Abo, 28);
+  Agu := Agu xor Du;
+  Bge := TBits.RotateLeft64(Agu, 20);
+  Aka := Aka xor Da;
+  Bgi := TBits.RotateLeft64(Aka, 3);
+  Ame := Ame xor De;
+  Bgo := TBits.RotateLeft64(Ame, 45);
+  Asi := Asi xor Di;
+  Bgu := TBits.RotateLeft64(Asi, 61);
+  Ega := Bga xor (Bge or Bgi);
+  Ca := Ca xor Ega;
+  Ege := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Ege;
+  Egi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Egi;
+  Ego := Bgo xor (Bgu or Bga);
+  Co := Co xor Ego;
+  Egu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Egu;
+  Abe := Abe xor De;
+  Bka := TBits.RotateLeft64(Abe, 1);
+  Agi := Agi xor Di;
+  Bke := TBits.RotateLeft64(Agi, 6);
+  Ako := Ako xor &Do;
+  Bki := TBits.RotateLeft64(Ako, 25);
+  Amu := Amu xor Du;
+  Bko := TBits.RotateLeft64(Amu, 8);
+  Asa := Asa xor Da;
+  Bku := TBits.RotateLeft64(Asa, 18);
+  Eka := Bka xor (Bke or Bki);
+  Ca := Ca xor Eka;
+  Eke := Bke xor (Bki and Bko);
+  Ce := Ce xor Eke;
+  Eki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Eki;
+  Eko := (not Bko) xor (Bku or Bka);
+  Co := Co xor Eko;
+  Eku := Bku xor (Bka and Bke);
+  Cu := Cu xor Eku;
+  Abu := Abu xor Du;
+  Bma := TBits.RotateLeft64(Abu, 27);
+  Aga := Aga xor Da;
+  Bme := TBits.RotateLeft64(Aga, 36);
+  Ake := Ake xor De;
+  Bmi := TBits.RotateLeft64(Ake, 10);
+  Ami := Ami xor Di;
+  Bmo := TBits.RotateLeft64(Ami, 15);
+  Aso := Aso xor &Do;
+  Bmu := TBits.RotateLeft64(Aso, 56);
+  Ema := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ema;
+  Eme := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Eme;
+  Emi := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Emi;
+  Emo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Emo;
+  Emu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Emu;
+  Abi := Abi xor Di;
+  Bsa := TBits.RotateLeft64(Abi, 62);
+  Ago := Ago xor &Do;
+  Bse := TBits.RotateLeft64(Ago, 55);
+  Aku := Aku xor Du;
+  Bsi := TBits.RotateLeft64(Aku, 39);
+  Ama := Ama xor Da;
+  Bso := TBits.RotateLeft64(Ama, 41);
+  Ase := Ase xor De;
+  Bsu := TBits.RotateLeft64(Ase, 2);
+  Esa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Esa;
+  Ese := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ese;
+  Esi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Esi;
+  Eso := Bso xor (Bsu or Bsa);
+  Co := Co xor Eso;
+  Esu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Esu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Eba := Eba xor Da;
+  Bba := Eba;
+  Ege := Ege xor De;
+  Bbe := TBits.RotateLeft64(Ege, 44);
+  Eki := Eki xor Di;
+  Bbi := TBits.RotateLeft64(Eki, 43);
+  Emo := Emo xor &Do;
+  Bbo := TBits.RotateLeft64(Emo, 21);
+  Esu := Esu xor Du;
+  Bbu := TBits.RotateLeft64(Esu, 14);
+  Aba := Bba xor (Bbe or Bbi);
+  // Aba := Aba xor RC[7];
+  Aba := Aba xor $8000000000008009;
+  Ca := Aba;
+  Abe := Bbe xor (not Bbi or Bbo);
+  Ce := Abe;
+  Abi := Bbi xor (Bbo and Bbu);
+  Ci := Abi;
+  Abo := Bbo xor (Bbu or Bba);
+  Co := Abo;
+  Abu := Bbu xor (Bba and Bbe);
+  Cu := Abu;
+  Ebo := Ebo xor &Do;
+  Bga := TBits.RotateLeft64(Ebo, 28);
+  Egu := Egu xor Du;
+  Bge := TBits.RotateLeft64(Egu, 20);
+  Eka := Eka xor Da;
+  Bgi := TBits.RotateLeft64(Eka, 3);
+  Eme := Eme xor De;
+  Bgo := TBits.RotateLeft64(Eme, 45);
+  Esi := Esi xor Di;
+  Bgu := TBits.RotateLeft64(Esi, 61);
+  Aga := Bga xor (Bge or Bgi);
+  Ca := Ca xor Aga;
+  Age := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Age;
+  Agi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Agi;
+  Ago := Bgo xor (Bgu or Bga);
+  Co := Co xor Ago;
+  Agu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Agu;
+  Ebe := Ebe xor De;
+  Bka := TBits.RotateLeft64(Ebe, 1);
+  Egi := Egi xor Di;
+  Bke := TBits.RotateLeft64(Egi, 6);
+  Eko := Eko xor &Do;
+  Bki := TBits.RotateLeft64(Eko, 25);
+  Emu := Emu xor Du;
+  Bko := TBits.RotateLeft64(Emu, 8);
+  Esa := Esa xor Da;
+  Bku := TBits.RotateLeft64(Esa, 18);
+  Aka := Bka xor (Bke or Bki);
+  Ca := Ca xor Aka;
+  Ake := Bke xor (Bki and Bko);
+  Ce := Ce xor Ake;
+  Aki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Aki;
+  Ako := (not Bko) xor (Bku or Bka);
+  Co := Co xor Ako;
+  Aku := Bku xor (Bka and Bke);
+  Cu := Cu xor Aku;
+  Ebu := Ebu xor Du;
+  Bma := TBits.RotateLeft64(Ebu, 27);
+  Ega := Ega xor Da;
+  Bme := TBits.RotateLeft64(Ega, 36);
+  Eke := Eke xor De;
+  Bmi := TBits.RotateLeft64(Eke, 10);
+  Emi := Emi xor Di;
+  Bmo := TBits.RotateLeft64(Emi, 15);
+  Eso := Eso xor &Do;
+  Bmu := TBits.RotateLeft64(Eso, 56);
+  Ama := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ama;
+  Ame := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Ame;
+  Ami := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Ami;
+  Amo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Amo;
+  Amu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Amu;
+  Ebi := Ebi xor Di;
+  Bsa := TBits.RotateLeft64(Ebi, 62);
+  Ego := Ego xor &Do;
+  Bse := TBits.RotateLeft64(Ego, 55);
+  Eku := Eku xor Du;
+  Bsi := TBits.RotateLeft64(Eku, 39);
+  Ema := Ema xor Da;
+  Bso := TBits.RotateLeft64(Ema, 41);
+  Ese := Ese xor De;
+  Bsu := TBits.RotateLeft64(Ese, 2);
+  Asa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Asa;
+  Ase := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ase;
+  Asi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Asi;
+  Aso := Bso xor (Bsu or Bsa);
+  Co := Co xor Aso;
+  Asu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Asu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Aba := Aba xor Da;
+  Bba := Aba;
+  Age := Age xor De;
+  Bbe := TBits.RotateLeft64(Age, 44);
+  Aki := Aki xor Di;
+  Bbi := TBits.RotateLeft64(Aki, 43);
+  Amo := Amo xor &Do;
+  Bbo := TBits.RotateLeft64(Amo, 21);
+  Asu := Asu xor Du;
+  Bbu := TBits.RotateLeft64(Asu, 14);
+  Eba := Bba xor (Bbe or Bbi);
+  // Eba := Eba xor RC[8];
+  Eba := Eba xor $000000000000008A;
+  Ca := Eba;
+  Ebe := Bbe xor (not Bbi or Bbo);
+  Ce := Ebe;
+  Ebi := Bbi xor (Bbo and Bbu);
+  Ci := Ebi;
+  Ebo := Bbo xor (Bbu or Bba);
+  Co := Ebo;
+  Ebu := Bbu xor (Bba and Bbe);
+  Cu := Ebu;
+  Abo := Abo xor &Do;
+  Bga := TBits.RotateLeft64(Abo, 28);
+  Agu := Agu xor Du;
+  Bge := TBits.RotateLeft64(Agu, 20);
+  Aka := Aka xor Da;
+  Bgi := TBits.RotateLeft64(Aka, 3);
+  Ame := Ame xor De;
+  Bgo := TBits.RotateLeft64(Ame, 45);
+  Asi := Asi xor Di;
+  Bgu := TBits.RotateLeft64(Asi, 61);
+  Ega := Bga xor (Bge or Bgi);
+  Ca := Ca xor Ega;
+  Ege := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Ege;
+  Egi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Egi;
+  Ego := Bgo xor (Bgu or Bga);
+  Co := Co xor Ego;
+  Egu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Egu;
+  Abe := Abe xor De;
+  Bka := TBits.RotateLeft64(Abe, 1);
+  Agi := Agi xor Di;
+  Bke := TBits.RotateLeft64(Agi, 6);
+  Ako := Ako xor &Do;
+  Bki := TBits.RotateLeft64(Ako, 25);
+  Amu := Amu xor Du;
+  Bko := TBits.RotateLeft64(Amu, 8);
+  Asa := Asa xor Da;
+  Bku := TBits.RotateLeft64(Asa, 18);
+  Eka := Bka xor (Bke or Bki);
+  Ca := Ca xor Eka;
+  Eke := Bke xor (Bki and Bko);
+  Ce := Ce xor Eke;
+  Eki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Eki;
+  Eko := (not Bko) xor (Bku or Bka);
+  Co := Co xor Eko;
+  Eku := Bku xor (Bka and Bke);
+  Cu := Cu xor Eku;
+  Abu := Abu xor Du;
+  Bma := TBits.RotateLeft64(Abu, 27);
+  Aga := Aga xor Da;
+  Bme := TBits.RotateLeft64(Aga, 36);
+  Ake := Ake xor De;
+  Bmi := TBits.RotateLeft64(Ake, 10);
+  Ami := Ami xor Di;
+  Bmo := TBits.RotateLeft64(Ami, 15);
+  Aso := Aso xor &Do;
+  Bmu := TBits.RotateLeft64(Aso, 56);
+  Ema := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ema;
+  Eme := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Eme;
+  Emi := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Emi;
+  Emo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Emo;
+  Emu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Emu;
+  Abi := Abi xor Di;
+  Bsa := TBits.RotateLeft64(Abi, 62);
+  Ago := Ago xor &Do;
+  Bse := TBits.RotateLeft64(Ago, 55);
+  Aku := Aku xor Du;
+  Bsi := TBits.RotateLeft64(Aku, 39);
+  Ama := Ama xor Da;
+  Bso := TBits.RotateLeft64(Ama, 41);
+  Ase := Ase xor De;
+  Bsu := TBits.RotateLeft64(Ase, 2);
+  Esa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Esa;
+  Ese := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ese;
+  Esi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Esi;
+  Eso := Bso xor (Bsu or Bsa);
+  Co := Co xor Eso;
+  Esu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Esu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Eba := Eba xor Da;
+  Bba := Eba;
+  Ege := Ege xor De;
+  Bbe := TBits.RotateLeft64(Ege, 44);
+  Eki := Eki xor Di;
+  Bbi := TBits.RotateLeft64(Eki, 43);
+  Emo := Emo xor &Do;
+  Bbo := TBits.RotateLeft64(Emo, 21);
+  Esu := Esu xor Du;
+  Bbu := TBits.RotateLeft64(Esu, 14);
+  Aba := Bba xor (Bbe or Bbi);
+  // Aba := Aba xor RC[9];
+  Aba := Aba xor $0000000000000088;
+  Ca := Aba;
+  Abe := Bbe xor (not Bbi or Bbo);
+  Ce := Abe;
+  Abi := Bbi xor (Bbo and Bbu);
+  Ci := Abi;
+  Abo := Bbo xor (Bbu or Bba);
+  Co := Abo;
+  Abu := Bbu xor (Bba and Bbe);
+  Cu := Abu;
+  Ebo := Ebo xor &Do;
+  Bga := TBits.RotateLeft64(Ebo, 28);
+  Egu := Egu xor Du;
+  Bge := TBits.RotateLeft64(Egu, 20);
+  Eka := Eka xor Da;
+  Bgi := TBits.RotateLeft64(Eka, 3);
+  Eme := Eme xor De;
+  Bgo := TBits.RotateLeft64(Eme, 45);
+  Esi := Esi xor Di;
+  Bgu := TBits.RotateLeft64(Esi, 61);
+  Aga := Bga xor (Bge or Bgi);
+  Ca := Ca xor Aga;
+  Age := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Age;
+  Agi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Agi;
+  Ago := Bgo xor (Bgu or Bga);
+  Co := Co xor Ago;
+  Agu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Agu;
+  Ebe := Ebe xor De;
+  Bka := TBits.RotateLeft64(Ebe, 1);
+  Egi := Egi xor Di;
+  Bke := TBits.RotateLeft64(Egi, 6);
+  Eko := Eko xor &Do;
+  Bki := TBits.RotateLeft64(Eko, 25);
+  Emu := Emu xor Du;
+  Bko := TBits.RotateLeft64(Emu, 8);
+  Esa := Esa xor Da;
+  Bku := TBits.RotateLeft64(Esa, 18);
+  Aka := Bka xor (Bke or Bki);
+  Ca := Ca xor Aka;
+  Ake := Bke xor (Bki and Bko);
+  Ce := Ce xor Ake;
+  Aki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Aki;
+  Ako := (not Bko) xor (Bku or Bka);
+  Co := Co xor Ako;
+  Aku := Bku xor (Bka and Bke);
+  Cu := Cu xor Aku;
+  Ebu := Ebu xor Du;
+  Bma := TBits.RotateLeft64(Ebu, 27);
+  Ega := Ega xor Da;
+  Bme := TBits.RotateLeft64(Ega, 36);
+  Eke := Eke xor De;
+  Bmi := TBits.RotateLeft64(Eke, 10);
+  Emi := Emi xor Di;
+  Bmo := TBits.RotateLeft64(Emi, 15);
+  Eso := Eso xor &Do;
+  Bmu := TBits.RotateLeft64(Eso, 56);
+  Ama := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ama;
+  Ame := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Ame;
+  Ami := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Ami;
+  Amo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Amo;
+  Amu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Amu;
+  Ebi := Ebi xor Di;
+  Bsa := TBits.RotateLeft64(Ebi, 62);
+  Ego := Ego xor &Do;
+  Bse := TBits.RotateLeft64(Ego, 55);
+  Eku := Eku xor Du;
+  Bsi := TBits.RotateLeft64(Eku, 39);
+  Ema := Ema xor Da;
+  Bso := TBits.RotateLeft64(Ema, 41);
+  Ese := Ese xor De;
+  Bsu := TBits.RotateLeft64(Ese, 2);
+  Asa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Asa;
+  Ase := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ase;
+  Asi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Asi;
+  Aso := Bso xor (Bsu or Bsa);
+  Co := Co xor Aso;
+  Asu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Asu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Aba := Aba xor Da;
+  Bba := Aba;
+  Age := Age xor De;
+  Bbe := TBits.RotateLeft64(Age, 44);
+  Aki := Aki xor Di;
+  Bbi := TBits.RotateLeft64(Aki, 43);
+  Amo := Amo xor &Do;
+  Bbo := TBits.RotateLeft64(Amo, 21);
+  Asu := Asu xor Du;
+  Bbu := TBits.RotateLeft64(Asu, 14);
+  Eba := Bba xor (Bbe or Bbi);
+  // Eba := Eba xor RC[10];
+  Eba := Eba xor $0000000080008009;
+  Ca := Eba;
+  Ebe := Bbe xor (not Bbi or Bbo);
+  Ce := Ebe;
+  Ebi := Bbi xor (Bbo and Bbu);
+  Ci := Ebi;
+  Ebo := Bbo xor (Bbu or Bba);
+  Co := Ebo;
+  Ebu := Bbu xor (Bba and Bbe);
+  Cu := Ebu;
+  Abo := Abo xor &Do;
+  Bga := TBits.RotateLeft64(Abo, 28);
+  Agu := Agu xor Du;
+  Bge := TBits.RotateLeft64(Agu, 20);
+  Aka := Aka xor Da;
+  Bgi := TBits.RotateLeft64(Aka, 3);
+  Ame := Ame xor De;
+  Bgo := TBits.RotateLeft64(Ame, 45);
+  Asi := Asi xor Di;
+  Bgu := TBits.RotateLeft64(Asi, 61);
+  Ega := Bga xor (Bge or Bgi);
+  Ca := Ca xor Ega;
+  Ege := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Ege;
+  Egi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Egi;
+  Ego := Bgo xor (Bgu or Bga);
+  Co := Co xor Ego;
+  Egu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Egu;
+  Abe := Abe xor De;
+  Bka := TBits.RotateLeft64(Abe, 1);
+  Agi := Agi xor Di;
+  Bke := TBits.RotateLeft64(Agi, 6);
+  Ako := Ako xor &Do;
+  Bki := TBits.RotateLeft64(Ako, 25);
+  Amu := Amu xor Du;
+  Bko := TBits.RotateLeft64(Amu, 8);
+  Asa := Asa xor Da;
+  Bku := TBits.RotateLeft64(Asa, 18);
+  Eka := Bka xor (Bke or Bki);
+  Ca := Ca xor Eka;
+  Eke := Bke xor (Bki and Bko);
+  Ce := Ce xor Eke;
+  Eki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Eki;
+  Eko := (not Bko) xor (Bku or Bka);
+  Co := Co xor Eko;
+  Eku := Bku xor (Bka and Bke);
+  Cu := Cu xor Eku;
+  Abu := Abu xor Du;
+  Bma := TBits.RotateLeft64(Abu, 27);
+  Aga := Aga xor Da;
+  Bme := TBits.RotateLeft64(Aga, 36);
+  Ake := Ake xor De;
+  Bmi := TBits.RotateLeft64(Ake, 10);
+  Ami := Ami xor Di;
+  Bmo := TBits.RotateLeft64(Ami, 15);
+  Aso := Aso xor &Do;
+  Bmu := TBits.RotateLeft64(Aso, 56);
+  Ema := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ema;
+  Eme := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Eme;
+  Emi := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Emi;
+  Emo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Emo;
+  Emu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Emu;
+  Abi := Abi xor Di;
+  Bsa := TBits.RotateLeft64(Abi, 62);
+  Ago := Ago xor &Do;
+  Bse := TBits.RotateLeft64(Ago, 55);
+  Aku := Aku xor Du;
+  Bsi := TBits.RotateLeft64(Aku, 39);
+  Ama := Ama xor Da;
+  Bso := TBits.RotateLeft64(Ama, 41);
+  Ase := Ase xor De;
+  Bsu := TBits.RotateLeft64(Ase, 2);
+  Esa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Esa;
+  Ese := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ese;
+  Esi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Esi;
+  Eso := Bso xor (Bsu or Bsa);
+  Co := Co xor Eso;
+  Esu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Esu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Eba := Eba xor Da;
+  Bba := Eba;
+  Ege := Ege xor De;
+  Bbe := TBits.RotateLeft64(Ege, 44);
+  Eki := Eki xor Di;
+  Bbi := TBits.RotateLeft64(Eki, 43);
+  Emo := Emo xor &Do;
+  Bbo := TBits.RotateLeft64(Emo, 21);
+  Esu := Esu xor Du;
+  Bbu := TBits.RotateLeft64(Esu, 14);
+  Aba := Bba xor (Bbe or Bbi);
+  // Aba := Aba xor RC[11];
+  Aba := Aba xor $000000008000000A;
+  Ca := Aba;
+  Abe := Bbe xor (not Bbi or Bbo);
+  Ce := Abe;
+  Abi := Bbi xor (Bbo and Bbu);
+  Ci := Abi;
+  Abo := Bbo xor (Bbu or Bba);
+  Co := Abo;
+  Abu := Bbu xor (Bba and Bbe);
+  Cu := Abu;
+  Ebo := Ebo xor &Do;
+  Bga := TBits.RotateLeft64(Ebo, 28);
+  Egu := Egu xor Du;
+  Bge := TBits.RotateLeft64(Egu, 20);
+  Eka := Eka xor Da;
+  Bgi := TBits.RotateLeft64(Eka, 3);
+  Eme := Eme xor De;
+  Bgo := TBits.RotateLeft64(Eme, 45);
+  Esi := Esi xor Di;
+  Bgu := TBits.RotateLeft64(Esi, 61);
+  Aga := Bga xor (Bge or Bgi);
+  Ca := Ca xor Aga;
+  Age := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Age;
+  Agi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Agi;
+  Ago := Bgo xor (Bgu or Bga);
+  Co := Co xor Ago;
+  Agu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Agu;
+  Ebe := Ebe xor De;
+  Bka := TBits.RotateLeft64(Ebe, 1);
+  Egi := Egi xor Di;
+  Bke := TBits.RotateLeft64(Egi, 6);
+  Eko := Eko xor &Do;
+  Bki := TBits.RotateLeft64(Eko, 25);
+  Emu := Emu xor Du;
+  Bko := TBits.RotateLeft64(Emu, 8);
+  Esa := Esa xor Da;
+  Bku := TBits.RotateLeft64(Esa, 18);
+  Aka := Bka xor (Bke or Bki);
+  Ca := Ca xor Aka;
+  Ake := Bke xor (Bki and Bko);
+  Ce := Ce xor Ake;
+  Aki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Aki;
+  Ako := (not Bko) xor (Bku or Bka);
+  Co := Co xor Ako;
+  Aku := Bku xor (Bka and Bke);
+  Cu := Cu xor Aku;
+  Ebu := Ebu xor Du;
+  Bma := TBits.RotateLeft64(Ebu, 27);
+  Ega := Ega xor Da;
+  Bme := TBits.RotateLeft64(Ega, 36);
+  Eke := Eke xor De;
+  Bmi := TBits.RotateLeft64(Eke, 10);
+  Emi := Emi xor Di;
+  Bmo := TBits.RotateLeft64(Emi, 15);
+  Eso := Eso xor &Do;
+  Bmu := TBits.RotateLeft64(Eso, 56);
+  Ama := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ama;
+  Ame := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Ame;
+  Ami := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Ami;
+  Amo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Amo;
+  Amu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Amu;
+  Ebi := Ebi xor Di;
+  Bsa := TBits.RotateLeft64(Ebi, 62);
+  Ego := Ego xor &Do;
+  Bse := TBits.RotateLeft64(Ego, 55);
+  Eku := Eku xor Du;
+  Bsi := TBits.RotateLeft64(Eku, 39);
+  Ema := Ema xor Da;
+  Bso := TBits.RotateLeft64(Ema, 41);
+  Ese := Ese xor De;
+  Bsu := TBits.RotateLeft64(Ese, 2);
+  Asa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Asa;
+  Ase := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ase;
+  Asi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Asi;
+  Aso := Bso xor (Bsu or Bsa);
+  Co := Co xor Aso;
+  Asu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Asu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Aba := Aba xor Da;
+  Bba := Aba;
+  Age := Age xor De;
+  Bbe := TBits.RotateLeft64(Age, 44);
+  Aki := Aki xor Di;
+  Bbi := TBits.RotateLeft64(Aki, 43);
+  Amo := Amo xor &Do;
+  Bbo := TBits.RotateLeft64(Amo, 21);
+  Asu := Asu xor Du;
+  Bbu := TBits.RotateLeft64(Asu, 14);
+  Eba := Bba xor (Bbe or Bbi);
+  // Eba := Eba xor RC[12];
+  Eba := Eba xor $000000008000808B;
+  Ca := Eba;
+  Ebe := Bbe xor (not Bbi or Bbo);
+  Ce := Ebe;
+  Ebi := Bbi xor (Bbo and Bbu);
+  Ci := Ebi;
+  Ebo := Bbo xor (Bbu or Bba);
+  Co := Ebo;
+  Ebu := Bbu xor (Bba and Bbe);
+  Cu := Ebu;
+  Abo := Abo xor &Do;
+  Bga := TBits.RotateLeft64(Abo, 28);
+  Agu := Agu xor Du;
+  Bge := TBits.RotateLeft64(Agu, 20);
+  Aka := Aka xor Da;
+  Bgi := TBits.RotateLeft64(Aka, 3);
+  Ame := Ame xor De;
+  Bgo := TBits.RotateLeft64(Ame, 45);
+  Asi := Asi xor Di;
+  Bgu := TBits.RotateLeft64(Asi, 61);
+  Ega := Bga xor (Bge or Bgi);
+  Ca := Ca xor Ega;
+  Ege := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Ege;
+  Egi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Egi;
+  Ego := Bgo xor (Bgu or Bga);
+  Co := Co xor Ego;
+  Egu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Egu;
+  Abe := Abe xor De;
+  Bka := TBits.RotateLeft64(Abe, 1);
+  Agi := Agi xor Di;
+  Bke := TBits.RotateLeft64(Agi, 6);
+  Ako := Ako xor &Do;
+  Bki := TBits.RotateLeft64(Ako, 25);
+  Amu := Amu xor Du;
+  Bko := TBits.RotateLeft64(Amu, 8);
+  Asa := Asa xor Da;
+  Bku := TBits.RotateLeft64(Asa, 18);
+  Eka := Bka xor (Bke or Bki);
+  Ca := Ca xor Eka;
+  Eke := Bke xor (Bki and Bko);
+  Ce := Ce xor Eke;
+  Eki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Eki;
+  Eko := (not Bko) xor (Bku or Bka);
+  Co := Co xor Eko;
+  Eku := Bku xor (Bka and Bke);
+  Cu := Cu xor Eku;
+  Abu := Abu xor Du;
+  Bma := TBits.RotateLeft64(Abu, 27);
+  Aga := Aga xor Da;
+  Bme := TBits.RotateLeft64(Aga, 36);
+  Ake := Ake xor De;
+  Bmi := TBits.RotateLeft64(Ake, 10);
+  Ami := Ami xor Di;
+  Bmo := TBits.RotateLeft64(Ami, 15);
+  Aso := Aso xor &Do;
+  Bmu := TBits.RotateLeft64(Aso, 56);
+  Ema := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ema;
+  Eme := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Eme;
+  Emi := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Emi;
+  Emo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Emo;
+  Emu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Emu;
+  Abi := Abi xor Di;
+  Bsa := TBits.RotateLeft64(Abi, 62);
+  Ago := Ago xor &Do;
+  Bse := TBits.RotateLeft64(Ago, 55);
+  Aku := Aku xor Du;
+  Bsi := TBits.RotateLeft64(Aku, 39);
+  Ama := Ama xor Da;
+  Bso := TBits.RotateLeft64(Ama, 41);
+  Ase := Ase xor De;
+  Bsu := TBits.RotateLeft64(Ase, 2);
+  Esa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Esa;
+  Ese := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ese;
+  Esi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Esi;
+  Eso := Bso xor (Bsu or Bsa);
+  Co := Co xor Eso;
+  Esu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Esu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Eba := Eba xor Da;
+  Bba := Eba;
+  Ege := Ege xor De;
+  Bbe := TBits.RotateLeft64(Ege, 44);
+  Eki := Eki xor Di;
+  Bbi := TBits.RotateLeft64(Eki, 43);
+  Emo := Emo xor &Do;
+  Bbo := TBits.RotateLeft64(Emo, 21);
+  Esu := Esu xor Du;
+  Bbu := TBits.RotateLeft64(Esu, 14);
+  Aba := Bba xor (Bbe or Bbi);
+  // Aba := Aba xor RC[13];
+  Aba := Aba xor $800000000000008B;
+  Ca := Aba;
+  Abe := Bbe xor (not Bbi or Bbo);
+  Ce := Abe;
+  Abi := Bbi xor (Bbo and Bbu);
+  Ci := Abi;
+  Abo := Bbo xor (Bbu or Bba);
+  Co := Abo;
+  Abu := Bbu xor (Bba and Bbe);
+  Cu := Abu;
+  Ebo := Ebo xor &Do;
+  Bga := TBits.RotateLeft64(Ebo, 28);
+  Egu := Egu xor Du;
+  Bge := TBits.RotateLeft64(Egu, 20);
+  Eka := Eka xor Da;
+  Bgi := TBits.RotateLeft64(Eka, 3);
+  Eme := Eme xor De;
+  Bgo := TBits.RotateLeft64(Eme, 45);
+  Esi := Esi xor Di;
+  Bgu := TBits.RotateLeft64(Esi, 61);
+  Aga := Bga xor (Bge or Bgi);
+  Ca := Ca xor Aga;
+  Age := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Age;
+  Agi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Agi;
+  Ago := Bgo xor (Bgu or Bga);
+  Co := Co xor Ago;
+  Agu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Agu;
+  Ebe := Ebe xor De;
+  Bka := TBits.RotateLeft64(Ebe, 1);
+  Egi := Egi xor Di;
+  Bke := TBits.RotateLeft64(Egi, 6);
+  Eko := Eko xor &Do;
+  Bki := TBits.RotateLeft64(Eko, 25);
+  Emu := Emu xor Du;
+  Bko := TBits.RotateLeft64(Emu, 8);
+  Esa := Esa xor Da;
+  Bku := TBits.RotateLeft64(Esa, 18);
+  Aka := Bka xor (Bke or Bki);
+  Ca := Ca xor Aka;
+  Ake := Bke xor (Bki and Bko);
+  Ce := Ce xor Ake;
+  Aki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Aki;
+  Ako := (not Bko) xor (Bku or Bka);
+  Co := Co xor Ako;
+  Aku := Bku xor (Bka and Bke);
+  Cu := Cu xor Aku;
+  Ebu := Ebu xor Du;
+  Bma := TBits.RotateLeft64(Ebu, 27);
+  Ega := Ega xor Da;
+  Bme := TBits.RotateLeft64(Ega, 36);
+  Eke := Eke xor De;
+  Bmi := TBits.RotateLeft64(Eke, 10);
+  Emi := Emi xor Di;
+  Bmo := TBits.RotateLeft64(Emi, 15);
+  Eso := Eso xor &Do;
+  Bmu := TBits.RotateLeft64(Eso, 56);
+  Ama := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ama;
+  Ame := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Ame;
+  Ami := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Ami;
+  Amo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Amo;
+  Amu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Amu;
+  Ebi := Ebi xor Di;
+  Bsa := TBits.RotateLeft64(Ebi, 62);
+  Ego := Ego xor &Do;
+  Bse := TBits.RotateLeft64(Ego, 55);
+  Eku := Eku xor Du;
+  Bsi := TBits.RotateLeft64(Eku, 39);
+  Ema := Ema xor Da;
+  Bso := TBits.RotateLeft64(Ema, 41);
+  Ese := Ese xor De;
+  Bsu := TBits.RotateLeft64(Ese, 2);
+  Asa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Asa;
+  Ase := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ase;
+  Asi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Asi;
+  Aso := Bso xor (Bsu or Bsa);
+  Co := Co xor Aso;
+  Asu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Asu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Aba := Aba xor Da;
+  Bba := Aba;
+  Age := Age xor De;
+  Bbe := TBits.RotateLeft64(Age, 44);
+  Aki := Aki xor Di;
+  Bbi := TBits.RotateLeft64(Aki, 43);
+  Amo := Amo xor &Do;
+  Bbo := TBits.RotateLeft64(Amo, 21);
+  Asu := Asu xor Du;
+  Bbu := TBits.RotateLeft64(Asu, 14);
+  Eba := Bba xor (Bbe or Bbi);
+  // Eba := Eba xor RC[14];
+  Eba := Eba xor $8000000000008089;
+  Ca := Eba;
+  Ebe := Bbe xor (not Bbi or Bbo);
+  Ce := Ebe;
+  Ebi := Bbi xor (Bbo and Bbu);
+  Ci := Ebi;
+  Ebo := Bbo xor (Bbu or Bba);
+  Co := Ebo;
+  Ebu := Bbu xor (Bba and Bbe);
+  Cu := Ebu;
+  Abo := Abo xor &Do;
+  Bga := TBits.RotateLeft64(Abo, 28);
+  Agu := Agu xor Du;
+  Bge := TBits.RotateLeft64(Agu, 20);
+  Aka := Aka xor Da;
+  Bgi := TBits.RotateLeft64(Aka, 3);
+  Ame := Ame xor De;
+  Bgo := TBits.RotateLeft64(Ame, 45);
+  Asi := Asi xor Di;
+  Bgu := TBits.RotateLeft64(Asi, 61);
+  Ega := Bga xor (Bge or Bgi);
+  Ca := Ca xor Ega;
+  Ege := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Ege;
+  Egi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Egi;
+  Ego := Bgo xor (Bgu or Bga);
+  Co := Co xor Ego;
+  Egu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Egu;
+  Abe := Abe xor De;
+  Bka := TBits.RotateLeft64(Abe, 1);
+  Agi := Agi xor Di;
+  Bke := TBits.RotateLeft64(Agi, 6);
+  Ako := Ako xor &Do;
+  Bki := TBits.RotateLeft64(Ako, 25);
+  Amu := Amu xor Du;
+  Bko := TBits.RotateLeft64(Amu, 8);
+  Asa := Asa xor Da;
+  Bku := TBits.RotateLeft64(Asa, 18);
+  Eka := Bka xor (Bke or Bki);
+  Ca := Ca xor Eka;
+  Eke := Bke xor (Bki and Bko);
+  Ce := Ce xor Eke;
+  Eki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Eki;
+  Eko := (not Bko) xor (Bku or Bka);
+  Co := Co xor Eko;
+  Eku := Bku xor (Bka and Bke);
+  Cu := Cu xor Eku;
+  Abu := Abu xor Du;
+  Bma := TBits.RotateLeft64(Abu, 27);
+  Aga := Aga xor Da;
+  Bme := TBits.RotateLeft64(Aga, 36);
+  Ake := Ake xor De;
+  Bmi := TBits.RotateLeft64(Ake, 10);
+  Ami := Ami xor Di;
+  Bmo := TBits.RotateLeft64(Ami, 15);
+  Aso := Aso xor &Do;
+  Bmu := TBits.RotateLeft64(Aso, 56);
+  Ema := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ema;
+  Eme := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Eme;
+  Emi := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Emi;
+  Emo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Emo;
+  Emu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Emu;
+  Abi := Abi xor Di;
+  Bsa := TBits.RotateLeft64(Abi, 62);
+  Ago := Ago xor &Do;
+  Bse := TBits.RotateLeft64(Ago, 55);
+  Aku := Aku xor Du;
+  Bsi := TBits.RotateLeft64(Aku, 39);
+  Ama := Ama xor Da;
+  Bso := TBits.RotateLeft64(Ama, 41);
+  Ase := Ase xor De;
+  Bsu := TBits.RotateLeft64(Ase, 2);
+  Esa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Esa;
+  Ese := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ese;
+  Esi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Esi;
+  Eso := Bso xor (Bsu or Bsa);
+  Co := Co xor Eso;
+  Esu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Esu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Eba := Eba xor Da;
+  Bba := Eba;
+  Ege := Ege xor De;
+  Bbe := TBits.RotateLeft64(Ege, 44);
+  Eki := Eki xor Di;
+  Bbi := TBits.RotateLeft64(Eki, 43);
+  Emo := Emo xor &Do;
+  Bbo := TBits.RotateLeft64(Emo, 21);
+  Esu := Esu xor Du;
+  Bbu := TBits.RotateLeft64(Esu, 14);
+  Aba := Bba xor (Bbe or Bbi);
+  // Aba := Aba xor RC[15];
+  Aba := Aba xor $8000000000008003;
+  Ca := Aba;
+  Abe := Bbe xor (not Bbi or Bbo);
+  Ce := Abe;
+  Abi := Bbi xor (Bbo and Bbu);
+  Ci := Abi;
+  Abo := Bbo xor (Bbu or Bba);
+  Co := Abo;
+  Abu := Bbu xor (Bba and Bbe);
+  Cu := Abu;
+  Ebo := Ebo xor &Do;
+  Bga := TBits.RotateLeft64(Ebo, 28);
+  Egu := Egu xor Du;
+  Bge := TBits.RotateLeft64(Egu, 20);
+  Eka := Eka xor Da;
+  Bgi := TBits.RotateLeft64(Eka, 3);
+  Eme := Eme xor De;
+  Bgo := TBits.RotateLeft64(Eme, 45);
+  Esi := Esi xor Di;
+  Bgu := TBits.RotateLeft64(Esi, 61);
+  Aga := Bga xor (Bge or Bgi);
+  Ca := Ca xor Aga;
+  Age := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Age;
+  Agi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Agi;
+  Ago := Bgo xor (Bgu or Bga);
+  Co := Co xor Ago;
+  Agu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Agu;
+  Ebe := Ebe xor De;
+  Bka := TBits.RotateLeft64(Ebe, 1);
+  Egi := Egi xor Di;
+  Bke := TBits.RotateLeft64(Egi, 6);
+  Eko := Eko xor &Do;
+  Bki := TBits.RotateLeft64(Eko, 25);
+  Emu := Emu xor Du;
+  Bko := TBits.RotateLeft64(Emu, 8);
+  Esa := Esa xor Da;
+  Bku := TBits.RotateLeft64(Esa, 18);
+  Aka := Bka xor (Bke or Bki);
+  Ca := Ca xor Aka;
+  Ake := Bke xor (Bki and Bko);
+  Ce := Ce xor Ake;
+  Aki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Aki;
+  Ako := (not Bko) xor (Bku or Bka);
+  Co := Co xor Ako;
+  Aku := Bku xor (Bka and Bke);
+  Cu := Cu xor Aku;
+  Ebu := Ebu xor Du;
+  Bma := TBits.RotateLeft64(Ebu, 27);
+  Ega := Ega xor Da;
+  Bme := TBits.RotateLeft64(Ega, 36);
+  Eke := Eke xor De;
+  Bmi := TBits.RotateLeft64(Eke, 10);
+  Emi := Emi xor Di;
+  Bmo := TBits.RotateLeft64(Emi, 15);
+  Eso := Eso xor &Do;
+  Bmu := TBits.RotateLeft64(Eso, 56);
+  Ama := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ama;
+  Ame := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Ame;
+  Ami := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Ami;
+  Amo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Amo;
+  Amu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Amu;
+  Ebi := Ebi xor Di;
+  Bsa := TBits.RotateLeft64(Ebi, 62);
+  Ego := Ego xor &Do;
+  Bse := TBits.RotateLeft64(Ego, 55);
+  Eku := Eku xor Du;
+  Bsi := TBits.RotateLeft64(Eku, 39);
+  Ema := Ema xor Da;
+  Bso := TBits.RotateLeft64(Ema, 41);
+  Ese := Ese xor De;
+  Bsu := TBits.RotateLeft64(Ese, 2);
+  Asa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Asa;
+  Ase := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ase;
+  Asi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Asi;
+  Aso := Bso xor (Bsu or Bsa);
+  Co := Co xor Aso;
+  Asu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Asu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Aba := Aba xor Da;
+  Bba := Aba;
+  Age := Age xor De;
+  Bbe := TBits.RotateLeft64(Age, 44);
+  Aki := Aki xor Di;
+  Bbi := TBits.RotateLeft64(Aki, 43);
+  Amo := Amo xor &Do;
+  Bbo := TBits.RotateLeft64(Amo, 21);
+  Asu := Asu xor Du;
+  Bbu := TBits.RotateLeft64(Asu, 14);
+  Eba := Bba xor (Bbe or Bbi);
+  // Eba := Eba xor RC[16];
+  Eba := Eba xor $8000000000008002;
+  Ca := Eba;
+  Ebe := Bbe xor (not Bbi or Bbo);
+  Ce := Ebe;
+  Ebi := Bbi xor (Bbo and Bbu);
+  Ci := Ebi;
+  Ebo := Bbo xor (Bbu or Bba);
+  Co := Ebo;
+  Ebu := Bbu xor (Bba and Bbe);
+  Cu := Ebu;
+  Abo := Abo xor &Do;
+  Bga := TBits.RotateLeft64(Abo, 28);
+  Agu := Agu xor Du;
+  Bge := TBits.RotateLeft64(Agu, 20);
+  Aka := Aka xor Da;
+  Bgi := TBits.RotateLeft64(Aka, 3);
+  Ame := Ame xor De;
+  Bgo := TBits.RotateLeft64(Ame, 45);
+  Asi := Asi xor Di;
+  Bgu := TBits.RotateLeft64(Asi, 61);
+  Ega := Bga xor (Bge or Bgi);
+  Ca := Ca xor Ega;
+  Ege := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Ege;
+  Egi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Egi;
+  Ego := Bgo xor (Bgu or Bga);
+  Co := Co xor Ego;
+  Egu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Egu;
+  Abe := Abe xor De;
+  Bka := TBits.RotateLeft64(Abe, 1);
+  Agi := Agi xor Di;
+  Bke := TBits.RotateLeft64(Agi, 6);
+  Ako := Ako xor &Do;
+  Bki := TBits.RotateLeft64(Ako, 25);
+  Amu := Amu xor Du;
+  Bko := TBits.RotateLeft64(Amu, 8);
+  Asa := Asa xor Da;
+  Bku := TBits.RotateLeft64(Asa, 18);
+  Eka := Bka xor (Bke or Bki);
+  Ca := Ca xor Eka;
+  Eke := Bke xor (Bki and Bko);
+  Ce := Ce xor Eke;
+  Eki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Eki;
+  Eko := (not Bko) xor (Bku or Bka);
+  Co := Co xor Eko;
+  Eku := Bku xor (Bka and Bke);
+  Cu := Cu xor Eku;
+  Abu := Abu xor Du;
+  Bma := TBits.RotateLeft64(Abu, 27);
+  Aga := Aga xor Da;
+  Bme := TBits.RotateLeft64(Aga, 36);
+  Ake := Ake xor De;
+  Bmi := TBits.RotateLeft64(Ake, 10);
+  Ami := Ami xor Di;
+  Bmo := TBits.RotateLeft64(Ami, 15);
+  Aso := Aso xor &Do;
+  Bmu := TBits.RotateLeft64(Aso, 56);
+  Ema := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ema;
+  Eme := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Eme;
+  Emi := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Emi;
+  Emo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Emo;
+  Emu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Emu;
+  Abi := Abi xor Di;
+  Bsa := TBits.RotateLeft64(Abi, 62);
+  Ago := Ago xor &Do;
+  Bse := TBits.RotateLeft64(Ago, 55);
+  Aku := Aku xor Du;
+  Bsi := TBits.RotateLeft64(Aku, 39);
+  Ama := Ama xor Da;
+  Bso := TBits.RotateLeft64(Ama, 41);
+  Ase := Ase xor De;
+  Bsu := TBits.RotateLeft64(Ase, 2);
+  Esa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Esa;
+  Ese := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ese;
+  Esi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Esi;
+  Eso := Bso xor (Bsu or Bsa);
+  Co := Co xor Eso;
+  Esu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Esu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Eba := Eba xor Da;
+  Bba := Eba;
+  Ege := Ege xor De;
+  Bbe := TBits.RotateLeft64(Ege, 44);
+  Eki := Eki xor Di;
+  Bbi := TBits.RotateLeft64(Eki, 43);
+  Emo := Emo xor &Do;
+  Bbo := TBits.RotateLeft64(Emo, 21);
+  Esu := Esu xor Du;
+  Bbu := TBits.RotateLeft64(Esu, 14);
+  Aba := Bba xor (Bbe or Bbi);
+  // Aba := Aba xor RC[17];
+  Aba := Aba xor $8000000000000080;
+  Ca := Aba;
+  Abe := Bbe xor (not Bbi or Bbo);
+  Ce := Abe;
+  Abi := Bbi xor (Bbo and Bbu);
+  Ci := Abi;
+  Abo := Bbo xor (Bbu or Bba);
+  Co := Abo;
+  Abu := Bbu xor (Bba and Bbe);
+  Cu := Abu;
+  Ebo := Ebo xor &Do;
+  Bga := TBits.RotateLeft64(Ebo, 28);
+  Egu := Egu xor Du;
+  Bge := TBits.RotateLeft64(Egu, 20);
+  Eka := Eka xor Da;
+  Bgi := TBits.RotateLeft64(Eka, 3);
+  Eme := Eme xor De;
+  Bgo := TBits.RotateLeft64(Eme, 45);
+  Esi := Esi xor Di;
+  Bgu := TBits.RotateLeft64(Esi, 61);
+  Aga := Bga xor (Bge or Bgi);
+  Ca := Ca xor Aga;
+  Age := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Age;
+  Agi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Agi;
+  Ago := Bgo xor (Bgu or Bga);
+  Co := Co xor Ago;
+  Agu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Agu;
+  Ebe := Ebe xor De;
+  Bka := TBits.RotateLeft64(Ebe, 1);
+  Egi := Egi xor Di;
+  Bke := TBits.RotateLeft64(Egi, 6);
+  Eko := Eko xor &Do;
+  Bki := TBits.RotateLeft64(Eko, 25);
+  Emu := Emu xor Du;
+  Bko := TBits.RotateLeft64(Emu, 8);
+  Esa := Esa xor Da;
+  Bku := TBits.RotateLeft64(Esa, 18);
+  Aka := Bka xor (Bke or Bki);
+  Ca := Ca xor Aka;
+  Ake := Bke xor (Bki and Bko);
+  Ce := Ce xor Ake;
+  Aki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Aki;
+  Ako := (not Bko) xor (Bku or Bka);
+  Co := Co xor Ako;
+  Aku := Bku xor (Bka and Bke);
+  Cu := Cu xor Aku;
+  Ebu := Ebu xor Du;
+  Bma := TBits.RotateLeft64(Ebu, 27);
+  Ega := Ega xor Da;
+  Bme := TBits.RotateLeft64(Ega, 36);
+  Eke := Eke xor De;
+  Bmi := TBits.RotateLeft64(Eke, 10);
+  Emi := Emi xor Di;
+  Bmo := TBits.RotateLeft64(Emi, 15);
+  Eso := Eso xor &Do;
+  Bmu := TBits.RotateLeft64(Eso, 56);
+  Ama := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ama;
+  Ame := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Ame;
+  Ami := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Ami;
+  Amo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Amo;
+  Amu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Amu;
+  Ebi := Ebi xor Di;
+  Bsa := TBits.RotateLeft64(Ebi, 62);
+  Ego := Ego xor &Do;
+  Bse := TBits.RotateLeft64(Ego, 55);
+  Eku := Eku xor Du;
+  Bsi := TBits.RotateLeft64(Eku, 39);
+  Ema := Ema xor Da;
+  Bso := TBits.RotateLeft64(Ema, 41);
+  Ese := Ese xor De;
+  Bsu := TBits.RotateLeft64(Ese, 2);
+  Asa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Asa;
+  Ase := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ase;
+  Asi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Asi;
+  Aso := Bso xor (Bsu or Bsa);
+  Co := Co xor Aso;
+  Asu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Asu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Aba := Aba xor Da;
+  Bba := Aba;
+  Age := Age xor De;
+  Bbe := TBits.RotateLeft64(Age, 44);
+  Aki := Aki xor Di;
+  Bbi := TBits.RotateLeft64(Aki, 43);
+  Amo := Amo xor &Do;
+  Bbo := TBits.RotateLeft64(Amo, 21);
+  Asu := Asu xor Du;
+  Bbu := TBits.RotateLeft64(Asu, 14);
+  Eba := Bba xor (Bbe or Bbi);
+  // Eba := Eba xor RC[18];
+  Eba := Eba xor $000000000000800A;
+  Ca := Eba;
+  Ebe := Bbe xor (not Bbi or Bbo);
+  Ce := Ebe;
+  Ebi := Bbi xor (Bbo and Bbu);
+  Ci := Ebi;
+  Ebo := Bbo xor (Bbu or Bba);
+  Co := Ebo;
+  Ebu := Bbu xor (Bba and Bbe);
+  Cu := Ebu;
+  Abo := Abo xor &Do;
+  Bga := TBits.RotateLeft64(Abo, 28);
+  Agu := Agu xor Du;
+  Bge := TBits.RotateLeft64(Agu, 20);
+  Aka := Aka xor Da;
+  Bgi := TBits.RotateLeft64(Aka, 3);
+  Ame := Ame xor De;
+  Bgo := TBits.RotateLeft64(Ame, 45);
+  Asi := Asi xor Di;
+  Bgu := TBits.RotateLeft64(Asi, 61);
+  Ega := Bga xor (Bge or Bgi);
+  Ca := Ca xor Ega;
+  Ege := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Ege;
+  Egi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Egi;
+  Ego := Bgo xor (Bgu or Bga);
+  Co := Co xor Ego;
+  Egu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Egu;
+  Abe := Abe xor De;
+  Bka := TBits.RotateLeft64(Abe, 1);
+  Agi := Agi xor Di;
+  Bke := TBits.RotateLeft64(Agi, 6);
+  Ako := Ako xor &Do;
+  Bki := TBits.RotateLeft64(Ako, 25);
+  Amu := Amu xor Du;
+  Bko := TBits.RotateLeft64(Amu, 8);
+  Asa := Asa xor Da;
+  Bku := TBits.RotateLeft64(Asa, 18);
+  Eka := Bka xor (Bke or Bki);
+  Ca := Ca xor Eka;
+  Eke := Bke xor (Bki and Bko);
+  Ce := Ce xor Eke;
+  Eki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Eki;
+  Eko := (not Bko) xor (Bku or Bka);
+  Co := Co xor Eko;
+  Eku := Bku xor (Bka and Bke);
+  Cu := Cu xor Eku;
+  Abu := Abu xor Du;
+  Bma := TBits.RotateLeft64(Abu, 27);
+  Aga := Aga xor Da;
+  Bme := TBits.RotateLeft64(Aga, 36);
+  Ake := Ake xor De;
+  Bmi := TBits.RotateLeft64(Ake, 10);
+  Ami := Ami xor Di;
+  Bmo := TBits.RotateLeft64(Ami, 15);
+  Aso := Aso xor &Do;
+  Bmu := TBits.RotateLeft64(Aso, 56);
+  Ema := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ema;
+  Eme := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Eme;
+  Emi := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Emi;
+  Emo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Emo;
+  Emu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Emu;
+  Abi := Abi xor Di;
+  Bsa := TBits.RotateLeft64(Abi, 62);
+  Ago := Ago xor &Do;
+  Bse := TBits.RotateLeft64(Ago, 55);
+  Aku := Aku xor Du;
+  Bsi := TBits.RotateLeft64(Aku, 39);
+  Ama := Ama xor Da;
+  Bso := TBits.RotateLeft64(Ama, 41);
+  Ase := Ase xor De;
+  Bsu := TBits.RotateLeft64(Ase, 2);
+  Esa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Esa;
+  Ese := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ese;
+  Esi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Esi;
+  Eso := Bso xor (Bsu or Bsa);
+  Co := Co xor Eso;
+  Esu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Esu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Eba := Eba xor Da;
+  Bba := Eba;
+  Ege := Ege xor De;
+  Bbe := TBits.RotateLeft64(Ege, 44);
+  Eki := Eki xor Di;
+  Bbi := TBits.RotateLeft64(Eki, 43);
+  Emo := Emo xor &Do;
+  Bbo := TBits.RotateLeft64(Emo, 21);
+  Esu := Esu xor Du;
+  Bbu := TBits.RotateLeft64(Esu, 14);
+  Aba := Bba xor (Bbe or Bbi);
+  // Aba := Aba xor RC[19];
+  Aba := Aba xor $800000008000000A;
+  Ca := Aba;
+  Abe := Bbe xor (not Bbi or Bbo);
+  Ce := Abe;
+  Abi := Bbi xor (Bbo and Bbu);
+  Ci := Abi;
+  Abo := Bbo xor (Bbu or Bba);
+  Co := Abo;
+  Abu := Bbu xor (Bba and Bbe);
+  Cu := Abu;
+  Ebo := Ebo xor &Do;
+  Bga := TBits.RotateLeft64(Ebo, 28);
+  Egu := Egu xor Du;
+  Bge := TBits.RotateLeft64(Egu, 20);
+  Eka := Eka xor Da;
+  Bgi := TBits.RotateLeft64(Eka, 3);
+  Eme := Eme xor De;
+  Bgo := TBits.RotateLeft64(Eme, 45);
+  Esi := Esi xor Di;
+  Bgu := TBits.RotateLeft64(Esi, 61);
+  Aga := Bga xor (Bge or Bgi);
+  Ca := Ca xor Aga;
+  Age := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Age;
+  Agi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Agi;
+  Ago := Bgo xor (Bgu or Bga);
+  Co := Co xor Ago;
+  Agu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Agu;
+  Ebe := Ebe xor De;
+  Bka := TBits.RotateLeft64(Ebe, 1);
+  Egi := Egi xor Di;
+  Bke := TBits.RotateLeft64(Egi, 6);
+  Eko := Eko xor &Do;
+  Bki := TBits.RotateLeft64(Eko, 25);
+  Emu := Emu xor Du;
+  Bko := TBits.RotateLeft64(Emu, 8);
+  Esa := Esa xor Da;
+  Bku := TBits.RotateLeft64(Esa, 18);
+  Aka := Bka xor (Bke or Bki);
+  Ca := Ca xor Aka;
+  Ake := Bke xor (Bki and Bko);
+  Ce := Ce xor Ake;
+  Aki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Aki;
+  Ako := (not Bko) xor (Bku or Bka);
+  Co := Co xor Ako;
+  Aku := Bku xor (Bka and Bke);
+  Cu := Cu xor Aku;
+  Ebu := Ebu xor Du;
+  Bma := TBits.RotateLeft64(Ebu, 27);
+  Ega := Ega xor Da;
+  Bme := TBits.RotateLeft64(Ega, 36);
+  Eke := Eke xor De;
+  Bmi := TBits.RotateLeft64(Eke, 10);
+  Emi := Emi xor Di;
+  Bmo := TBits.RotateLeft64(Emi, 15);
+  Eso := Eso xor &Do;
+  Bmu := TBits.RotateLeft64(Eso, 56);
+  Ama := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ama;
+  Ame := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Ame;
+  Ami := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Ami;
+  Amo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Amo;
+  Amu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Amu;
+  Ebi := Ebi xor Di;
+  Bsa := TBits.RotateLeft64(Ebi, 62);
+  Ego := Ego xor &Do;
+  Bse := TBits.RotateLeft64(Ego, 55);
+  Eku := Eku xor Du;
+  Bsi := TBits.RotateLeft64(Eku, 39);
+  Ema := Ema xor Da;
+  Bso := TBits.RotateLeft64(Ema, 41);
+  Ese := Ese xor De;
+  Bsu := TBits.RotateLeft64(Ese, 2);
+  Asa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Asa;
+  Ase := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ase;
+  Asi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Asi;
+  Aso := Bso xor (Bsu or Bsa);
+  Co := Co xor Aso;
+  Asu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Asu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Aba := Aba xor Da;
+  Bba := Aba;
+  Age := Age xor De;
+  Bbe := TBits.RotateLeft64(Age, 44);
+  Aki := Aki xor Di;
+  Bbi := TBits.RotateLeft64(Aki, 43);
+  Amo := Amo xor &Do;
+  Bbo := TBits.RotateLeft64(Amo, 21);
+  Asu := Asu xor Du;
+  Bbu := TBits.RotateLeft64(Asu, 14);
+  Eba := Bba xor (Bbe or Bbi);
+  // Eba := Eba xor RC[20];
+  Eba := Eba xor $8000000080008081;
+  Ca := Eba;
+  Ebe := Bbe xor (not Bbi or Bbo);
+  Ce := Ebe;
+  Ebi := Bbi xor (Bbo and Bbu);
+  Ci := Ebi;
+  Ebo := Bbo xor (Bbu or Bba);
+  Co := Ebo;
+  Ebu := Bbu xor (Bba and Bbe);
+  Cu := Ebu;
+  Abo := Abo xor &Do;
+  Bga := TBits.RotateLeft64(Abo, 28);
+  Agu := Agu xor Du;
+  Bge := TBits.RotateLeft64(Agu, 20);
+  Aka := Aka xor Da;
+  Bgi := TBits.RotateLeft64(Aka, 3);
+  Ame := Ame xor De;
+  Bgo := TBits.RotateLeft64(Ame, 45);
+  Asi := Asi xor Di;
+  Bgu := TBits.RotateLeft64(Asi, 61);
+  Ega := Bga xor (Bge or Bgi);
+  Ca := Ca xor Ega;
+  Ege := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Ege;
+  Egi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Egi;
+  Ego := Bgo xor (Bgu or Bga);
+  Co := Co xor Ego;
+  Egu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Egu;
+  Abe := Abe xor De;
+  Bka := TBits.RotateLeft64(Abe, 1);
+  Agi := Agi xor Di;
+  Bke := TBits.RotateLeft64(Agi, 6);
+  Ako := Ako xor &Do;
+  Bki := TBits.RotateLeft64(Ako, 25);
+  Amu := Amu xor Du;
+  Bko := TBits.RotateLeft64(Amu, 8);
+  Asa := Asa xor Da;
+  Bku := TBits.RotateLeft64(Asa, 18);
+  Eka := Bka xor (Bke or Bki);
+  Ca := Ca xor Eka;
+  Eke := Bke xor (Bki and Bko);
+  Ce := Ce xor Eke;
+  Eki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Eki;
+  Eko := (not Bko) xor (Bku or Bka);
+  Co := Co xor Eko;
+  Eku := Bku xor (Bka and Bke);
+  Cu := Cu xor Eku;
+  Abu := Abu xor Du;
+  Bma := TBits.RotateLeft64(Abu, 27);
+  Aga := Aga xor Da;
+  Bme := TBits.RotateLeft64(Aga, 36);
+  Ake := Ake xor De;
+  Bmi := TBits.RotateLeft64(Ake, 10);
+  Ami := Ami xor Di;
+  Bmo := TBits.RotateLeft64(Ami, 15);
+  Aso := Aso xor &Do;
+  Bmu := TBits.RotateLeft64(Aso, 56);
+  Ema := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ema;
+  Eme := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Eme;
+  Emi := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Emi;
+  Emo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Emo;
+  Emu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Emu;
+  Abi := Abi xor Di;
+  Bsa := TBits.RotateLeft64(Abi, 62);
+  Ago := Ago xor &Do;
+  Bse := TBits.RotateLeft64(Ago, 55);
+  Aku := Aku xor Du;
+  Bsi := TBits.RotateLeft64(Aku, 39);
+  Ama := Ama xor Da;
+  Bso := TBits.RotateLeft64(Ama, 41);
+  Ase := Ase xor De;
+  Bsu := TBits.RotateLeft64(Ase, 2);
+  Esa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Esa;
+  Ese := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ese;
+  Esi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Esi;
+  Eso := Bso xor (Bsu or Bsa);
+  Co := Co xor Eso;
+  Esu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Esu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Eba := Eba xor Da;
+  Bba := Eba;
+  Ege := Ege xor De;
+  Bbe := TBits.RotateLeft64(Ege, 44);
+  Eki := Eki xor Di;
+  Bbi := TBits.RotateLeft64(Eki, 43);
+  Emo := Emo xor &Do;
+  Bbo := TBits.RotateLeft64(Emo, 21);
+  Esu := Esu xor Du;
+  Bbu := TBits.RotateLeft64(Esu, 14);
+  Aba := Bba xor (Bbe or Bbi);
+  // Aba := Aba xor RC[21];
+  Aba := Aba xor $8000000000008080;
+  Ca := Aba;
+  Abe := Bbe xor (not Bbi or Bbo);
+  Ce := Abe;
+  Abi := Bbi xor (Bbo and Bbu);
+  Ci := Abi;
+  Abo := Bbo xor (Bbu or Bba);
+  Co := Abo;
+  Abu := Bbu xor (Bba and Bbe);
+  Cu := Abu;
+  Ebo := Ebo xor &Do;
+  Bga := TBits.RotateLeft64(Ebo, 28);
+  Egu := Egu xor Du;
+  Bge := TBits.RotateLeft64(Egu, 20);
+  Eka := Eka xor Da;
+  Bgi := TBits.RotateLeft64(Eka, 3);
+  Eme := Eme xor De;
+  Bgo := TBits.RotateLeft64(Eme, 45);
+  Esi := Esi xor Di;
+  Bgu := TBits.RotateLeft64(Esi, 61);
+  Aga := Bga xor (Bge or Bgi);
+  Ca := Ca xor Aga;
+  Age := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Age;
+  Agi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Agi;
+  Ago := Bgo xor (Bgu or Bga);
+  Co := Co xor Ago;
+  Agu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Agu;
+  Ebe := Ebe xor De;
+  Bka := TBits.RotateLeft64(Ebe, 1);
+  Egi := Egi xor Di;
+  Bke := TBits.RotateLeft64(Egi, 6);
+  Eko := Eko xor &Do;
+  Bki := TBits.RotateLeft64(Eko, 25);
+  Emu := Emu xor Du;
+  Bko := TBits.RotateLeft64(Emu, 8);
+  Esa := Esa xor Da;
+  Bku := TBits.RotateLeft64(Esa, 18);
+  Aka := Bka xor (Bke or Bki);
+  Ca := Ca xor Aka;
+  Ake := Bke xor (Bki and Bko);
+  Ce := Ce xor Ake;
+  Aki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Aki;
+  Ako := (not Bko) xor (Bku or Bka);
+  Co := Co xor Ako;
+  Aku := Bku xor (Bka and Bke);
+  Cu := Cu xor Aku;
+  Ebu := Ebu xor Du;
+  Bma := TBits.RotateLeft64(Ebu, 27);
+  Ega := Ega xor Da;
+  Bme := TBits.RotateLeft64(Ega, 36);
+  Eke := Eke xor De;
+  Bmi := TBits.RotateLeft64(Eke, 10);
+  Emi := Emi xor Di;
+  Bmo := TBits.RotateLeft64(Emi, 15);
+  Eso := Eso xor &Do;
+  Bmu := TBits.RotateLeft64(Eso, 56);
+  Ama := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ama;
+  Ame := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Ame;
+  Ami := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Ami;
+  Amo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Amo;
+  Amu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Amu;
+  Ebi := Ebi xor Di;
+  Bsa := TBits.RotateLeft64(Ebi, 62);
+  Ego := Ego xor &Do;
+  Bse := TBits.RotateLeft64(Ego, 55);
+  Eku := Eku xor Du;
+  Bsi := TBits.RotateLeft64(Eku, 39);
+  Ema := Ema xor Da;
+  Bso := TBits.RotateLeft64(Ema, 41);
+  Ese := Ese xor De;
+  Bsu := TBits.RotateLeft64(Ese, 2);
+  Asa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Asa;
+  Ase := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ase;
+  Asi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Asi;
+  Aso := Bso xor (Bsu or Bsa);
+  Co := Co xor Aso;
+  Asu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Asu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Aba := Aba xor Da;
+  Bba := Aba;
+  Age := Age xor De;
+  Bbe := TBits.RotateLeft64(Age, 44);
+  Aki := Aki xor Di;
+  Bbi := TBits.RotateLeft64(Aki, 43);
+  Amo := Amo xor &Do;
+  Bbo := TBits.RotateLeft64(Amo, 21);
+  Asu := Asu xor Du;
+  Bbu := TBits.RotateLeft64(Asu, 14);
+  Eba := Bba xor (Bbe or Bbi);
+  // Eba := Eba xor RC[22];
+  Eba := Eba xor $0000000080000001;
+  Ca := Eba;
+  Ebe := Bbe xor (not Bbi or Bbo);
+  Ce := Ebe;
+  Ebi := Bbi xor (Bbo and Bbu);
+  Ci := Ebi;
+  Ebo := Bbo xor (Bbu or Bba);
+  Co := Ebo;
+  Ebu := Bbu xor (Bba and Bbe);
+  Cu := Ebu;
+  Abo := Abo xor &Do;
+  Bga := TBits.RotateLeft64(Abo, 28);
+  Agu := Agu xor Du;
+  Bge := TBits.RotateLeft64(Agu, 20);
+  Aka := Aka xor Da;
+  Bgi := TBits.RotateLeft64(Aka, 3);
+  Ame := Ame xor De;
+  Bgo := TBits.RotateLeft64(Ame, 45);
+  Asi := Asi xor Di;
+  Bgu := TBits.RotateLeft64(Asi, 61);
+  Ega := Bga xor (Bge or Bgi);
+  Ca := Ca xor Ega;
+  Ege := Bge xor (Bgi and Bgo);
+  Ce := Ce xor Ege;
+  Egi := Bgi xor (Bgo or not Bgu);
+  Ci := Ci xor Egi;
+  Ego := Bgo xor (Bgu or Bga);
+  Co := Co xor Ego;
+  Egu := Bgu xor (Bga and Bge);
+  Cu := Cu xor Egu;
+  Abe := Abe xor De;
+  Bka := TBits.RotateLeft64(Abe, 1);
+  Agi := Agi xor Di;
+  Bke := TBits.RotateLeft64(Agi, 6);
+  Ako := Ako xor &Do;
+  Bki := TBits.RotateLeft64(Ako, 25);
+  Amu := Amu xor Du;
+  Bko := TBits.RotateLeft64(Amu, 8);
+  Asa := Asa xor Da;
+  Bku := TBits.RotateLeft64(Asa, 18);
+  Eka := Bka xor (Bke or Bki);
+  Ca := Ca xor Eka;
+  Eke := Bke xor (Bki and Bko);
+  Ce := Ce xor Eke;
+  Eki := Bki xor (not Bko and Bku);
+  Ci := Ci xor Eki;
+  Eko := (not Bko) xor (Bku or Bka);
+  Co := Co xor Eko;
+  Eku := Bku xor (Bka and Bke);
+  Cu := Cu xor Eku;
+  Abu := Abu xor Du;
+  Bma := TBits.RotateLeft64(Abu, 27);
+  Aga := Aga xor Da;
+  Bme := TBits.RotateLeft64(Aga, 36);
+  Ake := Ake xor De;
+  Bmi := TBits.RotateLeft64(Ake, 10);
+  Ami := Ami xor Di;
+  Bmo := TBits.RotateLeft64(Ami, 15);
+  Aso := Aso xor &Do;
+  Bmu := TBits.RotateLeft64(Aso, 56);
+  Ema := Bma xor (Bme and Bmi);
+  Ca := Ca xor Ema;
+  Eme := Bme xor (Bmi or Bmo);
+  Ce := Ce xor Eme;
+  Emi := Bmi xor (not Bmo or Bmu);
+  Ci := Ci xor Emi;
+  Emo := not Bmo xor (Bmu and Bma);
+  Co := Co xor Emo;
+  Emu := Bmu xor (Bma or Bme);
+  Cu := Cu xor Emu;
+  Abi := Abi xor Di;
+  Bsa := TBits.RotateLeft64(Abi, 62);
+  Ago := Ago xor &Do;
+  Bse := TBits.RotateLeft64(Ago, 55);
+  Aku := Aku xor Du;
+  Bsi := TBits.RotateLeft64(Aku, 39);
+  Ama := Ama xor Da;
+  Bso := TBits.RotateLeft64(Ama, 41);
+  Ase := Ase xor De;
+  Bsu := TBits.RotateLeft64(Ase, 2);
+  Esa := Bsa xor (not Bse and Bsi);
+  Ca := Ca xor Esa;
+  Ese := not Bse xor (Bsi or Bso);
+  Ce := Ce xor Ese;
+  Esi := Bsi xor (Bso and Bsu);
+  Ci := Ci xor Esi;
+  Eso := Bso xor (Bsu or Bsa);
+  Co := Co xor Eso;
+  Esu := Bsu xor (Bsa and Bse);
+  Cu := Cu xor Esu;
+  Da := Cu xor TBits.RotateLeft64(Ce, 1);
+  De := Ca xor TBits.RotateLeft64(Ci, 1);
+  Di := Ce xor TBits.RotateLeft64(Co, 1);
+  &Do := Ci xor TBits.RotateLeft64(Cu, 1);
+  Du := Co xor TBits.RotateLeft64(Ca, 1);
+  Eba := Eba xor Da;
+  Bba := Eba;
+  Ege := Ege xor De;
+  Bbe := TBits.RotateLeft64(Ege, 44);
+  Eki := Eki xor Di;
+  Bbi := TBits.RotateLeft64(Eki, 43);
+  Emo := Emo xor &Do;
+  Bbo := TBits.RotateLeft64(Emo, 21);
+  Esu := Esu xor Du;
+  Bbu := TBits.RotateLeft64(Esu, 14);
+  Aba := Bba xor (Bbe or Bbi);
+  // Aba := Aba xor RC[23];
+  Aba := Aba xor $8000000080008008;
+  Abe := Bbe xor (not Bbi or Bbo);
+  Abi := Bbi xor (Bbo and Bbu);
+  Abo := Bbo xor (Bbu or Bba);
+  Abu := Bbu xor (Bba and Bbe);
+  Ebo := Ebo xor &Do;
+  Bga := TBits.RotateLeft64(Ebo, 28);
+  Egu := Egu xor Du;
+  Bge := TBits.RotateLeft64(Egu, 20);
+  Eka := Eka xor Da;
+  Bgi := TBits.RotateLeft64(Eka, 3);
+  Eme := Eme xor De;
+  Bgo := TBits.RotateLeft64(Eme, 45);
+  Esi := Esi xor Di;
+  Bgu := TBits.RotateLeft64(Esi, 61);
+  Aga := Bga xor (Bge or Bgi);
+  Age := Bge xor (Bgi and Bgo);
+  Agi := Bgi xor (Bgo or not Bgu);
+  Ago := Bgo xor (Bgu or Bga);
+  Agu := Bgu xor (Bga and Bge);
+  Ebe := Ebe xor De;
+  Bka := TBits.RotateLeft64(Ebe, 1);
+  Egi := Egi xor Di;
+  Bke := TBits.RotateLeft64(Egi, 6);
+  Eko := Eko xor &Do;
+  Bki := TBits.RotateLeft64(Eko, 25);
+  Emu := Emu xor Du;
+  Bko := TBits.RotateLeft64(Emu, 8);
+  Esa := Esa xor Da;
+  Bku := TBits.RotateLeft64(Esa, 18);
+  Aka := Bka xor (Bke or Bki);
+  Ake := Bke xor (Bki and Bko);
+  Aki := Bki xor (not Bko and Bku);
+  Ako := not Bko xor (Bku or Bka);
+  Aku := Bku xor (Bka and Bke);
+  Ebu := Ebu xor Du;
+  Bma := TBits.RotateLeft64(Ebu, 27);
+  Ega := Ega xor Da;
+  Bme := TBits.RotateLeft64(Ega, 36);
+  Eke := Eke xor De;
+  Bmi := TBits.RotateLeft64(Eke, 10);
+  Emi := Emi xor Di;
+  Bmo := TBits.RotateLeft64(Emi, 15);
+  Eso := Eso xor &Do;
+  Bmu := TBits.RotateLeft64(Eso, 56);
+  Ama := Bma xor (Bme and Bmi);
+  Ame := Bme xor (Bmi or Bmo);
+  Ami := Bmi xor (not Bmo or Bmu);
+  Amo := not Bmo xor (Bmu and Bma);
+  Amu := Bmu xor (Bma or Bme);
+  Ebi := Ebi xor Di;
+  Bsa := TBits.RotateLeft64(Ebi, 62);
+  Ego := Ego xor &Do;
+  Bse := TBits.RotateLeft64(Ego, 55);
+  Eku := Eku xor Du;
+  Bsi := TBits.RotateLeft64(Eku, 39);
+  Ema := Ema xor Da;
+  Bso := TBits.RotateLeft64(Ema, 41);
+  Ese := Ese xor De;
+  Bsu := TBits.RotateLeft64(Ese, 2);
+  Asa := Bsa xor (not Bse and Bsi);
+  Ase := not Bse xor (Bsi or Bso);
+  Asi := Bsi xor (Bso and Bsu);
+  Aso := Bso xor (Bsu or Bsa);
+  Asu := Bsu xor (Bsa and Bse);
+
+  Fm_state[0] := Aba;
+  Fm_state[1] := Abe;
+  Fm_state[2] := Abi;
+  Fm_state[3] := Abo;
+  Fm_state[4] := Abu;
+  Fm_state[5] := Aga;
+  Fm_state[6] := Age;
+  Fm_state[7] := Agi;
+  Fm_state[8] := Ago;
+  Fm_state[9] := Agu;
+  Fm_state[10] := Aka;
+  Fm_state[11] := Ake;
+  Fm_state[12] := Aki;
+  Fm_state[13] := Ako;
+  Fm_state[14] := Aku;
+  Fm_state[15] := Ama;
+  Fm_state[16] := Ame;
+  Fm_state[17] := Ami;
+  Fm_state[18] := Amo;
+  Fm_state[19] := Amu;
+  Fm_state[20] := Asa;
+  Fm_state[21] := Ase;
+  Fm_state[22] := Asi;
+  Fm_state[23] := Aso;
+  Fm_state[24] := Asu;
+
+  System.FillChar(data, System.SizeOf(data), 0);
+end;
+
+{ TSHA3_224 }
+
+constructor TSHA3_224.Create;
+begin
+  Inherited Create(THashSize.hsHashSize224);
+end;
+
+{ TSHA3_256 }
+
+constructor TSHA3_256.Create;
+begin
+  Inherited Create(THashSize.hsHashSize256);
+end;
+
+{ TSHA3_384 }
+
+constructor TSHA3_384.Create;
+begin
+  Inherited Create(THashSize.hsHashSize384);
+end;
+
+{ TSHA3_512 }
+
+constructor TSHA3_512.Create;
+begin
+  Inherited Create(THashSize.hsHashSize512);
+end;
+
+end.

+ 815 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpSnefru.pas

@@ -0,0 +1,815 @@
+unit HlpSnefru;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpHashBuffer,
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpBits,
+  HlpHashSize,
+  HlpConverters,
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn;
+
+resourcestring
+  SInvalidSnefruLevel =
+    'Snefru Security Level Cannot be Less than 1. Standard Level is 8';
+  SInvalidSnefruHashSize =
+    'Snefru HashSize Must be Either 128 bit(16 byte) or 256 bit(32 byte)';
+
+type
+
+  TSnefru = class sealed(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+  strict private
+
+    Fm_state: THashLibUInt32Array;
+    Fm_security_level, FHashSize, FBlockSize: Int32;
+
+  const
+    s_shifts: array [0 .. 3] of Int32 = (16, 8, 16, 24);
+
+    class var
+
+      Fs_boxes: THashLibMatrixUInt32Array;
+
+    class constructor Snefru();
+
+  strict protected
+    function GetResult(): THashLibByteArray; override;
+    procedure Finish(); override;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    /// <summary>
+    ///
+    /// </summary>
+    /// <param name="a_security_level">any Integer value greater than 0. Standard is 8. </param>
+    /// <param name="a_hash_size">128bit, 256bit</param>
+    /// <returns></returns>
+    constructor Create(a_security_level: Int32; a_hash_size: THashSize);
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TSnefru }
+
+constructor TSnefru.Create(a_security_level: Int32; a_hash_size: THashSize);
+begin
+
+  Inherited Create(Int32(a_hash_size), 64 - (Int32(a_hash_size)));
+  Fm_security_level := Int32(a_security_level);
+  FHashSize := HashSize;
+  FBlockSize := BlockSize;
+  System.SetLength(Fm_state, FHashSize shr 2);
+
+end;
+
+procedure TSnefru.Finish;
+var
+  bits: UInt64;
+  padindex: Int32;
+  pad: THashLibByteArray;
+begin
+  bits := Fm_processed_bytes * 8;
+  if Fm_buffer.Pos > 0 then
+    padindex := 2 * FBlockSize - Fm_buffer.Pos - 8
+  else
+    padindex := FBlockSize - Fm_buffer.Pos - 8;
+
+  System.SetLength(pad, padindex + 8);
+
+  bits := TConverters.be2me_64(bits);
+
+  TConverters.ReadUInt64AsBytesLE(bits, pad, padindex);
+
+  padindex := padindex + 8;
+
+  TransformBytes(pad, 0, padindex);
+
+end;
+
+function TSnefru.GetResult: THashLibByteArray;
+begin
+  System.SetLength(result, System.Length(Fm_state) * System.SizeOf(UInt32));
+  TConverters.be32_copy(PCardinal(Fm_state), 0, PByte(result), 0,
+    System.Length(result));
+end;
+
+procedure TSnefru.Initialize;
+begin
+
+  System.FillChar(Fm_state[0], System.Length(Fm_state) * System.SizeOf(UInt32),
+    UInt32(0));
+  Inherited Initialize();
+end;
+
+procedure TSnefru.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  sbox0, sbox1: THashLibUInt32Array;
+  i, j, k, shift: Int32;
+  work: array [0 .. 15] of UInt32;
+  ptr_work: PCardinal;
+begin
+
+  ptr_work := @(work[0]);
+  System.Move(Fm_state[0], work[0], System.Length(Fm_state) *
+    System.SizeOf(UInt32));
+
+  TConverters.be32_copy(a_data, a_index, ptr_work + System.Length(Fm_state), 0,
+    a_data_length);
+
+  i := 0;
+
+  while i < Fm_security_level do
+
+  begin
+    sbox0 := Fs_boxes[i * 2 + 0];
+    sbox1 := Fs_boxes[i * 2 + 1];
+
+    j := 0;
+    while j < 4 do
+
+    begin
+
+      work[15] := work[15] xor sbox0[Byte(work[0])];
+      work[1] := work[1] xor sbox0[Byte(work[0])];
+      work[0] := work[0] xor sbox0[Byte(work[1])];
+      work[2] := work[2] xor sbox0[Byte(work[1])];
+      work[1] := work[1] xor sbox1[Byte(work[2])];
+      work[3] := work[3] xor sbox1[Byte(work[2])];
+      work[2] := work[2] xor sbox1[Byte(work[3])];
+      work[4] := work[4] xor sbox1[Byte(work[3])];
+      work[3] := work[3] xor sbox0[Byte(work[4])];
+      work[5] := work[5] xor sbox0[Byte(work[4])];
+      work[4] := work[4] xor sbox0[Byte(work[5])];
+      work[6] := work[6] xor sbox0[Byte(work[5])];
+      work[5] := work[5] xor sbox1[Byte(work[6])];
+      work[7] := work[7] xor sbox1[Byte(work[6])];
+      work[6] := work[6] xor sbox1[Byte(work[7])];
+      work[8] := work[8] xor sbox1[Byte(work[7])];
+      work[7] := work[7] xor sbox0[Byte(work[8])];
+      work[9] := work[9] xor sbox0[Byte(work[8])];
+      work[8] := work[8] xor sbox0[Byte(work[9])];
+      work[10] := work[10] xor sbox0[Byte(work[9])];
+      work[9] := work[9] xor sbox1[Byte(work[10])];
+      work[11] := work[11] xor sbox1[Byte(work[10])];
+      work[10] := work[10] xor sbox1[Byte(work[11])];
+      work[12] := work[12] xor sbox1[Byte(work[11])];
+      work[11] := work[11] xor sbox0[Byte(work[12])];
+      work[13] := work[13] xor sbox0[Byte(work[12])];
+      work[12] := work[12] xor sbox0[Byte(work[13])];
+      work[14] := work[14] xor sbox0[Byte(work[13])];
+      work[13] := work[13] xor sbox1[Byte(work[14])];
+      work[15] := work[15] xor sbox1[Byte(work[14])];
+      work[14] := work[14] xor sbox1[Byte(work[15])];
+      work[0] := work[0] xor sbox1[Byte(work[15])];
+
+      shift := s_shifts[j];
+
+      k := 0;
+
+      while k < 16 do
+      begin
+        work[k] := TBits.RotateRight32(work[k], shift);
+        System.Inc(k);
+      end;
+
+      System.Inc(j);
+    end;
+
+    System.Inc(i);
+  end;
+
+  Fm_state[0] := Fm_state[0] xor work[15];
+  Fm_state[1] := Fm_state[1] xor work[14];
+  Fm_state[2] := Fm_state[2] xor work[13];
+  Fm_state[3] := Fm_state[3] xor work[12];
+
+  if (FHashSize = 32) then
+  begin
+    Fm_state[4] := Fm_state[4] xor work[11];
+    Fm_state[5] := Fm_state[5] xor work[10];
+    Fm_state[6] := Fm_state[6] xor work[9];
+    Fm_state[7] := Fm_state[7] xor work[8];
+  end;
+
+  System.FillChar(work, System.SizeOf(work), 0);
+
+end;
+
+class constructor TSnefru.Snefru;
+begin
+
+{$REGION 'Consts'}
+  Fs_boxes := THashLibMatrixUInt32Array.Create
+    (THashLibUInt32Array.Create($64F9001B, $FEDDCDF6, $7C8FF1E2, $11D71514,
+    $8B8C18D3, $DDDF881E, $6EAB5056, $88CED8E1, $49148959, $69C56FD5, $B7994F03,
+    $0FBCEE3E, $3C264940, $21557E58, $E14B3FC2, $2E5CF591, $DCEFF8CE, $092A1648,
+    $BE812936, $FF7B0C6A, $D5251037, $AFA448F1, $7DAFC95A, $1EA69C3F, $A417ABE7,
+    $5890E423, $B0CB70C0, $C85025F7, $244D97E3, $1FF3595F, $C4EC6396, $59181E17,
+    $E635B477, $354E7DBF, $796F7753, $66EB52CC, $77C3F995, $32E3A927, $80CCAED6,
+    $4E2BE89D, $375BBD28, $AD1A3D05, $2B1B42B3, $16C44C71, $4D54BFA8, $E57DDC7A,
+    $EC6D8144, $5A71046B, $D8229650, $87FC8F24, $CBC60E09, $B6390366, $D9F76092,
+    $D393A70B, $1D31A08A, $9CD971C9, $5C1EF445, $86FAB694, $FDB44165, $8EAAFCBE,
+    $4BCAC6EB, $FB7A94E5, $5789D04E, $FA13CF35, $236B8DA9, $4133F000, $6224261C,
+    $F412F23B, $E75E56A4, $30022116, $BAF17F1F, $D09872F9, $C1A3699C, $F1E802AA,
+    $0DD145DC, $4FDCE093, $8D8412F0, $6CD0F376, $3DE6B73D, $84BA737F, $B43A30F2,
+    $44569F69, $00E4EACA, $B58DE3B0, $959113C8, $D62EFEE9, $90861F83, $CED69874,
+    $2F793CEE, $E8571C30, $483665D1, $AB07B031, $914C844F, $15BF3BE8, $2C3F2A9A,
+    $9EB95FD4, $92E7472D, $2297CC5B, $EE5F2782, $5377B562, $DB8EBBCF, $F961DEDD,
+    $C59B5C60, $1BD3910D, $26D206AD, $B28514D8, $5ECF6B52, $7FEA78BB, $504879AC,
+    $ED34A884, $36E51D3C, $1753741D, $8C47CAED, $9D0A40EF, $3145E221, $DA27EB70,
+    $DF730BA3, $183C8789, $739AC0A6, $9A58DFC6, $54B134C1, $AC3E242E, $CC493902,
+    $7B2DDA99, $8F15BC01, $29FD38C7, $27D5318F, $604AAFF5, $F29C6818, $C38AA2EC,
+    $1019D4C3, $A8FB936E, $20ED7B39, $0B686119, $89A0906F, $1CC7829E, $9952EF4B,
+    $850E9E8C, $CD063A90, $67002F8E, $CFAC8CB7, $EAA24B11, $988B4E6C, $46F066DF,
+    $CA7EEC08, $C7BBA664, $831D17BD, $63F575E6, $9764350E, $47870D42, $026CA4A2,
+    $8167D587, $61B6ADAB, $AA6564D2, $70DA237B, $25E1C74A, $A1C901A0, $0EB0A5DA,
+    $7670F741, $51C05AEA, $933DFA32, $0759FF1A, $56010AB8, $5FDECB78, $3F32EDF8,
+    $AEBEDBB9, $39F8326D, $D20858C5, $9B638BE4, $A572C80A, $28E0A19F, $432099FC,
+    $3A37C3CD, $BF95C585, $B392C12A, $6AA707D7, $52F66A61, $12D483B1, $96435B5E,
+    $3E75802B, $3BA52B33, $A99F51A5, $BDA1E157, $78C2E70C, $FCAE7CE0, $D1602267,
+    $2AFFAC4D, $4A510947, $0AB2B83A, $7A04E579, $340DFD80, $B916E922, $E29D5E9B,
+    $F5624AF4, $4CA9D9AF, $6BBD2CFE, $E3B7F620, $C2746E07, $5B42B9B6, $A06919BC,
+    $F0F2C40F, $72217AB5, $14C19DF3, $F3802DAE, $E094BEB4, $A2101AFF, $0529575D,
+    $55CDB27C, $A33BDDB2, $6528B37D, $740C05DB, $E96A62C4, $40782846, $6D30D706,
+    $BBF48E2C, $BCE2D3DE, $049E37FA, $01B5E634, $2D886D8D, $7E5A2E7E, $D7412013,
+    $06E90F97, $E45D3EBA, $B8AD3386, $13051B25, $0C035354, $71C89B75, $C638FBD0,
+    $197F11A1, $EF0F08FB, $F8448651, $38409563, $452F4443, $5D464D55, $03D8764C,
+    $B1B8D638, $A70BBA2F, $94B3D210, $EB6692A7, $D409C2D9, $68838526, $A6DB8A15,
+    $751F6C98, $DE769A88, $C9EE4668, $1A82A373, $0896AA49, $42233681, $F62C55CB,
+    $9F1C5404, $F74FB15C, $C06E4312, $6FFE5D72, $8AA8678B, $337CD129,
+    $8211CEFD), THashLibUInt32Array.Create($074A1D09, $52A10E5A, $9275A3F8,
+    $4B82506C, $37DF7E1B, $4C78B3C5, $CEFAB1DA, $F472267E, $B63045F6, $D66A1FC0,
+    $400298E3, $27E60C94, $87D2F1B8, $DF9E56CC, $45CD1803, $1D35E098, $CCE7C736,
+    $03483BF1, $1F7307D7, $C6E8F948, $E613C111, $3955C6FF, $1170ED7C, $8E95DA41,
+    $99C31BF4, $A4DA8021, $7B5F94FB, $DD0DA51F, $6562AA77, $556BCB23, $DB1BACC6,
+    $798040B9, $BFE5378F, $731D55E6, $DAA5BFEE, $389BBC60, $1B33FBA4, $9C567204,
+    $36C26C68, $77EE9D69, $8AEB3E88, $2D50B5CE, $9579E790, $42B13CFC, $33FBD32B,
+    $EE0503A7, $B5862824, $15E41EAD, $C8412EF7, $9D441275, $2FCEC582, $5FF483B7,
+    $8F3931DF, $2E5D2A7B, $49467BF9, $0653DEA9, $2684CE35, $7E655E5C, $F12771D8,
+    $BB15CC67, $AB097CA1, $983DCF52, $10DDF026, $21267F57, $2C58F6B4, $31043265,
+    $0BAB8C01, $D5492099, $ACAAE619, $944CE54A, $F2D13D39, $ADD3FC32, $CDA08A40,
+    $E2B0D451, $9EFE08AE, $B9D50FD2, $EA5CD7FD, $C9A749DD, $13EA2253, $832DEBAA,
+    $24BE640F, $E03E926A, $29E01CDE, $8BF59F18, $0F9D00B6, $E1238B46, $1E7D8E34,
+    $93619ADB, $76B32F9F, $BD972CEC, $E31FA976, $A68FBB10, $FB3BA49D, $8587C41D,
+    $A5ADD1D0, $F3CF84BF, $D4E11150, $D9FFA6BC, $C3F6018C, $AEF10572, $74A64B2F,
+    $E7DC9559, $2AAE35D5, $5B6F587F, $A9E353FE, $CA4FB674, $04BA24A8, $E5C6875F,
+    $DCBC6266, $6BC5C03F, $661EEF02, $ED740BAB, $058E34E4, $B7E946CF, $88698125,
+    $72EC48ED, $B11073A3, $A13485EB, $A2A2429C, $FA407547, $50B76713, $5418C37D,
+    $96192DA5, $170BB04B, $518A021E, $B0AC13D1, $0963FA2A, $4A6E10E1, $58472BDC,
+    $F7F8D962, $979139EA, $8D856538, $C0997042, $48324D7A, $447623CB, $8CBBE364,
+    $6E0C6B0E, $D36D63B0, $3F244C84, $3542C971, $2B228DC1, $CB0325BB, $F8C0D6E9,
+    $DE11066B, $A8649327, $FC31F83E, $7DD80406, $F916DD61, $D89F79D3, $615144C2,
+    $EBB45D31, $28002958, $56890A37, $F05B3808, $123AE844, $86839E16, $914B0D83,
+    $C506B43C, $CF3CBA5E, $7C60F5C9, $22DEB2A0, $5D9C2715, $C77BA0EF, $4F45360B,
+    $C1017D8B, $E45ADC29, $A759909B, $412CD293, $D7D796B1, $00C8FF30, $23A34A80,
+    $4EC15C91, $714E78B5, $47B9E42E, $78F3EA4D, $7F078F5B, $346C593A, $A3A87A1A,
+    $9BCBFE12, $3D439963, $B2EF6D8E, $B8D46028, $6C2FD5CA, $62675256, $01F2A2F3,
+    $BC96AE0A, $709A8920, $B4146E87, $6308B9E2, $64BDA7BA, $AFED6892, $6037F2A2,
+    $F52969E0, $0ADB43A6, $82811400, $90D0BDF0, $19C9549E, $203F6A73, $1ACCAF4F,
+    $89714E6D, $164D4705, $67665F07, $EC206170, $0C2182B2, $A02B9C81, $53289722,
+    $F6A97686, $140E4179, $9F778849, $9A88E15D, $25CADB54, $D157F36F, $32A421C3,
+    $B368E98A, $5A92CD0D, $757AA8D4, $C20AC278, $08B551C7, $849491E8, $4DC75AD6,
+    $697C33BE, $BAF0CA33, $46125B4E, $59D677B3, $30D9C8F2, $D0AF860C, $1C7FD0FA,
+    $FE0FF72C, $5C8D6F43, $57FDEC3B, $6AB6AD97, $D22ADF89, $18171785, $02BFE22D,
+    $6DB80917, $80B216AF, $E85E4F9A, $7A1C306E, $6FC49BF5, $3AF7A11C, $81E215E7,
+    $68363FCD, $3E9357C8, $EF52FD55, $3B8BAB4C, $3C8CF495, $BEFCEEBD, $FD25B714,
+    $C498D83D, $0D2E1A8D, $E9F966AC, $0E387445, $435419E5, $5E7EBEC4, $AA90B8D9,
+    $FF1A3A96), THashLibUInt32Array.Create($4A8FE4E3, $F27D99CD, $D04A40CA,
+    $CB5FF194, $3668275A, $FF4816BE, $A78B394C, $4C6BE9DB, $4EEC38D2, $4296EC80,
+    $CDCE96F8, $888C2F38, $E75508F5, $7B916414, $060AA14A, $A214F327, $BE608DAF,
+    $1EBBDEC2, $61F98CE9, $E92156FE, $4F22D7A3, $3F76A8D9, $559A4B33, $38AD2959,
+    $F3F17E9E, $85E1BA91, $E5EBA6FB, $73DCD48C, $F5C3FF78, $481B6058, $8A3297F7,
+    $8F1F3BF4, $93785AB2, $477A4A5B, $6334EB5D, $6D251B2E, $74A9102D, $07E38FFA,
+    $915C9C62, $CCC275EA, $6BE273EC, $3EBDDD70, $D895796C, $DC54A91B, $C9AFDF81,
+    $23633F73, $275119B4, $B19F6B67, $50756E22, $2BB152E2, $76EA46A2, $A353E232,
+    $2F596AD6, $0B1EDB0B, $02D3D9A4, $78B47843, $64893E90, $40F0CAAD, $F68D3AD7,
+    $46FD1707, $1C9C67EF, $B5E086DE, $96EE6CA6, $9AA34774, $1BA4F48A, $8D01ABFD,
+    $183EE1F6, $5FF8AA7A, $17E4FAAE, $303983B0, $6C08668B, $D4AC4382, $E6C5849F,
+    $92FEFB53, $C1CAC4CE, $43501388, $441118CF, $EC4FB308, $53A08E86, $9E0FE0C5,
+    $F91C1525, $AC45BE05, $D7987CB5, $49BA1487, $57938940, $D5877648, $A958727F,
+    $58DFE3C3, $F436CF77, $399E4D11, $F0A5BFA9, $EF61A33B, $A64CAC60, $04A8D0BA,
+    $030DD572, $B83D320F, $CAB23045, $E366F2F0, $815D008D, $C897A43A, $1D352DF3,
+    $B9CC571D, $8BF38744, $72209092, $EBA124EB, $FB99CE5E, $3BB94293, $28DA549C,
+    $AAB8A228, $A4197785, $33C70296, $25F6259B, $5C85DA21, $DF15BDEE, $15B7C7E8,
+    $E2ABEF75, $FCC19BC1, $417FF868, $14884434, $62825179, $C6D5C11C, $0E4705DC,
+    $22700DE0, $D3D2AF18, $9BE822A0, $35B669F1, $C42BB55C, $0A801252, $115BF0FC,
+    $3CD7D856, $B43F5F9D, $C2306516, $A1231C47, $F149207E, $5209A795, $34B3CCD8,
+    $67AEFE54, $2C83924E, $6662CBAC, $5EEDD161, $84E681AA, $5D57D26B, $FA465CC4,
+    $7E3AC3A8, $BF7C0CC6, $E18A9AA1, $C32F0A6F, $B22CC00D, $3D280369, $994E554F,
+    $68F480D3, $ADCFF5E6, $3A8EB265, $83269831, $BD568A09, $4BC8AE6A, $69F56D2B,
+    $0F17EAC8, $772EB6C7, $9F41343C, $AB1D0742, $826A6F50, $FEA2097C, $1912C283,
+    $CE185899, $E4444839, $2D8635D5, $65D0B1FF, $865A7F17, $326D9FB1, $59E52820,
+    $0090ADE1, $753C7149, $9DDD8B98, $A5A691DA, $0D0382BB, $8904C930, $086CB000,
+    $6E69D3BD, $24D4E7A7, $05244FD0, $101A5E0C, $6A947DCB, $E840F77B, $7D0C5003,
+    $7C370F1F, $805245ED, $E05E3D3F, $7906880E, $BABFCD35, $1A7EC697, $8C052324,
+    $0C6EC8DF, $D129A589, $C7A75B02, $12D81DE7, $D9BE2A66, $1F4263AB, $DE73FDB6,
+    $2A00680A, $56649E36, $3133ED55, $90FA0BF2, $2910A02A, $949D9D46, $A0D1DCDD,
+    $CFC9B7D4, $D2677BE5, $95CB36B3, $13CD9410, $DBF73313, $B7C6E8C0, $F781414B,
+    $510B016D, $B0DE1157, $D6B0F62C, $BB074ECC, $7F1395B7, $EE792CF9, $EA6FD63E,
+    $5BD6938E, $AF02FC64, $DAB57AB8, $8EDB3784, $8716318F, $164D1A01, $26F26141,
+    $B372E6B9, $F8FC2B06, $7AC00E04, $3727B89A, $97E9BCA5, $9C2A742F, $BC3B1F7D,
+    $7165B471, $609B4C29, $20925351, $5AE72112, $454BE5D1, $C0FFB95F, $DD0EF919,
+    $6F2D70C9, $0974C5BF, $98AA6263, $01D91E4D, $2184BB6E, $70C43C1E, $4D435915,
+    $AE7B8523, $B6FB06BC, $5431EE76, $FDBC5D26, $ED77493D, $C5712EE4, $A8380437,
+    $2EEF261A), THashLibUInt32Array.Create($5A79392B, $B8AF32C2, $41F7720A,
+    $833A61EC, $13DFEDAC, $C4990BC4, $DC0F54BC, $FEDD5E88, $80DA1881, $4DEA1AFD,
+    $FD402CC6, $AE67CC7A, $C5238525, $8EA01254, $B56B9BD5, $862FBD6D, $AC8575D3,
+    $6FBA3714, $DA7EBF46, $59CD5238, $8AC9DBFE, $353729FC, $E497D7F2, $C3AB84E0,
+    $F05A114B, $7B887A75, $EDC603DD, $5E6FE680, $2C84B399, $884EB1DA, $1CB8C8BF,
+    $AA51098A, $C862231C, $8BAC2221, $21B387E5, $208A430D, $2A3F0F8B, $A5FF9CD2,
+    $6012A2EA, $147A9EE7, $F62A501D, $B4B2E51A, $3EF3484C, $C0253C59, $2B82B536,
+    $0AA9696B, $BE0C109B, $C70B7929, $CE3E8A19, $2F66950E, $459F1C2C, $E68FB93D,
+    $A3C3FF3E, $62B45C62, $300991CB, $01914C57, $7F7BC06A, $182831F5, $E7B74BCA,
+    $FA50F6D0, $523CAA61, $E3A7CF05, $E9E41311, $280A21D1, $6A4297E1, $F24DC67E,
+    $FC3189E6, $B72BF34F, $4B1E67AF, $543402CE, $79A59867, $0648E02A, $00A3AC17,
+    $C6208D35, $6E7F5F76, $A45BB4BE, $F168FA63, $3F4125F3, $F311406F, $02706565,
+    $BFE58022, $0CFCFDD9, $0735A7F7, $8F049092, $D98EDC27, $F5C5D55C, $E0F201DB,
+    $0DCAFC9A, $7727FB79, $AF43ABF4, $26E938C1, $401B26A6, $900720FA, $2752D97B,
+    $CFF1D1B3, $A9D9E424, $42DB99AB, $6CF8BE5F, $E82CEBE3, $3AFB733B, $6B734EB6,
+    $1036414A, $975F667C, $049D6377, $BA587C60, $B1D10483, $DE1AEFCC, $1129D055,
+    $72051E91, $6946D623, $F9E86EA7, $48768C00, $B0166C93, $9956BBF0, $1F1F6D84,
+    $FB15E18E, $033B495D, $56E3362E, $4F44C53C, $747CBA51, $89D37872, $5D9C331B,
+    $D2EF9FA8, $254917F8, $1B106F47, $37D75553, $B3F053B0, $7DCCD8EF, $D30EB802,
+    $5889F42D, $610206D7, $1A7D34A1, $92D87DD8, $E5F4A315, $D1CF0E71, $B22DFE45,
+    $B901E8EB, $0FC0CE5E, $2EFA60C9, $2DE74290, $36D0C906, $381C70E4, $4C6DA5B5,
+    $3D81A682, $7E381F34, $396C4F52, $95AD5901, $1DB50C5A, $29982E9E, $1557689F,
+    $3471EE42, $D7E2F7C0, $8795A1E2, $BC324D8D, $E224C3C8, $12837E39, $CDEE3D74,
+    $7AD2143F, $0E13D40C, $78BD4A68, $A2EB194D, $DB9451F9, $859B71DC, $5C4F5B89,
+    $CA14A8A4, $EF92F003, $16741D98, $33AA4444, $9E967FBB, $092E3020, $D86A35B8,
+    $8CC17B10, $E1BF08AE, $55693FC5, $7680AD13, $1E6546E8, $23B6E7B9, $EE77A4B2,
+    $08ED0533, $44FD2895, $B6393B69, $05D6CACF, $9819B209, $ECBBB72F, $9A75779C,
+    $EAEC0749, $94A65AEE, $BDF52DC3, $D6A25D04, $82008E4E, $A6DE160F, $9B036AFB,
+    $228B3A66, $5FB10A70, $CC338B58, $5378A9DF, $C908BCA9, $4959E25B, $46909A97,
+    $66AE8F6E, $DD0683E9, $65F994B4, $6426CDA5, $C24B8840, $32539DA0, $63175650,
+    $D0C815FF, $50CBC41E, $F7C774A3, $31B0C231, $8D0D8116, $24BEF16C, $D555D256,
+    $DF47EA8C, $6D21ECCD, $A887A012, $84542AED, $A7B9C1BD, $914C1BB1, $A0D5B67D,
+    $438CE937, $7030F873, $71F6B0C7, $574576BA, $F8BC4541, $9C61D348, $1960579D,
+    $17C4DAAD, $96A4CB0B, $C193F2F6, $756EAFA2, $7C1D2F94, $F4FE2B43, $CB86E33A,
+    $EBD4C728, $9D18AE64, $9FE13E30, $3CE0F5DE, $ABA1F985, $ADDC2718, $68CE6278,
+    $D45E241F, $A15C82B7, $3B2293D4, $739EDD32, $674A6BF1, $5B5D587F, $4772DEAA,
+    $4A63968F, $0BE68686, $513D6426, $939A4787, $BBA89296, $4EC20007, $818D0D08,
+    $FF64DFD6), THashLibUInt32Array.Create($CB2297CB, $DB48A144, $A16CBE4B,
+    $BBEA1D6C, $5AF6B6B7, $8A8110B6, $F9236EF9, $C98F83E6, $0F9C65B8, $252D4A89,
+    $A497F068, $A5D7ED2D, $94C22845, $9DA1C8C4, $E27C2E2E, $6E8BA2B4, $C3DD17FB,
+    $498CD482, $0DFE6A9F, $B0705829, $9A1E6DC1, $F829717C, $07BB8E3A, $DA3C0B02,
+    $1AF82FC7, $73B70955, $7A04379C, $5EE20A28, $83712AE5, $F4C47C6D, $DF72BA56,
+    $D794858D, $8C0CF709, $18F0F390, $B6C69B35, $BF2F01DB, $2FA74DCA, $D0CD9127,
+    $BDE66CEC, $3DEEBD46, $57C88FC3, $CEE1406F, $0066385A, $F3C3444F, $3A79D5D5,
+    $75751EB9, $3E7F8185, $521C2605, $E1AAAB6E, $38EBB80F, $BEE7E904, $61CB9647,
+    $EA54904E, $05AE00E4, $2D7AC65F, $087751A1, $DCD82915, $0921EE16, $DD86D33B,
+    $D6BD491A, $40FBADF0, $4232CBD2, $33808D10, $39098C42, $193F3199, $0BC1E47A,
+    $4A82B149, $02B65A8A, $104CDC8E, $24A8F52C, $685C6077, $C79F95C9, $1D11FE50,
+    $C08DAFCD, $7B1A9A03, $1C1F11D8, $84250E7F, $979DB248, $EBDC0501, $B9553395,
+    $E3C05EA8, $B1E51C4C, $13B0E681, $3B407766, $36DB3087, $EE17C9FC, $6C53ECF2,
+    $ADCCC58F, $C427660B, $EFD5867D, $9B6D54A5, $6FF1AEFF, $8E787952, $9E2BFFE0,
+    $8761D034, $E00BDBAD, $AE99A8D3, $CC03F6E2, $FD0ED807, $0E508AE3, $B74182AB,
+    $4349245D, $D120A465, $B246A641, $AF3B7AB0, $2A6488BB, $4B3A0D1F, $E7C7E58C,
+    $3FAFF2EB, $90445FFD, $CF38C393, $995D07E7, $F24F1B36, $356F6891, $6D6EBCBE,
+    $8DA9E262, $50FD520E, $5BCA9E1E, $37472CF3, $69075057, $7EC5FDED, $0CAB892A,
+    $FB2412BA, $1728DEBF, $A000A988, $D843CE79, $042E20DD, $4FE8F853, $56659C3C,
+    $2739D119, $A78A6120, $80960375, $70420611, $85E09F78, $ABD17E96, $1B513EAF,
+    $1E01EB63, $26AD2133, $A890C094, $7613CF60, $817E781B, $A39113D7, $E957FA58,
+    $4131B99E, $28B1EFDA, $66ACFBA7, $FF68944A, $77A44FD1, $7F331522, $59FFB3FA,
+    $A6DF935B, $FA12D9DF, $C6BF6F3F, $89520CF6, $659EDD6A, $544DA739, $8B052538,
+    $7C30EA21, $C2345525, $15927FB2, $144A436B, $BA107B8B, $1219AC97, $06730432,
+    $31831AB3, $C55A5C24, $AA0FCD3E, $E5606BE8, $5C88F19B, $4C0841EE, $1FE37267,
+    $11F9C4F4, $9F1B9DAE, $864E76D0, $E637C731, $D97D23A6, $32F53D5C, $B8161980,
+    $93FA0F84, $CAEF0870, $8874487E, $98F2CC73, $645FB5C6, $CD853659, $2062470D,
+    $16EDE8E9, $6B06DAB5, $78B43900, $FC95B786, $5D8E7DE1, $465B5954, $FE7BA014,
+    $F7D23F7B, $92BC8B18, $03593592, $55CEF4F7, $74B27317, $79DE1FC2, $C8A0BFBD,
+    $229398CC, $62A602CE, $BCB94661, $5336D206, $D2A375FE, $6A6AB483, $4702A5A4,
+    $A2E9D73D, $23A2E0F1, $9189140A, $581D18DC, $B39A922B, $82356212, $D5F432A9,
+    $D356C2A3, $5F765B4D, $450AFCC8, $4415E137, $E8ECDFBC, $ED0DE3EA, $60D42B13,
+    $F13DF971, $71FC5DA2, $C1455340, $F087742F, $F55E5751, $67B3C1F8, $AC6B8774,
+    $7DCFAAAC, $95983BC0, $489BB0B1, $2C184223, $964B6726, $2BD3271C, $72266472,
+    $DED64530, $0A2AA343, $D4F716A0, $B4DAD6D9, $2184345E, $512C990C, $29D92D08,
+    $2EBE709A, $01144C69, $34584B9D, $E4634ED6, $ECC963CF, $3C6984AA, $4ED056EF,
+    $9CA56976, $8F3E80D4, $B5BAE7C5, $30B5CAF5, $63F33A64, $A9E4BBDE, $F6B82298,
+    $4D673C1D), THashLibUInt32Array.Create($4B4F1121, $BA183081, $C784F41F,
+    $D17D0BAC, $083D2267, $37B1361E, $3581AD05, $FDA2F6BC, $1E892CDD, $B56D3C3A,
+    $32140E46, $138D8AAB, $E14773D4, $5B0E71DF, $5D1FE055, $3FB991D3, $F1F46C71,
+    $A325988C, $10F66E80, $B1006348, $726A9F60, $3B67F8BA, $4E114EF4, $05C52115,
+    $4C5CA11C, $99E1EFD8, $471B83B3, $CBF7E524, $43AD82F5, $690CA93B, $FAA61BB2,
+    $12A832B5, $B734F943, $BD22AEA7, $88FEC626, $5E80C3E7, $BE3EAF5E, $44617652,
+    $A5724475, $BB3B9695, $7F3FEE8F, $964E7DEB, $518C052D, $2A0BBC2B, $C2175F5C,
+    $9A7B3889, $A70D8D0C, $EACCDD29, $CCCD6658, $34BB25E6, $B8391090, $F651356F,
+    $52987C9E, $0C16C1CD, $8E372D3C, $2FC6EBBD, $6E5DA3E3, $B0E27239, $5F685738,
+    $45411786, $067F65F8, $61778B40, $81AB2E65, $14C8F0F9, $A6B7B4CE, $4036EAEC,
+    $BF62B00A, $ECFD5E02, $045449A6, $B20AFD28, $2166D273, $0D13A863, $89508756,
+    $D51A7530, $2D653F7A, $3CDBDBC3, $80C9DF4F, $3D5812D9, $53FBB1F3, $C0F185C0,
+    $7A3C3D7E, $68646410, $857607A0, $1D12622E, $97F33466, $DB4C9917, $6469607C,
+    $566E043D, $79EF1EDB, $2C05898D, $C9578E25, $CD380101, $46E04377, $7D1CC7A9,
+    $6552B837, $20192608, $B97500C5, $ED296B44, $368648B4, $62995CD5, $82731400,
+    $F9AEBD8B, $3844C0C7, $7C2DE794, $33A1A770, $8AE528C2, $5A2BE812, $1F8F4A07,
+    $2B5ED7CA, $937EB564, $6FDA7E11, $E49B5D6C, $B4B3244E, $18AA53A4, $3A061334,
+    $4D6067A3, $83BA5868, $9BDF4DFE, $7449F261, $709F8450, $CAD133CB, $DE941C3F,
+    $F52AE484, $781D77ED, $7E4395F0, $AE103B59, $922331BB, $42CE50C8, $E6F08153,
+    $E7D941D0, $5028ED6B, $B3D2C49B, $AD4D9C3E, $D201FB6E, $A45BD5BE, $FFCB7F4B,
+    $579D7806, $F821BB5B, $59D592AD, $D0BE0C31, $D4E3B676, $0107165A, $0FE939D2,
+    $49BCAAFD, $55FFCFE5, $2EC1F783, $F39A09A5, $3EB42772, $19B55A5D, $024A0679,
+    $8C83B3F7, $8642BA1D, $ACACD9EA, $87D352C4, $60931F45, $A05F97D7, $1CECD42C,
+    $E2FCC87B, $B60F94E2, $67A34B0B, $FCDD40C9, $0B150A27, $D3EE9E04, $582E29E9,
+    $4AC22B41, $6AC4E1B8, $BCCAA51A, $237AF30E, $EBC3B709, $C4A59D19, $284BC98A,
+    $E9D41A93, $6BFA2018, $73B2D651, $11F9A2FA, $CE09BFF1, $41A470AA, $25888F22,
+    $77E754E8, $F7330D8E, $158EAB16, $C5D68842, $C685A6F6, $E5B82FDE, $09EA3A96,
+    $6DDE1536, $4FA919DA, $26C0BE9F, $9EED6F69, $F05555F2, $E06FC285, $9CD76D23,
+    $AF452A92, $EFC74CB7, $9D6B4732, $8BE408EE, $22401D0D, $EE6C459D, $7587CB82,
+    $E8746862, $5CBDDE87, $98794278, $31AFB94D, $C11E0F2F, $30E8FC2A, $CF3261EF,
+    $1A3023E1, $AA2F86CF, $F202E24A, $8D08DCFF, $764837C6, $A26374CC, $9F7C3E88,
+    $949CC57D, $DD26A07F, $C39EFAB0, $C8F879A1, $DCE67BB9, $F4B0A435, $912C9AE0,
+    $D85603E4, $953A9BBF, $FB8290D6, $0AEBCD5F, $16206A9A, $6C787A14, $D9A0F16A,
+    $29BF4F74, $8F8BCE91, $0E5A9354, $AB038CB1, $1B8AD11B, $E327FF49, $0053DA20,
+    $90CF51DC, $DA92FE6D, $0390CA47, $A8958097, $A9DC5BAF, $3931E3C1, $840446B6,
+    $63D069FB, $D7460299, $7124ECD1, $0791E613, $485918FC, $D635D04C, $DF96AC33,
+    $66F2D303, $247056AE, $A1A7B2A8, $27D8CC9C, $17B6E998, $7BF5590F, $FE97F557,
+    $5471D8A2), THashLibUInt32Array.Create($83A327A1, $9F379F51, $40A7D007,
+    $11307423, $224587C1, $AC27D63B, $3B7E64EA, $2E1CBFA6, $09996000, $03BC0E2C,
+    $D4C4478A, $4542E0AB, $FEDA26D4, $C1D10FCB, $8252F596, $4494EB5C, $A362F314,
+    $F5BA81FD, $75C3A376, $4CA214CA, $E164DEDD, $5088FA97, $4B0930E0, $2FCFB7E8,
+    $33A6F4B2, $C7E94211, $2D66C774, $43BE8BAE, $C663D445, $908EB130, $F4E3BE15,
+    $63B9D566, $529396B5, $1E1BE743, $4D5FF63F, $985E4A83, $71AB9DF7, $C516C6F5,
+    $85C19AB4, $1F4DAEE4, $F2973431, $B713DC5E, $3F2E159A, $C824DA16, $06BF376A,
+    $B2FE23EC, $E39B1C22, $F1EECB5F, $08E82D52, $565686C2, $AB0AEA93, $FD47219F,
+    $EBDBABD7, $2404A185, $8C7312B9, $A8F2D828, $0C8902DA, $65B42B63, $C0BBEF62,
+    $4E3E4CEF, $788F8018, $EE1EBAB7, $93928F9D, $683D2903, $D3B60689, $AFCB0DDC,
+    $88A4C47A, $F6DD9C3D, $7EA5FCA0, $8A6D7244, $BE11F120, $04FF91B8, $8D2DC8C0,
+    $27F97FDB, $7F9E1F47, $1734F0C7, $26F3ED8E, $0DF8F2BF, $B0833D9E, $E420A4E5,
+    $A423CAE6, $95616772, $9AE6C049, $075941F2, $D8E12812, $000F6F4F, $3C0D6B05,
+    $6CEF921C, $B82BC264, $396CB008, $5D608A6F, $6D7782C8, $186550AA, $6B6FEC09,
+    $28E70B13, $57CE5688, $ECD3AF84, $23335A95, $91F40CD2, $7B6A3B26, $BD32B3B6,
+    $3754A6FB, $8ED088F0, $F867E87C, $20851746, $6410F9C6, $35380442, $C2CA10A7,
+    $1ADEA27F, $76BDDD79, $92742CF4, $0E98F7EE, $164E931D, $B9C835B3, $69060A99,
+    $B44C531E, $FA7B66FE, $C98A5B53, $7D95AAE9, $302F467B, $74B811DE, $F3866ABD,
+    $B5B3D32D, $FC3157A4, $D251FE19, $0B5D8EAC, $DA71FFD5, $47EA05A3, $05C6A9E1,
+    $CA0EE958, $9939034D, $25DC5EDF, $79083CB1, $86768450, $CF757D6D, $5972B6BC,
+    $A78D59C9, $C4AD8D41, $2A362AD3, $D1179991, $601407FF, $DCF50917, $587069D0,
+    $E0821ED6, $DBB59427, $73911A4B, $7C904FC3, $844AFB92, $6F8C955D, $E8C0C5BB,
+    $B67AB987, $A529D96C, $F91F7181, $618B1B06, $E718BB0C, $8BD7615B, $D5A93A59,
+    $54AEF81B, $772136E3, $CE44FD9C, $10CDA57E, $87D66E0B, $3D798967, $1B2C1804,
+    $3EDFBD68, $15F6E62B, $EF68B854, $3896DB35, $12B7B5E2, $CB489029, $9E4F98A5,
+    $62EB77A8, $217C24A2, $964152F6, $49B2080A, $53D23EE7, $48FB6D69, $1903D190,
+    $9449E494, $BF6E7886, $FB356CFA, $3A261365, $424BC1EB, $A1192570, $019CA782,
+    $9D3F7E0E, $9C127575, $EDF02039, $AD57BCCE, $5C153277, $81A84540, $BCAA7356,
+    $CCD59B60, $A62A629B, $A25CCD10, $2B5B65CF, $1C535832, $55FD4E3A, $31D9790D,
+    $F06BC37D, $4AFC1D71, $AEED5533, $BA461634, $BB694B78, $5F3A5C73, $6A3C764A,
+    $8FB0CCA9, $F725684C, $4FE5382F, $1D0163AF, $5AA07A8F, $E205A8ED, $C30BAD38,
+    $FF22CF1F, $72432E2E, $32C2518B, $3487CE4E, $7AE0AC02, $709FA098, $0A3B395A,
+    $5B4043F8, $A9E48C36, $149A8521, $D07DEE6B, $46ACD2F3, $8958DFFC, $B3A1223C,
+    $B11D31C4, $CD7F4D3E, $0F28E3AD, $E5B100BE, $AAC54824, $E9C9D7BA, $9BD47001,
+    $80F149B0, $66022F0F, $020C4048, $6EFA192A, $67073F8D, $13EC7BF9, $3655011A,
+    $E6AFE157, $D9845F6E, $DECC4425, $511AE2CC, $DF81B4D8, $D7809E55, $D6D883D9,
+    $2CC7978C, $5E787CC5, $DD0033D1, $A050C937, $97F75DCD, $299DE580, $41E2B261,
+    $EA5A54F1), THashLibUInt32Array.Create($7E672590, $BEA513BB, $2C906FE6,
+    $86029C2B, $55DC4F74, $0553398E, $63E09647, $CAFD0BAB, $264C37DF, $8272210F,
+    $67AFA669, $12D98A5F, $8CAB23C4, $75C68BD1, $C3370470, $33F37F4E, $283992FF,
+    $E73A3A67, $1032F283, $F5AD9FC2, $963F0C5D, $664FBC45, $202BA41C, $C7C02D80,
+    $54731E84, $8A1085F5, $601D80FB, $2F968E55, $35E96812, $E45A8F78, $BD7DE662,
+    $3B6E6EAD, $8097C5EF, $070B6781, $B1E508F3, $24E4FAE3, $B81A7805, $EC0FC918,
+    $43C8774B, $9B2512A9, $2B05AD04, $32C2536F, $EDF236E0, $8BC4B0CF, $BACEB837,
+    $4535B289, $0D0E94C3, $A5A371D0, $AD695A58, $39E3437D, $9186BFFC, $21038C3B,
+    $0AA9DFF9, $5D1F06CE, $62DEF8A4, $F740A2B4, $A2575868, $682683C1, $DBB30FAC,
+    $61FE1928, $468A6511, $C61CD5F4, $E54D9800, $6B98D7F7, $8418B6A5, $5F09A5D2,
+    $90B4E80B, $49B2C852, $69F11C77, $17412B7E, $7F6FC0ED, $56838DCC, $6E9546A2,
+    $D0758619, $087B9B9A, $D231A01D, $AF46D415, $097060FD, $D920F657, $882D3F9F,
+    $3AE7C3C9, $E8A00D9B, $4FE67EBE, $2EF80EB2, $C1916B0C, $F4DFFEA0, $B97EB3EB,
+    $FDFF84DD, $FF8B14F1, $E96B0572, $F64B508C, $AE220A6E, $4423AE5A, $C2BECE5E,
+    $DE27567C, $FC935C63, $47075573, $E65B27F0, $E121FD22, $F2668753, $2DEBF5D7,
+    $8347E08D, $AC5EDA03, $2A7CEBE9, $3FE8D92E, $23542FE4, $1FA7BD50, $CF9B4102,
+    $9D0DBA39, $9CB8902A, $A7249D8B, $0F6D667A, $5EBFA9EC, $6A594DF2, $79600938,
+    $023B7591, $EA2C79C8, $C99D07EA, $64CB5EE1, $1A9CAB3D, $76DB9527, $C08E012F,
+    $3DFB481A, $872F22E7, $2948D15C, $A4782C79, $6F50D232, $78F0728A, $5A87AAB1,
+    $C4E2C19C, $EE767387, $1B2A1864, $7B8D10D3, $D1713161, $0EEAC456, $D8799E06,
+    $B645B548, $4043CB65, $A874FB29, $4B12D030, $7D687413, $18EF9A1F, $D7631D4C,
+    $5829C7DA, $CDFA30FA, $C5084BB0, $92CD20E2, $D4C16940, $03283EC0, $A917813F,
+    $9A587D01, $70041F8F, $DC6AB1DC, $DDAEE3D5, $31829742, $198C022D, $1C9EAFCB,
+    $5BBC6C49, $D3D3293A, $16D50007, $04BB8820, $3C5C2A41, $37EE7AF8, $8EB04025,
+    $9313ECBA, $BFFC4799, $8955A744, $EF85D633, $504499A7, $A6CA6A86, $BB3D3297,
+    $B34A8236, $6DCCBE4F, $06143394, $CE19FC7B, $CCC3C6C6, $E36254AE, $77B7EDA1,
+    $A133DD9E, $EBF9356A, $513CCF88, $E2A1B417, $972EE5BD, $853824CD, $5752F4EE,
+    $6C1142E8, $3EA4F309, $B2B5934A, $DFD628AA, $59ACEA3E, $A01EB92C, $389964BC,
+    $DA305DD4, $019A59B7, $11D2CA93, $FAA6D3B9, $4E772ECA, $72651776, $FB4E5B0E,
+    $A38F91A8, $1D0663B5, $30F4F192, $B50051B6, $B716CCB3, $4ABD1B59, $146C5F26,
+    $F134E2DE, $00F67C6C, $B0E1B795, $98AA4EC7, $0CC73B34, $654276A3, $8D1BA871,
+    $740A5216, $E0D01A23, $9ED161D6, $9F36A324, $993EBB7F, $FEB9491B, $365DDCDB,
+    $810CFFC5, $71EC0382, $2249E7BF, $48817046, $F3A24A5B, $4288E4D9, $0BF5C243,
+    $257FE151, $95B64C0D, $4164F066, $AAF7DB08, $73B1119D, $8F9F7BB8, $D6844596,
+    $F07A34A6, $53943D0A, $F9DD166D, $7A8957AF, $F8BA3CE5, $27C9621E, $5CDAE910,
+    $C8518998, $941538FE, $136115D8, $ABA8443C, $4D01F931, $34EDF760, $B45F266B,
+    $D5D4DE14, $52D8AC35, $15CFD885, $CBC5CD21, $4CD76D4D, $7C80EF54, $BC92EE75,
+    $1E56A1F6), THashLibUInt32Array.Create($BAA20B6C, $9FFBAD26, $E1F7D738,
+    $794AEC8D, $C9E9CF3C, $8A9A7846, $C57C4685, $B9A92FED, $29CB141F, $52F9DDB7,
+    $F68BA6BC, $19CCC020, $4F584AAA, $3BF6A596, $003B7CF7, $54F0CE9A, $A7EC4303,
+    $46CF0077, $78D33AA1, $215247D9, $74BCDF91, $08381D30, $DAC43E40, $64872531,
+    $0BEFFE5F, $B317F457, $AEBB12DA, $D5D0D67B, $7D75C6B4, $42A6D241, $1502D0A9,
+    $3FD97FFF, $C6C3ED28, $81868D0A, $92628BC5, $86679544, $FD1867AF, $5CA3EA61,
+    $568D5578, $4A2D71F4, $43C9D549, $8D95DE2B, $6E5C74A0, $9120FFC7, $0D05D14A,
+    $A93049D3, $BFA80E17, $F4096810, $043F5EF5, $A673B4F1, $6D780298, $A4847783,
+    $5EE726FB, $9934C281, $220A588C, $384E240F, $933D5C69, $39E5EF47, $26E8B8F3,
+    $4C1C6212, $8040F75D, $074B7093, $6625A8D7, $36298945, $76285088, $651D37C3,
+    $24F5274D, $DBCA3DAB, $186B7EE1, $D80F8182, $14210C89, $943A3075, $4E6E11C4,
+    $4D7E6BAD, $F05064C8, $025DCD97, $4BC10302, $7CEDE572, $8F90A970, $AB88EEBA,
+    $B5998029, $5124D839, $B0EEB6A3, $89DDABDC, $E8074D76, $A1465223, $32518CF2,
+    $9D39D4EB, $C0D84524, $E35E6EA8, $7ABF3804, $113E2348, $9AE6069D, $B4DFDABB,
+    $A8C5313F, $23EA3F79, $530E36A2, $A5FD228B, $95D1D350, $2B14CC09, $40042956,
+    $879D05CC, $2064B9CA, $ACACA40E, $B29C846E, $9676C9E3, $752B7B8A, $7BE2BCC2,
+    $6BD58F5E, $D48F4C32, $606835E4, $9CD7C364, $2C269B7A, $3A0D079C, $73B683FE,
+    $45374F1E, $10AFA242, $577F8666, $DDAA10F6, $F34F561C, $3D355D6B, $E47048AE,
+    $AA13C492, $050344FD, $2AAB5151, $F5B26AE5, $ED919A59, $5AC67900, $F1CDE380,
+    $0C79A11B, $351533FC, $CD4D8E36, $1F856005, $690B9FDD, $E736DCCF, $1D47BF6A,
+    $7F66C72A, $85F21B7F, $983CBDB6, $01EBBEBF, $035F3B99, $EB111F34, $28CEFDC6,
+    $5BFC9ECD, $F22EACB0, $9E41CBB2, $E0F8327C, $82E3E26F, $FC43FC86, $D0BA66DF,
+    $489EF2A7, $D9E0C81D, $68690D52, $CC451367, $C2232E16, $E95A7335, $0FDAE19B,
+    $FF5B962C, $97596527, $C46DB333, $3ED4C562, $C14C9D9E, $5D6FAA21, $638E940D,
+    $F9316D58, $47B3B0EA, $30FFCAD2, $CE1BBA7D, $1E6108E6, $2E1EA33D, $507BF05B,
+    $FAFEF94B, $D17DE8E2, $5598B214, $1663F813, $17D25A2D, $EEFA5FF9, $582F4E37,
+    $12128773, $FEF17AB8, $06005322, $BB32BBC9, $8C898508, $592C15F0, $D38A4054,
+    $4957B7D6, $D2B891DB, $37BD2D3E, $34AD20CB, $622288E9, $2DC7345A, $AFB416C0,
+    $1CF459B1, $DC7739FA, $0A711A25, $13E18A0C, $5F72AF4C, $6AC8DB11, $BE53C18E,
+    $1AA569B9, $EF551EA4, $A02A429F, $BD16E790, $7EB9171A, $77D693D8, $8E06993A,
+    $9BDE7560, $E5801987, $C37A09BE, $B8DB76AC, $E2087294, $6C81616D, $B7F30FE7,
+    $BC9B82BD, $FBA4E4D4, $C7B1012F, $A20C043B, $DE9FEBD0, $2F9297CE, $E610AEF8,
+    $70B06F19, $C86AE00B, $0E01988F, $41192AE0, $448C1CB5, $ADBE92EE, $7293A007,
+    $1B54B5B3, $D61F63D1, $EAE40A74, $61A72B55, $EC83A7D5, $88942806, $90A07DA5,
+    $D7424B95, $67745B4E, $A31A1853, $CA6021EF, $DFB56C4F, $CBC2D915, $3C48E918,
+    $8BAE3C63, $6F659C71, $F8B754C1, $2782F3DE, $F796F168, $71492C84, $33C0F5A6,
+    $3144F6EC, $25DC412E, $B16C5743, $83A1FA7E, $0997B101, $B627E6E8, $CF33905C,
+    $8456FB65), THashLibUInt32Array.Create($B29BEA74, $C35DA605, $305C1CA3,
+    $D2E9F5BC, $6FD5BFF4, $FF347703, $FC45B163, $F498E068, $B71229FC, $81ACC3FB,
+    $78538A8B, $984ECF81, $A5DA47A4, $8F259EEF, $6475DC65, $081865B9, $49E14A3C,
+    $19E66079, $D382E91B, $5B109794, $3F9F81E1, $4470A388, $41601ABE, $AAF9F407,
+    $8E175EF6, $ED842297, $893A4271, $1790839A, $D566A99E, $6B417DEE, $75C90D23,
+    $715EDB31, $723553F7, $9AFB50C9, $FBC5F600, $CD3B6A4E, $97ED0FBA, $29689AEC,
+    $63135C8E, $F0E26C7E, $0692AE7F, $DBB208FF, $2EDE3E9B, $6A65BEBD, $D40867E9,
+    $C954AFC5, $73B08201, $7FFDF809, $1195C24F, $1CA5ADCA, $74BD6D1F, $B393C455,
+    $CADFD3FA, $99F13011, $0EBCA813, $60E791B8, $6597AC7A, $18A7E46B, $09CB49D3,
+    $0B27DF6D, $CFE52F87, $CEF66837, $E6328035, $FA87C592, $37BAFF93, $D71FCC99,
+    $DCAB205C, $4D7A5638, $48012510, $62797558, $B6CF1FE5, $BC311834, $9C2373AC,
+    $14EC6175, $A439CBDF, $54AFB0EA, $D686960B, $FDD0D47B, $7B063902, $8B78BAC3,
+    $26C6A4D5, $5C0055B6, $2376102E, $0411783E, $2AA3F1CD, $51FC6EA8, $701CE243,
+    $9B2A0ABB, $0AD93733, $6E80D03D, $AF6295D1, $F629896F, $A30B0648, $463D8DD4,
+    $963F84CB, $01FF94F8, $8D7FEFDC, $553611C0, $A97C1719, $B96AF759, $E0E3C95E,
+    $0528335B, $21FE5925, $821A5245, $807238B1, $67F23DB5, $EA6B4EAB, $0DA6F985,
+    $AB1BC85A, $EF8C90E4, $4526230E, $38EB8B1C, $1B91CD91, $9FCE5F0C, $F72CC72B,
+    $C64F2617, $DAF7857D, $7D373CF1, $28EAEDD7, $203887D0, $C49A155F, $A251B3B0,
+    $F2D47AE3, $3D9EF267, $4A94AB2F, $7755A222, $0205E329, $C28FA7A7, $AEC1FE51,
+    $270F164C, $8C6D01BF, $53B5BC98, $C09D3FEB, $834986CC, $4309A12C, $578B2A96,
+    $3BB74B86, $69561B4A, $037E32F3, $DE335B08, $C5156BE0, $E7EF09AD, $93B834C7,
+    $A7719352, $59302821, $E3529D26, $F961DA76, $CB142C44, $A0F3B98D, $76502457,
+    $945A414B, $078EEB12, $DFF8DE69, $EB6C8C2D, $BDA90C4D, $E9C44D16, $168DFD66,
+    $AD64763B, $A65FD764, $95A29C06, $32D7713F, $40F0B277, $224AF08F, $004CB5E8,
+    $92574814, $8877D827, $3E5B2D04, $68C2D5F2, $86966273, $1D433ADA, $8774988A,
+    $3C0E0BFE, $DDAD581D, $2FD654ED, $0F4769FD, $C181EE9D, $5FD88F61, $341DBB3A,
+    $528543F9, $D92235CF, $1EA82EB4, $B5CD790F, $91D24F1E, $A869E6C2, $61F474D2,
+    $CC205ADD, $0C7BFBA9, $BF2B0489, $B02D72D8, $2B46ECE6, $E4DCD90A, $B8A11440,
+    $EE8A63B7, $854DD1A1, $D1E00583, $42B40E24, $9E8964DE, $B4B35D78, $BEC76F6E,
+    $24B9C620, $D8D399A6, $5ADB2190, $2DB12730, $3A5866AF, $58C8FADB, $5D8844E7,
+    $8A4BF380, $15A01D70, $79F5C028, $66BE3B8C, $F3E42B53, $56990039, $2C0C3182,
+    $5E16407C, $ECC04515, $6C440284, $4CB6701A, $13BFC142, $9D039F6A, $4F6E92C8,
+    $A1407C62, $8483A095, $C70AE1C4, $E20213A2, $BACAFC41, $4ECC12B3, $4BEE3646,
+    $1FE807AE, $25217F9C, $35DDE5F5, $7A7DD6CE, $F89CCE50, $AC07B718, $7E73D2C6,
+    $E563E76C, $123CA536, $3948CA56, $9019DD49, $10AA88D9, $C82451E2, $473EB6D6,
+    $506FE854, $E8BB03A5, $332F4C32, $FE1E1E72, $B1AE572A, $7C0D7BC1, $E1C37EB2,
+    $F542AA60, $F1A48EA0, $D067B89F, $BBFA195D, $1A049B0D, $315946AA, $36D1B447,
+    $6D2EBDF0), THashLibUInt32Array.Create($0D188A6D, $12CEA0DB, $7E63740E,
+    $6A444821, $253D234F, $6FFC6597, $94A6BDEF, $33EE1B2F, $0A6C00C0, $3AA336B1,
+    $5AF55D17, $265FB3DC, $0E89CF4D, $0786B008, $C80055B8, $6B17C3CE, $72B05A74,
+    $D21A8D78, $A6B70840, $FE8EAE77, $ED69565C, $55E1BCF4, $585C2F60, $E06F1A62,
+    $AD67C0CD, $7712AF88, $9CC26ACA, $1888053D, $37EB853E, $9215ABD7, $DE30ADFC,
+    $1F1038E6, $70C51C8A, $8D586C26, $F72BDD90, $4DC3CE15, $68EAEEFA, $D0E9C8B9,
+    $200F9C44, $DDD141BA, $024BF1D3, $0F64C9D4, $C421E9E9, $9D11C14C, $9A0DD9E4,
+    $5F92EC19, $1B980DF0, $1DCC4542, $B8FE8C56, $0C9C9167, $4E81EB49, $CA368F27,
+    $E3603B37, $EA08ACCC, $AC516992, $C34F513B, $804D100D, $6EDCA4C4, $FC912939,
+    $29D219B0, $278AAA3C, $4868DA7D, $54E890B7, $B46D735A, $514589AA, $D6C630AF,
+    $4980DFE8, $BE3CCC55, $59D41202, $650C078B, $AF3A9E7B, $3ED9827A, $9E79FC6E,
+    $AADBFBAE, $C5F7D803, $3DAF7F50, $67B4F465, $73406E11, $39313F8C, $8A6E6686,
+    $D8075F1F, $D3CBFED1, $69C7E49C, $930581E0, $E4B1A5A8, $BBC45472, $09DDBF58,
+    $C91D687E, $BDBFFDA5, $88C08735, $E9E36BF9, $DB5EA9B6, $95559404, $08F432FB,
+    $E24EA281, $64663579, $000B8010, $7914E7D5, $32FD0473, $D1A7F0A4, $445AB98E,
+    $EC72993F, $A29A4D32, $B77306D8, $C7C97CF6, $7B6AB645, $F5EF7ADF, $FB2E15F7,
+    $E747F757, $5E944354, $234A2669, $47E46359, $9B9D11A9, $40762CED, $56F1DE98,
+    $11334668, $890A9A70, $1A296113, $B3BD4AF5, $163B7548, $D51B4F84, $B99B2ABC,
+    $3CC1DC30, $A9F0B56C, $812272B2, $0B233A5F, $B650DBF2, $F1A0771B, $36562B76,
+    $DC037B0F, $104C97FF, $C2EC98D2, $90596F22, $28B6620B, $DF42B212, $FDBC4243,
+    $F3FB175E, $4A2D8B00, $E8F3869B, $30D69BC3, $853714C8, $A7751D2E, $31E56DEA,
+    $D4840B0C, $9685D783, $068C9333, $8FBA032C, $76D7BB47, $6D0EE22B, $B546794B,
+    $D971B894, $8B09D253, $A0AD5761, $EE77BA06, $46359F31, $577CC7EC, $52825EFD,
+    $A4BEED95, $9825C52A, $EB48029A, $BAAE59F8, $CF490EE1, $BC990164, $8CA49DFE,
+    $4F38A6E7, $2BA98389, $8228F538, $199F64AC, $01A1CAC5, $A8B51641, $5CE72D01,
+    $8E5DF26B, $60F28E1E, $CD5BE125, $E5B376BF, $1C8D3116, $7132CBB3, $CB7AE320,
+    $C0FA5366, $D7653E34, $971C88C2, $C62C7DD0, $34D0A3DA, $868F6709, $7AE6FA8F,
+    $22BBD523, $66CD3D5B, $1EF9288D, $F9CF58C1, $5B784E80, $7439A191, $AE134C36,
+    $9116C463, $2E9E1396, $F8611F3A, $2D2F3307, $247F37DD, $C1E2FF9D, $43C821E5,
+    $05ED5CAB, $EF74E80A, $4CCA6028, $F0AC3CBD, $5D874B29, $6C62F6A6, $4B2A2EF3,
+    $B1AA2087, $62A5D0A3, $0327221C, $B096B4C6, $417EC693, $ABA840D6, $789725EB,
+    $F4B9E02D, $E6E00975, $CC04961A, $63F624BB, $7FA21ECB, $2C01EA7F, $B2415005,
+    $2A8BBEB5, $83B2B14E, $A383D1A7, $5352F96A, $043ECDAD, $CE1918A1, $FA6BE6C9,
+    $50DEF36F, $F6B80CE2, $4543EF7C, $9953D651, $F257955D, $87244914, $DA1E0A24,
+    $FFDA4785, $14D327A2, $3B93C29F, $840684B4, $61AB71A0, $9F7B784A, $2FD570CF,
+    $15955BDE, $38F8D471, $3534A718, $133FB71D, $3FD80F52, $4290A8BE, $75FF44C7,
+    $A554E546, $E1023499, $BF2652E3, $7D20399E, $A1DF7E82, $177092EE, $217DD3F1,
+    $7C1FF8D9), THashLibUInt32Array.Create($12113F2E, $BFBD0785, $F11793FB,
+    $A5BFF566, $83C7B0E5, $72FB316B, $75526A9A, $41E0E612, $7156BA09, $53CE7DEE,
+    $0AA26881, $A43E0D7D, $3DA73CA3, $182761ED, $BD5077FF, $56DB4AA0, $E792711C,
+    $F0A4EB1D, $7F878237, $EC65C4E8, $08DC8D43, $0F8CE142, $8258ABDA, $F4154E16,
+    $49DEC2FD, $CD8D5705, $6C2C3A0F, $5C12BB88, $EFF3CDB6, $2C89ED8C, $7BEBA967,
+    $2A142157, $C6D0836F, $B4F97E96, $6931E969, $514E6C7C, $A7792600, $0BBBF780,
+    $59671BBD, $0707B676, $37482D93, $80AF1479, $3805A60D, $E1F4CAC1, $580B3074,
+    $30B8D6CE, $05A304BE, $D176626D, $EBCA97F3, $BB201F11, $6A1AFE23, $FFAA86E4,
+    $62B4DA49, $1B6629F5, $F5D9E092, $F37F3DD1, $619BD45B, $A6EC8E4F, $29C80939,
+    $0C7C0C34, $9CFE6E48, $E65FD3AC, $73613B65, $B3C669F9, $BE2E8A9E, $286F9678,
+    $5797FD13, $99805D75, $CFB641C5, $A91074BA, $6343AF47, $6403CB46, $8894C8DB,
+    $2663034C, $3C40DC5E, $00995231, $96789AA2, $2EFDE4B9, $7DC195E1, $547DADD5,
+    $06A8EA04, $F2347A63, $5E0DC6F7, $8462DFC2, $1E6B2C3C, $9BD275B3, $91D419E2,
+    $BCEFD17E, $B9003924, $D07E7320, $DEF0495C, $C36AD00E, $1785B1AB, $92E20BCF,
+    $B139F0E9, $675BB9A1, $AECFA4AF, $132376CB, $E84589D3, $79A05456, $A2F860BC,
+    $1AE4F8B5, $20DF4DB4, $A1E1428B, $3BF60A1A, $27FF7BF1, $CB44C0E7, $F7F587C4,
+    $1F3B9B21, $94368F01, $856E23A4, $6F93DE3F, $773F5BBF, $8B22056E, $DF41F654,
+    $B8246FF4, $8D57BFF2, $D57167EA, $C5699F22, $40734BA7, $5D5C2772, $033020A8,
+    $E30A7C4D, $ADC40FD6, $76353441, $5AA5229B, $81516590, $DA49F14E, $4FA672A5,
+    $4D9FAC5F, $154BE230, $8A7A5CC0, $CE3D2F84, $CCA15514, $5221360C, $AF0FB81E,
+    $5BDD5873, $F6825F8F, $1113D228, $70AD996C, $93320051, $60471C53, $E9BA567B,
+    $3A462AE3, $5F55E72D, $1D3C5AD7, $DCFC45EC, $34D812EF, $FA96EE1B, $369D1EF8,
+    $C9B1A189, $7C1D3555, $50845EDC, $4BB31877, $8764A060, $8C9A9415, $230E1A3A,
+    $B05E9133, $242B9E03, $A3B99DB7, $C2D7FB0A, $3333849D, $D27278D4, $B5D3EFA6,
+    $78AC28AD, $C7B2C135, $0926ECF0, $C1374C91, $74F16D98, $2274084A, $3F6D9CFA,
+    $7AC0A383, $B73AFF1F, $3909A23D, $9F1653AE, $4E2F3E71, $CA5AB22A, $E01E3858,
+    $90C5A7EB, $3E4A17DF, $AA987FB0, $488BBD62, $B625062B, $2D776BB8, $43B5FC08,
+    $1490D532, $D6D12495, $44E89845, $2FE60118, $9D9EF950, $AC38133E, $D3864329,
+    $017B255A, $FDC2DD26, $256851E6, $318E7086, $2BFA4861, $89EAC706, $EE5940C6,
+    $68C3BC2F, $E260334B, $98DA90BB, $F818F270, $4706D897, $212D3799, $4CF7E5D0,
+    $D9C9649F, $A85DB5CD, $35E90E82, $6B881152, $AB1C02C7, $46752B02, $664F598E,
+    $45AB2E64, $C4CDB4B2, $BA42107F, $EA2A808A, $971BF3DE, $4A54A836, $4253AECC,
+    $1029BE68, $6DCC9225, $E4BCA56A, $C0AE50B1, $7E011D94, $E59C162C, $D8E5C340,
+    $D470FA0B, $B2BE79DD, $D783889C, $1CEDE8F6, $8F4C817A, $DDB785C9, $860232D8,
+    $198AAAD9, $A0814738, $3219CFFC, $169546D2, $FC0CB759, $55911510, $04D5CEC3,
+    $ED08CC3B, $0D6CF427, $C8E38CCA, $0EEEE3FE, $9EE7D7C8, $F9F24FA9, $DB04B35D,
+    $9AB0C9E0, $651F4417, $028F8B07, $6E28D9AA, $FBA96319, $8ED66687, $FECBC58D,
+    $954DDB44), THashLibUInt32Array.Create($7B0BDFFE, $865D16B1, $49A058C0,
+    $97ABAA3F, $CAACC75D, $ABA6C17D, $F8746F92, $6F48AEED, $8841D4B5, $F36A146A,
+    $73C390AB, $E6FB558F, $87B1019E, $26970252, $246377B2, $CBF676AE, $F923DB06,
+    $F7389116, $14C81A90, $83114EB4, $8B137559, $95A86A7A, $D5B8DA8C, $C4DF780E,
+    $5A9CB3E2, $E44D4062, $E8DC8EF6, $9D180845, $817AD18B, $C286C85B, $251F20DE,
+    $EE6D5933, $F6EDEF81, $D4D16C1E, $C94A0C32, $8437FD22, $3271EE43, $42572AEE,
+    $5F91962A, $1C522D98, $59B23F0C, $D86B8804, $08C63531, $2C0D7A40, $B97C4729,
+    $04964DF9, $13C74A17, $5878362F, $4C808CD6, $092CB1E0, $6DF02885, $A0C2105E,
+    $8ABA9E68, $64E03057, $E5D61325, $0E43A628, $16DBD62B, $2733D90B, $3AE57283,
+    $C0C1052C, $4B6FB620, $37513953, $FC898BB3, $471B179F, $DF6E66B8, $D32142F5,
+    $9B30FAFC, $4ED92549, $105C6D99, $4ACD69FF, $2B1A27D3, $6BFCC067, $6301A278,
+    $AD36E6F2, $EF3FF64E, $56B3CADB, $0184BB61, $17BEB9FD, $FAEC6109, $A2E1FFA1,
+    $2FD224F8, $238F5BE6, $8F8570CF, $AEB5F25A, $4F1D3E64, $4377EB24, $1FA45346,
+    $B2056386, $52095E76, $BB7B5ADC, $3514E472, $DDE81E6E, $7ACEA9C4, $AC15CC48,
+    $71C97D93, $767F941C, $911052A2, $FFEA09BF, $FE3DDCF0, $15EBF3AA, $9235B8BC,
+    $75408615, $9A723437, $E1A1BD38, $33541B7E, $1BDD6856, $B307E13E, $90814BB0,
+    $51D7217B, $0BB92219, $689F4500, $C568B01F, $5DF3D2D7, $3C0ECD0D, $2A0244C8,
+    $852574E8, $E72F23A9, $8E26ED02, $2D92CBDD, $DABC0458, $CDF5FEB6, $9E4E8DCC,
+    $F4F1E344, $0D8C436D, $4427603B, $BDD37FDA, $80505F26, $8C7D2B8E, $B73273C5,
+    $397362EA, $618A3811, $608BFB88, $06F7D714, $212E4677, $28EFCEAD, $076C0371,
+    $36A3A4D9, $5487B455, $3429A365, $65D467AC, $78EE7EEB, $99BF12B7, $4D129896,
+    $772A5601, $CCE284C7, $2ED85C21, $D099E8A4, $A179158A, $6AC0AB1A, $299A4807,
+    $BE67A58D, $DC19544A, $B8949B54, $8D315779, $B6F849C1, $53C5AC34, $66DE92A5,
+    $F195DD13, $318D3A73, $301EC542, $0CC40DA6, $F253ADE4, $467EE566, $EA5585EC,
+    $3BAF19BB, $7DE9F480, $79006E7C, $A9B7A197, $A44BD8F1, $FB2BA739, $EC342FD4,
+    $ED4FD32D, $3D1789BA, $400F5D7F, $C798F594, $4506A847, $034C0A95, $E2162C9D,
+    $55A9CFD0, $692D832E, $CF9DB2CA, $5E2287E9, $D2610EF3, $1AE7ECC2, $48399CA0,
+    $A7E4269B, $6EE3A0AF, $7065BFE1, $A6FFE708, $2256804C, $7476E21B, $41B0796C,
+    $7C243B05, $000A950F, $1858416B, $F5A53C89, $E9FEF823, $3F443275, $E0CBF091,
+    $0AF27B84, $3EBB0F27, $1DE6F7F4, $C31C29F7, $B166DE3D, $12932EC3, $9C0C0674,
+    $5CDA81B9, $D1BD9D12, $AFFD7C82, $8962BCA7, $A342C4A8, $62457151, $82089F03,
+    $EB49C670, $5B5F6530, $7E28BAD2, $20880BA3, $F0FAAFCD, $CE82B56F, $0275335C,
+    $C18E8AFB, $DE601D69, $BA9B820A, $C8A2BE4F, $D7CAC335, $D9A73741, $115E974D,
+    $7F5AC21D, $383BF9C6, $BCAEB75F, $FD0350CE, $B5D06B87, $9820E03C, $72D5F163,
+    $E3644FC9, $A5464C4B, $57048FCB, $9690C9DF, $DBF9EAFA, $BFF4649A, $053C00E3,
+    $B4B61136, $67593DD1, $503EE960, $9FB4993A, $19831810, $C670D518, $B05B51D8,
+    $0F3A1CE5, $6CAA1F9C, $AACC31BE, $949ED050, $1EAD07E7, $A8479ABD, $D6CFFCD5,
+    $936993EF), THashLibUInt32Array.Create($472E91CB, $5444B5B6, $62BE5861,
+    $1BE102C7, $63E4B31E, $E81F71B7, $9E2317C9, $39A408AE, $518024F4, $1731C66F,
+    $68CBC918, $71FB0C9E, $D03B7FDD, $7D6222EB, $9057EDA3, $1A34A407, $8CC2253D,
+    $B6F6979D, $835675DC, $F319BE9F, $BE1CD743, $4D32FEE4, $77E7D887, $37E9EBFD,
+    $15F851E8, $23DC3706, $19D78385, $BD506933, $A13AD4A6, $913F1A0E, $DDE560B9,
+    $9A5F0996, $A65A0435, $48D34C4D, $E90839A7, $8ABBA54E, $6FD13CE1, $C7EEBD3C,
+    $0E297602, $58B9BBB4, $EF7901E6, $64A28A62, $A509875A, $F8834442, $2702C709,
+    $07353F31, $3B39F665, $F5B18B49, $4010AE37, $784DE00B, $7A1121E9, $DE918ED3,
+    $C8529DCD, $816A5D05, $02ED8298, $04E3DD84, $FD2BC3E2, $AF167089, $96AF367E,
+    $A4DA6232, $18FF7325, $05F9A9F1, $4FEFB9F9, $CD94EAA5, $BFAA5069, $A0B8C077,
+    $60D86F57, $FE71C813, $29EBD2C8, $4CA86538, $6BF1A030, $A237B88A, $AA8AF41D,
+    $E1F7B6EC, $E214D953, $33057879, $49CAA736, $FA45CFF3, $C063B411, $BA7E27D0,
+    $31533819, $2A004AC1, $210EFC3F, $2646885E, $66727DCF, $9D7FBF54, $A8DD0EA8,
+    $3447CACE, $3F0C14DB, $B8382AAC, $4ACE3539, $0A518D51, $95178981, $35AEE2CA,
+    $73F0F7E3, $94281140, $59D0E523, $D292CB88, $565D1B27, $7EC8FBAF, $069AF08D,
+    $C127FD24, $0BC77B10, $5F03E7EF, $453E99BA, $EED9FF7F, $87B55215, $7915AB4C,
+    $D389A358, $5E75CE6D, $28D655C0, $DAD26C73, $2E2510FF, $9FA7EECC, $1D0629C3,
+    $DC9C9C46, $2D67ECD7, $E75E94BD, $3D649E2A, $6C413A2B, $706F0D7C, $DFB0127B,
+    $4E366B55, $2C825650, $24205720, $B5C998F7, $3E95462C, $756E5C72, $3259488F,
+    $11E8771A, $A7C0A617, $577663E5, $089B6401, $8EAB1941, $AE55EF8C, $3AAC5460,
+    $D4E6262F, $5D979A47, $B19823B0, $7F8D6A0C, $FFA08683, $0170CD0F, $858CD5D8,
+    $53961C90, $C4C61556, $41F2F226, $CFCD062D, $F24C03B8, $EA81DF5B, $7BE2FA52,
+    $B361F98B, $C2901316, $55BA4BBC, $93B234A9, $0FBC6603, $80A96822, $6D60491F,
+    $22BD00F8, $BCAD5AAD, $52F3F13B, $42FD2B28, $B41DD01C, $C52C93BF, $FC663094,
+    $8F58D100, $43FECC08, $C6331E5D, $E6480F66, $CA847204, $4BDF1DA0, $30CC2EFB,
+    $13E02DEA, $FB49AC45, $F9D4434F, $F47C5B9C, $148879C2, $039FC234, $A3DB9BFC,
+    $D1A1DC5C, $763D7CD4, $ED6D2F93, $AB13AF6E, $1E8E054A, $D68F4F9A, $C30484B3,
+    $D7D50AFA, $6930855F, $CC07DB95, $CE746DB1, $744E967D, $F16CF575, $8643E8B5,
+    $F0EAE38E, $E52DE1D1, $6587DAE0, $0C4B8121, $1C7AC567, $AC0DB20A, $36C3A812,
+    $5B1A4514, $A9A3F868, $B9263BAA, $CB3CE9D2, $E44FB1A4, $9221BC82, $B29390FE,
+    $6AB41863, $974A3E2E, $89F531C5, $255CA13E, $8B65D348, $EC248F78, $D8FC16F0,
+    $50ECDEEE, $09010792, $3C7D1FB2, $EBA5426B, $847B417A, $468B40D9, $8DC4E680,
+    $7CC1F391, $2F1EB086, $6E5BAA6A, $E0B395DA, $E31B2CF6, $D9690B0D, $729EC464,
+    $38403DDE, $610B80A2, $5CF433AB, $B0785FC4, $D512E4C6, $BBB7D699, $5A86591B,
+    $10CF5376, $12BF9F4B, $980FBAA1, $992A4E70, $20FA7AE7, $F7996EBB, $C918A2BE,
+    $82DE74F2, $AD54209B, $F66B4D74, $1FC5B771, $169D9229, $887761DF, $00B667D5,
+    $DB425E59, $B72F2844, $9B0AC1F5, $9C737E3A, $2B85476C, $6722ADD6, $44A63297,
+    $0D688CED), THashLibUInt32Array.Create($ABC59484, $4107778A, $8AD94C6F,
+    $FE83DF90, $0F64053F, $D1292E9D, $C5744356, $8DD1ABB4, $4C4E7667, $FB4A7FC1,
+    $74F402CB, $70F06AFD, $A82286F2, $918DD076, $7A97C5CE, $48F7BDE3, $6A04D11D,
+    $AC243EF7, $33AC10CA, $2F7A341E, $5F75157A, $F4773381, $591C870E, $78DF8CC8,
+    $22F3ADB0, $251A5993, $09FBEF66, $796942A8, $97541D2E, $2373DAA9, $1BD2F142,
+    $B57E8EB2, $E1A5BFDB, $7D0EFA92, $B3442C94, $D2CB6447, $386AC97E, $66D61805,
+    $BDADA15E, $11BC1AA7, $14E9F6EA, $E533A0C0, $F935EE0A, $8FEE8A04, $810D6D85,
+    $7C68B6D6, $4EDC9AA2, $956E897D, $ED87581A, $264BE9D7, $FF4DDB29, $823857C2,
+    $E005A9A0, $F1CC2450, $6F9951E1, $AADE2310, $E70C75F5, $83E1A31F, $4F7DDE8E,
+    $F723B563, $368E0928, $86362B71, $21E8982D, $DFB3F92B, $44676352, $99EFBA31,
+    $2EAB4E1C, $FC6CA5E7, $0EBE5D4E, $A0717D0C, $B64F8199, $946B31A1, $5656CBC6,
+    $CFFEC3EF, $622766C9, $FA211E35, $52F98B89, $6D01674B, $4978A802, $F651F701,
+    $15B0D43D, $D6FF4683, $3463855F, $672BA29C, $BC128312, $4626A70D, $C8927A5A,
+    $B8481CF9, $1C962262, $A21196BA, $BABA5EE9, $5BB162D0, $69943BD1, $0C47E35C,
+    $8CC9619A, $E284D948, $271BF264, $C27FB398, $4BC70897, $60CF202C, $7F42D6AA,
+    $A5A13506, $5D3E8860, $CEA63D3C, $63BF0A8F, $F02E9EFA, $B17B0674, $B072B1D3,
+    $06E5723B, $3737E436, $24AA49C7, $0DED0D18, $DB256B14, $58B27877, $ECB49F54,
+    $6C40256A, $6EA92FFB, $3906AA4C, $C9866FD5, $4549323E, $A7B85FAB, $1918CC27,
+    $7308D7B5, $1E16C7AD, $71850B37, $3095FD78, $A63B70E6, $D880E2AE, $3E282769,
+    $A39BA6BC, $98700FA3, $F34C53E8, $288AF426, $B99D930F, $F5B99DF1, $E9D0C8CF,
+    $5AC8405D, $50E7217B, $511FBBBE, $2CA2E639, $C020301B, $356DBC00, $8E43DDB9,
+    $4D327B4A, $F20FF3ED, $1DBB29BD, $43D44779, $A1B68F70, $6114455B, $E63D280B,
+    $6BF6FF65, $10FC39E5, $3DAE126E, $C1D7CF11, $CB60B795, $1789D5B3, $9BCA36B7,
+    $08306075, $84615608, $8B3A0186, $E88FBECD, $7BA47C4D, $2DE44DAC, $653FE58D,
+    $CCA0B968, $D7FA0E72, $93901780, $1F2C26CC, $AE595B6B, $A9ECEA9B, $E3DBF8C4,
+    $319CC130, $12981196, $01A3A4DE, $32C454B6, $755BD817, $3CD871E4, $A48BB8DA,
+    $02FDEC09, $FD2DC2E2, $9E578088, $9A9F916D, $4065FE6C, $1853999E, $C7793F23,
+    $DC1016BB, $969355FF, $7EF292F6, $CDCE4ADC, $05E24416, $85C16C46, $D441D37F,
+    $57BD6855, $8746F54F, $9CA773DF, $770BAE22, $54828413, $B75E4B19, $04C35C03,
+    $BF7CCA07, $2955C4DD, $721DB041, $B2394F33, $03F51387, $89B73C9F, $0B1737F3,
+    $07E69024, $9231D245, $76193861, $88159C15, $DEB552D9, $D9767E40, $20C6C0C3,
+    $4281977C, $F8AFE1E0, $D32A0751, $3FC27432, $DDF1DCC5, $68581F34, $3BCD5025,
+    $0091B2EE, $4AEB6944, $1602E743, $EA09EB58, $EF0A2A8B, $641E03A5, $EB50E021,
+    $5C8CCEF8, $802FF0B8, $D5E3EDFE, $C4DD1B49, $5334CD2A, $13F82D2F, $47450C20,
+    $55DAFBD2, $BEC0C6F4, $B45D7959, $3AD36E8C, $0AA8AC57, $1A3C8D73, $E45AAFB1,
+    $9F664838, $C6880053, $D0039BBF, $EE5F19EB, $CA0041D8, $BBEA3AAF, $DA628291,
+    $9D5C95D4, $ADD504A6, $C39AB482, $5E9E14A4, $2BE065F0, $2A13FC3A, $9052E8EC,
+    $AF6F5AFC), THashLibUInt32Array.Create($519AA8B5, $BB303DA9, $E00E2B10,
+    $DFA6C1DB, $2E6B952E, $EE10DC23, $37936D09, $1FC42E92, $39B25A9F, $13FF89F4,
+    $C8F53FEA, $18500BC7, $95A0379D, $98F751C2, $2289C42F, $A21E4098, $6F391F41,
+    $F27E7E58, $0D0DF887, $4B79D540, $8E8409AA, $71FE46F8, $688A9B29, $3F08B548,
+    $84ABE03A, $5E91B6C1, $FDE4C2AE, $251D0E72, $92D4FEE5, $F9371967, $9175108F,
+    $E6E81835, $8C8CB8EE, $B55A67B3, $CEF138CC, $8B256268, $00D815F5, $E8810812,
+    $77826189, $EA73267D, $19B90F8D, $45C33BB4, $82477056, $E1770075, $09467AA6,
+    $A7C6F54A, $79768742, $61B86BCA, $D6644A44, $E33F0171, $C229FBCD, $41B08FEB,
+    $D1903E30, $65EC9080, $563D6FBD, $F56DA488, $EBF64CD8, $4934426B, $7C8592FC,
+    $6ACA8CF2, $1CEA111B, $3A57EE7A, $ACE11C0D, $9942D85E, $C4613407, $FA8E643B,
+    $327FC701, $4CA9BE82, $3352526D, $2C047F63, $F3A8F7DD, $1A4A98A8, $762ED4D1,
+    $27C75008, $BDF497C0, $7A7B84DF, $315C28AB, $801F93E3, $F19B0CA1, $8F14E46A,
+    $E48BA333, $9605E625, $F03ECB60, $60385F2D, $902845BA, $7F96D66F, $24BFF05C,
+    $2820730B, $947133CB, $D444828A, $B343F6F1, $0BEF4705, $8DA574F9, $01E25D6C,
+    $1732793E, $4F0F7B27, $364B7117, $B2D1DA77, $A6C5F1E9, $574CA5B1, $386A3076,
+    $AD6894D6, $1156D7FA, $A48D1D9A, $4794C0AF, $150C0AA0, $26D348AC, $29FDEABE,
+    $A5DEDE53, $81671E8E, $594EE3BF, $A96C56E6, $3426A726, $C5976579, $BC22E5E4,
+    $C1006319, $DAAFDD2A, $A1A1AA83, $3BADD0E7, $C3B14981, $D770B155, $CCD7C693,
+    $42E944C5, $03E0064F, $CA95B4EF, $3DEE81C3, $FBBCD98C, $1E07E15B, $667CE949,
+    $E7D6773F, $21B6124B, $6B2A6EF7, $D3278A9C, $9A988304, $75D2AE9B, $FE49E2FF,
+    $9BC24F46, $74CC2CF6, $A3139F36, $6C9EF35A, $9FC1DFFE, $9E5FACDC, $AADC8BBB,
+    $5ABDBC5F, $44B3B390, $F754EFA7, $5FE3BDB7, $4E59C886, $06A4C984, $A0338878,
+    $CD513CD7, $63EBD27E, $8ABA80AD, $50DA144E, $5D9F4E97, $025B751C, $2D580200,
+    $B6C05837, $580AA15D, $54022A6E, $B41A5415, $4863FAB6, $B0B79957, $46D0D159,
+    $DC2B8650, $20A7BB0C, $4A032974, $EC8636A2, $8548F24C, $F6A2BF16, $1088F4B0,
+    $0C2F3A94, $525DC396, $14065785, $2B4DCA52, $08AEED39, $ABEDFC99, $B1DBCF18,
+    $87F85BBC, $AE3AFF61, $433CCD70, $5B23CC64, $7B453213, $5355C545, $9318EC0A,
+    $78692D31, $0A21693D, $D5666814, $05FB59D9, $C71985B2, $2ABB8E0E, $CF6E6C91,
+    $D9CFE7C6, $EFE7132C, $9711AB28, $3CE52732, $12D516D2, $7209A0D0, $D278D306,
+    $70FA4B7B, $1D407DD3, $DB0BEBA4, $BFD97621, $A8BE21E1, $1B6F1B66, $30650DDA,
+    $BA7DDBB9, $7DF953FB, $9D1C3902, $EDF0E8D5, $B8741AE0, $0F240565, $62CD438B,
+    $C616A924, $AF7A96A3, $35365538, $E583AF4D, $73415EB8, $23176A47, $FC9CCEE8,
+    $7EFC9DE2, $695E03CF, $F8CE66D4, $88B4781D, $67DD9C03, $3E8F9E73, $C0C95C51,
+    $BE314D22, $55AA0795, $CB1BB011, $E980FDC8, $9C62B7CE, $DE2D239E, $042CADF3,
+    $FFDF04DE, $5CE6A60F, $D8C831ED, $B7B5B9EC, $B9CBF962, $E253B254, $0735BA1F,
+    $16AC917F, $DD607C2B, $64A335C4, $40159A7C, $869222F0, $6EF21769, $839D20A5,
+    $D03B24C9, $F412601E, $6D72A243, $0E018DFD, $89F3721A, $C94F4134, $2F992F20,
+    $4D87253C));
+
+{$ENDREGION}
+end;
+
+end.

+ 1038 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpTiger.pas

@@ -0,0 +1,1038 @@
+unit HlpTiger;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+{$IFDEF DELPHI}
+  HlpBitConverter,
+  HlpHashBuffer,
+{$ENDIF DELPHI}
+  HlpHashLibTypes,
+  HlpConverters,
+  HlpHashRounds,
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn;
+
+resourcestring
+  SInvalidTigerHashSize =
+    'Tiger HashSize Must be Either 128 bit(16 byte), 160 bit(20 byte) or 192 bit(24 byte)';
+
+type
+  TTiger = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+  strict private
+
+    Fm_rounds: Int32;
+
+{$REGION 'Consts'}
+
+  const
+
+    C1 = UInt64($A5A5A5A5A5A5A5A5);
+    C2 = UInt64($0123456789ABCDEF);
+
+    s_T1: array [0 .. 255] of UInt64 = (UInt64($02AAB17CF7E90C5E),
+      UInt64($AC424B03E243A8EC), UInt64($72CD5BE30DD5FCD3),
+      UInt64($6D019B93F6F97F3A), UInt64($CD9978FFD21F9193),
+      UInt64($7573A1C9708029E2), UInt64($B164326B922A83C3),
+      UInt64($46883EEE04915870), UInt64($EAACE3057103ECE6),
+      UInt64($C54169B808A3535C), UInt64($4CE754918DDEC47C),
+      UInt64($0AA2F4DFDC0DF40C), UInt64($10B76F18A74DBEFA),
+      UInt64($C6CCB6235AD1AB6A), UInt64($13726121572FE2FF),
+      UInt64($1A488C6F199D921E), UInt64($4BC9F9F4DA0007CA),
+      UInt64($26F5E6F6E85241C7), UInt64($859079DBEA5947B6),
+      UInt64($4F1885C5C99E8C92), UInt64($D78E761EA96F864B),
+      UInt64($8E36428C52B5C17D), UInt64($69CF6827373063C1),
+      UInt64($B607C93D9BB4C56E), UInt64($7D820E760E76B5EA),
+      UInt64($645C9CC6F07FDC42), UInt64($BF38A078243342E0),
+      UInt64($5F6B343C9D2E7D04), UInt64($F2C28AEB600B0EC6),
+      UInt64($6C0ED85F7254BCAC), UInt64($71592281A4DB4FE5),
+      UInt64($1967FA69CE0FED9F), UInt64($FD5293F8B96545DB),
+      UInt64($C879E9D7F2A7600B), UInt64($860248920193194E),
+      UInt64($A4F9533B2D9CC0B3), UInt64($9053836C15957613),
+      UInt64($DB6DCF8AFC357BF1), UInt64($18BEEA7A7A370F57),
+      UInt64($037117CA50B99066), UInt64($6AB30A9774424A35),
+      UInt64($F4E92F02E325249B), UInt64($7739DB07061CCAE1),
+      UInt64($D8F3B49CECA42A05), UInt64($BD56BE3F51382F73),
+      UInt64($45FAED5843B0BB28), UInt64($1C813D5C11BF1F83),
+      UInt64($8AF0E4B6D75FA169), UInt64($33EE18A487AD9999),
+      UInt64($3C26E8EAB1C94410), UInt64($B510102BC0A822F9),
+      UInt64($141EEF310CE6123B), UInt64($FC65B90059DDB154),
+      UInt64($E0158640C5E0E607), UInt64($884E079826C3A3CF),
+      UInt64($930D0D9523C535FD), UInt64($35638D754E9A2B00),
+      UInt64($4085FCCF40469DD5), UInt64($C4B17AD28BE23A4C),
+      UInt64($CAB2F0FC6A3E6A2E), UInt64($2860971A6B943FCD),
+      UInt64($3DDE6EE212E30446), UInt64($6222F32AE01765AE),
+      UInt64($5D550BB5478308FE), UInt64($A9EFA98DA0EDA22A),
+      UInt64($C351A71686C40DA7), UInt64($1105586D9C867C84),
+      UInt64($DCFFEE85FDA22853), UInt64($CCFBD0262C5EEF76),
+      UInt64($BAF294CB8990D201), UInt64($E69464F52AFAD975),
+      UInt64($94B013AFDF133E14), UInt64($06A7D1A32823C958),
+      UInt64($6F95FE5130F61119), UInt64($D92AB34E462C06C0),
+      UInt64($ED7BDE33887C71D2), UInt64($79746D6E6518393E),
+      UInt64($5BA419385D713329), UInt64($7C1BA6B948A97564),
+      UInt64($31987C197BFDAC67), UInt64($DE6C23C44B053D02),
+      UInt64($581C49FED002D64D), UInt64($DD474D6338261571),
+      UInt64($AA4546C3E473D062), UInt64($928FCE349455F860),
+      UInt64($48161BBACAAB94D9), UInt64($63912430770E6F68),
+      UInt64($6EC8A5E602C6641C), UInt64($87282515337DDD2B),
+      UInt64($2CDA6B42034B701B), UInt64($B03D37C181CB096D),
+      UInt64($E108438266C71C6F), UInt64($2B3180C7EB51B255),
+      UInt64($DF92B82F96C08BBC), UInt64($5C68C8C0A632F3BA),
+      UInt64($5504CC861C3D0556), UInt64($ABBFA4E55FB26B8F),
+      UInt64($41848B0AB3BACEB4), UInt64($B334A273AA445D32),
+      UInt64($BCA696F0A85AD881), UInt64($24F6EC65B528D56C),
+      UInt64($0CE1512E90F4524A), UInt64($4E9DD79D5506D35A),
+      UInt64($258905FAC6CE9779), UInt64($2019295B3E109B33),
+      UInt64($F8A9478B73A054CC), UInt64($2924F2F934417EB0),
+      UInt64($3993357D536D1BC4), UInt64($38A81AC21DB6FF8B),
+      UInt64($47C4FBF17D6016BF), UInt64($1E0FAADD7667E3F5),
+      UInt64($7ABCFF62938BEB96), UInt64($A78DAD948FC179C9),
+      UInt64($8F1F98B72911E50D), UInt64($61E48EAE27121A91),
+      UInt64($4D62F7AD31859808), UInt64($ECEBA345EF5CEAEB),
+      UInt64($F5CEB25EBC9684CE), UInt64($F633E20CB7F76221),
+      UInt64($A32CDF06AB8293E4), UInt64($985A202CA5EE2CA4),
+      UInt64($CF0B8447CC8A8FB1), UInt64($9F765244979859A3),
+      UInt64($A8D516B1A1240017), UInt64($0BD7BA3EBB5DC726),
+      UInt64($E54BCA55B86ADB39), UInt64($1D7A3AFD6C478063),
+      UInt64($519EC608E7669EDD), UInt64($0E5715A2D149AA23),
+      UInt64($177D4571848FF194), UInt64($EEB55F3241014C22),
+      UInt64($0F5E5CA13A6E2EC2), UInt64($8029927B75F5C361),
+      UInt64($AD139FABC3D6E436), UInt64($0D5DF1A94CCF402F),
+      UInt64($3E8BD948BEA5DFC8), UInt64($A5A0D357BD3FF77E),
+      UInt64($A2D12E251F74F645), UInt64($66FD9E525E81A082),
+      UInt64($2E0C90CE7F687A49), UInt64($C2E8BCBEBA973BC5),
+      UInt64($000001BCE509745F), UInt64($423777BBE6DAB3D6),
+      UInt64($D1661C7EAEF06EB5), UInt64($A1781F354DAACFD8),
+      UInt64($2D11284A2B16AFFC), UInt64($F1FC4F67FA891D1F),
+      UInt64($73ECC25DCB920ADA), UInt64($AE610C22C2A12651),
+      UInt64($96E0A810D356B78A), UInt64($5A9A381F2FE7870F),
+      UInt64($D5AD62EDE94E5530), UInt64($D225E5E8368D1427),
+      UInt64($65977B70C7AF4631), UInt64($99F889B2DE39D74F),
+      UInt64($233F30BF54E1D143), UInt64($9A9675D3D9A63C97),
+      UInt64($5470554FF334F9A8), UInt64($166ACB744A4F5688),
+      UInt64($70C74CAAB2E4AEAD), UInt64($F0D091646F294D12),
+      UInt64($57B82A89684031D1), UInt64($EFD95A5A61BE0B6B),
+      UInt64($2FBD12E969F2F29A), UInt64($9BD37013FEFF9FE8),
+      UInt64($3F9B0404D6085A06), UInt64($4940C1F3166CFE15),
+      UInt64($09542C4DCDF3DEFB), UInt64($B4C5218385CD5CE3),
+      UInt64($C935B7DC4462A641), UInt64($3417F8A68ED3B63F),
+      UInt64($B80959295B215B40), UInt64($F99CDAEF3B8C8572),
+      UInt64($018C0614F8FCB95D), UInt64($1B14ACCD1A3ACDF3),
+      UInt64($84D471F200BB732D), UInt64($C1A3110E95E8DA16),
+      UInt64($430A7220BF1A82B8), UInt64($B77E090D39DF210E),
+      UInt64($5EF4BD9F3CD05E9D), UInt64($9D4FF6DA7E57A444),
+      UInt64($DA1D60E183D4A5F8), UInt64($B287C38417998E47),
+      UInt64($FE3EDC121BB31886), UInt64($C7FE3CCC980CCBEF),
+      UInt64($E46FB590189BFD03), UInt64($3732FD469A4C57DC),
+      UInt64($7EF700A07CF1AD65), UInt64($59C64468A31D8859),
+      UInt64($762FB0B4D45B61F6), UInt64($155BAED099047718),
+      UInt64($68755E4C3D50BAA6), UInt64($E9214E7F22D8B4DF),
+      UInt64($2ADDBF532EAC95F4), UInt64($32AE3909B4BD0109),
+      UInt64($834DF537B08E3450), UInt64($FA209DA84220728D),
+      UInt64($9E691D9B9EFE23F7), UInt64($0446D288C4AE8D7F),
+      UInt64($7B4CC524E169785B), UInt64($21D87F0135CA1385),
+      UInt64($CEBB400F137B8AA5), UInt64($272E2B66580796BE),
+      UInt64($3612264125C2B0DE), UInt64($057702BDAD1EFBB2),
+      UInt64($D4BABB8EACF84BE9), UInt64($91583139641BC67B),
+      UInt64($8BDC2DE08036E024), UInt64($603C8156F49F68ED),
+      UInt64($F7D236F7DBEF5111), UInt64($9727C4598AD21E80),
+      UInt64($A08A0896670A5FD7), UInt64($CB4A8F4309EBA9CB),
+      UInt64($81AF564B0F7036A1), UInt64($C0B99AA778199ABD),
+      UInt64($959F1EC83FC8E952), UInt64($8C505077794A81B9),
+      UInt64($3ACAAF8F056338F0), UInt64($07B43F50627A6778),
+      UInt64($4A44AB49F5ECCC77), UInt64($3BC3D6E4B679EE98),
+      UInt64($9CC0D4D1CF14108C), UInt64($4406C00B206BC8A0),
+      UInt64($82A18854C8D72D89), UInt64($67E366B35C3C432C),
+      UInt64($B923DD61102B37F2), UInt64($56AB2779D884271D),
+      UInt64($BE83E1B0FF1525AF), UInt64($FB7C65D4217E49A9),
+      UInt64($6BDBE0E76D48E7D4), UInt64($08DF828745D9179E),
+      UInt64($22EA6A9ADD53BD34), UInt64($E36E141C5622200A),
+      UInt64($7F805D1B8CB750EE), UInt64($AFE5C7A59F58E837),
+      UInt64($E27F996A4FB1C23C), UInt64($D3867DFB0775F0D0),
+      UInt64($D0E673DE6E88891A), UInt64($123AEB9EAFB86C25),
+      UInt64($30F1D5D5C145B895), UInt64($BB434A2DEE7269E7),
+      UInt64($78CB67ECF931FA38), UInt64($F33B0372323BBF9C),
+      UInt64($52D66336FB279C74), UInt64($505F33AC0AFB4EAA),
+      UInt64($E8A5CD99A2CCE187), UInt64($534974801E2D30BB),
+      UInt64($8D2D5711D5876D90), UInt64($1F1A412891BC038E),
+      UInt64($D6E2E71D82E56648), UInt64($74036C3A497732B7),
+      UInt64($89B67ED96361F5AB), UInt64($FFED95D8F1EA02A2),
+      UInt64($E72B3BD61464D43D), UInt64($A6300F170BDC4820),
+      UInt64($EBC18760ED78A77A));
+
+    s_T2: array [0 .. 255] of UInt64 = (UInt64($E6A6BE5A05A12138),
+      UInt64($B5A122A5B4F87C98), UInt64($563C6089140B6990),
+      UInt64($4C46CB2E391F5DD5), UInt64($D932ADDBC9B79434),
+      UInt64($08EA70E42015AFF5), UInt64($D765A6673E478CF1),
+      UInt64($C4FB757EAB278D99), UInt64($DF11C6862D6E0692),
+      UInt64($DDEB84F10D7F3B16), UInt64($6F2EF604A665EA04),
+      UInt64($4A8E0F0FF0E0DFB3), UInt64($A5EDEEF83DBCBA51),
+      UInt64($FC4F0A2A0EA4371E), UInt64($E83E1DA85CB38429),
+      UInt64($DC8FF882BA1B1CE2), UInt64($CD45505E8353E80D),
+      UInt64($18D19A00D4DB0717), UInt64($34A0CFEDA5F38101),
+      UInt64($0BE77E518887CAF2), UInt64($1E341438B3C45136),
+      UInt64($E05797F49089CCF9), UInt64($FFD23F9DF2591D14),
+      UInt64($543DDA228595C5CD), UInt64($661F81FD99052A33),
+      UInt64($8736E641DB0F7B76), UInt64($15227725418E5307),
+      UInt64($E25F7F46162EB2FA), UInt64($48A8B2126C13D9FE),
+      UInt64($AFDC541792E76EEA), UInt64($03D912BFC6D1898F),
+      UInt64($31B1AAFA1B83F51B), UInt64($F1AC2796E42AB7D9),
+      UInt64($40A3A7D7FCD2EBAC), UInt64($1056136D0AFBBCC5),
+      UInt64($7889E1DD9A6D0C85), UInt64($D33525782A7974AA),
+      UInt64($A7E25D09078AC09B), UInt64($BD4138B3EAC6EDD0),
+      UInt64($920ABFBE71EB9E70), UInt64($A2A5D0F54FC2625C),
+      UInt64($C054E36B0B1290A3), UInt64($F6DD59FF62FE932B),
+      UInt64($3537354511A8AC7D), UInt64($CA845E9172FADCD4),
+      UInt64($84F82B60329D20DC), UInt64($79C62CE1CD672F18),
+      UInt64($8B09A2ADD124642C), UInt64($D0C1E96A19D9E726),
+      UInt64($5A786A9B4BA9500C), UInt64($0E020336634C43F3),
+      UInt64($C17B474AEB66D822), UInt64($6A731AE3EC9BAAC2),
+      UInt64($8226667AE0840258), UInt64($67D4567691CAECA5),
+      UInt64($1D94155C4875ADB5), UInt64($6D00FD985B813FDF),
+      UInt64($51286EFCB774CD06), UInt64($5E8834471FA744AF),
+      UInt64($F72CA0AEE761AE2E), UInt64($BE40E4CDAEE8E09A),
+      UInt64($E9970BBB5118F665), UInt64($726E4BEB33DF1964),
+      UInt64($703B000729199762), UInt64($4631D816F5EF30A7),
+      UInt64($B880B5B51504A6BE), UInt64($641793C37ED84B6C),
+      UInt64($7B21ED77F6E97D96), UInt64($776306312EF96B73),
+      UInt64($AE528948E86FF3F4), UInt64($53DBD7F286A3F8F8),
+      UInt64($16CADCE74CFC1063), UInt64($005C19BDFA52C6DD),
+      UInt64($68868F5D64D46AD3), UInt64($3A9D512CCF1E186A),
+      UInt64($367E62C2385660AE), UInt64($E359E7EA77DCB1D7),
+      UInt64($526C0773749ABE6E), UInt64($735AE5F9D09F734B),
+      UInt64($493FC7CC8A558BA8), UInt64($B0B9C1533041AB45),
+      UInt64($321958BA470A59BD), UInt64($852DB00B5F46C393),
+      UInt64($91209B2BD336B0E5), UInt64($6E604F7D659EF19F),
+      UInt64($B99A8AE2782CCB24), UInt64($CCF52AB6C814C4C7),
+      UInt64($4727D9AFBE11727B), UInt64($7E950D0C0121B34D),
+      UInt64($756F435670AD471F), UInt64($F5ADD442615A6849),
+      UInt64($4E87E09980B9957A), UInt64($2ACFA1DF50AEE355),
+      UInt64($D898263AFD2FD556), UInt64($C8F4924DD80C8FD6),
+      UInt64($CF99CA3D754A173A), UInt64($FE477BACAF91BF3C),
+      UInt64($ED5371F6D690C12D), UInt64($831A5C285E687094),
+      UInt64($C5D3C90A3708A0A4), UInt64($0F7F903717D06580),
+      UInt64($19F9BB13B8FDF27F), UInt64($B1BD6F1B4D502843),
+      UInt64($1C761BA38FFF4012), UInt64($0D1530C4E2E21F3B),
+      UInt64($8943CE69A7372C8A), UInt64($E5184E11FEB5CE66),
+      UInt64($618BDB80BD736621), UInt64($7D29BAD68B574D0B),
+      UInt64($81BB613E25E6FE5B), UInt64($071C9C10BC07913F),
+      UInt64($C7BEEB7909AC2D97), UInt64($C3E58D353BC5D757),
+      UInt64($EB017892F38F61E8), UInt64($D4EFFB9C9B1CC21A),
+      UInt64($99727D26F494F7AB), UInt64($A3E063A2956B3E03),
+      UInt64($9D4A8B9A4AA09C30), UInt64($3F6AB7D500090FB4),
+      UInt64($9CC0F2A057268AC0), UInt64($3DEE9D2DEDBF42D1),
+      UInt64($330F49C87960A972), UInt64($C6B2720287421B41),
+      UInt64($0AC59EC07C00369C), UInt64($EF4EAC49CB353425),
+      UInt64($F450244EEF0129D8), UInt64($8ACC46E5CAF4DEB6),
+      UInt64($2FFEAB63989263F7), UInt64($8F7CB9FE5D7A4578),
+      UInt64($5BD8F7644E634635), UInt64($427A7315BF2DC900),
+      UInt64($17D0C4AA2125261C), UInt64($3992486C93518E50),
+      UInt64($B4CBFEE0A2D7D4C3), UInt64($7C75D6202C5DDD8D),
+      UInt64($DBC295D8E35B6C61), UInt64($60B369D302032B19),
+      UInt64($CE42685FDCE44132), UInt64($06F3DDB9DDF65610),
+      UInt64($8EA4D21DB5E148F0), UInt64($20B0FCE62FCD496F),
+      UInt64($2C1B912358B0EE31), UInt64($B28317B818F5A308),
+      UInt64($A89C1E189CA6D2CF), UInt64($0C6B18576AAADBC8),
+      UInt64($B65DEAA91299FAE3), UInt64($FB2B794B7F1027E7),
+      UInt64($04E4317F443B5BEB), UInt64($4B852D325939D0A6),
+      UInt64($D5AE6BEEFB207FFC), UInt64($309682B281C7D374),
+      UInt64($BAE309A194C3B475), UInt64($8CC3F97B13B49F05),
+      UInt64($98A9422FF8293967), UInt64($244B16B01076FF7C),
+      UInt64($F8BF571C663D67EE), UInt64($1F0D6758EEE30DA1),
+      UInt64($C9B611D97ADEB9B7), UInt64($B7AFD5887B6C57A2),
+      UInt64($6290AE846B984FE1), UInt64($94DF4CDEACC1A5FD),
+      UInt64($058A5BD1C5483AFF), UInt64($63166CC142BA3C37),
+      UInt64($8DB8526EB2F76F40), UInt64($E10880036F0D6D4E),
+      UInt64($9E0523C9971D311D), UInt64($45EC2824CC7CD691),
+      UInt64($575B8359E62382C9), UInt64($FA9E400DC4889995),
+      UInt64($D1823ECB45721568), UInt64($DAFD983B8206082F),
+      UInt64($AA7D29082386A8CB), UInt64($269FCD4403B87588),
+      UInt64($1B91F5F728BDD1E0), UInt64($E4669F39040201F6),
+      UInt64($7A1D7C218CF04ADE), UInt64($65623C29D79CE5CE),
+      UInt64($2368449096C00BB1), UInt64($AB9BF1879DA503BA),
+      UInt64($BC23ECB1A458058E), UInt64($9A58DF01BB401ECC),
+      UInt64($A070E868A85F143D), UInt64($4FF188307DF2239E),
+      UInt64($14D565B41A641183), UInt64($EE13337452701602),
+      UInt64($950E3DCF3F285E09), UInt64($59930254B9C80953),
+      UInt64($3BF299408930DA6D), UInt64($A955943F53691387),
+      UInt64($A15EDECAA9CB8784), UInt64($29142127352BE9A0),
+      UInt64($76F0371FFF4E7AFB), UInt64($0239F450274F2228),
+      UInt64($BB073AF01D5E868B), UInt64($BFC80571C10E96C1),
+      UInt64($D267088568222E23), UInt64($9671A3D48E80B5B0),
+      UInt64($55B5D38AE193BB81), UInt64($693AE2D0A18B04B8),
+      UInt64($5C48B4ECADD5335F), UInt64($FD743B194916A1CA),
+      UInt64($2577018134BE98C4), UInt64($E77987E83C54A4AD),
+      UInt64($28E11014DA33E1B9), UInt64($270CC59E226AA213),
+      UInt64($71495F756D1A5F60), UInt64($9BE853FB60AFEF77),
+      UInt64($ADC786A7F7443DBF), UInt64($0904456173B29A82),
+      UInt64($58BC7A66C232BD5E), UInt64($F306558C673AC8B2),
+      UInt64($41F639C6B6C9772A), UInt64($216DEFE99FDA35DA),
+      UInt64($11640CC71C7BE615), UInt64($93C43694565C5527),
+      UInt64($EA038E6246777839), UInt64($F9ABF3CE5A3E2469),
+      UInt64($741E768D0FD312D2), UInt64($0144B883CED652C6),
+      UInt64($C20B5A5BA33F8552), UInt64($1AE69633C3435A9D),
+      UInt64($97A28CA4088CFDEC), UInt64($8824A43C1E96F420),
+      UInt64($37612FA66EEEA746), UInt64($6B4CB165F9CF0E5A),
+      UInt64($43AA1C06A0ABFB4A), UInt64($7F4DC26FF162796B),
+      UInt64($6CBACC8E54ED9B0F), UInt64($A6B7FFEFD2BB253E),
+      UInt64($2E25BC95B0A29D4F), UInt64($86D6A58BDEF1388C),
+      UInt64($DED74AC576B6F054), UInt64($8030BDBC2B45805D),
+      UInt64($3C81AF70E94D9289), UInt64($3EFF6DDA9E3100DB),
+      UInt64($B38DC39FDFCC8847), UInt64($123885528D17B87E),
+      UInt64($F2DA0ED240B1B642), UInt64($44CEFADCD54BF9A9),
+      UInt64($1312200E433C7EE6), UInt64($9FFCC84F3A78C748),
+      UInt64($F0CD1F72248576BB), UInt64($EC6974053638CFE4),
+      UInt64($2BA7B67C0CEC4E4C), UInt64($AC2F4DF3E5CE32ED),
+      UInt64($CB33D14326EA4C11), UInt64($A4E9044CC77E58BC),
+      UInt64($5F513293D934FCEF), UInt64($5DC9645506E55444),
+      UInt64($50DE418F317DE40A), UInt64($388CB31A69DDE259),
+      UInt64($2DB4A83455820A86), UInt64($9010A91E84711AE9),
+      UInt64($4DF7F0B7B1498371), UInt64($D62A2EABC0977179),
+      UInt64($22FAC097AA8D5C0E));
+
+    s_T3: array [0 .. 255] of UInt64 = (UInt64($F49FCC2FF1DAF39B),
+      UInt64($487FD5C66FF29281), UInt64($E8A30667FCDCA83F),
+      UInt64($2C9B4BE3D2FCCE63), UInt64($DA3FF74B93FBBBC2),
+      UInt64($2FA165D2FE70BA66), UInt64($A103E279970E93D4),
+      UInt64($BECDEC77B0E45E71), UInt64($CFB41E723985E497),
+      UInt64($B70AAA025EF75017), UInt64($D42309F03840B8E0),
+      UInt64($8EFC1AD035898579), UInt64($96C6920BE2B2ABC5),
+      UInt64($66AF4163375A9172), UInt64($2174ABDCCA7127FB),
+      UInt64($B33CCEA64A72FF41), UInt64($F04A4933083066A5),
+      UInt64($8D970ACDD7289AF5), UInt64($8F96E8E031C8C25E),
+      UInt64($F3FEC02276875D47), UInt64($EC7BF310056190DD),
+      UInt64($F5ADB0AEBB0F1491), UInt64($9B50F8850FD58892),
+      UInt64($4975488358B74DE8), UInt64($A3354FF691531C61),
+      UInt64($0702BBE481D2C6EE), UInt64($89FB24057DEDED98),
+      UInt64($AC3075138596E902), UInt64($1D2D3580172772ED),
+      UInt64($EB738FC28E6BC30D), UInt64($5854EF8F63044326),
+      UInt64($9E5C52325ADD3BBE), UInt64($90AA53CF325C4623),
+      UInt64($C1D24D51349DD067), UInt64($2051CFEEA69EA624),
+      UInt64($13220F0A862E7E4F), UInt64($CE39399404E04864),
+      UInt64($D9C42CA47086FCB7), UInt64($685AD2238A03E7CC),
+      UInt64($066484B2AB2FF1DB), UInt64($FE9D5D70EFBF79EC),
+      UInt64($5B13B9DD9C481854), UInt64($15F0D475ED1509AD),
+      UInt64($0BEBCD060EC79851), UInt64($D58C6791183AB7F8),
+      UInt64($D1187C5052F3EEE4), UInt64($C95D1192E54E82FF),
+      UInt64($86EEA14CB9AC6CA2), UInt64($3485BEB153677D5D),
+      UInt64($DD191D781F8C492A), UInt64($F60866BAA784EBF9),
+      UInt64($518F643BA2D08C74), UInt64($8852E956E1087C22),
+      UInt64($A768CB8DC410AE8D), UInt64($38047726BFEC8E1A),
+      UInt64($A67738B4CD3B45AA), UInt64($AD16691CEC0DDE19),
+      UInt64($C6D4319380462E07), UInt64($C5A5876D0BA61938),
+      UInt64($16B9FA1FA58FD840), UInt64($188AB1173CA74F18),
+      UInt64($ABDA2F98C99C021F), UInt64($3E0580AB134AE816),
+      UInt64($5F3B05B773645ABB), UInt64($2501A2BE5575F2F6),
+      UInt64($1B2F74004E7E8BA9), UInt64($1CD7580371E8D953),
+      UInt64($7F6ED89562764E30), UInt64($B15926FF596F003D),
+      UInt64($9F65293DA8C5D6B9), UInt64($6ECEF04DD690F84C),
+      UInt64($4782275FFF33AF88), UInt64($E41433083F820801),
+      UInt64($FD0DFE409A1AF9B5), UInt64($4325A3342CDB396B),
+      UInt64($8AE77E62B301B252), UInt64($C36F9E9F6655615A),
+      UInt64($85455A2D92D32C09), UInt64($F2C7DEA949477485),
+      UInt64($63CFB4C133A39EBA), UInt64($83B040CC6EBC5462),
+      UInt64($3B9454C8FDB326B0), UInt64($56F56A9E87FFD78C),
+      UInt64($2DC2940D99F42BC6), UInt64($98F7DF096B096E2D),
+      UInt64($19A6E01E3AD852BF), UInt64($42A99CCBDBD4B40B),
+      UInt64($A59998AF45E9C559), UInt64($366295E807D93186),
+      UInt64($6B48181BFAA1F773), UInt64($1FEC57E2157A0A1D),
+      UInt64($4667446AF6201AD5), UInt64($E615EBCACFB0F075),
+      UInt64($B8F31F4F68290778), UInt64($22713ED6CE22D11E),
+      UInt64($3057C1A72EC3C93B), UInt64($CB46ACC37C3F1F2F),
+      UInt64($DBB893FD02AAF50E), UInt64($331FD92E600B9FCF),
+      UInt64($A498F96148EA3AD6), UInt64($A8D8426E8B6A83EA),
+      UInt64($A089B274B7735CDC), UInt64($87F6B3731E524A11),
+      UInt64($118808E5CBC96749), UInt64($9906E4C7B19BD394),
+      UInt64($AFED7F7E9B24A20C), UInt64($6509EADEEB3644A7),
+      UInt64($6C1EF1D3E8EF0EDE), UInt64($B9C97D43E9798FB4),
+      UInt64($A2F2D784740C28A3), UInt64($7B8496476197566F),
+      UInt64($7A5BE3E6B65F069D), UInt64($F96330ED78BE6F10),
+      UInt64($EEE60DE77A076A15), UInt64($2B4BEE4AA08B9BD0),
+      UInt64($6A56A63EC7B8894E), UInt64($02121359BA34FEF4),
+      UInt64($4CBF99F8283703FC), UInt64($398071350CAF30C8),
+      UInt64($D0A77A89F017687A), UInt64($F1C1A9EB9E423569),
+      UInt64($8C7976282DEE8199), UInt64($5D1737A5DD1F7ABD),
+      UInt64($4F53433C09A9FA80), UInt64($FA8B0C53DF7CA1D9),
+      UInt64($3FD9DCBC886CCB77), UInt64($C040917CA91B4720),
+      UInt64($7DD00142F9D1DCDF), UInt64($8476FC1D4F387B58),
+      UInt64($23F8E7C5F3316503), UInt64($032A2244E7E37339),
+      UInt64($5C87A5D750F5A74B), UInt64($082B4CC43698992E),
+      UInt64($DF917BECB858F63C), UInt64($3270B8FC5BF86DDA),
+      UInt64($10AE72BB29B5DD76), UInt64($576AC94E7700362B),
+      UInt64($1AD112DAC61EFB8F), UInt64($691BC30EC5FAA427),
+      UInt64($FF246311CC327143), UInt64($3142368E30E53206),
+      UInt64($71380E31E02CA396), UInt64($958D5C960AAD76F1),
+      UInt64($F8D6F430C16DA536), UInt64($C8FFD13F1BE7E1D2),
+      UInt64($7578AE66004DDBE1), UInt64($05833F01067BE646),
+      UInt64($BB34B5AD3BFE586D), UInt64($095F34C9A12B97F0),
+      UInt64($247AB64525D60CA8), UInt64($DCDBC6F3017477D1),
+      UInt64($4A2E14D4DECAD24D), UInt64($BDB5E6D9BE0A1EEB),
+      UInt64($2A7E70F7794301AB), UInt64($DEF42D8A270540FD),
+      UInt64($01078EC0A34C22C1), UInt64($E5DE511AF4C16387),
+      UInt64($7EBB3A52BD9A330A), UInt64($77697857AA7D6435),
+      UInt64($004E831603AE4C32), UInt64($E7A21020AD78E312),
+      UInt64($9D41A70C6AB420F2), UInt64($28E06C18EA1141E6),
+      UInt64($D2B28CBD984F6B28), UInt64($26B75F6C446E9D83),
+      UInt64($BA47568C4D418D7F), UInt64($D80BADBFE6183D8E),
+      UInt64($0E206D7F5F166044), UInt64($E258A43911CBCA3E),
+      UInt64($723A1746B21DC0BC), UInt64($C7CAA854F5D7CDD3),
+      UInt64($7CAC32883D261D9C), UInt64($7690C26423BA942C),
+      UInt64($17E55524478042B8), UInt64($E0BE477656A2389F),
+      UInt64($4D289B5E67AB2DA0), UInt64($44862B9C8FBBFD31),
+      UInt64($B47CC8049D141365), UInt64($822C1B362B91C793),
+      UInt64($4EB14655FB13DFD8), UInt64($1ECBBA0714E2A97B),
+      UInt64($6143459D5CDE5F14), UInt64($53A8FBF1D5F0AC89),
+      UInt64($97EA04D81C5E5B00), UInt64($622181A8D4FDB3F3),
+      UInt64($E9BCD341572A1208), UInt64($1411258643CCE58A),
+      UInt64($9144C5FEA4C6E0A4), UInt64($0D33D06565CF620F),
+      UInt64($54A48D489F219CA1), UInt64($C43E5EAC6D63C821),
+      UInt64($A9728B3A72770DAF), UInt64($D7934E7B20DF87EF),
+      UInt64($E35503B61A3E86E5), UInt64($CAE321FBC819D504),
+      UInt64($129A50B3AC60BFA6), UInt64($CD5E68EA7E9FB6C3),
+      UInt64($B01C90199483B1C7), UInt64($3DE93CD5C295376C),
+      UInt64($AED52EDF2AB9AD13), UInt64($2E60F512C0A07884),
+      UInt64($BC3D86A3E36210C9), UInt64($35269D9B163951CE),
+      UInt64($0C7D6E2AD0CDB5FA), UInt64($59E86297D87F5733),
+      UInt64($298EF221898DB0E7), UInt64($55000029D1A5AA7E),
+      UInt64($8BC08AE1B5061B45), UInt64($C2C31C2B6C92703A),
+      UInt64($94CC596BAF25EF42), UInt64($0A1D73DB22540456),
+      UInt64($04B6A0F9D9C4179A), UInt64($EFFDAFA2AE3D3C60),
+      UInt64($F7C8075BB49496C4), UInt64($9CC5C7141D1CD4E3),
+      UInt64($78BD1638218E5534), UInt64($B2F11568F850246A),
+      UInt64($EDFABCFA9502BC29), UInt64($796CE5F2DA23051B),
+      UInt64($AAE128B0DC93537C), UInt64($3A493DA0EE4B29AE),
+      UInt64($B5DF6B2C416895D7), UInt64($FCABBD25122D7F37),
+      UInt64($70810B58105DC4B1), UInt64($E10FDD37F7882A90),
+      UInt64($524DCAB5518A3F5C), UInt64($3C9E85878451255B),
+      UInt64($4029828119BD34E2), UInt64($74A05B6F5D3CECCB),
+      UInt64($B610021542E13ECA), UInt64($0FF979D12F59E2AC),
+      UInt64($6037DA27E4F9CC50), UInt64($5E92975A0DF1847D),
+      UInt64($D66DE190D3E623FE), UInt64($5032D6B87B568048),
+      UInt64($9A36B7CE8235216E), UInt64($80272A7A24F64B4A),
+      UInt64($93EFED8B8C6916F7), UInt64($37DDBFF44CCE1555),
+      UInt64($4B95DB5D4B99BD25), UInt64($92D3FDA169812FC0),
+      UInt64($FB1A4A9A90660BB6), UInt64($730C196946A4B9B2),
+      UInt64($81E289AA7F49DA68), UInt64($64669A0F83B1A05F),
+      UInt64($27B3FF7D9644F48B), UInt64($CC6B615C8DB675B3),
+      UInt64($674F20B9BCEBBE95), UInt64($6F31238275655982),
+      UInt64($5AE488713E45CF05), UInt64($BF619F9954C21157),
+      UInt64($EABAC46040A8EAE9), UInt64($454C6FE9F2C0C1CD),
+      UInt64($419CF6496412691C), UInt64($D3DC3BEF265B0F70),
+      UInt64($6D0E60F5C3578A9E));
+
+    s_T4: array [0 .. 255] of UInt64 = (UInt64($5B0E608526323C55),
+      UInt64($1A46C1A9FA1B59F5), UInt64($A9E245A17C4C8FFA),
+      UInt64($65CA5159DB2955D7), UInt64($05DB0A76CE35AFC2),
+      UInt64($81EAC77EA9113D45), UInt64($528EF88AB6AC0A0D),
+      UInt64($A09EA253597BE3FF), UInt64($430DDFB3AC48CD56),
+      UInt64($C4B3A67AF45CE46F), UInt64($4ECECFD8FBE2D05E),
+      UInt64($3EF56F10B39935F0), UInt64($0B22D6829CD619C6),
+      UInt64($17FD460A74DF2069), UInt64($6CF8CC8E8510ED40),
+      UInt64($D6C824BF3A6ECAA7), UInt64($61243D581A817049),
+      UInt64($048BACB6BBC163A2), UInt64($D9A38AC27D44CC32),
+      UInt64($7FDDFF5BAAF410AB), UInt64($AD6D495AA804824B),
+      UInt64($E1A6A74F2D8C9F94), UInt64($D4F7851235DEE8E3),
+      UInt64($FD4B7F886540D893), UInt64($247C20042AA4BFDA),
+      UInt64($096EA1C517D1327C), UInt64($D56966B4361A6685),
+      UInt64($277DA5C31221057D), UInt64($94D59893A43ACFF7),
+      UInt64($64F0C51CCDC02281), UInt64($3D33BCC4FF6189DB),
+      UInt64($E005CB184CE66AF1), UInt64($FF5CCD1D1DB99BEA),
+      UInt64($B0B854A7FE42980F), UInt64($7BD46A6A718D4B9F),
+      UInt64($D10FA8CC22A5FD8C), UInt64($D31484952BE4BD31),
+      UInt64($C7FA975FCB243847), UInt64($4886ED1E5846C407),
+      UInt64($28CDDB791EB70B04), UInt64($C2B00BE2F573417F),
+      UInt64($5C9590452180F877), UInt64($7A6BDDFFF370EB00),
+      UInt64($CE509E38D6D9D6A4), UInt64($EBEB0F00647FA702),
+      UInt64($1DCC06CF76606F06), UInt64($E4D9F28BA286FF0A),
+      UInt64($D85A305DC918C262), UInt64($475B1D8732225F54),
+      UInt64($2D4FB51668CCB5FE), UInt64($A679B9D9D72BBA20),
+      UInt64($53841C0D912D43A5), UInt64($3B7EAA48BF12A4E8),
+      UInt64($781E0E47F22F1DDF), UInt64($EFF20CE60AB50973),
+      UInt64($20D261D19DFFB742), UInt64($16A12B03062A2E39),
+      UInt64($1960EB2239650495), UInt64($251C16FED50EB8B8),
+      UInt64($9AC0C330F826016E), UInt64($ED152665953E7671),
+      UInt64($02D63194A6369570), UInt64($5074F08394B1C987),
+      UInt64($70BA598C90B25CE1), UInt64($794A15810B9742F6),
+      UInt64($0D5925E9FCAF8C6C), UInt64($3067716CD868744E),
+      UInt64($910AB077E8D7731B), UInt64($6A61BBDB5AC42F61),
+      UInt64($93513EFBF0851567), UInt64($F494724B9E83E9D5),
+      UInt64($E887E1985C09648D), UInt64($34B1D3C675370CFD),
+      UInt64($DC35E433BC0D255D), UInt64($D0AAB84234131BE0),
+      UInt64($08042A50B48B7EAF), UInt64($9997C4EE44A3AB35),
+      UInt64($829A7B49201799D0), UInt64($263B8307B7C54441),
+      UInt64($752F95F4FD6A6CA6), UInt64($927217402C08C6E5),
+      UInt64($2A8AB754A795D9EE), UInt64($A442F7552F72943D),
+      UInt64($2C31334E19781208), UInt64($4FA98D7CEAEE6291),
+      UInt64($55C3862F665DB309), UInt64($BD0610175D53B1F3),
+      UInt64($46FE6CB840413F27), UInt64($3FE03792DF0CFA59),
+      UInt64($CFE700372EB85E8F), UInt64($A7BE29E7ADBCE118),
+      UInt64($E544EE5CDE8431DD), UInt64($8A781B1B41F1873E),
+      UInt64($A5C94C78A0D2F0E7), UInt64($39412E2877B60728),
+      UInt64($A1265EF3AFC9A62C), UInt64($BCC2770C6A2506C5),
+      UInt64($3AB66DD5DCE1CE12), UInt64($E65499D04A675B37),
+      UInt64($7D8F523481BFD216), UInt64($0F6F64FCEC15F389),
+      UInt64($74EFBE618B5B13C8), UInt64($ACDC82B714273E1D),
+      UInt64($DD40BFE003199D17), UInt64($37E99257E7E061F8),
+      UInt64($FA52626904775AAA), UInt64($8BBBF63A463D56F9),
+      UInt64($F0013F1543A26E64), UInt64($A8307E9F879EC898),
+      UInt64($CC4C27A4150177CC), UInt64($1B432F2CCA1D3348),
+      UInt64($DE1D1F8F9F6FA013), UInt64($606602A047A7DDD6),
+      UInt64($D237AB64CC1CB2C7), UInt64($9B938E7225FCD1D3),
+      UInt64($EC4E03708E0FF476), UInt64($FEB2FBDA3D03C12D),
+      UInt64($AE0BCED2EE43889A), UInt64($22CB8923EBFB4F43),
+      UInt64($69360D013CF7396D), UInt64($855E3602D2D4E022),
+      UInt64($073805BAD01F784C), UInt64($33E17A133852F546),
+      UInt64($DF4874058AC7B638), UInt64($BA92B29C678AA14A),
+      UInt64($0CE89FC76CFAADCD), UInt64($5F9D4E0908339E34),
+      UInt64($F1AFE9291F5923B9), UInt64($6E3480F60F4A265F),
+      UInt64($EEBF3A2AB29B841C), UInt64($E21938A88F91B4AD),
+      UInt64($57DFEFF845C6D3C3), UInt64($2F006B0BF62CAAF2),
+      UInt64($62F479EF6F75EE78), UInt64($11A55AD41C8916A9),
+      UInt64($F229D29084FED453), UInt64($42F1C27B16B000E6),
+      UInt64($2B1F76749823C074), UInt64($4B76ECA3C2745360),
+      UInt64($8C98F463B91691BD), UInt64($14BCC93CF1ADE66A),
+      UInt64($8885213E6D458397), UInt64($8E177DF0274D4711),
+      UInt64($B49B73B5503F2951), UInt64($10168168C3F96B6B),
+      UInt64($0E3D963B63CAB0AE), UInt64($8DFC4B5655A1DB14),
+      UInt64($F789F1356E14DE5C), UInt64($683E68AF4E51DAC1),
+      UInt64($C9A84F9D8D4B0FD9), UInt64($3691E03F52A0F9D1),
+      UInt64($5ED86E46E1878E80), UInt64($3C711A0E99D07150),
+      UInt64($5A0865B20C4E9310), UInt64($56FBFC1FE4F0682E),
+      UInt64($EA8D5DE3105EDF9B), UInt64($71ABFDB12379187A),
+      UInt64($2EB99DE1BEE77B9C), UInt64($21ECC0EA33CF4523),
+      UInt64($59A4D7521805C7A1), UInt64($3896F5EB56AE7C72),
+      UInt64($AA638F3DB18F75DC), UInt64($9F39358DABE9808E),
+      UInt64($B7DEFA91C00B72AC), UInt64($6B5541FD62492D92),
+      UInt64($6DC6DEE8F92E4D5B), UInt64($353F57ABC4BEEA7E),
+      UInt64($735769D6DA5690CE), UInt64($0A234AA642391484),
+      UInt64($F6F9508028F80D9D), UInt64($B8E319A27AB3F215),
+      UInt64($31AD9C1151341A4D), UInt64($773C22A57BEF5805),
+      UInt64($45C7561A07968633), UInt64($F913DA9E249DBE36),
+      UInt64($DA652D9B78A64C68), UInt64($4C27A97F3BC334EF),
+      UInt64($76621220E66B17F4), UInt64($967743899ACD7D0B),
+      UInt64($F3EE5BCAE0ED6782), UInt64($409F753600C879FC),
+      UInt64($06D09A39B5926DB6), UInt64($6F83AEB0317AC588),
+      UInt64($01E6CA4A86381F21), UInt64($66FF3462D19F3025),
+      UInt64($72207C24DDFD3BFB), UInt64($4AF6B6D3E2ECE2EB),
+      UInt64($9C994DBEC7EA08DE), UInt64($49ACE597B09A8BC4),
+      UInt64($B38C4766CF0797BA), UInt64($131B9373C57C2A75),
+      UInt64($B1822CCE61931E58), UInt64($9D7555B909BA1C0C),
+      UInt64($127FAFDD937D11D2), UInt64($29DA3BADC66D92E4),
+      UInt64($A2C1D57154C2ECBC), UInt64($58C5134D82F6FE24),
+      UInt64($1C3AE3515B62274F), UInt64($E907C82E01CB8126),
+      UInt64($F8ED091913E37FCB), UInt64($3249D8F9C80046C9),
+      UInt64($80CF9BEDE388FB63), UInt64($1881539A116CF19E),
+      UInt64($5103F3F76BD52457), UInt64($15B7E6F5AE47F7A8),
+      UInt64($DBD7C6DED47E9CCF), UInt64($44E55C410228BB1A),
+      UInt64($B647D4255EDB4E99), UInt64($5D11882BB8AAFC30),
+      UInt64($F5098BBB29D3212A), UInt64($8FB5EA14E90296B3),
+      UInt64($677B942157DD025A), UInt64($FB58E7C0A390ACB5),
+      UInt64($89D3674C83BD4A01), UInt64($9E2DA4DF4BF3B93B),
+      UInt64($FCC41E328CAB4829), UInt64($03F38C96BA582C52),
+      UInt64($CAD1BDBD7FD85DB2), UInt64($BBB442C16082AE83),
+      UInt64($B95FE86BA5DA9AB0), UInt64($B22E04673771A93F),
+      UInt64($845358C9493152D8), UInt64($BE2A488697B4541E),
+      UInt64($95A2DC2DD38E6966), UInt64($C02C11AC923C852B),
+      UInt64($2388B1990DF2A87B), UInt64($7C8008FA1B4F37BE),
+      UInt64($1F70D0C84D54E503), UInt64($5490ADEC7ECE57D4),
+      UInt64($002B3C27D9063A3A), UInt64($7EAEA3848030A2BF),
+      UInt64($C602326DED2003C0), UInt64($83A7287D69A94086),
+      UInt64($C57A5FCB30F57A8A), UInt64($B56844E479EBE779),
+      UInt64($A373B40F05DCBCE9), UInt64($D71A786E88570EE2),
+      UInt64($879CBACDBDE8F6A0), UInt64($976AD1BCC164A32F),
+      UInt64($AB21E25E9666D78B), UInt64($901063AAE5E5C33C),
+      UInt64($9818B34448698D90), UInt64($E36487AE3E1E8ABB),
+      UInt64($AFBDF931893BDCB4), UInt64($6345A0DC5FBBD519),
+      UInt64($8628FE269B9465CA), UInt64($1E5D01603F9C51EC),
+      UInt64($4DE44006A15049B7), UInt64($BF6C70E5F776CBB1),
+      UInt64($411218F2EF552BED), UInt64($CB0C0708705A36A3),
+      UInt64($E74D14754F986044), UInt64($CD56D9430EA8280E),
+      UInt64($C12591D7535F5065), UInt64($C83223F1720AEF96),
+      UInt64($C3A0396F7363A51F));
+
+{$ENDREGION}
+  strict protected
+    Fm_hash: THashLibUInt64Array;
+
+    constructor Create(a_hash_size: Int32; a_rounds: THashRounds);
+
+    function GetResult(): THashLibByteArray; override;
+    procedure Finish(); override;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    procedure Initialize(); override;
+
+  end;
+
+type
+
+  TTiger_Base = class sealed(TTiger)
+
+  public
+    constructor Create(a_hash_size: Int32; a_rounds: THashRounds);
+
+  end;
+
+type
+
+  TTiger_128 = class sealed(TTiger)
+
+  public
+    constructor CreateRound3();
+    constructor CreateRound4();
+    constructor CreateRound5();
+
+  end;
+
+type
+
+  TTiger_160 = class sealed(TTiger)
+
+  public
+    constructor CreateRound3();
+    constructor CreateRound4();
+    constructor CreateRound5();
+
+  end;
+
+type
+  TTiger_192 = class sealed(TTiger)
+
+  public
+    constructor CreateRound3();
+    constructor CreateRound4();
+    constructor CreateRound5();
+
+  end;
+
+implementation
+
+{ TTiger }
+
+constructor TTiger.Create(a_hash_size: Int32; a_rounds: THashRounds);
+begin
+  Inherited Create(a_hash_size, 64);
+  System.SetLength(Fm_hash, 3);
+  Fm_rounds := Int32(a_rounds);
+end;
+
+procedure TTiger.Finish;
+var
+  bits: UInt64;
+  padindex: Int32;
+  pad: THashLibByteArray;
+
+begin
+  bits := Fm_processed_bytes * 8;
+  if Fm_buffer.Pos < 56 then
+    padindex := 56 - Fm_buffer.Pos
+  else
+    padindex := 120 - Fm_buffer.Pos;
+  System.SetLength(pad, padindex + 8);
+
+  pad[0] := 1;
+
+  bits := TConverters.le2me_64(bits);
+
+  TConverters.ReadUInt64AsBytesLE(bits, pad, padindex);
+
+  padindex := padindex + 8;
+
+  TransformBytes(pad, 0, padindex);
+
+end;
+
+function TTiger.GetResult: THashLibByteArray;
+begin
+  System.SetLength(result, HashSize);
+  TConverters.le64_copy(PUInt64(Fm_hash), 0, PByte(result), 0,
+    System.Length(result));
+end;
+
+procedure TTiger.Initialize;
+begin
+
+  Fm_hash[0] := $0123456789ABCDEF;
+  Fm_hash[1] := UInt64($FEDCBA9876543210);
+  Fm_hash[2] := UInt64($F096A5B4C3B2E187);
+
+  Inherited Initialize();
+
+end;
+
+procedure TTiger.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  a, b, c, temp_a: UInt64;
+  rounds: Int32;
+  data: array [0 .. 7] of UInt64;
+begin
+
+  TConverters.le64_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+
+  a := Fm_hash[0];
+  b := Fm_hash[1];
+  c := Fm_hash[2];
+
+  c := c xor data[0];
+  a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+    ] xor s_T4[Byte(c shr 48)]);
+  b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+    ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+  b := b * 5;
+
+  a := a xor data[1];
+  b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+    ] xor s_T4[Byte(a shr 48)]);
+  c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2[Byte(a shr 40)
+    ] xor s_T1[Byte(a shr 56)]);
+  c := c * 5;
+
+  b := b xor data[2];
+  c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+    ] xor s_T4[Byte(b shr 48)]);
+  a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2[Byte(b shr 40)
+    ] xor s_T1[Byte(b shr 56)]);
+  a := a * 5;
+
+  c := c xor data[3];
+  a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+    ] xor s_T4[Byte(c shr 48)]);
+  b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+    ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+  b := b * 5;
+
+  a := a xor data[4];
+  b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+    ] xor s_T4[Byte(a shr 48)]);
+  c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2[Byte(a shr 40)
+    ] xor s_T1[Byte(a shr 56)]);
+  c := c * 5;
+
+  b := b xor data[5];
+  c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+    ] xor s_T4[Byte(b shr 48)]);
+  a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2[Byte(b shr 40)
+    ] xor s_T1[Byte(b shr 56)]);
+  a := a * 5;
+
+  c := c xor data[6];
+  a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+    ] xor s_T4[Byte(c shr 48)]);
+  b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+    ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+  b := b * 5;
+
+  a := a xor data[7];
+  b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+    ] xor s_T4[Byte(a shr 48)]);
+  c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2[Byte(a shr 40)
+    ] xor s_T1[Byte(a shr 56)]);
+  c := c * 5;
+
+  data[0] := data[0] - (data[7] xor C1);
+  data[1] := data[1] xor data[0];
+  data[2] := data[2] + data[1];
+  data[3] := data[3] - (data[2] xor (not data[1] shl 19));
+  data[4] := data[4] xor data[3];
+  data[5] := data[5] + data[4];
+  data[6] := data[6] - (data[5] xor (not data[4] shr 23));
+  data[7] := data[7] xor data[6];
+  data[0] := data[0] + data[7];
+  data[1] := data[1] - (data[0] xor (not data[7] shl 19));
+  data[2] := data[2] xor data[1];
+  data[3] := data[3] + data[2];
+  data[4] := data[4] - (data[3] xor (not data[2] shr 23));
+  data[5] := data[5] xor data[4];
+  data[6] := data[6] + data[5];
+  data[7] := data[7] - (data[6] xor C2);
+
+  b := b xor data[0];
+  c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+    ] xor s_T4[Byte(b shr 48)]);
+  a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2[Byte(b shr 40)
+    ] xor s_T1[Byte(b shr 56)]);
+  a := a * 7;
+
+  c := c xor data[1];
+  a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+    ] xor s_T4[Byte(c shr 48)]);
+  b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+    ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+  b := b * 7;
+
+  a := a xor data[2];
+  b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+    ] xor s_T4[Byte(a shr 48)]);
+  c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2[Byte(a shr 40)
+    ] xor s_T1[Byte(a shr 56)]);
+  c := c * 7;
+
+  b := b xor data[3];
+  c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+    ] xor s_T4[Byte(b shr 48)]);
+  a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2[Byte(b shr 40)
+    ] xor s_T1[Byte(b shr 56)]);
+  a := a * 7;
+
+  c := c xor data[4];
+  a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+    ] xor s_T4[Byte(c shr 48)]);
+  b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+    ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+  b := b * 7;
+
+  a := a xor data[5];
+  b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+    ] xor s_T4[Byte(a shr 48)]);
+  c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2[Byte(a shr 40)
+    ] xor s_T1[Byte(a shr 56)]);
+  c := c * 7;
+
+  b := b xor data[6];
+  c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+    ] xor s_T4[Byte(b shr 48)]);
+  a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2[Byte(b shr 40)
+    ] xor s_T1[Byte(b shr 56)]);
+  a := a * 7;
+
+  c := c xor data[7];
+  a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+    ] xor s_T4[Byte(c shr 48)]);
+  b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+    ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+  b := b * 7;
+
+  data[0] := data[0] - (data[7] xor C1);
+  data[1] := data[1] xor data[0];
+  data[2] := data[2] + data[1];
+  data[3] := data[3] - (data[2] xor (not data[1] shl 19));
+  data[4] := data[4] xor data[3];
+  data[5] := data[5] + data[4];
+  data[6] := data[6] - (data[5] xor (not data[4] shr 23));
+  data[7] := data[7] xor data[6];
+  data[0] := data[0] + data[7];
+  data[1] := data[1] - (data[0] xor (not data[7] shl 19));
+  data[2] := data[2] xor data[1];
+  data[3] := data[3] + data[2];
+  data[4] := data[4] - (data[3] xor (not data[2] shr 23));
+  data[5] := data[5] xor data[4];
+  data[6] := data[6] + data[5];
+  data[7] := data[7] - (data[6] xor C2);
+
+  a := a xor data[0];
+  b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+    ] xor s_T4[Byte(a shr 48)]);
+  c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2[Byte(a shr 40)
+    ] xor s_T1[Byte(a shr 56)]);
+  c := c * 9;
+
+  b := b xor data[1];
+  c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+    ] xor s_T4[Byte(b shr 48)]);
+  a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2[Byte(b shr 40)
+    ] xor s_T1[Byte(b shr 56)]);
+  a := a * 9;
+
+  c := c xor data[2];
+  a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+    ] xor s_T4[Byte(c shr 48)]);
+  b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+    ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+  b := b * 9;
+
+  a := a xor data[3];
+  b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+    ] xor s_T4[Byte(a shr 48)]);
+  c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2[Byte(a shr 40)
+    ] xor s_T1[Byte(a shr 56)]);
+  c := c * 9;
+
+  b := b xor data[4];
+  c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+    ] xor s_T4[Byte(b shr 48)]);
+  a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2[Byte(b shr 40)
+    ] xor s_T1[Byte(b shr 56)]);
+  a := a * 9;
+
+  c := c xor data[5];
+  a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+    ] xor s_T4[Byte(c shr 48)]);
+  b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+    ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+  b := b * 9;
+
+  a := a xor data[6];
+  b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+    ] xor s_T4[Byte(a shr 48)]);
+  c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2[Byte(a shr 40)
+    ] xor s_T1[Byte(a shr 56)]);
+  c := c * 9;
+
+  b := b xor data[7];
+  c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+    ] xor s_T4[Byte(b shr 48)]);
+  a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2[Byte(b shr 40)
+    ] xor s_T1[Byte(b shr 56)]);
+  a := a * 9;
+
+  rounds := 3;
+  while rounds < Fm_rounds do
+  begin
+
+    data[0] := data[0] - (data[7] xor C1);
+    data[1] := data[1] xor data[0];
+    data[2] := data[2] + data[1];
+    data[3] := data[3] - (data[2] xor (not data[1] shl 19));
+    data[4] := data[4] xor data[3];
+    data[5] := data[5] + data[4];
+    data[6] := data[6] - (data[5] xor (not data[4] shr 23));
+    data[7] := data[7] xor data[6];
+    data[0] := data[0] + data[7];
+    data[1] := data[1] - (data[0] xor (not data[7] shl 19));
+    data[2] := data[2] xor data[1];
+    data[3] := data[3] + data[2];
+    data[4] := data[4] - (data[3] xor (not data[2] shr 23));
+    data[5] := data[5] xor data[4];
+    data[6] := data[6] + data[5];
+    data[7] := data[7] - (data[6] xor C2);
+
+    c := c xor data[0];
+    a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+      ] xor s_T4[Byte(c shr 48)]);
+    b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+      ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+    b := b * 9;
+
+    a := a xor data[1];
+    b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+      ] xor s_T4[Byte(a shr 48)]);
+    c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2
+      [Byte(a shr 40)] xor s_T1[Byte(a shr 56)]);
+    c := c * 9;
+
+    b := b xor data[2];
+    c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+      ] xor s_T4[Byte(b shr 48)]);
+    a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2
+      [Byte(b shr 40)] xor s_T1[Byte(b shr 56)]);
+    a := a * 9;
+
+    c := c xor data[3];
+    a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+      ] xor s_T4[Byte(c shr 48)]);
+    b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+      ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+    b := b * 9;
+
+    a := a xor data[4];
+    b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+      ] xor s_T4[Byte(a shr 48)]);
+    c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2
+      [Byte(a shr 40)] xor s_T1[Byte(a shr 56)]);
+    c := c * 9;
+
+    b := b xor data[5];
+    c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+      ] xor s_T4[Byte(b shr 48)]);
+    a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2
+      [Byte(b shr 40)] xor s_T1[Byte(b shr 56)]);
+    a := a * 9;
+
+    c := c xor data[6];
+    a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+      ] xor s_T4[Byte(c shr 48)]);
+    b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+      ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+    b := b * 9;
+
+    a := a xor data[7];
+    b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+      ] xor s_T4[Byte(a shr 48)]);
+    c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2
+      [Byte(a shr 40)] xor s_T1[Byte(a shr 56)]);
+    c := c * 9;
+
+    temp_a := a;
+    a := c;
+    c := b;
+    b := temp_a;
+
+    System.Inc(rounds);
+  end;
+
+  Fm_hash[0] := Fm_hash[0] xor a;
+  Fm_hash[1] := b - Fm_hash[1];
+  Fm_hash[2] := Fm_hash[2] + c;
+
+  System.FillChar(data, System.SizeOf(data), 0);
+
+end;
+
+{ TTiger_128 }
+
+constructor TTiger_128.CreateRound3;
+begin
+  Inherited Create(16, THashRounds.hrRounds3);
+end;
+
+constructor TTiger_128.CreateRound4;
+begin
+  Inherited Create(16, THashRounds.hrRounds4);
+end;
+
+constructor TTiger_128.CreateRound5;
+begin
+  Inherited Create(16, THashRounds.hrRounds5);
+end;
+
+{ TTiger_160 }
+
+constructor TTiger_160.CreateRound3;
+begin
+  Inherited Create(20, THashRounds.hrRounds3);
+end;
+
+constructor TTiger_160.CreateRound4;
+begin
+  Inherited Create(20, THashRounds.hrRounds4);
+end;
+
+constructor TTiger_160.CreateRound5;
+begin
+  Inherited Create(20, THashRounds.hrRounds5);
+end;
+
+{ TTiger_192 }
+
+constructor TTiger_192.CreateRound3;
+begin
+  Inherited Create(24, THashRounds.hrRounds3);
+end;
+
+constructor TTiger_192.CreateRound4;
+begin
+  Inherited Create(24, THashRounds.hrRounds4);
+end;
+
+constructor TTiger_192.CreateRound5;
+begin
+  Inherited Create(24, THashRounds.hrRounds5);
+end;
+
+{ TTiger_Base }
+
+constructor TTiger_Base.Create(a_hash_size: Int32; a_rounds: THashRounds);
+begin
+  Inherited Create(a_hash_size, a_rounds);
+end;
+
+end.

+ 1038 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpTiger2.pas

@@ -0,0 +1,1038 @@
+unit HlpTiger2;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+  HlpHashBuffer,
+{$ENDIF DELPHI}
+  HlpConverters,
+  HlpHashRounds,
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn;
+
+resourcestring
+  SInvalidTiger2HashSize =
+    'Tiger2 HashSize Must be Either 128 bit(16 byte), 160 bit(20 byte) or 192 bit(24 byte)';
+
+type
+  TTiger2 = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+  strict private
+
+    Fm_rounds: Int32;
+
+{$REGION 'Consts'}
+
+  const
+
+    C1 = UInt64($A5A5A5A5A5A5A5A5);
+    C2 = UInt64($0123456789ABCDEF);
+
+    s_T1: array [0 .. 255] of UInt64 = (UInt64($02AAB17CF7E90C5E),
+      UInt64($AC424B03E243A8EC), UInt64($72CD5BE30DD5FCD3),
+      UInt64($6D019B93F6F97F3A), UInt64($CD9978FFD21F9193),
+      UInt64($7573A1C9708029E2), UInt64($B164326B922A83C3),
+      UInt64($46883EEE04915870), UInt64($EAACE3057103ECE6),
+      UInt64($C54169B808A3535C), UInt64($4CE754918DDEC47C),
+      UInt64($0AA2F4DFDC0DF40C), UInt64($10B76F18A74DBEFA),
+      UInt64($C6CCB6235AD1AB6A), UInt64($13726121572FE2FF),
+      UInt64($1A488C6F199D921E), UInt64($4BC9F9F4DA0007CA),
+      UInt64($26F5E6F6E85241C7), UInt64($859079DBEA5947B6),
+      UInt64($4F1885C5C99E8C92), UInt64($D78E761EA96F864B),
+      UInt64($8E36428C52B5C17D), UInt64($69CF6827373063C1),
+      UInt64($B607C93D9BB4C56E), UInt64($7D820E760E76B5EA),
+      UInt64($645C9CC6F07FDC42), UInt64($BF38A078243342E0),
+      UInt64($5F6B343C9D2E7D04), UInt64($F2C28AEB600B0EC6),
+      UInt64($6C0ED85F7254BCAC), UInt64($71592281A4DB4FE5),
+      UInt64($1967FA69CE0FED9F), UInt64($FD5293F8B96545DB),
+      UInt64($C879E9D7F2A7600B), UInt64($860248920193194E),
+      UInt64($A4F9533B2D9CC0B3), UInt64($9053836C15957613),
+      UInt64($DB6DCF8AFC357BF1), UInt64($18BEEA7A7A370F57),
+      UInt64($037117CA50B99066), UInt64($6AB30A9774424A35),
+      UInt64($F4E92F02E325249B), UInt64($7739DB07061CCAE1),
+      UInt64($D8F3B49CECA42A05), UInt64($BD56BE3F51382F73),
+      UInt64($45FAED5843B0BB28), UInt64($1C813D5C11BF1F83),
+      UInt64($8AF0E4B6D75FA169), UInt64($33EE18A487AD9999),
+      UInt64($3C26E8EAB1C94410), UInt64($B510102BC0A822F9),
+      UInt64($141EEF310CE6123B), UInt64($FC65B90059DDB154),
+      UInt64($E0158640C5E0E607), UInt64($884E079826C3A3CF),
+      UInt64($930D0D9523C535FD), UInt64($35638D754E9A2B00),
+      UInt64($4085FCCF40469DD5), UInt64($C4B17AD28BE23A4C),
+      UInt64($CAB2F0FC6A3E6A2E), UInt64($2860971A6B943FCD),
+      UInt64($3DDE6EE212E30446), UInt64($6222F32AE01765AE),
+      UInt64($5D550BB5478308FE), UInt64($A9EFA98DA0EDA22A),
+      UInt64($C351A71686C40DA7), UInt64($1105586D9C867C84),
+      UInt64($DCFFEE85FDA22853), UInt64($CCFBD0262C5EEF76),
+      UInt64($BAF294CB8990D201), UInt64($E69464F52AFAD975),
+      UInt64($94B013AFDF133E14), UInt64($06A7D1A32823C958),
+      UInt64($6F95FE5130F61119), UInt64($D92AB34E462C06C0),
+      UInt64($ED7BDE33887C71D2), UInt64($79746D6E6518393E),
+      UInt64($5BA419385D713329), UInt64($7C1BA6B948A97564),
+      UInt64($31987C197BFDAC67), UInt64($DE6C23C44B053D02),
+      UInt64($581C49FED002D64D), UInt64($DD474D6338261571),
+      UInt64($AA4546C3E473D062), UInt64($928FCE349455F860),
+      UInt64($48161BBACAAB94D9), UInt64($63912430770E6F68),
+      UInt64($6EC8A5E602C6641C), UInt64($87282515337DDD2B),
+      UInt64($2CDA6B42034B701B), UInt64($B03D37C181CB096D),
+      UInt64($E108438266C71C6F), UInt64($2B3180C7EB51B255),
+      UInt64($DF92B82F96C08BBC), UInt64($5C68C8C0A632F3BA),
+      UInt64($5504CC861C3D0556), UInt64($ABBFA4E55FB26B8F),
+      UInt64($41848B0AB3BACEB4), UInt64($B334A273AA445D32),
+      UInt64($BCA696F0A85AD881), UInt64($24F6EC65B528D56C),
+      UInt64($0CE1512E90F4524A), UInt64($4E9DD79D5506D35A),
+      UInt64($258905FAC6CE9779), UInt64($2019295B3E109B33),
+      UInt64($F8A9478B73A054CC), UInt64($2924F2F934417EB0),
+      UInt64($3993357D536D1BC4), UInt64($38A81AC21DB6FF8B),
+      UInt64($47C4FBF17D6016BF), UInt64($1E0FAADD7667E3F5),
+      UInt64($7ABCFF62938BEB96), UInt64($A78DAD948FC179C9),
+      UInt64($8F1F98B72911E50D), UInt64($61E48EAE27121A91),
+      UInt64($4D62F7AD31859808), UInt64($ECEBA345EF5CEAEB),
+      UInt64($F5CEB25EBC9684CE), UInt64($F633E20CB7F76221),
+      UInt64($A32CDF06AB8293E4), UInt64($985A202CA5EE2CA4),
+      UInt64($CF0B8447CC8A8FB1), UInt64($9F765244979859A3),
+      UInt64($A8D516B1A1240017), UInt64($0BD7BA3EBB5DC726),
+      UInt64($E54BCA55B86ADB39), UInt64($1D7A3AFD6C478063),
+      UInt64($519EC608E7669EDD), UInt64($0E5715A2D149AA23),
+      UInt64($177D4571848FF194), UInt64($EEB55F3241014C22),
+      UInt64($0F5E5CA13A6E2EC2), UInt64($8029927B75F5C361),
+      UInt64($AD139FABC3D6E436), UInt64($0D5DF1A94CCF402F),
+      UInt64($3E8BD948BEA5DFC8), UInt64($A5A0D357BD3FF77E),
+      UInt64($A2D12E251F74F645), UInt64($66FD9E525E81A082),
+      UInt64($2E0C90CE7F687A49), UInt64($C2E8BCBEBA973BC5),
+      UInt64($000001BCE509745F), UInt64($423777BBE6DAB3D6),
+      UInt64($D1661C7EAEF06EB5), UInt64($A1781F354DAACFD8),
+      UInt64($2D11284A2B16AFFC), UInt64($F1FC4F67FA891D1F),
+      UInt64($73ECC25DCB920ADA), UInt64($AE610C22C2A12651),
+      UInt64($96E0A810D356B78A), UInt64($5A9A381F2FE7870F),
+      UInt64($D5AD62EDE94E5530), UInt64($D225E5E8368D1427),
+      UInt64($65977B70C7AF4631), UInt64($99F889B2DE39D74F),
+      UInt64($233F30BF54E1D143), UInt64($9A9675D3D9A63C97),
+      UInt64($5470554FF334F9A8), UInt64($166ACB744A4F5688),
+      UInt64($70C74CAAB2E4AEAD), UInt64($F0D091646F294D12),
+      UInt64($57B82A89684031D1), UInt64($EFD95A5A61BE0B6B),
+      UInt64($2FBD12E969F2F29A), UInt64($9BD37013FEFF9FE8),
+      UInt64($3F9B0404D6085A06), UInt64($4940C1F3166CFE15),
+      UInt64($09542C4DCDF3DEFB), UInt64($B4C5218385CD5CE3),
+      UInt64($C935B7DC4462A641), UInt64($3417F8A68ED3B63F),
+      UInt64($B80959295B215B40), UInt64($F99CDAEF3B8C8572),
+      UInt64($018C0614F8FCB95D), UInt64($1B14ACCD1A3ACDF3),
+      UInt64($84D471F200BB732D), UInt64($C1A3110E95E8DA16),
+      UInt64($430A7220BF1A82B8), UInt64($B77E090D39DF210E),
+      UInt64($5EF4BD9F3CD05E9D), UInt64($9D4FF6DA7E57A444),
+      UInt64($DA1D60E183D4A5F8), UInt64($B287C38417998E47),
+      UInt64($FE3EDC121BB31886), UInt64($C7FE3CCC980CCBEF),
+      UInt64($E46FB590189BFD03), UInt64($3732FD469A4C57DC),
+      UInt64($7EF700A07CF1AD65), UInt64($59C64468A31D8859),
+      UInt64($762FB0B4D45B61F6), UInt64($155BAED099047718),
+      UInt64($68755E4C3D50BAA6), UInt64($E9214E7F22D8B4DF),
+      UInt64($2ADDBF532EAC95F4), UInt64($32AE3909B4BD0109),
+      UInt64($834DF537B08E3450), UInt64($FA209DA84220728D),
+      UInt64($9E691D9B9EFE23F7), UInt64($0446D288C4AE8D7F),
+      UInt64($7B4CC524E169785B), UInt64($21D87F0135CA1385),
+      UInt64($CEBB400F137B8AA5), UInt64($272E2B66580796BE),
+      UInt64($3612264125C2B0DE), UInt64($057702BDAD1EFBB2),
+      UInt64($D4BABB8EACF84BE9), UInt64($91583139641BC67B),
+      UInt64($8BDC2DE08036E024), UInt64($603C8156F49F68ED),
+      UInt64($F7D236F7DBEF5111), UInt64($9727C4598AD21E80),
+      UInt64($A08A0896670A5FD7), UInt64($CB4A8F4309EBA9CB),
+      UInt64($81AF564B0F7036A1), UInt64($C0B99AA778199ABD),
+      UInt64($959F1EC83FC8E952), UInt64($8C505077794A81B9),
+      UInt64($3ACAAF8F056338F0), UInt64($07B43F50627A6778),
+      UInt64($4A44AB49F5ECCC77), UInt64($3BC3D6E4B679EE98),
+      UInt64($9CC0D4D1CF14108C), UInt64($4406C00B206BC8A0),
+      UInt64($82A18854C8D72D89), UInt64($67E366B35C3C432C),
+      UInt64($B923DD61102B37F2), UInt64($56AB2779D884271D),
+      UInt64($BE83E1B0FF1525AF), UInt64($FB7C65D4217E49A9),
+      UInt64($6BDBE0E76D48E7D4), UInt64($08DF828745D9179E),
+      UInt64($22EA6A9ADD53BD34), UInt64($E36E141C5622200A),
+      UInt64($7F805D1B8CB750EE), UInt64($AFE5C7A59F58E837),
+      UInt64($E27F996A4FB1C23C), UInt64($D3867DFB0775F0D0),
+      UInt64($D0E673DE6E88891A), UInt64($123AEB9EAFB86C25),
+      UInt64($30F1D5D5C145B895), UInt64($BB434A2DEE7269E7),
+      UInt64($78CB67ECF931FA38), UInt64($F33B0372323BBF9C),
+      UInt64($52D66336FB279C74), UInt64($505F33AC0AFB4EAA),
+      UInt64($E8A5CD99A2CCE187), UInt64($534974801E2D30BB),
+      UInt64($8D2D5711D5876D90), UInt64($1F1A412891BC038E),
+      UInt64($D6E2E71D82E56648), UInt64($74036C3A497732B7),
+      UInt64($89B67ED96361F5AB), UInt64($FFED95D8F1EA02A2),
+      UInt64($E72B3BD61464D43D), UInt64($A6300F170BDC4820),
+      UInt64($EBC18760ED78A77A));
+
+    s_T2: array [0 .. 255] of UInt64 = (UInt64($E6A6BE5A05A12138),
+      UInt64($B5A122A5B4F87C98), UInt64($563C6089140B6990),
+      UInt64($4C46CB2E391F5DD5), UInt64($D932ADDBC9B79434),
+      UInt64($08EA70E42015AFF5), UInt64($D765A6673E478CF1),
+      UInt64($C4FB757EAB278D99), UInt64($DF11C6862D6E0692),
+      UInt64($DDEB84F10D7F3B16), UInt64($6F2EF604A665EA04),
+      UInt64($4A8E0F0FF0E0DFB3), UInt64($A5EDEEF83DBCBA51),
+      UInt64($FC4F0A2A0EA4371E), UInt64($E83E1DA85CB38429),
+      UInt64($DC8FF882BA1B1CE2), UInt64($CD45505E8353E80D),
+      UInt64($18D19A00D4DB0717), UInt64($34A0CFEDA5F38101),
+      UInt64($0BE77E518887CAF2), UInt64($1E341438B3C45136),
+      UInt64($E05797F49089CCF9), UInt64($FFD23F9DF2591D14),
+      UInt64($543DDA228595C5CD), UInt64($661F81FD99052A33),
+      UInt64($8736E641DB0F7B76), UInt64($15227725418E5307),
+      UInt64($E25F7F46162EB2FA), UInt64($48A8B2126C13D9FE),
+      UInt64($AFDC541792E76EEA), UInt64($03D912BFC6D1898F),
+      UInt64($31B1AAFA1B83F51B), UInt64($F1AC2796E42AB7D9),
+      UInt64($40A3A7D7FCD2EBAC), UInt64($1056136D0AFBBCC5),
+      UInt64($7889E1DD9A6D0C85), UInt64($D33525782A7974AA),
+      UInt64($A7E25D09078AC09B), UInt64($BD4138B3EAC6EDD0),
+      UInt64($920ABFBE71EB9E70), UInt64($A2A5D0F54FC2625C),
+      UInt64($C054E36B0B1290A3), UInt64($F6DD59FF62FE932B),
+      UInt64($3537354511A8AC7D), UInt64($CA845E9172FADCD4),
+      UInt64($84F82B60329D20DC), UInt64($79C62CE1CD672F18),
+      UInt64($8B09A2ADD124642C), UInt64($D0C1E96A19D9E726),
+      UInt64($5A786A9B4BA9500C), UInt64($0E020336634C43F3),
+      UInt64($C17B474AEB66D822), UInt64($6A731AE3EC9BAAC2),
+      UInt64($8226667AE0840258), UInt64($67D4567691CAECA5),
+      UInt64($1D94155C4875ADB5), UInt64($6D00FD985B813FDF),
+      UInt64($51286EFCB774CD06), UInt64($5E8834471FA744AF),
+      UInt64($F72CA0AEE761AE2E), UInt64($BE40E4CDAEE8E09A),
+      UInt64($E9970BBB5118F665), UInt64($726E4BEB33DF1964),
+      UInt64($703B000729199762), UInt64($4631D816F5EF30A7),
+      UInt64($B880B5B51504A6BE), UInt64($641793C37ED84B6C),
+      UInt64($7B21ED77F6E97D96), UInt64($776306312EF96B73),
+      UInt64($AE528948E86FF3F4), UInt64($53DBD7F286A3F8F8),
+      UInt64($16CADCE74CFC1063), UInt64($005C19BDFA52C6DD),
+      UInt64($68868F5D64D46AD3), UInt64($3A9D512CCF1E186A),
+      UInt64($367E62C2385660AE), UInt64($E359E7EA77DCB1D7),
+      UInt64($526C0773749ABE6E), UInt64($735AE5F9D09F734B),
+      UInt64($493FC7CC8A558BA8), UInt64($B0B9C1533041AB45),
+      UInt64($321958BA470A59BD), UInt64($852DB00B5F46C393),
+      UInt64($91209B2BD336B0E5), UInt64($6E604F7D659EF19F),
+      UInt64($B99A8AE2782CCB24), UInt64($CCF52AB6C814C4C7),
+      UInt64($4727D9AFBE11727B), UInt64($7E950D0C0121B34D),
+      UInt64($756F435670AD471F), UInt64($F5ADD442615A6849),
+      UInt64($4E87E09980B9957A), UInt64($2ACFA1DF50AEE355),
+      UInt64($D898263AFD2FD556), UInt64($C8F4924DD80C8FD6),
+      UInt64($CF99CA3D754A173A), UInt64($FE477BACAF91BF3C),
+      UInt64($ED5371F6D690C12D), UInt64($831A5C285E687094),
+      UInt64($C5D3C90A3708A0A4), UInt64($0F7F903717D06580),
+      UInt64($19F9BB13B8FDF27F), UInt64($B1BD6F1B4D502843),
+      UInt64($1C761BA38FFF4012), UInt64($0D1530C4E2E21F3B),
+      UInt64($8943CE69A7372C8A), UInt64($E5184E11FEB5CE66),
+      UInt64($618BDB80BD736621), UInt64($7D29BAD68B574D0B),
+      UInt64($81BB613E25E6FE5B), UInt64($071C9C10BC07913F),
+      UInt64($C7BEEB7909AC2D97), UInt64($C3E58D353BC5D757),
+      UInt64($EB017892F38F61E8), UInt64($D4EFFB9C9B1CC21A),
+      UInt64($99727D26F494F7AB), UInt64($A3E063A2956B3E03),
+      UInt64($9D4A8B9A4AA09C30), UInt64($3F6AB7D500090FB4),
+      UInt64($9CC0F2A057268AC0), UInt64($3DEE9D2DEDBF42D1),
+      UInt64($330F49C87960A972), UInt64($C6B2720287421B41),
+      UInt64($0AC59EC07C00369C), UInt64($EF4EAC49CB353425),
+      UInt64($F450244EEF0129D8), UInt64($8ACC46E5CAF4DEB6),
+      UInt64($2FFEAB63989263F7), UInt64($8F7CB9FE5D7A4578),
+      UInt64($5BD8F7644E634635), UInt64($427A7315BF2DC900),
+      UInt64($17D0C4AA2125261C), UInt64($3992486C93518E50),
+      UInt64($B4CBFEE0A2D7D4C3), UInt64($7C75D6202C5DDD8D),
+      UInt64($DBC295D8E35B6C61), UInt64($60B369D302032B19),
+      UInt64($CE42685FDCE44132), UInt64($06F3DDB9DDF65610),
+      UInt64($8EA4D21DB5E148F0), UInt64($20B0FCE62FCD496F),
+      UInt64($2C1B912358B0EE31), UInt64($B28317B818F5A308),
+      UInt64($A89C1E189CA6D2CF), UInt64($0C6B18576AAADBC8),
+      UInt64($B65DEAA91299FAE3), UInt64($FB2B794B7F1027E7),
+      UInt64($04E4317F443B5BEB), UInt64($4B852D325939D0A6),
+      UInt64($D5AE6BEEFB207FFC), UInt64($309682B281C7D374),
+      UInt64($BAE309A194C3B475), UInt64($8CC3F97B13B49F05),
+      UInt64($98A9422FF8293967), UInt64($244B16B01076FF7C),
+      UInt64($F8BF571C663D67EE), UInt64($1F0D6758EEE30DA1),
+      UInt64($C9B611D97ADEB9B7), UInt64($B7AFD5887B6C57A2),
+      UInt64($6290AE846B984FE1), UInt64($94DF4CDEACC1A5FD),
+      UInt64($058A5BD1C5483AFF), UInt64($63166CC142BA3C37),
+      UInt64($8DB8526EB2F76F40), UInt64($E10880036F0D6D4E),
+      UInt64($9E0523C9971D311D), UInt64($45EC2824CC7CD691),
+      UInt64($575B8359E62382C9), UInt64($FA9E400DC4889995),
+      UInt64($D1823ECB45721568), UInt64($DAFD983B8206082F),
+      UInt64($AA7D29082386A8CB), UInt64($269FCD4403B87588),
+      UInt64($1B91F5F728BDD1E0), UInt64($E4669F39040201F6),
+      UInt64($7A1D7C218CF04ADE), UInt64($65623C29D79CE5CE),
+      UInt64($2368449096C00BB1), UInt64($AB9BF1879DA503BA),
+      UInt64($BC23ECB1A458058E), UInt64($9A58DF01BB401ECC),
+      UInt64($A070E868A85F143D), UInt64($4FF188307DF2239E),
+      UInt64($14D565B41A641183), UInt64($EE13337452701602),
+      UInt64($950E3DCF3F285E09), UInt64($59930254B9C80953),
+      UInt64($3BF299408930DA6D), UInt64($A955943F53691387),
+      UInt64($A15EDECAA9CB8784), UInt64($29142127352BE9A0),
+      UInt64($76F0371FFF4E7AFB), UInt64($0239F450274F2228),
+      UInt64($BB073AF01D5E868B), UInt64($BFC80571C10E96C1),
+      UInt64($D267088568222E23), UInt64($9671A3D48E80B5B0),
+      UInt64($55B5D38AE193BB81), UInt64($693AE2D0A18B04B8),
+      UInt64($5C48B4ECADD5335F), UInt64($FD743B194916A1CA),
+      UInt64($2577018134BE98C4), UInt64($E77987E83C54A4AD),
+      UInt64($28E11014DA33E1B9), UInt64($270CC59E226AA213),
+      UInt64($71495F756D1A5F60), UInt64($9BE853FB60AFEF77),
+      UInt64($ADC786A7F7443DBF), UInt64($0904456173B29A82),
+      UInt64($58BC7A66C232BD5E), UInt64($F306558C673AC8B2),
+      UInt64($41F639C6B6C9772A), UInt64($216DEFE99FDA35DA),
+      UInt64($11640CC71C7BE615), UInt64($93C43694565C5527),
+      UInt64($EA038E6246777839), UInt64($F9ABF3CE5A3E2469),
+      UInt64($741E768D0FD312D2), UInt64($0144B883CED652C6),
+      UInt64($C20B5A5BA33F8552), UInt64($1AE69633C3435A9D),
+      UInt64($97A28CA4088CFDEC), UInt64($8824A43C1E96F420),
+      UInt64($37612FA66EEEA746), UInt64($6B4CB165F9CF0E5A),
+      UInt64($43AA1C06A0ABFB4A), UInt64($7F4DC26FF162796B),
+      UInt64($6CBACC8E54ED9B0F), UInt64($A6B7FFEFD2BB253E),
+      UInt64($2E25BC95B0A29D4F), UInt64($86D6A58BDEF1388C),
+      UInt64($DED74AC576B6F054), UInt64($8030BDBC2B45805D),
+      UInt64($3C81AF70E94D9289), UInt64($3EFF6DDA9E3100DB),
+      UInt64($B38DC39FDFCC8847), UInt64($123885528D17B87E),
+      UInt64($F2DA0ED240B1B642), UInt64($44CEFADCD54BF9A9),
+      UInt64($1312200E433C7EE6), UInt64($9FFCC84F3A78C748),
+      UInt64($F0CD1F72248576BB), UInt64($EC6974053638CFE4),
+      UInt64($2BA7B67C0CEC4E4C), UInt64($AC2F4DF3E5CE32ED),
+      UInt64($CB33D14326EA4C11), UInt64($A4E9044CC77E58BC),
+      UInt64($5F513293D934FCEF), UInt64($5DC9645506E55444),
+      UInt64($50DE418F317DE40A), UInt64($388CB31A69DDE259),
+      UInt64($2DB4A83455820A86), UInt64($9010A91E84711AE9),
+      UInt64($4DF7F0B7B1498371), UInt64($D62A2EABC0977179),
+      UInt64($22FAC097AA8D5C0E));
+
+    s_T3: array [0 .. 255] of UInt64 = (UInt64($F49FCC2FF1DAF39B),
+      UInt64($487FD5C66FF29281), UInt64($E8A30667FCDCA83F),
+      UInt64($2C9B4BE3D2FCCE63), UInt64($DA3FF74B93FBBBC2),
+      UInt64($2FA165D2FE70BA66), UInt64($A103E279970E93D4),
+      UInt64($BECDEC77B0E45E71), UInt64($CFB41E723985E497),
+      UInt64($B70AAA025EF75017), UInt64($D42309F03840B8E0),
+      UInt64($8EFC1AD035898579), UInt64($96C6920BE2B2ABC5),
+      UInt64($66AF4163375A9172), UInt64($2174ABDCCA7127FB),
+      UInt64($B33CCEA64A72FF41), UInt64($F04A4933083066A5),
+      UInt64($8D970ACDD7289AF5), UInt64($8F96E8E031C8C25E),
+      UInt64($F3FEC02276875D47), UInt64($EC7BF310056190DD),
+      UInt64($F5ADB0AEBB0F1491), UInt64($9B50F8850FD58892),
+      UInt64($4975488358B74DE8), UInt64($A3354FF691531C61),
+      UInt64($0702BBE481D2C6EE), UInt64($89FB24057DEDED98),
+      UInt64($AC3075138596E902), UInt64($1D2D3580172772ED),
+      UInt64($EB738FC28E6BC30D), UInt64($5854EF8F63044326),
+      UInt64($9E5C52325ADD3BBE), UInt64($90AA53CF325C4623),
+      UInt64($C1D24D51349DD067), UInt64($2051CFEEA69EA624),
+      UInt64($13220F0A862E7E4F), UInt64($CE39399404E04864),
+      UInt64($D9C42CA47086FCB7), UInt64($685AD2238A03E7CC),
+      UInt64($066484B2AB2FF1DB), UInt64($FE9D5D70EFBF79EC),
+      UInt64($5B13B9DD9C481854), UInt64($15F0D475ED1509AD),
+      UInt64($0BEBCD060EC79851), UInt64($D58C6791183AB7F8),
+      UInt64($D1187C5052F3EEE4), UInt64($C95D1192E54E82FF),
+      UInt64($86EEA14CB9AC6CA2), UInt64($3485BEB153677D5D),
+      UInt64($DD191D781F8C492A), UInt64($F60866BAA784EBF9),
+      UInt64($518F643BA2D08C74), UInt64($8852E956E1087C22),
+      UInt64($A768CB8DC410AE8D), UInt64($38047726BFEC8E1A),
+      UInt64($A67738B4CD3B45AA), UInt64($AD16691CEC0DDE19),
+      UInt64($C6D4319380462E07), UInt64($C5A5876D0BA61938),
+      UInt64($16B9FA1FA58FD840), UInt64($188AB1173CA74F18),
+      UInt64($ABDA2F98C99C021F), UInt64($3E0580AB134AE816),
+      UInt64($5F3B05B773645ABB), UInt64($2501A2BE5575F2F6),
+      UInt64($1B2F74004E7E8BA9), UInt64($1CD7580371E8D953),
+      UInt64($7F6ED89562764E30), UInt64($B15926FF596F003D),
+      UInt64($9F65293DA8C5D6B9), UInt64($6ECEF04DD690F84C),
+      UInt64($4782275FFF33AF88), UInt64($E41433083F820801),
+      UInt64($FD0DFE409A1AF9B5), UInt64($4325A3342CDB396B),
+      UInt64($8AE77E62B301B252), UInt64($C36F9E9F6655615A),
+      UInt64($85455A2D92D32C09), UInt64($F2C7DEA949477485),
+      UInt64($63CFB4C133A39EBA), UInt64($83B040CC6EBC5462),
+      UInt64($3B9454C8FDB326B0), UInt64($56F56A9E87FFD78C),
+      UInt64($2DC2940D99F42BC6), UInt64($98F7DF096B096E2D),
+      UInt64($19A6E01E3AD852BF), UInt64($42A99CCBDBD4B40B),
+      UInt64($A59998AF45E9C559), UInt64($366295E807D93186),
+      UInt64($6B48181BFAA1F773), UInt64($1FEC57E2157A0A1D),
+      UInt64($4667446AF6201AD5), UInt64($E615EBCACFB0F075),
+      UInt64($B8F31F4F68290778), UInt64($22713ED6CE22D11E),
+      UInt64($3057C1A72EC3C93B), UInt64($CB46ACC37C3F1F2F),
+      UInt64($DBB893FD02AAF50E), UInt64($331FD92E600B9FCF),
+      UInt64($A498F96148EA3AD6), UInt64($A8D8426E8B6A83EA),
+      UInt64($A089B274B7735CDC), UInt64($87F6B3731E524A11),
+      UInt64($118808E5CBC96749), UInt64($9906E4C7B19BD394),
+      UInt64($AFED7F7E9B24A20C), UInt64($6509EADEEB3644A7),
+      UInt64($6C1EF1D3E8EF0EDE), UInt64($B9C97D43E9798FB4),
+      UInt64($A2F2D784740C28A3), UInt64($7B8496476197566F),
+      UInt64($7A5BE3E6B65F069D), UInt64($F96330ED78BE6F10),
+      UInt64($EEE60DE77A076A15), UInt64($2B4BEE4AA08B9BD0),
+      UInt64($6A56A63EC7B8894E), UInt64($02121359BA34FEF4),
+      UInt64($4CBF99F8283703FC), UInt64($398071350CAF30C8),
+      UInt64($D0A77A89F017687A), UInt64($F1C1A9EB9E423569),
+      UInt64($8C7976282DEE8199), UInt64($5D1737A5DD1F7ABD),
+      UInt64($4F53433C09A9FA80), UInt64($FA8B0C53DF7CA1D9),
+      UInt64($3FD9DCBC886CCB77), UInt64($C040917CA91B4720),
+      UInt64($7DD00142F9D1DCDF), UInt64($8476FC1D4F387B58),
+      UInt64($23F8E7C5F3316503), UInt64($032A2244E7E37339),
+      UInt64($5C87A5D750F5A74B), UInt64($082B4CC43698992E),
+      UInt64($DF917BECB858F63C), UInt64($3270B8FC5BF86DDA),
+      UInt64($10AE72BB29B5DD76), UInt64($576AC94E7700362B),
+      UInt64($1AD112DAC61EFB8F), UInt64($691BC30EC5FAA427),
+      UInt64($FF246311CC327143), UInt64($3142368E30E53206),
+      UInt64($71380E31E02CA396), UInt64($958D5C960AAD76F1),
+      UInt64($F8D6F430C16DA536), UInt64($C8FFD13F1BE7E1D2),
+      UInt64($7578AE66004DDBE1), UInt64($05833F01067BE646),
+      UInt64($BB34B5AD3BFE586D), UInt64($095F34C9A12B97F0),
+      UInt64($247AB64525D60CA8), UInt64($DCDBC6F3017477D1),
+      UInt64($4A2E14D4DECAD24D), UInt64($BDB5E6D9BE0A1EEB),
+      UInt64($2A7E70F7794301AB), UInt64($DEF42D8A270540FD),
+      UInt64($01078EC0A34C22C1), UInt64($E5DE511AF4C16387),
+      UInt64($7EBB3A52BD9A330A), UInt64($77697857AA7D6435),
+      UInt64($004E831603AE4C32), UInt64($E7A21020AD78E312),
+      UInt64($9D41A70C6AB420F2), UInt64($28E06C18EA1141E6),
+      UInt64($D2B28CBD984F6B28), UInt64($26B75F6C446E9D83),
+      UInt64($BA47568C4D418D7F), UInt64($D80BADBFE6183D8E),
+      UInt64($0E206D7F5F166044), UInt64($E258A43911CBCA3E),
+      UInt64($723A1746B21DC0BC), UInt64($C7CAA854F5D7CDD3),
+      UInt64($7CAC32883D261D9C), UInt64($7690C26423BA942C),
+      UInt64($17E55524478042B8), UInt64($E0BE477656A2389F),
+      UInt64($4D289B5E67AB2DA0), UInt64($44862B9C8FBBFD31),
+      UInt64($B47CC8049D141365), UInt64($822C1B362B91C793),
+      UInt64($4EB14655FB13DFD8), UInt64($1ECBBA0714E2A97B),
+      UInt64($6143459D5CDE5F14), UInt64($53A8FBF1D5F0AC89),
+      UInt64($97EA04D81C5E5B00), UInt64($622181A8D4FDB3F3),
+      UInt64($E9BCD341572A1208), UInt64($1411258643CCE58A),
+      UInt64($9144C5FEA4C6E0A4), UInt64($0D33D06565CF620F),
+      UInt64($54A48D489F219CA1), UInt64($C43E5EAC6D63C821),
+      UInt64($A9728B3A72770DAF), UInt64($D7934E7B20DF87EF),
+      UInt64($E35503B61A3E86E5), UInt64($CAE321FBC819D504),
+      UInt64($129A50B3AC60BFA6), UInt64($CD5E68EA7E9FB6C3),
+      UInt64($B01C90199483B1C7), UInt64($3DE93CD5C295376C),
+      UInt64($AED52EDF2AB9AD13), UInt64($2E60F512C0A07884),
+      UInt64($BC3D86A3E36210C9), UInt64($35269D9B163951CE),
+      UInt64($0C7D6E2AD0CDB5FA), UInt64($59E86297D87F5733),
+      UInt64($298EF221898DB0E7), UInt64($55000029D1A5AA7E),
+      UInt64($8BC08AE1B5061B45), UInt64($C2C31C2B6C92703A),
+      UInt64($94CC596BAF25EF42), UInt64($0A1D73DB22540456),
+      UInt64($04B6A0F9D9C4179A), UInt64($EFFDAFA2AE3D3C60),
+      UInt64($F7C8075BB49496C4), UInt64($9CC5C7141D1CD4E3),
+      UInt64($78BD1638218E5534), UInt64($B2F11568F850246A),
+      UInt64($EDFABCFA9502BC29), UInt64($796CE5F2DA23051B),
+      UInt64($AAE128B0DC93537C), UInt64($3A493DA0EE4B29AE),
+      UInt64($B5DF6B2C416895D7), UInt64($FCABBD25122D7F37),
+      UInt64($70810B58105DC4B1), UInt64($E10FDD37F7882A90),
+      UInt64($524DCAB5518A3F5C), UInt64($3C9E85878451255B),
+      UInt64($4029828119BD34E2), UInt64($74A05B6F5D3CECCB),
+      UInt64($B610021542E13ECA), UInt64($0FF979D12F59E2AC),
+      UInt64($6037DA27E4F9CC50), UInt64($5E92975A0DF1847D),
+      UInt64($D66DE190D3E623FE), UInt64($5032D6B87B568048),
+      UInt64($9A36B7CE8235216E), UInt64($80272A7A24F64B4A),
+      UInt64($93EFED8B8C6916F7), UInt64($37DDBFF44CCE1555),
+      UInt64($4B95DB5D4B99BD25), UInt64($92D3FDA169812FC0),
+      UInt64($FB1A4A9A90660BB6), UInt64($730C196946A4B9B2),
+      UInt64($81E289AA7F49DA68), UInt64($64669A0F83B1A05F),
+      UInt64($27B3FF7D9644F48B), UInt64($CC6B615C8DB675B3),
+      UInt64($674F20B9BCEBBE95), UInt64($6F31238275655982),
+      UInt64($5AE488713E45CF05), UInt64($BF619F9954C21157),
+      UInt64($EABAC46040A8EAE9), UInt64($454C6FE9F2C0C1CD),
+      UInt64($419CF6496412691C), UInt64($D3DC3BEF265B0F70),
+      UInt64($6D0E60F5C3578A9E));
+
+    s_T4: array [0 .. 255] of UInt64 = (UInt64($5B0E608526323C55),
+      UInt64($1A46C1A9FA1B59F5), UInt64($A9E245A17C4C8FFA),
+      UInt64($65CA5159DB2955D7), UInt64($05DB0A76CE35AFC2),
+      UInt64($81EAC77EA9113D45), UInt64($528EF88AB6AC0A0D),
+      UInt64($A09EA253597BE3FF), UInt64($430DDFB3AC48CD56),
+      UInt64($C4B3A67AF45CE46F), UInt64($4ECECFD8FBE2D05E),
+      UInt64($3EF56F10B39935F0), UInt64($0B22D6829CD619C6),
+      UInt64($17FD460A74DF2069), UInt64($6CF8CC8E8510ED40),
+      UInt64($D6C824BF3A6ECAA7), UInt64($61243D581A817049),
+      UInt64($048BACB6BBC163A2), UInt64($D9A38AC27D44CC32),
+      UInt64($7FDDFF5BAAF410AB), UInt64($AD6D495AA804824B),
+      UInt64($E1A6A74F2D8C9F94), UInt64($D4F7851235DEE8E3),
+      UInt64($FD4B7F886540D893), UInt64($247C20042AA4BFDA),
+      UInt64($096EA1C517D1327C), UInt64($D56966B4361A6685),
+      UInt64($277DA5C31221057D), UInt64($94D59893A43ACFF7),
+      UInt64($64F0C51CCDC02281), UInt64($3D33BCC4FF6189DB),
+      UInt64($E005CB184CE66AF1), UInt64($FF5CCD1D1DB99BEA),
+      UInt64($B0B854A7FE42980F), UInt64($7BD46A6A718D4B9F),
+      UInt64($D10FA8CC22A5FD8C), UInt64($D31484952BE4BD31),
+      UInt64($C7FA975FCB243847), UInt64($4886ED1E5846C407),
+      UInt64($28CDDB791EB70B04), UInt64($C2B00BE2F573417F),
+      UInt64($5C9590452180F877), UInt64($7A6BDDFFF370EB00),
+      UInt64($CE509E38D6D9D6A4), UInt64($EBEB0F00647FA702),
+      UInt64($1DCC06CF76606F06), UInt64($E4D9F28BA286FF0A),
+      UInt64($D85A305DC918C262), UInt64($475B1D8732225F54),
+      UInt64($2D4FB51668CCB5FE), UInt64($A679B9D9D72BBA20),
+      UInt64($53841C0D912D43A5), UInt64($3B7EAA48BF12A4E8),
+      UInt64($781E0E47F22F1DDF), UInt64($EFF20CE60AB50973),
+      UInt64($20D261D19DFFB742), UInt64($16A12B03062A2E39),
+      UInt64($1960EB2239650495), UInt64($251C16FED50EB8B8),
+      UInt64($9AC0C330F826016E), UInt64($ED152665953E7671),
+      UInt64($02D63194A6369570), UInt64($5074F08394B1C987),
+      UInt64($70BA598C90B25CE1), UInt64($794A15810B9742F6),
+      UInt64($0D5925E9FCAF8C6C), UInt64($3067716CD868744E),
+      UInt64($910AB077E8D7731B), UInt64($6A61BBDB5AC42F61),
+      UInt64($93513EFBF0851567), UInt64($F494724B9E83E9D5),
+      UInt64($E887E1985C09648D), UInt64($34B1D3C675370CFD),
+      UInt64($DC35E433BC0D255D), UInt64($D0AAB84234131BE0),
+      UInt64($08042A50B48B7EAF), UInt64($9997C4EE44A3AB35),
+      UInt64($829A7B49201799D0), UInt64($263B8307B7C54441),
+      UInt64($752F95F4FD6A6CA6), UInt64($927217402C08C6E5),
+      UInt64($2A8AB754A795D9EE), UInt64($A442F7552F72943D),
+      UInt64($2C31334E19781208), UInt64($4FA98D7CEAEE6291),
+      UInt64($55C3862F665DB309), UInt64($BD0610175D53B1F3),
+      UInt64($46FE6CB840413F27), UInt64($3FE03792DF0CFA59),
+      UInt64($CFE700372EB85E8F), UInt64($A7BE29E7ADBCE118),
+      UInt64($E544EE5CDE8431DD), UInt64($8A781B1B41F1873E),
+      UInt64($A5C94C78A0D2F0E7), UInt64($39412E2877B60728),
+      UInt64($A1265EF3AFC9A62C), UInt64($BCC2770C6A2506C5),
+      UInt64($3AB66DD5DCE1CE12), UInt64($E65499D04A675B37),
+      UInt64($7D8F523481BFD216), UInt64($0F6F64FCEC15F389),
+      UInt64($74EFBE618B5B13C8), UInt64($ACDC82B714273E1D),
+      UInt64($DD40BFE003199D17), UInt64($37E99257E7E061F8),
+      UInt64($FA52626904775AAA), UInt64($8BBBF63A463D56F9),
+      UInt64($F0013F1543A26E64), UInt64($A8307E9F879EC898),
+      UInt64($CC4C27A4150177CC), UInt64($1B432F2CCA1D3348),
+      UInt64($DE1D1F8F9F6FA013), UInt64($606602A047A7DDD6),
+      UInt64($D237AB64CC1CB2C7), UInt64($9B938E7225FCD1D3),
+      UInt64($EC4E03708E0FF476), UInt64($FEB2FBDA3D03C12D),
+      UInt64($AE0BCED2EE43889A), UInt64($22CB8923EBFB4F43),
+      UInt64($69360D013CF7396D), UInt64($855E3602D2D4E022),
+      UInt64($073805BAD01F784C), UInt64($33E17A133852F546),
+      UInt64($DF4874058AC7B638), UInt64($BA92B29C678AA14A),
+      UInt64($0CE89FC76CFAADCD), UInt64($5F9D4E0908339E34),
+      UInt64($F1AFE9291F5923B9), UInt64($6E3480F60F4A265F),
+      UInt64($EEBF3A2AB29B841C), UInt64($E21938A88F91B4AD),
+      UInt64($57DFEFF845C6D3C3), UInt64($2F006B0BF62CAAF2),
+      UInt64($62F479EF6F75EE78), UInt64($11A55AD41C8916A9),
+      UInt64($F229D29084FED453), UInt64($42F1C27B16B000E6),
+      UInt64($2B1F76749823C074), UInt64($4B76ECA3C2745360),
+      UInt64($8C98F463B91691BD), UInt64($14BCC93CF1ADE66A),
+      UInt64($8885213E6D458397), UInt64($8E177DF0274D4711),
+      UInt64($B49B73B5503F2951), UInt64($10168168C3F96B6B),
+      UInt64($0E3D963B63CAB0AE), UInt64($8DFC4B5655A1DB14),
+      UInt64($F789F1356E14DE5C), UInt64($683E68AF4E51DAC1),
+      UInt64($C9A84F9D8D4B0FD9), UInt64($3691E03F52A0F9D1),
+      UInt64($5ED86E46E1878E80), UInt64($3C711A0E99D07150),
+      UInt64($5A0865B20C4E9310), UInt64($56FBFC1FE4F0682E),
+      UInt64($EA8D5DE3105EDF9B), UInt64($71ABFDB12379187A),
+      UInt64($2EB99DE1BEE77B9C), UInt64($21ECC0EA33CF4523),
+      UInt64($59A4D7521805C7A1), UInt64($3896F5EB56AE7C72),
+      UInt64($AA638F3DB18F75DC), UInt64($9F39358DABE9808E),
+      UInt64($B7DEFA91C00B72AC), UInt64($6B5541FD62492D92),
+      UInt64($6DC6DEE8F92E4D5B), UInt64($353F57ABC4BEEA7E),
+      UInt64($735769D6DA5690CE), UInt64($0A234AA642391484),
+      UInt64($F6F9508028F80D9D), UInt64($B8E319A27AB3F215),
+      UInt64($31AD9C1151341A4D), UInt64($773C22A57BEF5805),
+      UInt64($45C7561A07968633), UInt64($F913DA9E249DBE36),
+      UInt64($DA652D9B78A64C68), UInt64($4C27A97F3BC334EF),
+      UInt64($76621220E66B17F4), UInt64($967743899ACD7D0B),
+      UInt64($F3EE5BCAE0ED6782), UInt64($409F753600C879FC),
+      UInt64($06D09A39B5926DB6), UInt64($6F83AEB0317AC588),
+      UInt64($01E6CA4A86381F21), UInt64($66FF3462D19F3025),
+      UInt64($72207C24DDFD3BFB), UInt64($4AF6B6D3E2ECE2EB),
+      UInt64($9C994DBEC7EA08DE), UInt64($49ACE597B09A8BC4),
+      UInt64($B38C4766CF0797BA), UInt64($131B9373C57C2A75),
+      UInt64($B1822CCE61931E58), UInt64($9D7555B909BA1C0C),
+      UInt64($127FAFDD937D11D2), UInt64($29DA3BADC66D92E4),
+      UInt64($A2C1D57154C2ECBC), UInt64($58C5134D82F6FE24),
+      UInt64($1C3AE3515B62274F), UInt64($E907C82E01CB8126),
+      UInt64($F8ED091913E37FCB), UInt64($3249D8F9C80046C9),
+      UInt64($80CF9BEDE388FB63), UInt64($1881539A116CF19E),
+      UInt64($5103F3F76BD52457), UInt64($15B7E6F5AE47F7A8),
+      UInt64($DBD7C6DED47E9CCF), UInt64($44E55C410228BB1A),
+      UInt64($B647D4255EDB4E99), UInt64($5D11882BB8AAFC30),
+      UInt64($F5098BBB29D3212A), UInt64($8FB5EA14E90296B3),
+      UInt64($677B942157DD025A), UInt64($FB58E7C0A390ACB5),
+      UInt64($89D3674C83BD4A01), UInt64($9E2DA4DF4BF3B93B),
+      UInt64($FCC41E328CAB4829), UInt64($03F38C96BA582C52),
+      UInt64($CAD1BDBD7FD85DB2), UInt64($BBB442C16082AE83),
+      UInt64($B95FE86BA5DA9AB0), UInt64($B22E04673771A93F),
+      UInt64($845358C9493152D8), UInt64($BE2A488697B4541E),
+      UInt64($95A2DC2DD38E6966), UInt64($C02C11AC923C852B),
+      UInt64($2388B1990DF2A87B), UInt64($7C8008FA1B4F37BE),
+      UInt64($1F70D0C84D54E503), UInt64($5490ADEC7ECE57D4),
+      UInt64($002B3C27D9063A3A), UInt64($7EAEA3848030A2BF),
+      UInt64($C602326DED2003C0), UInt64($83A7287D69A94086),
+      UInt64($C57A5FCB30F57A8A), UInt64($B56844E479EBE779),
+      UInt64($A373B40F05DCBCE9), UInt64($D71A786E88570EE2),
+      UInt64($879CBACDBDE8F6A0), UInt64($976AD1BCC164A32F),
+      UInt64($AB21E25E9666D78B), UInt64($901063AAE5E5C33C),
+      UInt64($9818B34448698D90), UInt64($E36487AE3E1E8ABB),
+      UInt64($AFBDF931893BDCB4), UInt64($6345A0DC5FBBD519),
+      UInt64($8628FE269B9465CA), UInt64($1E5D01603F9C51EC),
+      UInt64($4DE44006A15049B7), UInt64($BF6C70E5F776CBB1),
+      UInt64($411218F2EF552BED), UInt64($CB0C0708705A36A3),
+      UInt64($E74D14754F986044), UInt64($CD56D9430EA8280E),
+      UInt64($C12591D7535F5065), UInt64($C83223F1720AEF96),
+      UInt64($C3A0396F7363A51F));
+
+{$ENDREGION}
+  strict protected
+    Fm_hash: THashLibUInt64Array;
+
+    constructor Create(a_hash_size: Int32; a_rounds: THashRounds);
+
+    function GetResult(): THashLibByteArray; override;
+    procedure Finish(); override;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    procedure Initialize(); override;
+
+  end;
+
+type
+
+  TTiger2_Base = class sealed(TTiger2)
+
+  public
+    constructor Create(a_hash_size: Int32; a_rounds: THashRounds);
+
+  end;
+
+type
+
+  TTiger2_128 = class sealed(TTiger2)
+
+  public
+    constructor CreateRound3();
+    constructor CreateRound4();
+    constructor CreateRound5();
+
+  end;
+
+type
+
+  TTiger2_160 = class sealed(TTiger2)
+
+  public
+    constructor CreateRound3();
+    constructor CreateRound4();
+    constructor CreateRound5();
+
+  end;
+
+type
+  TTiger2_192 = class sealed(TTiger2)
+
+  public
+    constructor CreateRound3();
+    constructor CreateRound4();
+    constructor CreateRound5();
+
+  end;
+
+implementation
+
+{ TTiger2 }
+
+constructor TTiger2.Create(a_hash_size: Int32; a_rounds: THashRounds);
+begin
+  Inherited Create(a_hash_size, 64);
+  System.SetLength(Fm_hash, 3);
+  Fm_rounds := Int32(a_rounds);
+end;
+
+procedure TTiger2.Finish;
+var
+  bits: UInt64;
+  padindex: Int32;
+  pad: THashLibByteArray;
+
+begin
+  bits := Fm_processed_bytes * 8;
+  if Fm_buffer.Pos < 56 then
+    padindex := 56 - Fm_buffer.Pos
+  else
+    padindex := 120 - Fm_buffer.Pos;
+  System.SetLength(pad, padindex + 8);
+
+  pad[0] := $80;
+
+  bits := TConverters.le2me_64(bits);
+
+  TConverters.ReadUInt64AsBytesLE(bits, pad, padindex);
+
+  padindex := padindex + 8;
+
+  TransformBytes(pad, 0, padindex);
+
+end;
+
+function TTiger2.GetResult: THashLibByteArray;
+begin
+  System.SetLength(result, HashSize);
+  TConverters.le64_copy(PUInt64(Fm_hash), 0, PByte(result), 0,
+    System.Length(result));
+end;
+
+procedure TTiger2.Initialize;
+begin
+
+  Fm_hash[0] := $0123456789ABCDEF;
+  Fm_hash[1] := UInt64($FEDCBA9876543210);
+  Fm_hash[2] := UInt64($F096A5B4C3B2E187);
+
+  Inherited Initialize();
+
+end;
+
+procedure TTiger2.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  a, b, c, temp_a: UInt64;
+  rounds: Int32;
+  data: array [0 .. 7] of UInt64;
+begin
+
+  TConverters.le64_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+
+  a := Fm_hash[0];
+  b := Fm_hash[1];
+  c := Fm_hash[2];
+
+  c := c xor data[0];
+  a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+    ] xor s_T4[Byte(c shr 48)]);
+  b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+    ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+  b := b * 5;
+
+  a := a xor data[1];
+  b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+    ] xor s_T4[Byte(a shr 48)]);
+  c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2[Byte(a shr 40)
+    ] xor s_T1[Byte(a shr 56)]);
+  c := c * 5;
+
+  b := b xor data[2];
+  c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+    ] xor s_T4[Byte(b shr 48)]);
+  a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2[Byte(b shr 40)
+    ] xor s_T1[Byte(b shr 56)]);
+  a := a * 5;
+
+  c := c xor data[3];
+  a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+    ] xor s_T4[Byte(c shr 48)]);
+  b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+    ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+  b := b * 5;
+
+  a := a xor data[4];
+  b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+    ] xor s_T4[Byte(a shr 48)]);
+  c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2[Byte(a shr 40)
+    ] xor s_T1[Byte(a shr 56)]);
+  c := c * 5;
+
+  b := b xor data[5];
+  c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+    ] xor s_T4[Byte(b shr 48)]);
+  a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2[Byte(b shr 40)
+    ] xor s_T1[Byte(b shr 56)]);
+  a := a * 5;
+
+  c := c xor data[6];
+  a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+    ] xor s_T4[Byte(c shr 48)]);
+  b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+    ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+  b := b * 5;
+
+  a := a xor data[7];
+  b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+    ] xor s_T4[Byte(a shr 48)]);
+  c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2[Byte(a shr 40)
+    ] xor s_T1[Byte(a shr 56)]);
+  c := c * 5;
+
+  data[0] := data[0] - (data[7] xor C1);
+  data[1] := data[1] xor data[0];
+  data[2] := data[2] + data[1];
+  data[3] := data[3] - (data[2] xor (not data[1] shl 19));
+  data[4] := data[4] xor data[3];
+  data[5] := data[5] + data[4];
+  data[6] := data[6] - (data[5] xor (not data[4] shr 23));
+  data[7] := data[7] xor data[6];
+  data[0] := data[0] + data[7];
+  data[1] := data[1] - (data[0] xor (not data[7] shl 19));
+  data[2] := data[2] xor data[1];
+  data[3] := data[3] + data[2];
+  data[4] := data[4] - (data[3] xor (not data[2] shr 23));
+  data[5] := data[5] xor data[4];
+  data[6] := data[6] + data[5];
+  data[7] := data[7] - (data[6] xor C2);
+
+  b := b xor data[0];
+  c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+    ] xor s_T4[Byte(b shr 48)]);
+  a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2[Byte(b shr 40)
+    ] xor s_T1[Byte(b shr 56)]);
+  a := a * 7;
+
+  c := c xor data[1];
+  a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+    ] xor s_T4[Byte(c shr 48)]);
+  b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+    ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+  b := b * 7;
+
+  a := a xor data[2];
+  b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+    ] xor s_T4[Byte(a shr 48)]);
+  c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2[Byte(a shr 40)
+    ] xor s_T1[Byte(a shr 56)]);
+  c := c * 7;
+
+  b := b xor data[3];
+  c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+    ] xor s_T4[Byte(b shr 48)]);
+  a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2[Byte(b shr 40)
+    ] xor s_T1[Byte(b shr 56)]);
+  a := a * 7;
+
+  c := c xor data[4];
+  a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+    ] xor s_T4[Byte(c shr 48)]);
+  b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+    ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+  b := b * 7;
+
+  a := a xor data[5];
+  b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+    ] xor s_T4[Byte(a shr 48)]);
+  c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2[Byte(a shr 40)
+    ] xor s_T1[Byte(a shr 56)]);
+  c := c * 7;
+
+  b := b xor data[6];
+  c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+    ] xor s_T4[Byte(b shr 48)]);
+  a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2[Byte(b shr 40)
+    ] xor s_T1[Byte(b shr 56)]);
+  a := a * 7;
+
+  c := c xor data[7];
+  a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+    ] xor s_T4[Byte(c shr 48)]);
+  b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+    ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+  b := b * 7;
+
+  data[0] := data[0] - (data[7] xor C1);
+  data[1] := data[1] xor data[0];
+  data[2] := data[2] + data[1];
+  data[3] := data[3] - (data[2] xor (not data[1] shl 19));
+  data[4] := data[4] xor data[3];
+  data[5] := data[5] + data[4];
+  data[6] := data[6] - (data[5] xor (not data[4] shr 23));
+  data[7] := data[7] xor data[6];
+  data[0] := data[0] + data[7];
+  data[1] := data[1] - (data[0] xor (not data[7] shl 19));
+  data[2] := data[2] xor data[1];
+  data[3] := data[3] + data[2];
+  data[4] := data[4] - (data[3] xor (not data[2] shr 23));
+  data[5] := data[5] xor data[4];
+  data[6] := data[6] + data[5];
+  data[7] := data[7] - (data[6] xor C2);
+
+  a := a xor data[0];
+  b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+    ] xor s_T4[Byte(a shr 48)]);
+  c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2[Byte(a shr 40)
+    ] xor s_T1[Byte(a shr 56)]);
+  c := c * 9;
+
+  b := b xor data[1];
+  c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+    ] xor s_T4[Byte(b shr 48)]);
+  a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2[Byte(b shr 40)
+    ] xor s_T1[Byte(b shr 56)]);
+  a := a * 9;
+
+  c := c xor data[2];
+  a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+    ] xor s_T4[Byte(c shr 48)]);
+  b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+    ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+  b := b * 9;
+
+  a := a xor data[3];
+  b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+    ] xor s_T4[Byte(a shr 48)]);
+  c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2[Byte(a shr 40)
+    ] xor s_T1[Byte(a shr 56)]);
+  c := c * 9;
+
+  b := b xor data[4];
+  c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+    ] xor s_T4[Byte(b shr 48)]);
+  a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2[Byte(b shr 40)
+    ] xor s_T1[Byte(b shr 56)]);
+  a := a * 9;
+
+  c := c xor data[5];
+  a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+    ] xor s_T4[Byte(c shr 48)]);
+  b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+    ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+  b := b * 9;
+
+  a := a xor data[6];
+  b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+    ] xor s_T4[Byte(a shr 48)]);
+  c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2[Byte(a shr 40)
+    ] xor s_T1[Byte(a shr 56)]);
+  c := c * 9;
+
+  b := b xor data[7];
+  c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+    ] xor s_T4[Byte(b shr 48)]);
+  a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2[Byte(b shr 40)
+    ] xor s_T1[Byte(b shr 56)]);
+  a := a * 9;
+
+  rounds := 3;
+  while rounds < Fm_rounds do
+  begin
+
+    data[0] := data[0] - (data[7] xor C1);
+    data[1] := data[1] xor data[0];
+    data[2] := data[2] + data[1];
+    data[3] := data[3] - (data[2] xor (not data[1] shl 19));
+    data[4] := data[4] xor data[3];
+    data[5] := data[5] + data[4];
+    data[6] := data[6] - (data[5] xor (not data[4] shr 23));
+    data[7] := data[7] xor data[6];
+    data[0] := data[0] + data[7];
+    data[1] := data[1] - (data[0] xor (not data[7] shl 19));
+    data[2] := data[2] xor data[1];
+    data[3] := data[3] + data[2];
+    data[4] := data[4] - (data[3] xor (not data[2] shr 23));
+    data[5] := data[5] xor data[4];
+    data[6] := data[6] + data[5];
+    data[7] := data[7] - (data[6] xor C2);
+
+    c := c xor data[0];
+    a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+      ] xor s_T4[Byte(c shr 48)]);
+    b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+      ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+    b := b * 9;
+
+    a := a xor data[1];
+    b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+      ] xor s_T4[Byte(a shr 48)]);
+    c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2
+      [Byte(a shr 40)] xor s_T1[Byte(a shr 56)]);
+    c := c * 9;
+
+    b := b xor data[2];
+    c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+      ] xor s_T4[Byte(b shr 48)]);
+    a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2
+      [Byte(b shr 40)] xor s_T1[Byte(b shr 56)]);
+    a := a * 9;
+
+    c := c xor data[3];
+    a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+      ] xor s_T4[Byte(c shr 48)]);
+    b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+      ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+    b := b * 9;
+
+    a := a xor data[4];
+    b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+      ] xor s_T4[Byte(a shr 48)]);
+    c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2
+      [Byte(a shr 40)] xor s_T1[Byte(a shr 56)]);
+    c := c * 9;
+
+    b := b xor data[5];
+    c := c - (s_T1[Byte(b)] xor s_T2[Byte(b shr 16)] xor s_T3[Byte(b shr 32)
+      ] xor s_T4[Byte(b shr 48)]);
+    a := a + (s_T4[Byte(b shr 8)] xor s_T3[Byte(b shr 24)] xor s_T2
+      [Byte(b shr 40)] xor s_T1[Byte(b shr 56)]);
+    a := a * 9;
+
+    c := c xor data[6];
+    a := a - (s_T1[Byte(c)] xor s_T2[Byte(c shr 16)] xor s_T3[Byte(c shr 32)
+      ] xor s_T4[Byte(c shr 48)]);
+    b := b + (s_T4[Byte(c shr 8) and $FF] xor s_T3[Byte(c shr 24)
+      ] xor s_T2[Byte(c shr 40)] xor s_T1[Byte(c shr 56)]);
+    b := b * 9;
+
+    a := a xor data[7];
+    b := b - (s_T1[Byte(a)] xor s_T2[Byte(a shr 16)] xor s_T3[Byte(a shr 32)
+      ] xor s_T4[Byte(a shr 48)]);
+    c := c + (s_T4[Byte(a shr 8)] xor s_T3[Byte(a shr 24)] xor s_T2
+      [Byte(a shr 40)] xor s_T1[Byte(a shr 56)]);
+    c := c * 9;
+
+    temp_a := a;
+    a := c;
+    c := b;
+    b := temp_a;
+
+    System.Inc(rounds);
+  end;
+
+  Fm_hash[0] := Fm_hash[0] xor a;
+  Fm_hash[1] := b - Fm_hash[1];
+  Fm_hash[2] := Fm_hash[2] + c;
+
+  System.FillChar(data, System.SizeOf(data), 0);
+
+end;
+
+{ TTiger2_128 }
+
+constructor TTiger2_128.CreateRound3;
+begin
+  Inherited Create(16, THashRounds.hrRounds3);
+end;
+
+constructor TTiger2_128.CreateRound4;
+begin
+  Inherited Create(16, THashRounds.hrRounds4);
+end;
+
+constructor TTiger2_128.CreateRound5;
+begin
+  Inherited Create(16, THashRounds.hrRounds5);
+end;
+
+{ TTiger2_160 }
+
+constructor TTiger2_160.CreateRound3;
+begin
+  Inherited Create(20, THashRounds.hrRounds3);
+end;
+
+constructor TTiger2_160.CreateRound4;
+begin
+  Inherited Create(20, THashRounds.hrRounds4);
+end;
+
+constructor TTiger2_160.CreateRound5;
+begin
+  Inherited Create(20, THashRounds.hrRounds5);
+end;
+
+{ TTiger2_192 }
+
+constructor TTiger2_192.CreateRound3;
+begin
+  Inherited Create(24, THashRounds.hrRounds3);
+end;
+
+constructor TTiger2_192.CreateRound4;
+begin
+  Inherited Create(24, THashRounds.hrRounds4);
+end;
+
+constructor TTiger2_192.CreateRound5;
+begin
+  Inherited Create(24, THashRounds.hrRounds5);
+end;
+
+{ TTiger2_Base }
+
+constructor TTiger2_Base.Create(a_hash_size: Int32; a_rounds: THashRounds);
+begin
+  Inherited Create(a_hash_size, a_rounds);
+end;
+
+end.

+ 292 - 0
src/libraries/hashlib4pascal/HashLib/src/Crypto/HlpWhirlPool.pas

@@ -0,0 +1,292 @@
+unit HlpWhirlPool;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+  HlpHashBuffer,
+{$ENDIF DELPHI}
+  HlpConverters,
+  HlpIHashInfo,
+  HlpHashCryptoNotBuildIn;
+
+type
+  TWhirlPool = class sealed(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
+
+  strict private
+
+    Fm_hash: THashLibUInt64Array;
+
+    class var
+
+      Fs_C0, Fs_C1, Fs_C2, Fs_C3, Fs_C4, Fs_C5, Fs_C6, Fs_C7,
+      Fs_rc: THashLibUInt64Array;
+
+{$REGION 'Consts'}
+
+  const
+
+    ROUNDS = Int32(10);
+    REDUCTION_POLYNOMIAL = UInt32($011D);
+
+    s_SBOX: array [0 .. 255] of UInt32 = ($18, $23, $C6, $E8, $87, $B8, $01,
+      $4F, $36, $A6, $D2, $F5, $79, $6F, $91, $52, $60, $BC, $9B, $8E, $A3, $0C,
+      $7B, $35, $1D, $E0, $D7, $C2, $2E, $4B, $FE, $57, $15, $77, $37, $E5, $9F,
+      $F0, $4A, $DA, $58, $C9, $29, $0A, $B1, $A0, $6B, $85, $BD, $5D, $10, $F4,
+      $CB, $3E, $05, $67, $E4, $27, $41, $8B, $A7, $7D, $95, $D8, $FB, $EE, $7C,
+      $66, $DD, $17, $47, $9E, $CA, $2D, $BF, $07, $AD, $5A, $83, $33, $63, $02,
+      $AA, $71, $C8, $19, $49, $D9, $F2, $E3, $5B, $88, $9A, $26, $32, $B0, $E9,
+      $0F, $D5, $80, $BE, $CD, $34, $48, $FF, $7A, $90, $5F, $20, $68, $1A, $AE,
+      $B4, $54, $93, $22, $64, $F1, $73, $12, $40, $08, $C3, $EC, $DB, $A1, $8D,
+      $3D, $97, $00, $CF, $2B, $76, $82, $D6, $1B, $B5, $AF, $6A, $50, $45, $F3,
+      $30, $EF, $3F, $55, $A2, $EA, $65, $BA, $2F, $C0, $DE, $1C, $FD, $4D, $92,
+      $75, $06, $8A, $B2, $E6, $0E, $1F, $62, $D4, $A8, $96, $F9, $C5, $25, $59,
+      $84, $72, $39, $4C, $5E, $78, $38, $8C, $D1, $A5, $E2, $61, $B3, $21, $9C,
+      $1E, $43, $C7, $FC, $04, $51, $99, $6D, $0D, $FA, $DF, $7E, $24, $3B, $AB,
+      $CE, $11, $8F, $4E, $B7, $EB, $3C, $81, $94, $F7, $B9, $13, $2C, $D3, $E7,
+      $6E, $C4, $03, $56, $44, $7F, $A9, $2A, $BB, $C1, $53, $DC, $0B, $9D, $6C,
+      $31, $74, $F6, $46, $AC, $89, $14, $E1, $16, $3A, $69, $09, $70, $B6, $D0,
+      $ED, $CC, $42, $98, $A4, $28, $5C, $F8, $86);
+
+{$ENDREGION}
+    class constructor WhirlPool;
+
+    class function packIntoUInt64(b7, b6, b5, b4, b3, b2, b1, b0: UInt32)
+      : UInt64; static; inline;
+    class function maskWithReductionPolynomial(input: UInt32): UInt32;
+      static; inline;
+
+  strict protected
+    function GetResult(): THashLibByteArray; override;
+    procedure Finish(); override;
+    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
+      a_index: Int32); override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+
+  end;
+
+implementation
+
+{ TWhirlPool }
+
+constructor TWhirlPool.Create;
+begin
+  Inherited Create(64, 64);
+
+  System.SetLength(Fm_hash, 8);
+
+end;
+
+procedure TWhirlPool.Finish;
+var
+  bits: UInt64;
+  padindex: Int32;
+  pad: THashLibByteArray;
+begin
+  bits := Fm_processed_bytes * 8;
+  if (Fm_buffer.Pos > 31) then
+
+    padindex := (120 - Fm_buffer.Pos)
+  else
+    padindex := (56 - Fm_buffer.Pos);
+
+  System.SetLength(pad, padindex + 8);
+
+  pad[0] := $80;
+
+  bits := TConverters.be2me_64(bits);
+
+  TConverters.ReadUInt64AsBytesLE(bits, pad, padindex);
+
+  padindex := padindex + 8;
+
+  TransformBytes(pad, 0, padindex);
+
+end;
+
+function TWhirlPool.GetResult: THashLibByteArray;
+begin
+  System.SetLength(result, System.Length(Fm_hash) * System.SizeOf(UInt64));
+  TConverters.be64_copy(PUInt64(Fm_hash), 0, PByte(result), 0,
+    System.Length(result));
+end;
+
+procedure TWhirlPool.Initialize;
+begin
+
+  System.FillChar(Fm_hash[0], System.Length(Fm_hash) * System.SizeOf(UInt64),
+    UInt64(0));
+  Inherited Initialize();
+end;
+
+class function TWhirlPool.maskWithReductionPolynomial(input: UInt32): UInt32;
+begin
+  if (input >= $100) then
+    input := input xor REDUCTION_POLYNOMIAL;
+  result := input;
+end;
+
+class function TWhirlPool.packIntoUInt64(b7, b6, b5, b4, b3, b2, b1,
+  b0: UInt32): UInt64;
+begin
+  result := (UInt64(b7) shl 56) xor (UInt64(b6) shl 48) xor (UInt64(b5) shl 40)
+    xor (UInt64(b4) shl 32) xor (UInt64(b3) shl 24) xor (UInt64(b2) shl 16)
+    xor (UInt64(b1) shl 8) xor b0;
+end;
+
+procedure TWhirlPool.TransformBlock(a_data: PByte; a_data_length: Int32;
+  a_index: Int32);
+var
+  data, k, m, temp: array [0 .. 7] of UInt64;
+  i, round: Int32;
+
+begin
+
+  TConverters.be64_copy(a_data, a_index, @(data[0]), 0, a_data_length);
+
+  i := 0;
+  while i < 8 do
+  begin
+    k[i] := Fm_hash[i];
+    temp[i] := data[i] xor k[i];
+    System.Inc(i);
+  end;
+
+  round := 1;
+
+  while round <= ROUNDS do
+  begin
+
+    i := 0;
+
+    while i < 8 do
+    begin
+
+      m[i] := 0;
+      m[i] := m[i] xor (Fs_C0[Byte(k[(i - 0) and 7] shr 56)]);
+      m[i] := m[i] xor (Fs_C1[Byte(k[(i - 1) and 7] shr 48)]);
+      m[i] := m[i] xor (Fs_C2[Byte(k[(i - 2) and 7] shr 40)]);
+      m[i] := m[i] xor (Fs_C3[Byte(k[(i - 3) and 7] shr 32)]);
+      m[i] := m[i] xor (Fs_C4[Byte(k[(i - 4) and 7] shr 24)]);
+      m[i] := m[i] xor (Fs_C5[Byte(k[(i - 5) and 7] shr 16)]);
+      m[i] := m[i] xor (Fs_C6[Byte(k[(i - 6) and 7] shr 8)]);
+      m[i] := m[i] xor (Fs_C7[Byte(k[(i - 7) and 7])]);
+
+      System.Inc(i);
+    end;
+
+    System.Move(m[0], k[0], 8 * System.SizeOf(UInt64));
+
+    k[0] := k[0] xor Fs_rc[round];
+
+    i := 0;
+
+    while i < 8 do
+
+    begin
+      m[i] := k[i];
+
+      m[i] := m[i] xor (Fs_C0[Byte(temp[(i - 0) and 7] shr 56)]);
+      m[i] := m[i] xor (Fs_C1[Byte(temp[(i - 1) and 7] shr 48)]);
+      m[i] := m[i] xor (Fs_C2[Byte(temp[(i - 2) and 7] shr 40)]);
+      m[i] := m[i] xor (Fs_C3[Byte(temp[(i - 3) and 7] shr 32)]);
+      m[i] := m[i] xor (Fs_C4[Byte(temp[(i - 4) and 7] shr 24)]);
+      m[i] := m[i] xor (Fs_C5[Byte(temp[(i - 5) and 7] shr 16)]);
+      m[i] := m[i] xor (Fs_C6[Byte(temp[(i - 6) and 7] shr 8)]);
+      m[i] := m[i] xor (Fs_C7[Byte(temp[(i - 7) and 7])]);
+
+      System.Inc(i);
+    end;
+
+    System.Move(m[0], temp[0], System.Length(temp) * System.SizeOf(UInt64));
+
+    System.Inc(round);
+
+  end;
+
+  i := 0;
+
+  while i < 8 do
+  begin
+    Fm_hash[i] := Fm_hash[i] xor (temp[i] xor data[i]);
+
+    System.Inc(i);
+  end;
+
+  System.FillChar(data, System.SizeOf(data), 0);
+
+end;
+
+class constructor TWhirlPool.WhirlPool;
+var
+  i, r: Int32;
+  v1, v2, v4, v5, v8, v9: UInt32;
+begin
+
+  System.SetLength(Fs_C0, 256);
+  System.SetLength(Fs_C1, 256);
+  System.SetLength(Fs_C2, 256);
+  System.SetLength(Fs_C3, 256);
+  System.SetLength(Fs_C4, 256);
+  System.SetLength(Fs_C5, 256);
+  System.SetLength(Fs_C6, 256);
+  System.SetLength(Fs_C7, 256);
+
+  System.SetLength(Fs_rc, ROUNDS + 1);
+
+  i := 0;
+  while i < 256 do
+
+  begin
+    v1 := s_SBOX[i];
+    v2 := maskWithReductionPolynomial(v1 shl 1);
+    v4 := maskWithReductionPolynomial(v2 shl 1);
+    v5 := v4 xor v1;
+    v8 := maskWithReductionPolynomial(v4 shl 1);
+    v9 := v8 xor v1;
+
+    Fs_C0[i] := packIntoUInt64(v1, v1, v4, v1, v8, v5, v2, v9);
+    Fs_C1[i] := packIntoUInt64(v9, v1, v1, v4, v1, v8, v5, v2);
+    Fs_C2[i] := packIntoUInt64(v2, v9, v1, v1, v4, v1, v8, v5);
+    Fs_C3[i] := packIntoUInt64(v5, v2, v9, v1, v1, v4, v1, v8);
+    Fs_C4[i] := packIntoUInt64(v8, v5, v2, v9, v1, v1, v4, v1);
+    Fs_C5[i] := packIntoUInt64(v1, v8, v5, v2, v9, v1, v1, v4);
+    Fs_C6[i] := packIntoUInt64(v4, v1, v8, v5, v2, v9, v1, v1);
+    Fs_C7[i] := packIntoUInt64(v1, v4, v1, v8, v5, v2, v9, v1);
+
+    System.Inc(i);
+  end;
+
+  Fs_rc[0] := 0;
+
+  r := 1;
+
+  while r <= ROUNDS do
+
+  begin
+
+    i := 8 * (r - 1);
+    Fs_rc[r] := (Fs_C0[i] and $FF00000000000000)
+      xor (Fs_C1[i + 1] and $00FF000000000000)
+      xor (Fs_C2[i + 2] and $0000FF0000000000)
+      xor (Fs_C3[i + 3] and $000000FF00000000)
+      xor (Fs_C4[i + 4] and $00000000FF000000)
+      xor (Fs_C5[i + 5] and $0000000000FF0000)
+      xor (Fs_C6[i + 6] and $000000000000FF00)
+      xor (Fs_C7[i + 7] and $00000000000000FF);
+
+    System.Inc(r);
+  end;
+end;
+
+end.

+ 494 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash128/HlpMurmurHash3_x64_128.pas

@@ -0,0 +1,494 @@
+unit HlpMurmurHash3_x64_128;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpHashLibTypes,
+  HlpConverters,
+  HlpIHashInfo,
+  HlpNullable,
+  HlpHash,
+  HlpHashResult,
+  HlpIHashResult,
+  HlpBits;
+
+resourcestring
+  SInvalidKeyLength = 'KeyLength Must Be Equal to %d';
+
+type
+  TMurmurHash3_x64_128 = class sealed(THash, IHash128, IHashWithKey,
+    ITransformBlock)
+
+  strict private
+
+    Fm_h1, Fm_h2, Fm_total_length: UInt64;
+    Fm_key: UInt32;
+    Fm_idx: Int32;
+    Fm_buf: THashLibByteArray;
+
+    procedure ByteUpdate(a_b: Byte); inline;
+    procedure Finish();
+
+{$REGION 'Consts'}
+
+  const
+    CKEY = UInt32($0);
+
+{$IFDEF FPC}
+    // to bypass Internal error (200706094) on FPC, We use "Typed Constant".
+
+    C1: UInt64 = UInt64($87C37B91114253D5);
+    C5: UInt64 = UInt64($FF51AFD7ED558CCD);
+    C6: UInt64 = UInt64($C4CEB9FE1A85EC53);
+
+{$ELSE}
+    C1 = UInt64($87C37B91114253D5);
+    C5 = UInt64($FF51AFD7ED558CCD);
+    C6 = UInt64($C4CEB9FE1A85EC53);
+{$ENDIF FPC}
+    C2 = UInt64($4CF5AD432745937F);
+    C3 = UInt32($52DCE729);
+    C4 = UInt32($38495AB5);
+{$ENDREGION}
+    function GetKeyLength(): TNullableInteger;
+    function GetKey: THashLibByteArray; inline;
+    procedure SetKey(value: THashLibByteArray); inline;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal: IHashResult; override;
+    property KeyLength: TNullableInteger read GetKeyLength;
+    property Key: THashLibByteArray read GetKey write SetKey;
+  end;
+
+implementation
+
+{ TMurmurHash3_x64_128 }
+
+procedure TMurmurHash3_x64_128.ByteUpdate(a_b: Byte);
+var
+  k1, k2: UInt64;
+  ptr_Fm_buf: PByte;
+begin
+  Fm_buf[Fm_idx] := a_b;
+  System.Inc(Fm_idx);
+  if Fm_idx >= 16 then
+  begin
+    ptr_Fm_buf := PByte(Fm_buf);
+    k1 := TConverters.ReadBytesAsUInt64LE(ptr_Fm_buf, 0);
+    k2 := TConverters.ReadBytesAsUInt64LE(ptr_Fm_buf, 8);
+
+    k1 := k1 * C1;
+    k1 := TBits.RotateLeft64(k1, 31);
+    k1 := k1 * C2;
+    Fm_h1 := Fm_h1 xor k1;
+
+    Fm_h1 := TBits.RotateLeft64(Fm_h1, 27);
+    Fm_h1 := Fm_h1 + Fm_h2;
+    Fm_h1 := Fm_h1 * 5 + C3;
+
+    k2 := k2 * C2;
+    k2 := TBits.RotateLeft64(k2, 33);
+    k2 := k2 * C1;
+    Fm_h2 := Fm_h2 xor k2;
+
+    Fm_h2 := TBits.RotateLeft64(Fm_h2, 31);
+    Fm_h2 := Fm_h2 + Fm_h1;
+    Fm_h2 := Fm_h2 * 5 + C4;
+
+    Fm_idx := 0;
+  end;
+end;
+
+constructor TMurmurHash3_x64_128.Create;
+begin
+  Inherited Create(16, 16);
+  Fm_key := CKEY;
+  System.SetLength(Fm_buf, 16);
+
+end;
+
+procedure TMurmurHash3_x64_128.Finish;
+var
+  &length: Int32;
+  k2, k1: UInt64;
+begin
+
+  // tail
+
+  k1 := 0;
+  k2 := 0;
+
+  length := Fm_idx;
+
+  if (length <> 0) then
+  begin
+
+    case length of
+      15:
+        begin
+
+          k2 := k2 xor (UInt64(Fm_buf[14]) shl 48);
+          k2 := k2 xor (UInt64(Fm_buf[13]) shl 40);
+          k2 := k2 xor (UInt64(Fm_buf[12]) shl 32);
+          k2 := k2 xor (UInt64(Fm_buf[11]) shl 24);
+          k2 := k2 xor (UInt64(Fm_buf[10]) shl 16);
+          k2 := k2 xor (UInt64(Fm_buf[9]) shl 8);
+          k2 := k2 xor (UInt64(Fm_buf[8]) shl 0);
+          k2 := k2 * C2;
+          k2 := TBits.RotateLeft64(k2, 33);
+          k2 := k2 * C1;
+          Fm_h2 := Fm_h2 xor k2;
+        end;
+
+      14:
+        begin
+
+          k2 := k2 xor (UInt64(Fm_buf[13]) shl 40);
+          k2 := k2 xor (UInt64(Fm_buf[12]) shl 32);
+          k2 := k2 xor (UInt64(Fm_buf[11]) shl 24);
+          k2 := k2 xor (UInt64(Fm_buf[10]) shl 16);
+          k2 := k2 xor (UInt64(Fm_buf[9]) shl 8);
+          k2 := k2 xor (UInt64(Fm_buf[8]) shl 0);
+          k2 := k2 * C2;
+          k2 := TBits.RotateLeft64(k2, 33);
+          k2 := k2 * C1;
+          Fm_h2 := Fm_h2 xor k2;
+        end;
+
+      13:
+        begin
+
+          k2 := k2 xor (UInt64(Fm_buf[12]) shl 32);
+          k2 := k2 xor (UInt64(Fm_buf[11]) shl 24);
+          k2 := k2 xor (UInt64(Fm_buf[10]) shl 16);
+          k2 := k2 xor (UInt64(Fm_buf[9]) shl 8);
+          k2 := k2 xor (UInt64(Fm_buf[8]) shl 0);
+          k2 := k2 * C2;
+          k2 := TBits.RotateLeft64(k2, 33);
+          k2 := k2 * C1;
+          Fm_h2 := Fm_h2 xor k2;
+        end;
+
+      12:
+        begin
+
+          k2 := k2 xor (UInt64(Fm_buf[11]) shl 24);
+          k2 := k2 xor (UInt64(Fm_buf[10]) shl 16);
+          k2 := k2 xor (UInt64(Fm_buf[9]) shl 8);
+          k2 := k2 xor (UInt64(Fm_buf[8]) shl 0);
+          k2 := k2 * C2;
+          k2 := TBits.RotateLeft64(k2, 33);
+          k2 := k2 * C1;
+          Fm_h2 := Fm_h2 xor k2;
+        end;
+
+      11:
+        begin
+
+          k2 := k2 xor (UInt64(Fm_buf[10]) shl 16);
+          k2 := k2 xor (UInt64(Fm_buf[9]) shl 8);
+          k2 := k2 xor (UInt64(Fm_buf[8]) shl 0);
+          k2 := k2 * C2;
+          k2 := TBits.RotateLeft64(k2, 33);
+          k2 := k2 * C1;
+          Fm_h2 := Fm_h2 xor k2;
+        end;
+
+      10:
+        begin
+
+          k2 := k2 xor (UInt64(Fm_buf[9]) shl 8);
+          k2 := k2 xor (UInt64(Fm_buf[8]) shl 0);
+          k2 := k2 * C2;
+          k2 := TBits.RotateLeft64(k2, 33);
+          k2 := k2 * C1;
+          Fm_h2 := Fm_h2 xor k2;
+        end;
+
+      9:
+        begin
+
+          k2 := k2 xor (UInt64(Fm_buf[8]) shl 0);
+          k2 := k2 * C2;
+          k2 := TBits.RotateLeft64(k2, 33);
+          k2 := k2 * C1;
+          Fm_h2 := Fm_h2 xor k2;
+        end;
+
+    end;
+
+    if (length > 8) then
+      length := 8;
+
+    case length of
+      8:
+        begin
+
+          k1 := k1 xor (UInt64(Fm_buf[7]) shl 56);
+          k1 := k1 xor (UInt64(Fm_buf[6]) shl 48);
+          k1 := k1 xor (UInt64(Fm_buf[5]) shl 40);
+          k1 := k1 xor (UInt64(Fm_buf[4]) shl 32);
+          k1 := k1 xor (UInt64(Fm_buf[3]) shl 24);
+          k1 := k1 xor (UInt64(Fm_buf[2]) shl 16);
+          k1 := k1 xor (UInt64(Fm_buf[1]) shl 8);
+          k1 := k1 xor (UInt64(Fm_buf[0]) shl 0);
+          k1 := k1 * C1;
+          k1 := TBits.RotateLeft64(k1, 31);
+          k1 := k1 * C2;
+          Fm_h1 := Fm_h1 xor k1;
+        end;
+
+      7:
+        begin
+
+          k1 := k1 xor (UInt64(Fm_buf[6]) shl 48);
+          k1 := k1 xor (UInt64(Fm_buf[5]) shl 40);
+          k1 := k1 xor (UInt64(Fm_buf[4]) shl 32);
+          k1 := k1 xor (UInt64(Fm_buf[3]) shl 24);
+          k1 := k1 xor (UInt64(Fm_buf[2]) shl 16);
+          k1 := k1 xor (UInt64(Fm_buf[1]) shl 8);
+          k1 := k1 xor (UInt64(Fm_buf[0]) shl 0);
+          k1 := k1 * C1;
+          k1 := TBits.RotateLeft64(k1, 31);
+          k1 := k1 * C2;
+          Fm_h1 := Fm_h1 xor k1;
+        end;
+
+      6:
+        begin
+
+          k1 := k1 xor (UInt64(Fm_buf[5]) shl 40);
+          k1 := k1 xor (UInt64(Fm_buf[4]) shl 32);
+          k1 := k1 xor (UInt64(Fm_buf[3]) shl 24);
+          k1 := k1 xor (UInt64(Fm_buf[2]) shl 16);
+          k1 := k1 xor (UInt64(Fm_buf[1]) shl 8);
+          k1 := k1 xor (UInt64(Fm_buf[0]) shl 0);
+          k1 := k1 * C1;
+          k1 := TBits.RotateLeft64(k1, 31);
+          k1 := k1 * C2;
+          Fm_h1 := Fm_h1 xor k1;
+        end;
+
+      5:
+        begin
+
+          k1 := k1 xor (UInt64(Fm_buf[4]) shl 32);
+          k1 := k1 xor (UInt64(Fm_buf[3]) shl 24);
+          k1 := k1 xor (UInt64(Fm_buf[2]) shl 16);
+          k1 := k1 xor (UInt64(Fm_buf[1]) shl 8);
+          k1 := k1 xor (UInt64(Fm_buf[0]) shl 0);
+          k1 := k1 * C1;
+          k1 := TBits.RotateLeft64(k1, 31);
+          k1 := k1 * C2;
+          Fm_h1 := Fm_h1 xor k1;
+        end;
+
+      4:
+        begin
+
+          k1 := k1 xor (UInt64(Fm_buf[3]) shl 24);
+          k1 := k1 xor (UInt64(Fm_buf[2]) shl 16);
+          k1 := k1 xor (UInt64(Fm_buf[1]) shl 8);
+          k1 := k1 xor (UInt64(Fm_buf[0]) shl 0);
+          k1 := k1 * C1;
+          k1 := TBits.RotateLeft64(k1, 31);
+          k1 := k1 * C2;
+          Fm_h1 := Fm_h1 xor k1;
+        end;
+
+      3:
+        begin
+
+          k1 := k1 xor (UInt64(Fm_buf[2]) shl 16);
+          k1 := k1 xor (UInt64(Fm_buf[1]) shl 8);
+          k1 := k1 xor (UInt64(Fm_buf[0]) shl 0);
+          k1 := k1 * C1;
+          k1 := TBits.RotateLeft64(k1, 31);
+          k1 := k1 * C2;
+          Fm_h1 := Fm_h1 xor k1;
+        end;
+
+      2:
+        begin
+
+          k1 := k1 xor (UInt64(Fm_buf[1]) shl 8);
+          k1 := k1 xor (UInt64(Fm_buf[0]) shl 0);
+          k1 := k1 * C1;
+          k1 := TBits.RotateLeft64(k1, 31);
+          k1 := k1 * C2;
+          Fm_h1 := Fm_h1 xor k1;
+        end;
+
+      1:
+        begin
+
+          k1 := k1 xor (UInt64(Fm_buf[0]) shl 0);
+          k1 := k1 * C1;
+          k1 := TBits.RotateLeft64(k1, 31);
+          k1 := k1 * C2;
+          Fm_h1 := Fm_h1 xor k1;
+        end;
+
+    end;
+
+  end;
+
+  Fm_h1 := Fm_h1 xor Fm_total_length;
+  Fm_h2 := Fm_h2 xor Fm_total_length;
+
+  Fm_h1 := Fm_h1 + Fm_h2;
+  Fm_h2 := Fm_h2 + Fm_h1;
+
+  Fm_h1 := Fm_h1 xor (Fm_h1 shr 33);
+  Fm_h1 := Fm_h1 * C5;
+  Fm_h1 := Fm_h1 xor (Fm_h1 shr 33);
+  Fm_h1 := Fm_h1 * C6;
+  Fm_h1 := Fm_h1 xor (Fm_h1 shr 33);
+
+  Fm_h2 := Fm_h2 xor (Fm_h2 shr 33);
+  Fm_h2 := Fm_h2 * C5;
+  Fm_h2 := Fm_h2 xor (Fm_h2 shr 33);
+  Fm_h2 := Fm_h2 * C6;
+  Fm_h2 := Fm_h2 xor (Fm_h2 shr 33);
+
+  Fm_h1 := Fm_h1 + Fm_h2;
+  Fm_h2 := Fm_h2 + Fm_h1;
+
+end;
+
+function TMurmurHash3_x64_128.GetKey: THashLibByteArray;
+begin
+  result := TConverters.ReadUInt32AsBytesLE(Fm_key);
+end;
+
+function TMurmurHash3_x64_128.GetKeyLength: TNullableInteger;
+begin
+  result := 4;
+end;
+
+procedure TMurmurHash3_x64_128.Initialize;
+begin
+  Fm_h1 := Fm_key;
+  Fm_h2 := Fm_key;
+
+  Fm_total_length := 0;
+  Fm_idx := 0;
+
+end;
+
+procedure TMurmurHash3_x64_128.SetKey(value: THashLibByteArray);
+begin
+  if (value = Nil) then
+  begin
+    Fm_key := CKEY;
+  end
+
+  else
+  begin
+    if System.length(value) <> KeyLength.value then
+      raise EArgumentHashLibException.CreateResFmt(@SInvalidKeyLength,
+        [KeyLength.value]);
+
+    Fm_key := TConverters.ReadBytesAsUInt32LE(PByte(value), 0);
+
+  end;
+end;
+
+procedure TMurmurHash3_x64_128.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  len, nBlocks, i, offset, lIdx: Int32;
+  k1, k2: UInt64;
+  ptr_a_data: PByte;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.length(a_data));
+{$ENDIF DEBUG}
+  len := a_length;
+  i := a_index;
+  lIdx := 0;
+  nBlocks := len shr 4;
+
+  ptr_a_data := PByte(a_data);
+
+  // body
+
+  while i < nBlocks do
+  begin
+
+    k1 := TConverters.ReadBytesAsUInt64LE(ptr_a_data, lIdx);
+
+    System.Inc(lIdx, 8);
+
+    k2 := TConverters.ReadBytesAsUInt64LE(ptr_a_data, lIdx);
+
+    System.Inc(lIdx, 8);
+
+    k1 := k1 * C1;
+    k1 := TBits.RotateLeft64(k1, 31);
+    k1 := k1 * C2;
+    Fm_h1 := Fm_h1 xor k1;
+
+    Fm_h1 := TBits.RotateLeft64(Fm_h1, 27);
+    Fm_h1 := Fm_h1 + Fm_h2;
+    Fm_h1 := Fm_h1 * 5 + C3;
+
+    k2 := k2 * C2;
+    k2 := TBits.RotateLeft64(k2, 33);
+    k2 := k2 * C1;
+    Fm_h2 := Fm_h2 xor k2;
+
+    Fm_h2 := TBits.RotateLeft64(Fm_h2, 31);
+    Fm_h2 := Fm_h2 + Fm_h1;
+    Fm_h2 := Fm_h2 * 5 + C4;
+
+    System.Inc(i);
+  end;
+
+  System.Inc(Fm_total_length, len);
+
+  offset := (i * 16);
+
+  while offset < len do
+  begin
+
+    ByteUpdate(a_data[offset]);
+    System.Inc(offset);
+
+  end;
+
+end;
+
+function TMurmurHash3_x64_128.TransformFinal: IHashResult;
+var
+  tempBufByte: THashLibByteArray;
+  tempBufUInt64: THashLibUInt64Array;
+begin
+  Finish();
+
+  tempBufUInt64 := THashLibUInt64Array.Create(Fm_h1, Fm_h2);
+  System.SetLength(tempBufByte, System.length(tempBufUInt64) *
+    System.SizeOf(UInt64));
+  TConverters.be64_copy(PUInt64(tempBufUInt64), 0, PByte(tempBufByte), 0,
+    System.length(tempBufByte));
+
+  result := THashResult.Create(tempBufByte);
+
+  Initialize();
+end;
+
+end.

+ 561 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash128/HlpMurmurHash3_x86_128.pas

@@ -0,0 +1,561 @@
+unit HlpMurmurHash3_x86_128;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+  HlpConverters,
+  HlpIHashInfo,
+  HlpNullable,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpHash,
+  HlpHashResult,
+  HlpIHashResult,
+  HlpBits;
+
+resourcestring
+  SInvalidKeyLength = 'KeyLength Must Be Equal to %d';
+
+type
+  TMurmurHash3_x86_128 = class sealed(THash, IHash128, IHashWithKey,
+    ITransformBlock)
+
+  strict private
+
+    Fm_key, Fm_h1, Fm_h2, Fm_h3, Fm_h4, Fm_total_length: UInt32;
+    Fm_idx: Int32;
+    Fm_buf: THashLibByteArray;
+
+    procedure ByteUpdate(a_b: Byte);
+    procedure Finish();
+
+{$REGION 'Consts'}
+
+  const
+    CKEY = UInt32($0);
+
+    C1 = UInt32($239B961B);
+    C2 = UInt32($AB0E9789);
+    C3 = UInt32($38B34AE5);
+    C4 = UInt32($A1E38B93);
+    C5 = UInt32($85EBCA6B);
+    C6 = UInt32($C2B2AE35);
+
+    C7 = UInt32($561CCD1B);
+    C8 = UInt32($0BCAA747);
+    C9 = UInt32($96CD1C35);
+    C10 = UInt32($32AC3B17);
+
+{$ENDREGION}
+    function GetKeyLength(): TNullableInteger;
+    function GetKey: THashLibByteArray; inline;
+    procedure SetKey(value: THashLibByteArray); inline;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal: IHashResult; override;
+    property KeyLength: TNullableInteger read GetKeyLength;
+    property Key: THashLibByteArray read GetKey write SetKey;
+  end;
+
+implementation
+
+{ TMurmurHash3_x86_128 }
+
+procedure TMurmurHash3_x86_128.ByteUpdate(a_b: Byte);
+var
+  k1, k2, k3, k4: UInt32;
+  ptr_Fm_buf: PByte;
+begin
+  Fm_buf[Fm_idx] := a_b;
+  System.Inc(Fm_idx);
+  if Fm_idx >= 16 then
+  begin
+    ptr_Fm_buf := PByte(Fm_buf);
+    k1 := TConverters.ReadBytesAsUInt32LE(ptr_Fm_buf, 0);
+    k2 := TConverters.ReadBytesAsUInt32LE(ptr_Fm_buf, 4);
+    k3 := TConverters.ReadBytesAsUInt32LE(ptr_Fm_buf, 8);
+    k4 := TConverters.ReadBytesAsUInt32LE(ptr_Fm_buf, 12);
+
+    k1 := k1 * C1;
+    k1 := TBits.RotateLeft32(k1, 15);
+    k1 := k1 * C2;
+    Fm_h1 := Fm_h1 xor k1;
+
+    Fm_h1 := TBits.RotateLeft32(Fm_h1, 19);
+
+    Fm_h1 := Fm_h1 + Fm_h2;
+    Fm_h1 := Fm_h1 * 5 + C7;
+
+    k2 := k2 * C2;
+    k2 := TBits.RotateLeft32(k2, 16);
+    k2 := k2 * C3;
+    Fm_h2 := Fm_h2 xor k2;
+
+    Fm_h2 := TBits.RotateLeft32(Fm_h2, 17);
+
+    Fm_h2 := Fm_h2 + Fm_h3;
+    Fm_h2 := Fm_h2 * 5 + C8;
+
+    k3 := k3 * C3;
+    k3 := TBits.RotateLeft32(k3, 17);
+    k3 := k3 * C4;
+    Fm_h3 := Fm_h3 xor k3;
+
+    Fm_h3 := TBits.RotateLeft32(Fm_h3, 15);
+
+    Fm_h3 := Fm_h3 + Fm_h4;
+    Fm_h3 := Fm_h3 * 5 + C9;
+
+    k4 := k4 * C4;
+    k4 := TBits.RotateLeft32(k4, 18);
+    k4 := k4 * C1;
+    Fm_h4 := Fm_h4 xor k4;
+
+    Fm_h4 := TBits.RotateLeft32(Fm_h4, 13);
+
+    Fm_h4 := Fm_h4 + Fm_h1;
+    Fm_h4 := Fm_h4 * 5 + C10;
+
+    Fm_idx := 0;
+  end;
+end;
+
+constructor TMurmurHash3_x86_128.Create;
+begin
+  Inherited Create(16, 16);
+  Fm_key := CKEY;
+  System.SetLength(Fm_buf, 16);
+
+end;
+
+procedure TMurmurHash3_x86_128.Finish;
+var
+  k1, k2, k3, k4: UInt32;
+  &length: Int32;
+begin
+
+  // tail
+
+  k1 := 0;
+  k2 := 0;
+  k3 := 0;
+  k4 := 0;
+
+  length := Fm_idx;
+  if (length <> 0) then
+  begin
+    case (length) of
+      15:
+        begin
+
+          k4 := k4 xor (Fm_buf[14] shl 16);
+          k4 := k4 xor (Fm_buf[13] shl 8);
+          k4 := k4 xor (Fm_buf[12] shl 0);
+
+          k4 := k4 * C4;
+          k4 := TBits.RotateLeft32(k4, 18);
+          k4 := k4 * C1;
+          Fm_h4 := Fm_h4 xor k4;
+        end;
+
+      14:
+        begin
+
+          k4 := k4 xor (Fm_buf[13] shl 8);
+          k4 := k4 xor (Fm_buf[12] shl 0);
+          k4 := k4 * C4;
+          k4 := TBits.RotateLeft32(k4, 18);
+          k4 := k4 * C1;
+          Fm_h4 := Fm_h4 xor k4;
+        end;
+
+      13:
+        begin
+
+          k4 := k4 xor (Fm_buf[12] shl 0);
+          k4 := k4 * C4;
+          k4 := TBits.RotateLeft32(k4, 18);
+          k4 := k4 * C1;
+          Fm_h4 := Fm_h4 xor k4;
+        end;
+
+    end;
+
+    if (length > 12) then
+      length := 12;
+
+    case length of
+
+      12:
+        begin
+
+          k3 := k3 xor (Fm_buf[11] shl 24);
+          k3 := k3 xor (Fm_buf[10] shl 16);
+          k3 := k3 xor (Fm_buf[9] shl 8);
+          k3 := k3 xor (Fm_buf[8] shl 0);
+
+          k3 := k3 * C3;
+          k3 := TBits.RotateLeft32(k3, 17);
+          k3 := k3 * C4;
+          Fm_h3 := Fm_h3 xor k3;
+        end;
+
+      11:
+        begin
+
+          k3 := k3 xor (Fm_buf[10] shl 16);
+          k3 := k3 xor (Fm_buf[9] shl 8);
+          k3 := k3 xor (Fm_buf[8] shl 0);
+
+          k3 := k3 * C3;
+          k3 := TBits.RotateLeft32(k3, 17);
+          k3 := k3 * C4;
+          Fm_h3 := Fm_h3 xor k3;
+        end;
+
+      10:
+        begin
+
+          k3 := k3 xor (Fm_buf[9] shl 8);
+          k3 := k3 xor (Fm_buf[8] shl 0);
+
+          k3 := k3 * C3;
+          k3 := TBits.RotateLeft32(k3, 17);
+          k3 := k3 * C4;
+          Fm_h3 := Fm_h3 xor k3;
+        end;
+
+      9:
+        begin
+
+          k3 := k3 xor (Fm_buf[8] shl 0);
+
+          k3 := k3 * C3;
+          k3 := TBits.RotateLeft32(k3, 17);
+          k3 := k3 * C4;
+          Fm_h3 := Fm_h3 xor k3;
+        end;
+
+    end;
+
+    if (length > 8) then
+      length := 8;
+
+    case length of
+
+      8:
+        begin
+
+          k2 := k2 xor (Fm_buf[7] shl 24);
+          k2 := k2 xor (Fm_buf[6] shl 16);
+          k2 := k2 xor (Fm_buf[5] shl 8);
+          k2 := k2 xor (Fm_buf[4] shl 0);
+
+          k2 := k2 * C2;
+          k2 := TBits.RotateLeft32(k2, 16);
+          k2 := k2 * C3;
+          Fm_h2 := Fm_h2 xor k2;
+        end;
+
+      7:
+        begin
+
+          k2 := k2 xor (Fm_buf[6] shl 16);
+          k2 := k2 xor (Fm_buf[5] shl 8);
+          k2 := k2 xor (Fm_buf[4] shl 0);
+
+          k2 := k2 * C2;
+          k2 := TBits.RotateLeft32(k2, 16);
+          k2 := k2 * C3;
+          Fm_h2 := Fm_h2 xor k2;
+        end;
+
+      6:
+        begin
+
+          k2 := k2 xor (Fm_buf[5] shl 8);
+          k2 := k2 xor (Fm_buf[4] shl 0);
+
+          k2 := k2 * C2;
+          k2 := TBits.RotateLeft32(k2, 16);
+          k2 := k2 * C3;
+          Fm_h2 := Fm_h2 xor k2;
+        end;
+
+      5:
+        begin
+
+          k2 := k2 xor (Fm_buf[4] shl 0);
+
+          k2 := k2 * C2;
+          k2 := TBits.RotateLeft32(k2, 16);
+          k2 := k2 * C3;
+          Fm_h2 := Fm_h2 xor k2;
+        end;
+
+    end;
+
+    if (length > 4) then
+      length := 4;
+
+    case length of
+
+      4:
+        begin
+
+          k1 := k1 xor (Fm_buf[3] shl 24);
+          k1 := k1 xor (Fm_buf[2] shl 16);
+          k1 := k1 xor (Fm_buf[1] shl 8);
+          k1 := k1 xor (Fm_buf[0] shl 0);
+
+          k1 := k1 * C1;
+          k1 := TBits.RotateLeft32(k1, 15);
+          k1 := k1 * C2;
+          Fm_h1 := Fm_h1 xor k1;
+        end;
+
+      3:
+        begin
+
+          k1 := k1 xor (Fm_buf[2] shl 16);
+          k1 := k1 xor (Fm_buf[1] shl 8);
+          k1 := k1 xor (Fm_buf[0] shl 0);
+
+          k1 := k1 * C1;
+          k1 := TBits.RotateLeft32(k1, 15);
+          k1 := k1 * C2;
+          Fm_h1 := Fm_h1 xor k1;
+        end;
+
+      2:
+        begin
+
+          k1 := k1 xor (Fm_buf[1] shl 8);
+          k1 := k1 xor (Fm_buf[0] shl 0);
+
+          k1 := k1 * C1;
+          k1 := TBits.RotateLeft32(k1, 15);
+          k1 := k1 * C2;
+          Fm_h1 := Fm_h1 xor k1;
+        end;
+
+      1:
+        begin
+
+          k1 := k1 xor (Fm_buf[0] shl 0);
+
+          k1 := k1 * C1;
+          k1 := TBits.RotateLeft32(k1, 15);
+          k1 := k1 * C2;
+          Fm_h1 := Fm_h1 xor k1;
+        end;
+
+    end;
+  end;
+
+  // finalization
+
+  Fm_h1 := Fm_h1 xor Fm_total_length;
+  Fm_h2 := Fm_h2 xor Fm_total_length;
+  Fm_h3 := Fm_h3 xor Fm_total_length;
+  Fm_h4 := Fm_h4 xor Fm_total_length;
+
+  Fm_h1 := Fm_h1 + Fm_h2;
+  Fm_h1 := Fm_h1 + Fm_h3;
+  Fm_h1 := Fm_h1 + Fm_h4;
+  Fm_h2 := Fm_h2 + Fm_h1;
+  Fm_h3 := Fm_h3 + Fm_h1;
+  Fm_h4 := Fm_h4 + Fm_h1;
+
+  Fm_h1 := Fm_h1 xor (Fm_h1 shr 16);
+  Fm_h1 := Fm_h1 * C5;
+  Fm_h1 := Fm_h1 xor (Fm_h1 shr 13);
+  Fm_h1 := Fm_h1 * C6;
+  Fm_h1 := Fm_h1 xor (Fm_h1 shr 16);
+
+  Fm_h2 := Fm_h2 xor (Fm_h2 shr 16);
+  Fm_h2 := Fm_h2 * C5;
+  Fm_h2 := Fm_h2 xor (Fm_h2 shr 13);
+  Fm_h2 := Fm_h2 * C6;
+  Fm_h2 := Fm_h2 xor (Fm_h2 shr 16);
+
+  Fm_h3 := Fm_h3 xor (Fm_h3 shr 16);
+  Fm_h3 := Fm_h3 * C5;
+  Fm_h3 := Fm_h3 xor (Fm_h3 shr 13);
+  Fm_h3 := Fm_h3 * C6;
+  Fm_h3 := Fm_h3 xor (Fm_h3 shr 16);
+
+  Fm_h4 := Fm_h4 xor (Fm_h4 shr 16);
+  Fm_h4 := Fm_h4 * C5;
+  Fm_h4 := Fm_h4 xor (Fm_h4 shr 13);
+  Fm_h4 := Fm_h4 * C6;
+  Fm_h4 := Fm_h4 xor (Fm_h4 shr 16);
+
+  Fm_h1 := Fm_h1 + Fm_h2;
+  Fm_h1 := Fm_h1 + Fm_h3;
+  Fm_h1 := Fm_h1 + Fm_h4;
+  Fm_h2 := Fm_h2 + Fm_h1;
+  Fm_h3 := Fm_h3 + Fm_h1;
+  Fm_h4 := Fm_h4 + Fm_h1;
+
+end;
+
+function TMurmurHash3_x86_128.GetKey: THashLibByteArray;
+begin
+  result := TConverters.ReadUInt32AsBytesLE(Fm_key);
+end;
+
+function TMurmurHash3_x86_128.GetKeyLength: TNullableInteger;
+begin
+  result := 4;
+end;
+
+procedure TMurmurHash3_x86_128.Initialize;
+begin
+  Fm_h1 := Fm_key;
+  Fm_h2 := Fm_key;
+  Fm_h3 := Fm_key;
+  Fm_h4 := Fm_key;
+
+  Fm_total_length := 0;
+  Fm_idx := 0;
+
+end;
+
+procedure TMurmurHash3_x86_128.SetKey(value: THashLibByteArray);
+begin
+  if (value = Nil) then
+  begin
+    Fm_key := CKEY;
+  end
+
+  else
+  begin
+    if System.length(value) <> KeyLength.value then
+      raise EArgumentHashLibException.CreateResFmt(@SInvalidKeyLength,
+        [KeyLength.value]);
+    Fm_key := TConverters.ReadBytesAsUInt32LE(PByte(value), 0);
+
+  end;
+end;
+
+procedure TMurmurHash3_x86_128.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  len, nBlocks, i, offset, lIdx: Int32;
+  k1, k2, k3, k4: UInt32;
+  ptr_a_data: PByte;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.length(a_data));
+{$ENDIF DEBUG}
+  len := a_length;
+  i := a_index;
+  lIdx := 0;
+  nBlocks := len shr 4;
+
+  ptr_a_data := PByte(a_data);
+
+  // body
+
+  while i < nBlocks do
+  begin
+
+    k1 := TConverters.ReadBytesAsUInt32LE(ptr_a_data, lIdx);
+    System.Inc(lIdx, 4);
+    k2 := TConverters.ReadBytesAsUInt32LE(ptr_a_data, lIdx);
+    System.Inc(lIdx, 4);
+    k3 := TConverters.ReadBytesAsUInt32LE(ptr_a_data, lIdx);
+    System.Inc(lIdx, 4);
+    k4 := TConverters.ReadBytesAsUInt32LE(ptr_a_data, lIdx);
+    System.Inc(lIdx, 4);
+
+    k1 := k1 * C1;
+    k1 := TBits.RotateLeft32(k1, 15);
+    k1 := k1 * C2;
+    Fm_h1 := Fm_h1 xor k1;
+
+    Fm_h1 := TBits.RotateLeft32(Fm_h1, 19);
+
+    Fm_h1 := Fm_h1 + Fm_h2;
+    Fm_h1 := Fm_h1 * 5 + C7;
+
+    k2 := k2 * C2;
+    k2 := TBits.RotateLeft32(k2, 16);
+    k2 := k2 * C3;
+    Fm_h2 := Fm_h2 xor k2;
+
+    Fm_h2 := TBits.RotateLeft32(Fm_h2, 17);
+
+    Fm_h2 := Fm_h2 + Fm_h3;
+    Fm_h2 := Fm_h2 * 5 + C8;
+
+    k3 := k3 * C3;
+    k3 := TBits.RotateLeft32(k3, 17);
+    k3 := k3 * C4;
+    Fm_h3 := Fm_h3 xor k3;
+
+    Fm_h3 := TBits.RotateLeft32(Fm_h3, 15);
+
+    Fm_h3 := Fm_h3 + Fm_h4;
+    Fm_h3 := Fm_h3 * 5 + C9;
+
+    k4 := k4 * C4;
+    k4 := TBits.RotateLeft32(k4, 18);
+    k4 := k4 * C1;
+    Fm_h4 := Fm_h4 xor k4;
+
+    Fm_h4 := TBits.RotateLeft32(Fm_h4, 13);
+
+    Fm_h4 := Fm_h4 + Fm_h1;
+    Fm_h4 := Fm_h4 * 5 + C10;
+
+    System.Inc(i);
+  end;
+
+  System.Inc(Fm_total_length, len);
+
+  offset := (i * 16);
+
+  while offset < len do
+  begin
+
+    ByteUpdate(a_data[offset]);
+    System.Inc(offset);
+
+  end;
+
+end;
+
+function TMurmurHash3_x86_128.TransformFinal: IHashResult;
+var
+  tempBufByte: THashLibByteArray;
+  tempBufUInt32: THashLibUInt32Array;
+begin
+  Finish();
+
+  tempBufUInt32 := THashLibUInt32Array.Create(Fm_h1, Fm_h2, Fm_h3, Fm_h4);
+  System.SetLength(tempBufByte, System.length(tempBufUInt32) *
+    System.SizeOf(UInt32));
+  TConverters.be32_copy(PCardinal(tempBufUInt32), 0, PByte(tempBufByte), 0,
+    System.length(tempBufByte));
+
+  result := THashResult.Create(tempBufByte);
+
+  Initialize();
+end;
+
+end.

+ 79 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpAP.pas

@@ -0,0 +1,79 @@
+unit HlpAP;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TAP = class sealed(THash, IHash32, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash: UInt32;
+    Fm_index: Int32;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+
+  end;
+
+implementation
+
+{ TAP }
+
+constructor TAP.Create;
+begin
+  Inherited Create(4, 1);
+end;
+
+procedure TAP.Initialize;
+begin
+  Fm_hash := $AAAAAAAA;
+  Fm_index := 0;
+end;
+
+procedure TAP.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+
+    if (Fm_index and 1) = 0 then
+      Fm_hash := Fm_hash xor ((Fm_hash shl 7) xor a_data[i] * (Fm_hash shr 3))
+
+    else
+
+      Fm_hash := Fm_hash xor
+        (not((Fm_hash shl 11) xor a_data[i] xor (Fm_hash shr 5)));
+
+    System.Inc(Fm_index);
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+end;
+
+function TAP.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 72 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpBKDR.pas

@@ -0,0 +1,72 @@
+unit HlpBKDR;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+
+  TBKDR = class sealed(THash, IHash32, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash: UInt32;
+
+  const
+    SEED = Int32(131);
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TBKDR }
+
+constructor TBKDR.Create;
+begin
+  Inherited Create(4, 1);
+end;
+
+procedure TBKDR.Initialize;
+begin
+  Fm_hash := 0;
+end;
+
+procedure TBKDR.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+    Fm_hash := (Fm_hash * UInt32(SEED)) + a_data[i];
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+
+end;
+
+function TBKDR.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 69 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpBernstein.pas

@@ -0,0 +1,69 @@
+unit HlpBernstein;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TBernstein = class sealed(THash, IHash32, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash: UInt32;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TBernstein }
+
+constructor TBernstein.Create;
+begin
+  Inherited Create(4, 1);
+
+end;
+
+procedure TBernstein.Initialize;
+begin
+  Fm_hash := 5381;
+end;
+
+procedure TBernstein.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+    Fm_hash := (Fm_hash * 33) + a_data[i];
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+
+end;
+
+function TBernstein.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 69 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpBernstein1.pas

@@ -0,0 +1,69 @@
+unit HlpBernstein1;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TBernstein1 = class sealed(THash, IHash32, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash: UInt32;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TBernstein1 }
+
+constructor TBernstein1.Create;
+begin
+  Inherited Create(4, 1);
+
+end;
+
+procedure TBernstein1.Initialize;
+begin
+  Fm_hash := 5381;
+end;
+
+procedure TBernstein1.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+    Fm_hash := (Fm_hash * 33) xor a_data[i];
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+
+end;
+
+function TBernstein1.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 51 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpDEK.pas

@@ -0,0 +1,51 @@
+unit HlpDEK;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpBits,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult,
+  HlpMultipleTransformNonBlock;
+
+type
+
+  TDEK = class sealed(TMultipleTransformNonBlock, IHash32, ITransformBlock)
+
+  strict protected
+    function ComputeAggregatedBytes(a_data: THashLibByteArray)
+      : IHashResult; override;
+  public
+    constructor Create();
+
+  end;
+
+implementation
+
+{ TDEK }
+
+constructor TDEK.Create;
+begin
+  Inherited Create(4, 1);
+end;
+
+function TDEK.ComputeAggregatedBytes(a_data: THashLibByteArray): IHashResult;
+var
+  hash: UInt32;
+  i: Int32;
+begin
+  hash := UInt32(System.Length(a_data));
+  for i := 0 to System.Length(a_data) - 1 do
+  begin
+
+    hash := TBits.RotateLeft32(hash, 5) xor a_data[i];
+  end;
+
+  result := THashResult.Create(hash);
+end;
+
+end.

+ 69 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpDJB.pas

@@ -0,0 +1,69 @@
+unit HlpDJB;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TDJB = class sealed(THash, IHash32, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash: UInt32;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TDJB }
+
+constructor TDJB.Create;
+begin
+  Inherited Create(4, 1);
+
+end;
+
+procedure TDJB.Initialize;
+begin
+  Fm_hash := 5381;
+end;
+
+procedure TDJB.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+    Fm_hash := ((Fm_hash shl 5) + Fm_hash) + a_data[i];
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+
+end;
+
+function TDJB.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 75 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpELF.pas

@@ -0,0 +1,75 @@
+unit HlpELF;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TELF = class sealed(THash, IHash32, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash: UInt32;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TELF }
+
+constructor TELF.Create;
+begin
+  Inherited Create(4, 1);
+end;
+
+procedure TELF.Initialize;
+begin
+  Fm_hash := 0;
+end;
+
+procedure TELF.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+  g: UInt32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+    Fm_hash := (Fm_hash shl 4) + a_data[i];
+    g := Fm_hash and $F0000000;
+
+    if (g <> 0) then
+      Fm_hash := Fm_hash xor (g shr 24);
+
+    Fm_hash := Fm_hash and (not g);
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+
+end;
+
+function TELF.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 69 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpFNV.pas

@@ -0,0 +1,69 @@
+unit HlpFNV;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TFNV = class sealed(THash, IHash32, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash: UInt32;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TFNV }
+
+constructor TFNV.Create;
+begin
+  Inherited Create(4, 1);
+
+end;
+
+procedure TFNV.Initialize;
+begin
+  Fm_hash := 0;
+end;
+
+procedure TFNV.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+    Fm_hash := (Fm_hash * 16777619) xor a_data[i];
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+
+end;
+
+function TFNV.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 69 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpFNV1a.pas

@@ -0,0 +1,69 @@
+unit HlpFNV1a;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TFNV1a = class sealed(THash, IHash32, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash: UInt32;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TFNV1a }
+
+constructor TFNV1a.Create;
+begin
+  Inherited Create(4, 1);
+
+end;
+
+procedure TFNV1a.Initialize;
+begin
+  Fm_hash := 2166136261;
+end;
+
+procedure TFNV1a.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+    Fm_hash := (Fm_hash xor a_data[i]) * 16777619;
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+
+end;
+
+function TFNV1a.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 69 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpJS.pas

@@ -0,0 +1,69 @@
+unit HlpJS;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TJS = class sealed(THash, IHash32, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash: UInt32;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TJS }
+
+constructor TJS.Create;
+begin
+  Inherited Create(4, 1);
+
+end;
+
+procedure TJS.Initialize;
+begin
+  Fm_hash := 1315423911;
+end;
+
+procedure TJS.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+    Fm_hash := Fm_hash xor ((Fm_hash shl 5) + a_data[i] + (Fm_hash shr 2));
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+
+end;
+
+function TJS.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 395 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpJenkins3.pas

@@ -0,0 +1,395 @@
+unit HlpJenkins3;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpBits,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult,
+  HlpMultipleTransformNonBlock;
+
+type
+
+  TJenkins3 = class sealed(TMultipleTransformNonBlock, IHash32, ITransformBlock)
+
+  strict protected
+    function ComputeAggregatedBytes(a_data: THashLibByteArray)
+      : IHashResult; override;
+  public
+    constructor Create();
+
+  end;
+
+implementation
+
+{ TJenkins3 }
+
+constructor TJenkins3.Create;
+begin
+  Inherited Create(4, 12);
+end;
+
+function TJenkins3.ComputeAggregatedBytes(a_data: THashLibByteArray)
+  : IHashResult;
+var
+  &length, currentIndex, i1, i2, i3, i4: Int32;
+  a, b, c: UInt32;
+begin
+  length := System.length(a_data);
+  if (length = 0) then
+  begin
+    result := THashResult.Create(UInt32(0));
+    Exit;
+  end;
+  a := $DEADBEEF + UInt32(length);
+  b := a;
+  c := b;
+  currentIndex := 0;
+  while (length > 12) do
+  begin
+
+    i1 := a_data[currentIndex];
+    System.Inc(currentIndex);
+    i2 := a_data[currentIndex] shl 8;
+    System.Inc(currentIndex);
+    i3 := a_data[currentIndex] shl 16;
+    System.Inc(currentIndex);
+    i4 := a_data[currentIndex] shl 24;
+    System.Inc(currentIndex);
+
+    a := a + UInt32(i1 or i2 or i3 or i4);
+
+    i1 := a_data[currentIndex];
+    System.Inc(currentIndex);
+    i2 := a_data[currentIndex] shl 8;
+    System.Inc(currentIndex);
+    i3 := a_data[currentIndex] shl 16;
+    System.Inc(currentIndex);
+    i4 := a_data[currentIndex] shl 24;
+    System.Inc(currentIndex);
+
+    b := b + UInt32(i1 or i2 or i3 or i4);
+
+    i1 := a_data[currentIndex];
+    System.Inc(currentIndex);
+    i2 := a_data[currentIndex] shl 8;
+    System.Inc(currentIndex);
+    i3 := a_data[currentIndex] shl 16;
+    System.Inc(currentIndex);
+    i4 := a_data[currentIndex] shl 24;
+    System.Inc(currentIndex);
+
+    c := c + UInt32(i1 or i2 or i3 or i4);
+
+    a := a - c;
+    a := a xor TBits.RotateLeft32(c, 4);
+    c := c + b;
+    b := b - a;
+    b := b xor TBits.RotateLeft32(a, 6);
+    a := a + c;
+    c := c - b;
+    c := c xor TBits.RotateLeft32(b, 8);
+    b := b + a;
+    a := a - c;
+    a := a xor TBits.RotateLeft32(c, 16);
+    c := c + b;
+    b := b - a;
+    b := b xor TBits.RotateLeft32(a, 19);
+    a := a + c;
+    c := c - b;
+    c := c xor TBits.RotateLeft32(b, 4);
+    b := b + a;
+
+    System.Dec(length, 12);
+  end;
+
+  case length of
+    12:
+      begin
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+        System.Inc(currentIndex);
+        i4 := a_data[currentIndex] shl 24;
+        System.Inc(currentIndex);
+
+        a := a + UInt32(i1 or i2 or i3 or i4);
+
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+        System.Inc(currentIndex);
+        i4 := a_data[currentIndex] shl 24;
+        System.Inc(currentIndex);
+
+        b := b + UInt32(i1 or i2 or i3 or i4);
+
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+        System.Inc(currentIndex);
+        i4 := a_data[currentIndex] shl 24;
+
+        c := c + UInt32(i1 or i2 or i3 or i4);
+      end;
+
+    11:
+      begin
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+        System.Inc(currentIndex);
+        i4 := a_data[currentIndex] shl 24;
+        System.Inc(currentIndex);
+
+        a := a + UInt32(i1 or i2 or i3 or i4);
+
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+        System.Inc(currentIndex);
+        i4 := a_data[currentIndex] shl 24;
+        System.Inc(currentIndex);
+
+        b := b + UInt32(i1 or i2 or i3 or i4);
+
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+
+        c := c + UInt32(i1 or i2 or i3);
+
+      end;
+
+    10:
+      begin
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+        System.Inc(currentIndex);
+        i4 := a_data[currentIndex] shl 24;
+        System.Inc(currentIndex);
+
+        a := a + UInt32(i1 or i2 or i3 or i4);
+
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+        System.Inc(currentIndex);
+        i4 := a_data[currentIndex] shl 24;
+        System.Inc(currentIndex);
+
+        b := b + UInt32(i1 or i2 or i3 or i4);
+
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+
+        c := c + UInt32(i1 or i2);
+
+      end;
+
+    9:
+      begin
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+        System.Inc(currentIndex);
+        i4 := a_data[currentIndex] shl 24;
+        System.Inc(currentIndex);
+
+        a := a + UInt32(i1 or i2 or i3 or i4);
+
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+        System.Inc(currentIndex);
+        i4 := a_data[currentIndex] shl 24;
+        System.Inc(currentIndex);
+
+        b := b + UInt32(i1 or i2 or i3 or i4);
+
+        i1 := a_data[currentIndex];
+
+        c := c + UInt32(i1);
+
+      end;
+
+    8:
+      begin
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+        System.Inc(currentIndex);
+        i4 := a_data[currentIndex] shl 24;
+        System.Inc(currentIndex);
+
+        a := a + UInt32(i1 or i2 or i3 or i4);
+
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+        System.Inc(currentIndex);
+        i4 := a_data[currentIndex] shl 24;
+
+        b := b + UInt32(i1 or i2 or i3 or i4);
+
+      end;
+
+    7:
+      begin
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+        System.Inc(currentIndex);
+        i4 := a_data[currentIndex] shl 24;
+        System.Inc(currentIndex);
+
+        a := a + UInt32(i1 or i2 or i3 or i4);
+
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+
+        b := b + UInt32(i1 or i2 or i3);
+
+      end;
+
+    6:
+      begin
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+        System.Inc(currentIndex);
+        i4 := a_data[currentIndex] shl 24;
+        System.Inc(currentIndex);
+
+        a := a + UInt32(i1 or i2 or i3 or i4);
+
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+
+        b := b + UInt32(i1 or i2);
+
+      end;
+
+    5:
+      begin
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+        System.Inc(currentIndex);
+        i4 := a_data[currentIndex] shl 24;
+        System.Inc(currentIndex);
+
+        a := a + UInt32(i1 or i2 or i3 or i4);
+
+        i1 := a_data[currentIndex];
+
+        b := b + UInt32(i1);
+
+      end;
+
+    4:
+      begin
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+        System.Inc(currentIndex);
+        i4 := a_data[currentIndex] shl 24;
+
+        a := a + UInt32(i1 or i2 or i3 or i4);
+
+      end;
+
+    3:
+      begin
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+        System.Inc(currentIndex);
+        i3 := a_data[currentIndex] shl 16;
+
+        a := a + UInt32(i1 or i2 or i3);
+
+      end;
+
+    2:
+      begin
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex] shl 8;
+
+        a := a + UInt32(i1 or i2);
+
+      end;
+
+    1:
+      begin
+        i1 := a_data[currentIndex];
+
+        a := a + UInt32(i1);
+
+      end;
+
+  end;
+
+  c := c xor b;
+  c := c - TBits.RotateLeft32(b, 14);
+  a := a xor c;
+  a := a - TBits.RotateLeft32(c, 11);
+  b := b xor a;
+  b := b - TBits.RotateLeft32(a, 25);
+  c := c xor b;
+  c := c - TBits.RotateLeft32(b, 16);
+  a := a xor c;
+  a := a - TBits.RotateLeft32(c, 4);
+  b := b xor a;
+  b := b - TBits.RotateLeft32(a, 14);
+  c := c xor b;
+  c := c - TBits.RotateLeft32(b, 24);
+
+  result := THashResult.Create(c);
+
+end;
+
+end.

+ 185 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpMurmur2.pas

@@ -0,0 +1,185 @@
+unit HlpMurmur2;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpConverters,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult,
+  HlpMultipleTransformNonBlock,
+  HlpNullable;
+
+resourcestring
+  SInvalidKeyLength = 'KeyLength Must Be Equal to %d';
+
+type
+
+  TMurmur2 = class sealed(TMultipleTransformNonBlock, IHash32, IHashWithKey,
+    ITransformBlock)
+
+  strict private
+
+    Fm_key, Fm_working_key, Fm_h: UInt32;
+
+  const
+    CKEY = UInt32($0);
+    M = UInt32($5BD1E995);
+    R = Int32(24);
+
+    function InternalComputeBytes(a_data: THashLibByteArray): Int32;
+    procedure TransformUInt32Fast(a_data: UInt32); inline;
+    function GetKeyLength(): TNullableInteger;
+    function GetKey: THashLibByteArray; inline;
+    procedure SetKey(value: THashLibByteArray); inline;
+
+  strict protected
+    function ComputeAggregatedBytes(a_data: THashLibByteArray)
+      : IHashResult; override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    property KeyLength: TNullableInteger read GetKeyLength;
+    property Key: THashLibByteArray read GetKey write SetKey;
+
+  end;
+
+implementation
+
+{ TMurmur2 }
+
+constructor TMurmur2.Create;
+begin
+  Inherited Create(4, 4);
+  Fm_key := CKEY;
+
+end;
+
+function TMurmur2.GetKey: THashLibByteArray;
+begin
+  result := TConverters.ReadUInt32AsBytesLE(Fm_key);
+end;
+
+procedure TMurmur2.SetKey(value: THashLibByteArray);
+begin
+  if (value = Nil) then
+  begin
+    Fm_key := CKEY;
+  end
+  else
+  begin
+    if System.Length(value) <> KeyLength.value then
+      raise EArgumentHashLibException.CreateResFmt(@SInvalidKeyLength,
+        [KeyLength.value]);
+    Fm_key := TConverters.ReadBytesAsUInt32LE(PByte(value), 0);
+  end;
+end;
+
+procedure TMurmur2.TransformUInt32Fast(a_data: UInt32);
+begin
+  a_data := a_data * M;
+  a_data := a_data xor (a_data shr R);
+  a_data := a_data * M;
+
+  Fm_h := Fm_h * M;
+  Fm_h := Fm_h xor a_data;
+end;
+
+function TMurmur2.GetKeyLength: TNullableInteger;
+begin
+  result := 4;
+end;
+
+procedure TMurmur2.Initialize;
+begin
+  Fm_working_key := Fm_key;
+  inherited Initialize();
+end;
+
+function TMurmur2.InternalComputeBytes(a_data: THashLibByteArray): Int32;
+var
+  &length, current_index: Int32;
+  k: UInt32;
+  ptr_a_data: PByte;
+begin
+  Length := System.Length(a_data);
+  ptr_a_data := PByte(a_data);
+
+  if (Length = 0) then
+  begin
+    result := 0;
+    Exit;
+  end;
+
+  Fm_h := Fm_working_key xor UInt32(Length);
+  current_index := 0;
+
+  while (Length >= 4) do
+  begin
+
+    k := TConverters.ReadBytesAsUInt32LE(ptr_a_data, current_index);
+
+    TransformUInt32Fast(k);
+    System.Inc(current_index, 4);
+    System.Dec(Length, 4);
+  end;
+
+  case Length of
+    3:
+      begin
+
+        Fm_h := Fm_h xor (a_data[current_index + 2] shl 16);
+
+        Fm_h := Fm_h xor (a_data[current_index + 1] shl 8);
+
+        Fm_h := Fm_h xor (a_data[current_index]);
+
+        Fm_h := Fm_h * M;
+      end;
+
+    2:
+      begin
+
+        Fm_h := Fm_h xor (a_data[current_index + 1] shl 8);
+
+        Fm_h := Fm_h xor (a_data[current_index]);
+
+        Fm_h := Fm_h * M;
+      end;
+
+    1:
+      begin
+
+        Fm_h := Fm_h xor (a_data[current_index]);
+
+        Fm_h := Fm_h * M;
+      end;
+
+  end;
+
+  Fm_h := Fm_h xor (Fm_h shr 13);
+
+  Fm_h := Fm_h * M;
+  Fm_h := Fm_h xor (Fm_h shr 15);
+
+  result := Int32(Fm_h);
+end;
+
+function TMurmur2.ComputeAggregatedBytes(a_data: THashLibByteArray)
+  : IHashResult;
+
+begin
+  result := THashResult.Create(InternalComputeBytes(a_data));
+end;
+
+end.

+ 253 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpMurmurHash3_x86_32.pas

@@ -0,0 +1,253 @@
+unit HlpMurmurHash3_x86_32;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpConverters,
+  HlpIHashInfo,
+  HlpNullable,
+  HlpHash,
+  HlpHashResult,
+  HlpIHashResult,
+  HlpBits;
+
+resourcestring
+  SInvalidKeyLength = 'KeyLength Must Be Equal to %d';
+
+type
+
+  TMurmurHash3_x86_32 = class sealed(THash, IHash32, IHashWithKey,
+    ITransformBlock)
+
+  strict private
+
+    Fm_key, Fm_h, Fm_total_length: UInt32;
+    Fm_idx: Int32;
+    Fm_buf: THashLibByteArray;
+
+    procedure TransformUInt32Fast(a_data: UInt32); inline;
+    procedure ByteUpdate(a_b: Byte); inline;
+    procedure Finish();
+
+  const
+    CKEY = UInt32($0);
+
+    C1 = UInt32($CC9E2D51);
+    C2 = UInt32($1B873593);
+    C3 = UInt32($E6546B64);
+    C4 = UInt32($85EBCA6B);
+    C5 = UInt32($C2B2AE35);
+
+    function GetKeyLength(): TNullableInteger;
+    function GetKey: THashLibByteArray; inline;
+    procedure SetKey(value: THashLibByteArray); inline;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal: IHashResult; override;
+    property KeyLength: TNullableInteger read GetKeyLength;
+    property Key: THashLibByteArray read GetKey write SetKey;
+
+  end;
+
+implementation
+
+{ TMurmurHash3_x86_32 }
+
+constructor TMurmurHash3_x86_32.Create;
+begin
+  Inherited Create(4, 4);
+  Fm_key := CKEY;
+  System.SetLength(Fm_buf, 4);
+
+end;
+
+procedure TMurmurHash3_x86_32.Finish;
+var
+  k: UInt32;
+begin
+
+  // tail
+
+  k := 0;
+
+  if (Fm_idx <> 0) then
+  begin
+
+    case (Fm_idx) of
+
+      3:
+        begin
+          k := k xor (Fm_buf[2] shl 16);
+          k := k xor (Fm_buf[1] shl 8);
+          k := k xor Fm_buf[0];
+          k := k * C1;
+          k := TBits.RotateLeft32(k, 15);
+          k := k * C2;
+          Fm_h := Fm_h xor k;
+
+        end;
+      2:
+        begin
+
+          k := k xor (Fm_buf[1] shl 8);
+          k := k xor Fm_buf[0];
+          k := k * C1;
+          k := TBits.RotateLeft32(k, 15);
+          k := k * C2;
+          Fm_h := Fm_h xor k;
+
+        end;
+      1:
+        begin
+
+          k := k xor Fm_buf[0];
+          k := k * C1;
+          k := TBits.RotateLeft32(k, 15);
+          k := k * C2;
+          Fm_h := Fm_h xor k;
+
+        end;
+    end;
+  end;
+
+  // finalization
+
+  Fm_h := Fm_h xor Fm_total_length;
+
+  Fm_h := Fm_h xor (Fm_h shr 16);
+  Fm_h := Fm_h * C4;
+  Fm_h := Fm_h xor (Fm_h shr 13);
+  Fm_h := Fm_h * C5;
+  Fm_h := Fm_h xor (Fm_h shr 16);
+end;
+
+procedure TMurmurHash3_x86_32.TransformUInt32Fast(a_data: UInt32);
+var
+  k: UInt32;
+begin
+  k := a_data;
+
+  k := k * C1;
+  k := TBits.RotateLeft32(k, 15);
+  k := k * C2;
+
+  Fm_h := Fm_h xor k;
+  Fm_h := TBits.RotateLeft32(Fm_h, 13);
+  Fm_h := (Fm_h * 5) + C3;
+end;
+
+procedure TMurmurHash3_x86_32.ByteUpdate(a_b: Byte);
+var
+  k: UInt32;
+  ptr_Fm_buf: PByte;
+begin
+
+  Fm_buf[Fm_idx] := a_b;
+  System.Inc(Fm_idx);
+  if Fm_idx >= 4 then
+  begin
+    ptr_Fm_buf := PByte(Fm_buf);
+    k := TConverters.ReadBytesAsUInt32LE(ptr_Fm_buf, 0);
+    TransformUInt32Fast(k);
+    Fm_idx := 0;
+  end;
+
+end;
+
+function TMurmurHash3_x86_32.GetKey: THashLibByteArray;
+begin
+  result := TConverters.ReadUInt32AsBytesLE(Fm_key);
+end;
+
+procedure TMurmurHash3_x86_32.SetKey(value: THashLibByteArray);
+begin
+  if (value = Nil) then
+  begin
+    Fm_key := CKEY;
+  end
+  else
+  begin
+    if System.Length(value) <> KeyLength.value then
+      raise EArgumentHashLibException.CreateResFmt(@SInvalidKeyLength,
+        [KeyLength.value]);
+    Fm_key := TConverters.ReadBytesAsUInt32LE(PByte(value), 0);
+  end;
+end;
+
+function TMurmurHash3_x86_32.GetKeyLength: TNullableInteger;
+begin
+  result := 4;
+end;
+
+procedure TMurmurHash3_x86_32.Initialize;
+begin
+  Fm_h := Fm_key;
+  Fm_total_length := 0;
+  Fm_idx := 0;
+end;
+
+procedure TMurmurHash3_x86_32.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  len, nBlocks, i, offset: Int32;
+  k: UInt32;
+  ptr_a_data: PByte;
+
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  len := a_length;
+  i := a_index;
+  ptr_a_data := PByte(a_data);
+  nBlocks := len shr 2;
+
+
+  // body
+
+  while i < nBlocks do
+  begin
+    k := TConverters.ReadBytesAsUInt32LE(ptr_a_data, a_index + i * 4);
+
+    TransformUInt32Fast(k);
+
+    System.Inc(i);
+  end;
+
+  System.Inc(Fm_total_length, len);
+
+  offset := (i * 4);
+
+  while offset < len do
+  begin
+
+    ByteUpdate(a_data[offset]);
+    System.Inc(offset);
+
+  end;
+
+end;
+
+function TMurmurHash3_x86_32.TransformFinal: IHashResult;
+begin
+  Finish();
+  result := THashResult.Create(Fm_h);
+  Initialize();
+end;
+
+end.

+ 74 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpOneAtTime.pas

@@ -0,0 +1,74 @@
+unit HlpOneAtTime;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TOneAtTime = class sealed(THash, IHash32, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash: UInt32;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TOneAtTime }
+
+constructor TOneAtTime.Create;
+begin
+  Inherited Create(4, 1);
+end;
+
+procedure TOneAtTime.Initialize;
+begin
+  Fm_hash := 0;
+end;
+
+procedure TOneAtTime.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+    Fm_hash := Fm_hash + a_data[i];
+    Fm_hash := Fm_hash + (Fm_hash shl 10);
+    Fm_hash := Fm_hash xor (Fm_hash shr 6);
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+
+end;
+
+function TOneAtTime.TransformFinal: IHashResult;
+begin
+  Fm_hash := Fm_hash + (Fm_hash shl 3);
+  Fm_hash := Fm_hash xor (Fm_hash shr 11);
+  Fm_hash := Fm_hash + (Fm_hash shl 15);
+
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 79 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpPJW.pas

@@ -0,0 +1,79 @@
+unit HlpPJW;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TPJW = class sealed(THash, IHash32, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash: UInt32;
+
+  const
+    UInt32MaxValue = UInt32(4294967295);
+    BitsInUnsignedInt = Int32(System.SizeOf(UInt32) * 8);
+    ThreeQuarters = Int32(BitsInUnsignedInt * 3) shr 2;
+    OneEighth = Int32(BitsInUnsignedInt shr 3);
+    HighBits = UInt32(UInt32MaxValue shl (BitsInUnsignedInt - OneEighth));
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TPJW }
+
+constructor TPJW.Create;
+begin
+  Inherited Create(4, 1);
+end;
+
+procedure TPJW.Initialize;
+begin
+  Fm_hash := 0;
+end;
+
+procedure TPJW.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+  test: UInt32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+    Fm_hash := (Fm_hash shl OneEighth) + a_data[i];
+    test := Fm_hash and HighBits;
+    if (test <> 0) then
+      Fm_hash := ((Fm_hash xor (test shr ThreeQuarters)) and (not HighBits));
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+
+end;
+
+function TPJW.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 73 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpRS.pas

@@ -0,0 +1,73 @@
+unit HlpRS;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TRS = class sealed(THash, IHash32, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash, Fm_a: UInt32;
+
+  const
+    B = UInt32(378551);
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TRS }
+
+constructor TRS.Create;
+begin
+  Inherited Create(4, 1);
+end;
+
+procedure TRS.Initialize;
+begin
+  Fm_hash := 0;
+  Fm_a := 63689;
+end;
+
+procedure TRS.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+    Fm_hash := (Fm_hash * Fm_a) + a_data[i];
+    Fm_a := Fm_a * B;
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+
+end;
+
+function TRS.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 70 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpRotating.pas

@@ -0,0 +1,70 @@
+unit HlpRotating;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpBits,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TRotating = class sealed(THash, IHash32, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash: UInt32;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TRotating }
+
+constructor TRotating.Create;
+begin
+  Inherited Create(4, 1);
+end;
+
+procedure TRotating.Initialize;
+begin
+  Fm_hash := 0;
+end;
+
+procedure TRotating.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+
+    Fm_hash := TBits.RotateLeft32(Fm_hash, 4) xor a_data[i];
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+
+end;
+
+function TRotating.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 69 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpSDBM.pas

@@ -0,0 +1,69 @@
+unit HlpSDBM;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TSDBM = class sealed(THash, IHash32, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash: UInt32;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TSDBM }
+
+constructor TSDBM.Create;
+begin
+  Inherited Create(4, 1);
+end;
+
+procedure TSDBM.Initialize;
+begin
+  Fm_hash := 0;
+end;
+
+procedure TSDBM.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+    Fm_hash := a_data[i] + Int64(Fm_hash shl 6) + Int64(Fm_hash shl 16)
+      - Fm_hash;
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+
+end;
+
+function TSDBM.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 68 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpShiftAndXor.pas

@@ -0,0 +1,68 @@
+unit HlpShiftAndXor;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TShiftAndXor = class sealed(THash, IHash32, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash: UInt32;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TShiftAndXor }
+
+constructor TShiftAndXor.Create;
+begin
+  Inherited Create(4, 1);
+end;
+
+procedure TShiftAndXor.Initialize;
+begin
+  Fm_hash := 0;
+end;
+
+procedure TShiftAndXor.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+    Fm_hash := Fm_hash xor ((Fm_hash shl 5) + (Fm_hash shr 2) + a_data[i]);
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+
+end;
+
+function TShiftAndXor.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 118 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpSuperFast.pas

@@ -0,0 +1,118 @@
+unit HlpSuperFast;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult,
+  HlpMultipleTransformNonBlock;
+
+type
+
+  TSuperFast = class sealed(TMultipleTransformNonBlock, IHash32,
+    ITransformBlock)
+
+  strict protected
+    function ComputeAggregatedBytes(a_data: THashLibByteArray)
+      : IHashResult; override;
+  public
+    constructor Create();
+
+  end;
+
+implementation
+
+{ TSuperFast }
+
+constructor TSuperFast.Create;
+begin
+  Inherited Create(4, 4);
+end;
+
+function TSuperFast.ComputeAggregatedBytes(a_data: THashLibByteArray)
+  : IHashResult;
+var
+  hash, tmp, u1: UInt32;
+  &length, currentIndex, i1, i2: Int32;
+begin
+  length := System.length(a_data);
+
+  if (length = 0) then
+  begin
+    result := THashResult.Create(Int32(0));
+    Exit;
+  end;
+
+  hash := UInt32(length);
+
+  currentIndex := 0;
+
+  while (length >= 4) do
+  begin
+    i1 := a_data[currentIndex];
+    System.Inc(currentIndex);
+    i2 := a_data[currentIndex] shl 8;
+    System.Inc(currentIndex);
+    hash := UInt16(hash + UInt32(i1 or i2));
+    u1 := UInt32(a_data[currentIndex]);
+    System.Inc(currentIndex);
+    tmp := UInt32((Byte(u1) or a_data[currentIndex] shl 8) shl 11) xor hash;
+    System.Inc(currentIndex);
+    hash := (hash shl 16) xor tmp;
+    hash := hash + (hash shr 11);
+
+    System.Dec(length, 4);
+  end;
+
+  case length of
+    3:
+      begin
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        hash := hash + UInt16(i1 or i2 shl 8);
+        hash := hash xor (hash shl 16);
+        hash := hash xor (UInt32(a_data[currentIndex]) shl 18);
+        hash := hash + (hash shr 11);
+
+      end;
+
+    2:
+      begin
+        i1 := a_data[currentIndex];
+        System.Inc(currentIndex);
+        i2 := a_data[currentIndex];
+        hash := hash + UInt16(i1 or i2 shl 8);
+        hash := hash xor (hash shl 11);
+        hash := hash + (hash shr 17);
+
+      end;
+
+    1:
+      begin
+        i1 := a_data[currentIndex];
+
+        hash := hash + UInt32(i1);
+        hash := hash xor (hash shl 10);
+        hash := hash + (hash shr 1);
+
+      end;
+
+  end;
+
+  hash := hash xor (hash shl 3);
+  hash := hash + (hash shr 5);
+  hash := hash xor (hash shl 4);
+  hash := hash + (hash shr 17);
+  hash := hash xor (hash shl 25);
+  hash := hash + (hash shr 6);
+
+  result := THashResult.Create(hash);
+end;
+
+end.

+ 244 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash32/HlpXXHash32.pas

@@ -0,0 +1,244 @@
+unit HlpXXHash32;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpConverters,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult,
+  HlpNullable,
+  HlpBits;
+
+resourcestring
+  SInvalidKeyLength = 'KeyLength Must Be Equal to %d';
+
+type
+
+  TXXHash32 = class sealed(THash, IHash32, IBlockHash, IHashWithKey,
+    ITransformBlock)
+
+  strict private
+
+    Fm_key, Fm_hash: UInt32;
+
+  const
+    CKEY = UInt32(0);
+
+    PRIME32_1 = UInt32(2654435761);
+    PRIME32_2 = UInt32(2246822519);
+    PRIME32_3 = UInt32(3266489917);
+    PRIME32_4 = UInt32(668265263);
+    PRIME32_5 = UInt32(374761393);
+
+    function GetKeyLength(): TNullableInteger;
+    function GetKey: THashLibByteArray; inline;
+    procedure SetKey(value: THashLibByteArray); inline;
+
+  type
+
+    TXXH_State = record
+
+    private
+
+      Ftotal_len: UInt64;
+      Fmemsize, Fv1, Fv2, Fv3, Fv4: UInt32;
+      Fmemory: THashLibByteArray;
+
+    end;
+
+  strict private
+    F_state: TXXH_State;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+    property KeyLength: TNullableInteger read GetKeyLength;
+    property Key: THashLibByteArray read GetKey write SetKey;
+
+  end;
+
+implementation
+
+{ TXXHash32 }
+
+constructor TXXHash32.Create;
+begin
+  Inherited Create(4, 16);
+  Fm_key := CKEY;
+  System.SetLength(F_state.Fmemory, 16);
+
+end;
+
+function TXXHash32.GetKey: THashLibByteArray;
+begin
+  result := TConverters.ReadUInt32AsBytesLE(Fm_key);
+end;
+
+function TXXHash32.GetKeyLength: TNullableInteger;
+begin
+  result := 4;
+end;
+
+procedure TXXHash32.Initialize;
+begin
+  Fm_hash := 0;
+  F_state.Fv1 := Fm_key + PRIME32_1 + PRIME32_2;
+  F_state.Fv2 := Fm_key + PRIME32_2;
+  F_state.Fv3 := Fm_key + 0;
+  F_state.Fv4 := Fm_key - PRIME32_1;
+  F_state.Ftotal_len := 0;
+  F_state.Fmemsize := 0;
+
+end;
+
+procedure TXXHash32.SetKey(value: THashLibByteArray);
+begin
+  if (value = Nil) then
+  begin
+    Fm_key := CKEY;
+  end
+  else
+  begin
+    if System.Length(value) <> KeyLength.value then
+      raise EArgumentHashLibException.CreateResFmt(@SInvalidKeyLength,
+        [KeyLength.value]);
+    Fm_key := TConverters.ReadBytesAsUInt32LE(PByte(value), 0);
+  end;
+end;
+
+procedure TXXHash32.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  v1, v2, v3, v4: UInt32;
+  ptrLimit, ptrEnd, ptrBuffer, ptrTemp, ptrMemory: PByte;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  ptrBuffer := @a_data[a_index];
+  ptrMemory := PByte(F_state.Fmemory);
+  F_state.Ftotal_len := F_state.Ftotal_len + UInt64(a_length);
+
+  if ((F_state.Fmemsize + UInt32(a_length)) < UInt32(16)) then
+  begin
+
+    ptrTemp := PByte(F_state.Fmemory) + F_state.Fmemsize;
+
+    System.Move(ptrBuffer^, ptrTemp^, a_length);
+
+    F_state.Fmemsize := F_state.Fmemsize + UInt32(a_length);
+
+    Exit;
+  end;
+
+  ptrEnd := ptrBuffer + UInt32(a_length);
+
+  if F_state.Fmemsize > 0 then
+  begin
+    ptrTemp := PByte(F_state.Fmemory) + F_state.Fmemsize;
+    System.Move(ptrBuffer^, ptrTemp^, 16 - F_state.Fmemsize);
+
+    F_state.Fv1 := PRIME32_1 * TBits.RotateLeft32(F_state.Fv1 + PRIME32_2 *
+      TConverters.ReadBytesAsUInt32LE(ptrMemory, 0), 13);
+    F_state.Fv2 := PRIME32_1 * TBits.RotateLeft32(F_state.Fv2 + PRIME32_2 *
+      TConverters.ReadBytesAsUInt32LE(ptrMemory, 4), 13);
+    F_state.Fv3 := PRIME32_1 * TBits.RotateLeft32(F_state.Fv3 + PRIME32_2 *
+      TConverters.ReadBytesAsUInt32LE(ptrMemory, 8), 13);
+    F_state.Fv4 := PRIME32_1 * TBits.RotateLeft32(F_state.Fv4 + PRIME32_2 *
+      TConverters.ReadBytesAsUInt32LE(ptrMemory, 12), 13);
+
+    ptrBuffer := ptrBuffer + (16 - F_state.Fmemsize);
+    F_state.Fmemsize := 0;
+  end;
+
+  if ptrBuffer <= (ptrEnd - 16) then
+  begin
+    v1 := F_state.Fv1;
+    v2 := F_state.Fv2;
+    v3 := F_state.Fv3;
+    v4 := F_state.Fv4;
+
+    ptrLimit := ptrEnd - 16;
+    repeat
+
+      v1 := PRIME32_1 * TBits.RotateLeft32
+        (v1 + PRIME32_2 * TConverters.ReadBytesAsUInt32LE(ptrBuffer, 0), 13);
+      v2 := PRIME32_1 * TBits.RotateLeft32
+        (v2 + PRIME32_2 * TConverters.ReadBytesAsUInt32LE(ptrBuffer, 4), 13);
+      v3 := PRIME32_1 * TBits.RotateLeft32
+        (v3 + PRIME32_2 * TConverters.ReadBytesAsUInt32LE(ptrBuffer, 8), 13);
+      v4 := PRIME32_1 * TBits.RotateLeft32
+        (v4 + PRIME32_2 * TConverters.ReadBytesAsUInt32LE(ptrBuffer, 12), 13);
+      System.Inc(ptrBuffer, 16);
+    until not(ptrBuffer <= ptrLimit);
+
+    F_state.Fv1 := v1;
+    F_state.Fv2 := v2;
+    F_state.Fv3 := v3;
+    F_state.Fv4 := v4;
+  end;
+
+  if ptrBuffer < ptrEnd then
+  begin
+    ptrTemp := PByte(F_state.Fmemory);
+    System.Move(ptrBuffer^, ptrTemp^, ptrEnd - ptrBuffer);
+    F_state.Fmemsize := ptrEnd - ptrBuffer;
+  end;
+
+end;
+
+function TXXHash32.TransformFinal: IHashResult;
+var
+  ptrEnd, ptrBuffer: PByte;
+begin
+
+  if F_state.Ftotal_len >= UInt64(16) then
+    Fm_hash := TBits.RotateLeft32(F_state.Fv1, 1) +
+      TBits.RotateLeft32(F_state.Fv2, 7) + TBits.RotateLeft32(F_state.Fv3, 12) +
+      TBits.RotateLeft32(F_state.Fv4, 18)
+  else
+    Fm_hash := Fm_key + PRIME32_5;
+  System.Inc(Fm_hash, F_state.Ftotal_len);
+
+  ptrBuffer := PByte(F_state.Fmemory);
+
+  ptrEnd := ptrBuffer + F_state.Fmemsize;
+  while ((ptrBuffer + 4) <= ptrEnd) do
+  begin
+    Fm_hash := Fm_hash + TConverters.ReadBytesAsUInt32LE(ptrBuffer, 0) *
+      PRIME32_3;
+    Fm_hash := TBits.RotateLeft32(Fm_hash, 17) * PRIME32_4;
+    System.Inc(ptrBuffer, 4);
+  end;
+
+  while ptrBuffer < ptrEnd do
+  begin
+    Fm_hash := Fm_hash + ptrBuffer^ * PRIME32_5;
+    Fm_hash := TBits.RotateLeft32(Fm_hash, 11) * PRIME32_1;
+    System.Inc(ptrBuffer);
+  end;
+
+  Fm_hash := Fm_hash xor (Fm_hash shr 15);
+  Fm_hash := Fm_hash * PRIME32_2;
+  Fm_hash := Fm_hash xor (Fm_hash shr 13);
+  Fm_hash := Fm_hash * PRIME32_3;
+  Fm_hash := Fm_hash xor (Fm_hash shr 16);
+
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 69 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash64/HlpFNV1a64.pas

@@ -0,0 +1,69 @@
+unit HlpFNV1a64;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TFNV1a64 = class sealed(THash, IHash64, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash: UInt64;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TFNV1a64 }
+
+constructor TFNV1a64.Create;
+begin
+  Inherited Create(8, 1);
+
+end;
+
+procedure TFNV1a64.Initialize;
+begin
+  Fm_hash := 14695981039346656037;
+end;
+
+procedure TFNV1a64.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+    Fm_hash := (Fm_hash xor a_data[i]) * 1099511628211;
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+
+end;
+
+function TFNV1a64.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 69 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash64/HlpFNV64.pas

@@ -0,0 +1,69 @@
+unit HlpFNV64;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TFNV64 = class sealed(THash, IHash64, IBlockHash, ITransformBlock)
+  strict private
+
+    Fm_hash: UInt64;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TFNV64 }
+
+constructor TFNV64.Create;
+begin
+  Inherited Create(8, 1);
+
+end;
+
+procedure TFNV64.Initialize;
+begin
+  Fm_hash := 0;
+end;
+
+procedure TFNV64.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  i := a_index;
+  while a_length > 0 do
+  begin
+    Fm_hash := (Fm_hash * 1099511628211) xor a_data[i];
+    System.Inc(i);
+    System.Dec(a_length);
+  end;
+
+end;
+
+function TFNV64.TransformFinal: IHashResult;
+begin
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+end;
+
+end.

+ 268 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash64/HlpMurmur2_64.pas

@@ -0,0 +1,268 @@
+unit HlpMurmur2_64;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpConverters,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult,
+  HlpMultipleTransformNonBlock,
+  HlpNullable;
+
+resourcestring
+  SInvalidKeyLength = 'KeyLength Must Be Equal to %d';
+
+type
+
+  TMurmur2_64 = class sealed(TMultipleTransformNonBlock, IHash64, IHashWithKey,
+    ITransformBlock)
+
+  strict private
+
+    Fm_key, Fm_working_key: UInt32;
+
+  const
+    CKEY = UInt32($0);
+{$IFDEF FPC}
+    // to bypass Internal error (200706094) on FPC, We use "Typed Constant".
+
+    M: UInt64 = UInt64($C6A4A7935BD1E995);
+
+{$ELSE}
+    M = UInt64($C6A4A7935BD1E995);
+{$ENDIF FPC}
+    R = Int32(47);
+
+    function GetKeyLength(): TNullableInteger;
+    function GetKey: THashLibByteArray; inline;
+    procedure SetKey(value: THashLibByteArray); inline;
+
+  strict protected
+    function ComputeAggregatedBytes(a_data: THashLibByteArray)
+      : IHashResult; override;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    property KeyLength: TNullableInteger read GetKeyLength;
+    property Key: THashLibByteArray read GetKey write SetKey;
+
+  end;
+
+implementation
+
+{ TMurmur2_64 }
+
+function TMurmur2_64.ComputeAggregatedBytes(a_data: THashLibByteArray)
+  : IHashResult;
+var
+  &length, current_index: Int32;
+  h, k: UInt64;
+  ptr_a_data: PByte;
+begin
+
+  length := System.length(a_data);
+  ptr_a_data := PByte(a_data);
+
+  if (length = 0) then
+  begin
+    result := THashResult.Create(UInt64(0));
+    Exit;
+  end;
+
+  h := Fm_working_key xor UInt64(length);
+  current_index := 0;
+
+  while (length >= 8) do
+  begin
+
+    k := TConverters.ReadBytesAsUInt64LE(ptr_a_data, current_index);
+
+    k := k * M;
+    k := k xor (k shr R);
+    k := k * M;
+
+    h := h xor k;
+    h := h * M;
+
+    System.Inc(current_index, 8);
+    System.Dec(length, 8);
+
+  end;
+
+  case length of
+    7:
+      begin
+
+        h := h xor ((UInt64(a_data[current_index]) shl 48));
+        System.Inc(current_index);
+
+        h := h xor (UInt64(a_data[current_index]) shl 40);
+        System.Inc(current_index);
+
+        h := h xor (UInt64(a_data[current_index]) shl 32);
+        System.Inc(current_index);
+
+        h := h xor (UInt64(a_data[current_index]) shl 24);
+        System.Inc(current_index);
+
+        h := h xor (UInt64(a_data[current_index]) shl 16);
+        System.Inc(current_index);
+
+        h := h xor (UInt64(a_data[current_index]) shl 8);
+        System.Inc(current_index);
+
+        h := h xor UInt64(a_data[current_index]);
+
+        h := h * M;
+      end;
+
+    6:
+      begin
+
+        h := h xor (UInt64(a_data[current_index]) shl 40);
+        System.Inc(current_index);
+
+        h := h xor (UInt64(a_data[current_index]) shl 32);
+        System.Inc(current_index);
+
+        h := h xor (UInt64(a_data[current_index]) shl 24);
+        System.Inc(current_index);
+
+        h := h xor (UInt64(a_data[current_index]) shl 16);
+        System.Inc(current_index);
+
+        h := h xor (UInt64(a_data[current_index]) shl 8);
+        System.Inc(current_index);
+
+        h := h xor UInt64(a_data[current_index]);
+
+        h := h * M;
+      end;
+
+    5:
+      begin
+
+        h := h xor (UInt64(a_data[current_index]) shl 32);
+        System.Inc(current_index);
+
+        h := h xor (UInt64(a_data[current_index]) shl 24);
+        System.Inc(current_index);
+
+        h := h xor (UInt64(a_data[current_index]) shl 16);
+        System.Inc(current_index);
+
+        h := h xor (UInt64(a_data[current_index]) shl 8);
+        System.Inc(current_index);
+
+        h := h xor UInt64(a_data[current_index]);
+        h := h * M;
+      end;
+
+    4:
+      begin
+
+        h := h xor (UInt64(a_data[current_index]) shl 24);
+        System.Inc(current_index);
+
+        h := h xor (UInt64(a_data[current_index]) shl 16);
+        System.Inc(current_index);
+
+        h := h xor (UInt64(a_data[current_index]) shl 8);
+        System.Inc(current_index);
+
+        h := h xor UInt64(a_data[current_index]);
+        h := h * M;
+      end;
+
+    3:
+      begin
+
+        h := h xor (UInt64(a_data[current_index]) shl 16);
+        System.Inc(current_index);
+
+        h := h xor (UInt64(a_data[current_index]) shl 8);
+        System.Inc(current_index);
+
+        h := h xor UInt64(a_data[current_index]);
+        h := h * M;
+      end;
+
+    2:
+      begin
+
+        h := h xor (UInt64(a_data[current_index]) shl 8);
+        System.Inc(current_index);
+
+        h := h xor UInt64(a_data[current_index]);
+
+        h := h * M;
+      end;
+
+    1:
+      begin
+
+        h := h xor UInt64(a_data[current_index]);
+
+        h := h * M;
+      end;
+
+  end;
+
+  h := h xor (h shr R);
+  h := h * M;
+  h := h xor (h shr R);
+
+  result := THashResult.Create(h);
+
+end;
+
+constructor TMurmur2_64.Create;
+begin
+  Inherited Create(8, 8);
+  Fm_key := CKEY;
+
+end;
+
+function TMurmur2_64.GetKey: THashLibByteArray;
+begin
+  result := TConverters.ReadUInt32AsBytesLE(Fm_key);
+end;
+
+function TMurmur2_64.GetKeyLength: TNullableInteger;
+begin
+  result := 4;
+end;
+
+procedure TMurmur2_64.Initialize;
+begin
+  Fm_working_key := Fm_key;
+
+  Inherited Initialize();
+
+end;
+
+procedure TMurmur2_64.SetKey(value: THashLibByteArray);
+begin
+  if (value = Nil) then
+  begin
+    Fm_key := CKEY;
+  end
+  else
+  begin
+    if System.length(value) <> KeyLength.value then
+      raise EArgumentHashLibException.CreateResFmt(@SInvalidKeyLength,
+        [KeyLength.value]);
+    Fm_key := TConverters.ReadBytesAsUInt32LE(PByte(value), 0);
+  end;
+
+end;
+
+end.

+ 332 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash64/HlpSipHash.pas

@@ -0,0 +1,332 @@
+unit HlpSipHash;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+
+{$IFDEF DELPHI2010}
+  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
+{$ENDIF DELPHI2010}
+  HlpHashLibTypes,
+  HlpConverters,
+  HlpIHashInfo,
+  HlpNullable,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpHash,
+  HlpHashResult,
+  HlpIHashResult,
+  HlpBits;
+
+resourcestring
+  SInvalidKeyLength = 'KeyLength Must Be Equal to %d';
+
+type
+  TSipHash = class abstract(THash, IHash64, IHashWithKey, ITransformBlock)
+
+  strict private
+
+    Fm_v0, Fm_v1, Fm_v2, Fm_v3, Fm_key0, Fm_key1, Fm_total_length, F_m: UInt64;
+    F_cr, F_fr, Fm_idx: Int32;
+    Fm_buf: THashLibByteArray;
+
+{$REGION 'Consts'}
+
+  const
+    V0 = UInt64($736F6D6570736575);
+    V1 = UInt64($646F72616E646F6D);
+    V2 = UInt64($6C7967656E657261);
+    V3 = UInt64($7465646279746573);
+    KEY0 = UInt64($0706050403020100);
+    KEY1 = UInt64($0F0E0D0C0B0A0908);
+
+{$ENDREGION}
+    procedure Compress(); inline;
+    procedure CompressTimes(a_times: Int32); inline;
+    procedure ProcessBlock(a_m: UInt64); inline;
+    procedure ByteUpdate(a_b: Byte); inline;
+    procedure Finish();
+
+    function GetKeyLength(): TNullableInteger;
+    function GetKey: THashLibByteArray;
+    procedure SetKey(value: THashLibByteArray);
+
+  public
+    constructor Create(a_compression_rounds: Int32 = 2;
+      a_finalization_rounds: Int32 = 4);
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal: IHashResult; override;
+    property KeyLength: TNullableInteger read GetKeyLength;
+    property Key: THashLibByteArray read GetKey write SetKey;
+
+  end;
+
+type
+  /// <summary>
+  /// SipHash 2 - 4 algorithm.
+  /// <summary>
+  TSipHash2_4 = class sealed(TSipHash)
+
+  public
+
+    constructor Create();
+
+  end;
+
+implementation
+
+{ TSipHash2_4 }
+
+constructor TSipHash2_4.Create;
+begin
+  Inherited Create(2, 4);
+
+end;
+
+{ TSipHash }
+
+procedure TSipHash.Compress;
+begin
+  Fm_v0 := Fm_v0 + Fm_v1;
+  Fm_v2 := Fm_v2 + Fm_v3;
+  Fm_v1 := TBits.RotateLeft64(Fm_v1, 13);
+  Fm_v3 := TBits.RotateLeft64(Fm_v3, 16);
+  Fm_v1 := Fm_v1 xor Fm_v0;
+  Fm_v3 := Fm_v3 xor Fm_v2;
+  Fm_v0 := TBits.RotateLeft64(Fm_v0, 32);
+  Fm_v2 := Fm_v2 + Fm_v1;
+  Fm_v0 := Fm_v0 + Fm_v3;
+  Fm_v1 := TBits.RotateLeft64(Fm_v1, 17);
+  Fm_v3 := TBits.RotateLeft64(Fm_v3, 21);
+  Fm_v1 := Fm_v1 xor Fm_v2;
+  Fm_v3 := Fm_v3 xor Fm_v0;
+  Fm_v2 := TBits.RotateLeft64(Fm_v2, 32);
+end;
+
+procedure TSipHash.CompressTimes(a_times: Int32);
+var
+  i: Int32;
+begin
+  i := 0;
+  while i < a_times do
+  begin
+    Compress();
+    System.Inc(i);
+  end;
+end;
+
+procedure TSipHash.ProcessBlock(a_m: UInt64);
+begin
+  Fm_v3 := Fm_v3 xor a_m;
+  CompressTimes(F_cr);
+  Fm_v0 := Fm_v0 xor a_m;
+end;
+
+procedure TSipHash.ByteUpdate(a_b: Byte);
+var
+  ptr_Fm_buf: PByte;
+  m: UInt64;
+begin
+
+  Fm_buf[Fm_idx] := a_b;
+  System.Inc(Fm_idx);
+  if Fm_idx >= 8 then
+  begin
+    ptr_Fm_buf := PByte(Fm_buf);
+    m := TConverters.ReadBytesAsUInt64LE(ptr_Fm_buf, 0);
+    ProcessBlock(m);
+    Fm_idx := 0;
+  end;
+
+end;
+
+constructor TSipHash.Create(a_compression_rounds, a_finalization_rounds: Int32);
+begin
+  Inherited Create(8, 8);
+  Fm_key0 := KEY0;
+  Fm_key1 := KEY1;
+  F_cr := a_compression_rounds;
+  F_fr := a_finalization_rounds;
+  System.SetLength(Fm_buf, 8);
+end;
+
+procedure TSipHash.Finish;
+var
+  b: UInt64;
+begin
+
+  b := UInt64(Fm_total_length and $FF) shl 56;
+
+  if (Fm_idx <> 0) then
+  begin
+
+    case (Fm_idx) of
+
+      7:
+        begin
+          b := b or (UInt64(Fm_buf[6]) shl 48);
+          b := b or (UInt64(Fm_buf[5]) shl 40);
+          b := b or (UInt64(Fm_buf[4]) shl 32);
+          b := b or (UInt64(Fm_buf[3]) shl 24);
+          b := b or (UInt64(Fm_buf[2]) shl 16);
+          b := b or (UInt64(Fm_buf[1]) shl 8);
+          b := b or (UInt64(Fm_buf[0]));
+        end;
+      6:
+        begin
+          b := b or (UInt64(Fm_buf[5]) shl 40);
+          b := b or (UInt64(Fm_buf[4]) shl 32);
+          b := b or (UInt64(Fm_buf[3]) shl 24);
+          b := b or (UInt64(Fm_buf[2]) shl 16);
+          b := b or (UInt64(Fm_buf[1]) shl 8);
+          b := b or (UInt64(Fm_buf[0]));
+        end;
+      5:
+        begin
+          b := b or (UInt64(Fm_buf[4]) shl 32);
+          b := b or (UInt64(Fm_buf[3]) shl 24);
+          b := b or (UInt64(Fm_buf[2]) shl 16);
+          b := b or (UInt64(Fm_buf[1]) shl 8);
+          b := b or (UInt64(Fm_buf[0]));
+        end;
+
+      4:
+        begin
+          b := b or (UInt64(Fm_buf[3]) shl 24);
+          b := b or (UInt64(Fm_buf[2]) shl 16);
+          b := b or (UInt64(Fm_buf[1]) shl 8);
+          b := b or (UInt64(Fm_buf[0]));
+        end;
+
+      3:
+        begin
+          b := b or (UInt64(Fm_buf[2]) shl 16);
+          b := b or (UInt64(Fm_buf[1]) shl 8);
+          b := b or (UInt64(Fm_buf[0]));
+        end;
+
+      2:
+        begin
+          b := b or (UInt64(Fm_buf[1]) shl 8);
+          b := b or (UInt64(Fm_buf[0]));
+        end;
+
+      1:
+        begin
+          b := b or (UInt64(Fm_buf[0]));
+        end;
+
+    end;
+  end;
+
+  Fm_v3 := Fm_v3 xor b;
+  CompressTimes(F_cr);
+  Fm_v0 := Fm_v0 xor b;
+  Fm_v2 := Fm_v2 xor $FF;
+  CompressTimes(F_fr);
+end;
+
+function TSipHash.GetKey: THashLibByteArray;
+var
+  LKey: THashLibByteArray;
+begin
+  System.SetLength(LKey, KeyLength.value);
+
+  TConverters.ReadUInt64AsBytesLE(Fm_key0, LKey, 0);
+  TConverters.ReadUInt64AsBytesLE(Fm_key1, LKey, 8);
+
+  result := LKey;
+end;
+
+function TSipHash.GetKeyLength: TNullableInteger;
+begin
+  result := 16;
+end;
+
+procedure TSipHash.Initialize;
+begin
+  Fm_v0 := V0;
+  Fm_v1 := V1;
+  Fm_v2 := V2;
+  Fm_v3 := V3;
+  Fm_total_length := 0;
+  Fm_idx := 0;
+
+  Fm_v3 := Fm_v3 xor Fm_key1;
+  Fm_v2 := Fm_v2 xor Fm_key0;
+  Fm_v1 := Fm_v1 xor Fm_key1;
+  Fm_v0 := Fm_v0 xor Fm_key0;
+
+end;
+
+procedure TSipHash.SetKey(value: THashLibByteArray);
+begin
+  if (value = Nil) then
+  begin
+    Fm_key0 := KEY0;
+    Fm_key1 := KEY1;
+  end
+
+  else
+  begin
+    if System.Length(value) <> KeyLength.value then
+      raise EArgumentHashLibException.CreateResFmt(@SInvalidKeyLength,
+        [KeyLength.value]);
+
+    Fm_key0 := TConverters.ReadBytesAsUInt64LE(PByte(value), 0);
+    Fm_key1 := TConverters.ReadBytesAsUInt64LE(PByte(value), 8);
+  end;
+end;
+
+procedure TSipHash.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  i, &length, iter, offset: Int32;
+  ptr_a_data: PByte;
+begin
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  Length := a_length;
+  i := a_index;
+
+  iter := Length shr 3;
+  ptr_a_data := PByte(a_data);
+
+  while i < iter do
+  begin
+    F_m := TConverters.ReadBytesAsUInt64LE(ptr_a_data, i * 8);
+    ProcessBlock(F_m);
+    F_m := 0;
+    System.Inc(i);
+  end;
+
+  System.Inc(Fm_total_length, Length);
+
+  offset := (i * 8);
+
+  while offset < Length do
+  begin
+
+    ByteUpdate(a_data[offset]);
+    System.Inc(offset);
+
+  end;
+
+end;
+
+function TSipHash.TransformFinal: IHashResult;
+begin
+  Finish();
+  result := THashResult.Create(Fm_v0 xor Fm_v1 xor Fm_v2 xor Fm_v3);
+  Initialize();
+end;
+
+end.

+ 283 - 0
src/libraries/hashlib4pascal/HashLib/src/Hash64/HlpXXHash64.pas

@@ -0,0 +1,283 @@
+unit HlpXXHash64;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpHash,
+  HlpConverters,
+{$IFDEF DELPHI}
+  HlpBitConverter,
+{$ENDIF DELPHI}
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult,
+  HlpNullable,
+  HlpBits;
+
+resourcestring
+  SInvalidKeyLength = 'KeyLength Must Be Equal to %d';
+
+type
+
+  TXXHash64 = class sealed(THash, IHash64, IBlockHash, IHashWithKey,
+    ITransformBlock)
+
+  strict private
+
+    Fm_key, Fm_hash: UInt64;
+
+  const
+    CKEY = UInt64(0);
+
+{$IFDEF FPC}
+    // to bypass Internal error (200706094) on FPC, We use "Typed Constant".
+    PRIME64_1: UInt64 = (11400714785074694791);
+    PRIME64_2: UInt64 = (14029467366897019727);
+    PRIME64_3: UInt64 = (1609587929392839161);
+    PRIME64_4: UInt64 = (9650029242287828579);
+    PRIME64_5: UInt64 = (2870177450012600261);
+{$ELSE}
+    PRIME64_1 = UInt64(11400714785074694791);
+    PRIME64_2 = UInt64(14029467366897019727);
+    PRIME64_3 = UInt64(1609587929392839161);
+    PRIME64_4 = UInt64(9650029242287828579);
+    PRIME64_5 = UInt64(2870177450012600261);
+{$ENDIF FPC}
+    function GetKeyLength(): TNullableInteger;
+    function GetKey: THashLibByteArray; inline;
+    procedure SetKey(value: THashLibByteArray); inline;
+
+  type
+
+    TXXH_State = record
+
+    private
+
+      Ftotal_len, Fv1, Fv2, Fv3, Fv4: UInt64;
+      Fmemsize: UInt32;
+      Fmemory: THashLibByteArray;
+
+    end;
+
+  strict private
+    F_state: TXXH_State;
+
+  public
+    constructor Create();
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+    property KeyLength: TNullableInteger read GetKeyLength;
+    property Key: THashLibByteArray read GetKey write SetKey;
+
+  end;
+
+implementation
+
+{ TXXHash64 }
+
+constructor TXXHash64.Create;
+begin
+  Inherited Create(8, 32);
+  Fm_key := CKEY;
+  System.SetLength(F_state.Fmemory, 32);
+
+end;
+
+function TXXHash64.GetKey: THashLibByteArray;
+begin
+  result := TConverters.ReadUInt64AsBytesLE(Fm_key);
+end;
+
+function TXXHash64.GetKeyLength: TNullableInteger;
+begin
+  result := 8;
+end;
+
+procedure TXXHash64.Initialize;
+begin
+  Fm_hash := 0;
+  F_state.Fv1 := Fm_key + PRIME64_1 + PRIME64_2;
+  F_state.Fv2 := Fm_key + PRIME64_2;
+  F_state.Fv3 := Fm_key + 0;
+  F_state.Fv4 := Fm_key - PRIME64_1;
+  F_state.Ftotal_len := 0;
+  F_state.Fmemsize := 0;
+
+end;
+
+procedure TXXHash64.SetKey(value: THashLibByteArray);
+begin
+  if (value = Nil) then
+  begin
+    Fm_key := CKEY;
+  end
+  else
+  begin
+    if System.Length(value) <> KeyLength.value then
+      raise EArgumentHashLibException.CreateResFmt(@SInvalidKeyLength,
+        [KeyLength.value]);
+
+    Fm_key := TConverters.ReadBytesAsUInt64LE(PByte(value), 0);
+  end;
+end;
+
+procedure TXXHash64.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+var
+  v1, v2, v3, v4: UInt64;
+  ptrLimit, ptrEnd, ptrBuffer, ptrTemp, ptrMemory: PByte;
+begin
+
+{$IFDEF DEBUG}
+  System.Assert(a_index >= 0);
+  System.Assert(a_length >= 0);
+  System.Assert(a_index + a_length <= System.Length(a_data));
+{$ENDIF DEBUG}
+  ptrBuffer := @a_data[a_index];
+  ptrMemory := PByte(F_state.Fmemory);
+  F_state.Ftotal_len := F_state.Ftotal_len + UInt64(a_length);
+
+  if ((F_state.Fmemsize + UInt32(a_length)) < UInt32(32)) then
+  begin
+
+    ptrTemp := PByte(F_state.Fmemory) + F_state.Fmemsize;
+
+    System.Move(ptrBuffer^, ptrTemp^, a_length);
+
+    F_state.Fmemsize := F_state.Fmemsize + UInt32(a_length);
+    Exit;
+  end;
+
+  ptrEnd := ptrBuffer + UInt32(a_length);
+
+  if F_state.Fmemsize > 0 then
+  begin
+    ptrTemp := PByte(F_state.Fmemory) + F_state.Fmemsize;
+    System.Move(ptrBuffer^, ptrTemp^, 32 - F_state.Fmemsize);
+
+    F_state.Fv1 := PRIME64_1 * TBits.RotateLeft64(F_state.Fv1 + PRIME64_2 *
+      TConverters.ReadBytesAsUInt64LE(ptrMemory, 0), 31);
+    F_state.Fv2 := PRIME64_1 * TBits.RotateLeft64(F_state.Fv2 + PRIME64_2 *
+      TConverters.ReadBytesAsUInt64LE(ptrMemory, 8), 31);
+    F_state.Fv3 := PRIME64_1 * TBits.RotateLeft64(F_state.Fv3 + PRIME64_2 *
+      TConverters.ReadBytesAsUInt64LE(ptrMemory, 16), 31);
+    F_state.Fv4 := PRIME64_1 * TBits.RotateLeft64(F_state.Fv4 + PRIME64_2 *
+      TConverters.ReadBytesAsUInt64LE(ptrMemory, 24), 31);
+
+    ptrBuffer := ptrBuffer + (32 - F_state.Fmemsize);
+    F_state.Fmemsize := 0;
+  end;
+
+  if ptrBuffer <= (ptrEnd - 32) then
+  begin
+    v1 := F_state.Fv1;
+    v2 := F_state.Fv2;
+    v3 := F_state.Fv3;
+    v4 := F_state.Fv4;
+
+    ptrLimit := ptrEnd - 32;
+    repeat
+
+      v1 := PRIME64_1 * TBits.RotateLeft64
+        (v1 + PRIME64_2 * TConverters.ReadBytesAsUInt64LE(ptrBuffer, 0), 31);
+      v2 := PRIME64_1 * TBits.RotateLeft64
+        (v2 + PRIME64_2 * TConverters.ReadBytesAsUInt64LE(ptrBuffer, 8), 31);
+      v3 := PRIME64_1 * TBits.RotateLeft64
+        (v3 + PRIME64_2 * TConverters.ReadBytesAsUInt64LE(ptrBuffer, 16), 31);
+      v4 := PRIME64_1 * TBits.RotateLeft64
+        (v4 + PRIME64_2 * TConverters.ReadBytesAsUInt64LE(ptrBuffer, 24), 31);
+
+      System.Inc(ptrBuffer, 32);
+    until not(ptrBuffer <= ptrLimit);
+
+    F_state.Fv1 := v1;
+    F_state.Fv2 := v2;
+    F_state.Fv3 := v3;
+    F_state.Fv4 := v4;
+  end;
+
+  if ptrBuffer < ptrEnd then
+  begin
+    ptrTemp := PByte(F_state.Fmemory);
+    System.Move(ptrBuffer^, ptrTemp^, ptrEnd - ptrBuffer);
+    F_state.Fmemsize := ptrEnd - ptrBuffer;
+  end;
+
+end;
+
+function TXXHash64.TransformFinal: IHashResult;
+var
+  v1, v2, v3, v4: UInt64;
+  ptrEnd, ptrBuffer: PByte;
+begin
+
+  if F_state.Ftotal_len >= UInt64(32) then
+  begin
+    v1 := F_state.Fv1;
+    v2 := F_state.Fv2;
+    v3 := F_state.Fv3;
+    v4 := F_state.Fv4;
+
+    Fm_hash := TBits.RotateLeft64(v1, 1) + TBits.RotateLeft64(v2, 7) +
+      TBits.RotateLeft64(v3, 12) + TBits.RotateLeft64(v4, 18);
+
+    v1 := TBits.RotateLeft64(v1 * PRIME64_2, 31) * PRIME64_1;
+    Fm_hash := (Fm_hash xor v1) * PRIME64_1 + PRIME64_4;
+
+    v2 := TBits.RotateLeft64(v2 * PRIME64_2, 31) * PRIME64_1;
+    Fm_hash := (Fm_hash xor v2) * PRIME64_1 + PRIME64_4;
+
+    v3 := TBits.RotateLeft64(v3 * PRIME64_2, 31) * PRIME64_1;
+    Fm_hash := (Fm_hash xor v3) * PRIME64_1 + PRIME64_4;
+
+    v4 := TBits.RotateLeft64(v4 * PRIME64_2, 31) * PRIME64_1;
+    Fm_hash := (Fm_hash xor v4) * PRIME64_1 + PRIME64_4;
+  end
+  else
+    Fm_hash := Fm_key + PRIME64_5;
+
+  System.Inc(Fm_hash, F_state.Ftotal_len);
+
+  ptrBuffer := PByte(F_state.Fmemory);
+  ptrEnd := ptrBuffer + F_state.Fmemsize;
+
+  while (ptrBuffer + 8) <= ptrEnd do
+  begin
+    Fm_hash := Fm_hash xor (PRIME64_1 * TBits.RotateLeft64(PRIME64_2 *
+      TConverters.ReadBytesAsUInt64LE(ptrBuffer, 0), 31));
+    Fm_hash := TBits.RotateLeft64(Fm_hash, 27) * PRIME64_1 + PRIME64_4;
+    System.Inc(ptrBuffer, 8);
+  end;
+
+  if (ptrBuffer + 4) <= ptrEnd then
+  begin
+    Fm_hash := Fm_hash xor TConverters.ReadBytesAsUInt32LE(ptrBuffer, 0) *
+      PRIME64_1;
+    Fm_hash := TBits.RotateLeft64(Fm_hash, 23) * PRIME64_2 + PRIME64_3;
+    System.Inc(ptrBuffer, 4);
+  end;
+
+  while ptrBuffer < ptrEnd do
+  begin
+    Fm_hash := Fm_hash xor ptrBuffer^ * PRIME64_5;
+    Fm_hash := TBits.RotateLeft64(Fm_hash, 11) * PRIME64_1;
+    System.Inc(ptrBuffer);
+  end;
+
+  Fm_hash := Fm_hash xor (Fm_hash shr 33);
+  Fm_hash := Fm_hash * PRIME64_2;
+  Fm_hash := Fm_hash xor (Fm_hash shr 29);
+  Fm_hash := Fm_hash * PRIME64_3;
+  Fm_hash := Fm_hash xor (Fm_hash shr 32);
+
+  result := THashResult.Create(Fm_hash);
+  Initialize();
+
+end;
+
+end.

+ 127 - 0
src/libraries/hashlib4pascal/HashLib/src/Include/HashLib.inc

@@ -0,0 +1,127 @@
+{ *********************************************************** }
+{ *                     HashLib Library                     * }
+{ *      Copyright (c) Ugochukwu Mmaduekwe 2016 - 2017      * }
+{ *********************************************************** }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+
+ {$DEFINE DELPHI}
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+{$IFDEF FPC}
+{$I HashLibHelper.inc} // Had to Include this Since Delphi Does not allow "FPC_FULLVERSION" to Compile.
+{$UNDEF DELPHI}
+{$MODE delphi}
+
+{$DEFINE USE_UNROLLED_VARIANT}
+
+// Disable Overflow and RangeChecks.
+{$OVERFLOWCHECKS OFF}
+{$RANGECHECKS OFF}
+
+// Enable Pointer Math
+{$POINTERMATH ON}
+
+// Disable Warnings and Hints.
+{$WARNINGS OFF}
+{$HINTS OFF}
+{$NOTES OFF}
+
+// Optimizations
+{$OPTIMIZATION LEVEL3}
+{$OPTIMIZATION PEEPHOLE}
+{$OPTIMIZATION REGVAR}
+{$OPTIMIZATION LOOPUNROLL}
+{$OPTIMIZATION STRENGTH}
+{$OPTIMIZATION CSE}
+{$OPTIMIZATION DFA}
+{$IFDEF CPUI386}
+{$OPTIMIZATION USEEBP}
+{$ENDIF}
+{$IFDEF CPUX86_64}
+{$OPTIMIZATION USERBP}
+{$ENDIF}
+{$ENDIF FPC}
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+{$IFDEF DELPHI}
+
+{$DEFINE USE_UNROLLED_VARIANT}
+
+// This option is needed to enable code browsing (aka Ctrl+Click)
+// It does not affect the binary size or generated code
+{$DEFINITIONINFO ON}
+
+// Disable Overflow and RangeChecks.
+{$OVERFLOWCHECKS OFF}
+{$RANGECHECKS OFF}
+
+ // Enable Pointer Math
+{$POINTERMATH ON}
+
+// Disable String Checks
+{$STRINGCHECKS OFF}
+
+// Disable Duplicate Constructor Warnings
+{$WARN DUPLICATE_CTOR_DTOR OFF}
+
+ // 2010 only
+{$IF CompilerVersion = 21.0}
+{$DEFINE DELPHI2010}
+{$IFEND}
+
+  // 2010 and Above
+{$IF CompilerVersion >= 21.0}
+{$DEFINE DELPHI2010_UP}
+{$IFEND}
+
+  // XE and Above
+{$IF CompilerVersion >= 22.0}
+{$DEFINE DELPHIXE_UP}
+{$IFEND}
+
+  // XE2 and Above
+{$IF CompilerVersion >= 23.0}
+{$DEFINE DELPHIXE2_UP}
+{$DEFINE HAS_UNITSCOPE}
+{$IFEND}
+
+// XE3 and Below
+{$IF CompilerVersion <= 24.0}
+{$DEFINE DELPHIXE3_DOWN}
+{$IFEND}
+
+ // XE3 and Above
+{$IF CompilerVersion >= 24.0}
+{$DEFINE DELPHIXE3_UP}
+{$LEGACYIFEND ON}
+{$ZEROBASEDSTRINGS OFF}
+{$IFEND}
+
+  // XE7 and Above
+{$IF CompilerVersion >= 28.0}
+{$DEFINE DELPHIXE7_UP}
+{$IFEND}
+
+  // 10.2 Tokyo and Above
+{$IF CompilerVersion >= 32.0}
+{$DEFINE DELPHI10.2_TOKYO_UP}
+{$IFEND}
+
+  // 2010 and Above
+{$IFNDEF DELPHI2010_UP}
+{$MESSAGE ERROR 'This Library requires Delphi 2010 or higher.'}
+{$ENDIF}
+
+  // 10.2 Tokyo and Above
+{$IFDEF DELPHI10.2_TOKYO_UP}
+{$WARN COMBINING_SIGNED_UNSIGNED64 OFF}
+{$ENDIF}
+
+
+{$ENDIF DELPHI}
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+

+ 16 - 0
src/libraries/hashlib4pascal/HashLib/src/Include/HashLibHelper.inc

@@ -0,0 +1,16 @@
+{ *********************************************************** }
+{ *                     HashLib Library                     * }
+{ *      Copyright (c) Ugochukwu Mmaduekwe 2016 - 2017      * }
+{ *********************************************************** }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+{$MACRO ON}
+{$IFDEF ENDIAN_BIG}
+{$MESSAGE FATAL 'This Library does not support "Big Endian" processors yet.'}
+{$ENDIF}
+// FPC 3.0.0 and Above
+// Had to Include this here since Delphi does not allow it Compile in "HashLib.inc".
+{$IF FPC_FULLVERSION < 30000}
+{$MESSAGE ERROR 'This Library requires FreePascal 3.0.0 or higher.'}
+{$IFEND}

+ 35 - 0
src/libraries/hashlib4pascal/HashLib/src/Interfaces/HlpICRC.pas

@@ -0,0 +1,35 @@
+unit HlpICRC;
+
+interface
+
+uses
+  HlpIHash,
+  HlpHashLibTypes;
+
+type
+
+  ICRC = Interface(IHash)
+    ['{44A105E5-6716-43C0-BE69-AE80F87FDC39}']
+
+    function GetNames: THashLibStringArray;
+    property Names: THashLibStringArray read GetNames;
+    function GetWidth: Int32;
+    property Width: Int32 read GetWidth;
+    function GetPolynomial: UInt64;
+    property Polynomial: UInt64 read GetPolynomial;
+    function GetInit: UInt64;
+    property Init: UInt64 read GetInit;
+    function GetReflectIn: Boolean;
+    property ReflectIn: Boolean read GetReflectIn;
+    function GetReflectOut: Boolean;
+    property ReflectOut: Boolean read GetReflectOut;
+    function GetXOROut: UInt64;
+    property XOROut: UInt64 read GetXOROut;
+    function GetCheckValue: UInt64;
+    property CheckValue: UInt64 read GetCheckValue;
+
+  end;
+
+implementation
+
+end.

+ 61 - 0
src/libraries/hashlib4pascal/HashLib/src/Interfaces/HlpIHash.pas

@@ -0,0 +1,61 @@
+unit HlpIHash;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+
+{$IFDEF HAS_UNITSCOPE}
+  System.SysUtils,
+  System.Classes,
+{$ELSE}
+  SysUtils,
+  Classes,
+{$ENDIF HAS_UNITSCOPE}
+  HlpHashLibTypes,
+  HlpIHashResult;
+
+type
+  IHash = interface(IInterface)
+    ['{E91711E1-FD37-4AFD-875A-DD122470D269}']
+    function GetName: String;
+    property Name: String read GetName;
+    function GetBlockSize: Int32;
+    property BlockSize: Int32 read GetBlockSize;
+    function GetHashSize: Int32;
+    property HashSize: Int32 read GetHashSize;
+    function GetBufferSize: Int32;
+    procedure SetBufferSize(value: Int32);
+    property BufferSize: Int32 read GetBufferSize write SetBufferSize;
+
+    function ComputeString(const a_data: String; a_encoding: TEncoding)
+      : IHashResult;
+    function ComputeBytes(a_data: THashLibByteArray): IHashResult;
+    function ComputeUntyped(const a_data; a_length: Int64): IHashResult;
+    function ComputeStream(a_stream: TStream; a_length: Int64 = -1)
+      : IHashResult;
+    function ComputeFile(const a_file_name: String; a_from: Int64 = 0;
+      a_length: Int64 = -1): IHashResult;
+
+    procedure Initialize();
+
+    procedure TransformBytes(a_data: THashLibByteArray); overload;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index: Int32); overload;
+    procedure TransformBytes(a_data: THashLibByteArray; a_index: Int32;
+      a_length: Int32); overload;
+    procedure TransformUntyped(const a_data; a_length: Int64);
+
+    function TransformFinal(): IHashResult;
+
+    procedure TransformString(const a_data: String; a_encoding: TEncoding);
+    procedure TransformStream(a_stream: TStream; a_length: Int64 = -1);
+    procedure TransformFile(const a_file_name: String; a_from: Int64 = 0;
+      a_length: Int64 = -1);
+
+  end;
+
+implementation
+
+end.

+ 86 - 0
src/libraries/hashlib4pascal/HashLib/src/Interfaces/HlpIHashInfo.pas

@@ -0,0 +1,86 @@
+unit HlpIHashInfo;
+
+interface
+
+uses
+  HlpHashLibTypes,
+  HlpIKDF,
+  HlpIHash,
+  HlpNullable;
+
+type
+
+  ITransformBlock = Interface(IInterface)
+    ['{0C375CFF-B379-41B8-955F-A32E22991651}']
+  end;
+
+  IBlockHash = Interface(IHash)
+    ['{3B9A2D29-AC4E-44E4-92B1-6AF9A64DFF0A}']
+  end;
+
+  INonBlockHash = Interface(IInterface)
+    ['{7C7E8B14-DBC7-44A3-BB7C-B24E0BFAA09C}']
+  end;
+
+  IChecksum = Interface(IInterface)
+    ['{EF0885C5-D331-44D8-89CA-05409E20F76E}']
+  end;
+
+  ICrypto = Interface(IBlockHash)
+    ['{5C669048-644C-4E96-B411-9FEA603D7086}']
+  end;
+
+  ICryptoNotBuildIn = Interface(ICrypto)
+    ['{391E62CE-219D-4D33-A753-C32D63353685}']
+  end;
+
+  IWithKey = Interface(IHash)
+    ['{DD5E0FE4-3573-4051-B7CF-F23BABE982D8}']
+
+    function GetKey(): THashLibByteArray;
+    procedure SetKey(value: THashLibByteArray);
+    property Key: THashLibByteArray read GetKey write SetKey;
+    function GetKeyLength(): TNullableInteger;
+    property KeyLength: TNullableInteger read GetKeyLength;
+
+  end;
+
+  IPBKDF2_HMAC = Interface(IKDF)
+    ['{0D409BA8-7F98-4417-858F-3C1EBA11B7E1}']
+  end;
+
+  IPBKDF2_HMACNotBuildIn = Interface(IPBKDF2_HMAC)
+    ['{D7E23DFB-036D-44AD-AA0C-FB83C9970565}']
+  end;
+
+  IHMAC = Interface(IWithKey)
+    ['{A6D4DCC6-F6C3-4110-8CA2-FBE85227676E}']
+  end;
+
+  IHMACNotBuildIn = Interface(IHMAC)
+    ['{A44E01D3-164E-4E3F-9551-3EFFDE95A36C}']
+  end;
+
+  IHash16 = Interface(IHash)
+    ['{C15AF648-C9F7-460D-9F74-B68CA593C2F8}']
+  end;
+
+  IHash32 = Interface(IHash)
+    ['{004BBFDB-71B6-4C74-ABE8-88EC1777263D}']
+  end;
+
+  IHash64 = Interface(IHash)
+    ['{F0354E86-3BEC-4EBC-B17D-ABFC91C02997}']
+  end;
+
+  IHash128 = Interface(IHash)
+    ['{8DD14E37-DDD6-455C-A795-21A15C9E5376}']
+  end;
+
+  IHashWithKey = Interface(IWithKey)
+    ['{D38AE885-651F-4F15-BF90-5B64A0F24E49}']
+  end;
+
+implementation
+
+end.

+ 28 - 0
src/libraries/hashlib4pascal/HashLib/src/Interfaces/HlpIHashResult.pas

@@ -0,0 +1,28 @@
+unit HlpIHashResult;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes;
+
+type
+  IHashResult = interface(IInterface)
+    ['{A467E23D-DBC4-41CC-848D-7267476430C1}']
+
+    function GetBytes(): THashLibByteArray;
+    function GetUInt8(): UInt8;
+    function GetUInt16(): UInt16;
+    function GetUInt32(): UInt32;
+    function GetInt32(): Int32;
+    function GetUInt64(): UInt64;
+    function ToString(a_group: Boolean = false): String;
+    function Equals(a_hashResult: IHashResult): Boolean; overload;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}
+  end;
+
+implementation
+
+end.

+ 24 - 0
src/libraries/hashlib4pascal/HashLib/src/Interfaces/HlpIKDF.pas

@@ -0,0 +1,24 @@
+unit HlpIKDF;
+
+interface
+
+uses
+  HlpHashLibTypes;
+
+type
+  IKDF = interface(IInterface)
+    ['{4697798C-9DC2-476C-A6C2-2D633B74D3FC}']
+    /// <summary>
+    /// Returns the pseudo-random bytes for this object.
+    /// </summary>
+    /// <param name="bc">The number of pseudo-random key bytes to generate.</param>
+    /// <returns>A byte array filled with pseudo-random key bytes.</returns>
+    /// <exception cref="EArgumentOutOfRangeHashLibException">bc must be greater than zero.</exception>
+    /// <exception cref="EArgumentHashLibException">invalid start index or end index of internal buffer.</exception>
+    function GetBytes(bc: Int32): THashLibByteArray;
+
+  end;
+
+implementation
+
+end.

+ 31 - 0
src/libraries/hashlib4pascal/HashLib/src/Interfaces/IBlake2BConfigurations/HlpIBlake2BConfig.pas

@@ -0,0 +1,31 @@
+unit HlpIBlake2BConfig;
+
+{$I ..\..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes;
+
+type
+  IBlake2BConfig = interface(IInterface)
+    ['{176861A3-B06E-4CA3-A1BB-DDEAFF40BFE1}']
+    function GetPersonalisation: THashLibByteArray;
+    procedure SetPersonalisation(value: THashLibByteArray);
+    property Personalisation: THashLibByteArray read GetPersonalisation
+      write SetPersonalisation;
+    function GetSalt: THashLibByteArray;
+    procedure SetSalt(value: THashLibByteArray);
+    property Salt: THashLibByteArray read GetSalt write SetSalt;
+    function GetKey: THashLibByteArray;
+    procedure SetKey(value: THashLibByteArray);
+    property Key: THashLibByteArray read GetKey write SetKey;
+    function GetHashSize: Int32;
+    procedure SetHashSize(value: Int32);
+    property HashSize: Int32 read GetHashSize write SetHashSize;
+
+  end;
+
+implementation
+
+end.

+ 28 - 0
src/libraries/hashlib4pascal/HashLib/src/Interfaces/IBlake2BConfigurations/HlpIBlake2BTreeConfig.pas

@@ -0,0 +1,28 @@
+unit HlpIBlake2BTreeConfig;
+
+{$I ..\..\Include\HashLib.inc}
+
+interface
+
+type
+  IBlake2BTreeConfig = interface(IInterface)
+    ['{3EFB1A70-4478-4375-BAF6-EF17B3673DA8}']
+    function GetIntermediateHashSize: Int32;
+    procedure SetIntermediateHashSize(value: Int32);
+    property IntermediateHashSize: Int32 read GetIntermediateHashSize
+      write SetIntermediateHashSize;
+    function GetMaxHeight: Int32;
+    procedure SetMaxHeight(value: Int32);
+    property MaxHeight: Int32 read GetMaxHeight write SetMaxHeight;
+    function GetLeafSize: Int64;
+    procedure SetLeafSize(value: Int64);
+    property LeafSize: Int64 read GetLeafSize write SetLeafSize;
+    function GetFanOut: Int32;
+    procedure SetFanOut(value: Int32);
+    property FanOut: Int32 read GetFanOut write SetFanOut;
+
+  end;
+
+implementation
+
+end.

+ 31 - 0
src/libraries/hashlib4pascal/HashLib/src/Interfaces/IBlake2SConfigurations/HlpIBlake2SConfig.pas

@@ -0,0 +1,31 @@
+unit HlpIBlake2SConfig;
+
+{$I ..\..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpHashLibTypes;
+
+type
+  IBlake2SConfig = interface(IInterface)
+    ['{C78DE94A-0290-467D-BE26-D0AD1639076C}']
+    function GetPersonalisation: THashLibByteArray;
+    procedure SetPersonalisation(value: THashLibByteArray);
+    property Personalisation: THashLibByteArray read GetPersonalisation
+      write SetPersonalisation;
+    function GetSalt: THashLibByteArray;
+    procedure SetSalt(value: THashLibByteArray);
+    property Salt: THashLibByteArray read GetSalt write SetSalt;
+    function GetKey: THashLibByteArray;
+    procedure SetKey(value: THashLibByteArray);
+    property Key: THashLibByteArray read GetKey write SetKey;
+    function GetHashSize: Int32;
+    procedure SetHashSize(value: Int32);
+    property HashSize: Int32 read GetHashSize write SetHashSize;
+
+  end;
+
+implementation
+
+end.

+ 28 - 0
src/libraries/hashlib4pascal/HashLib/src/Interfaces/IBlake2SConfigurations/HlpIBlake2STreeConfig.pas

@@ -0,0 +1,28 @@
+unit HlpIBlake2STreeConfig;
+
+{$I ..\..\Include\HashLib.inc}
+
+interface
+
+type
+  IBlake2STreeConfig = interface(IInterface)
+    ['{9B0E3927-6C85-46C4-8EFE-609D1FF24030}']
+    function GetIntermediateHashSize: Int32;
+    procedure SetIntermediateHashSize(value: Int32);
+    property IntermediateHashSize: Int32 read GetIntermediateHashSize
+      write SetIntermediateHashSize;
+    function GetMaxHeight: Int32;
+    procedure SetMaxHeight(value: Int32);
+    property MaxHeight: Int32 read GetMaxHeight write SetMaxHeight;
+    function GetLeafSize: Int64;
+    procedure SetLeafSize(value: Int64);
+    property LeafSize: Int64 read GetLeafSize write SetLeafSize;
+    function GetFanOut: Int32;
+    procedure SetFanOut(value: Int32);
+    property FanOut: Int32 read GetFanOut write SetFanOut;
+
+  end;
+
+implementation
+
+end.

+ 202 - 0
src/libraries/hashlib4pascal/HashLib/src/KDF/HlpPBKDF2_HMACNotBuildInAdapter.pas

@@ -0,0 +1,202 @@
+unit HlpPBKDF2_HMACNotBuildInAdapter;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  HlpIHash,
+  HlpKDF,
+  HlpIHashInfo,
+  HlpBitConverter,
+  HlpHashLibTypes;
+
+resourcestring
+  SInvalidArgument =
+    '"bc (ByteCount)" Argument must be a value greater than zero.';
+  SInvalidIndex = 'Invalid start or end index in the internal buffer';
+  SUninitializedInstance = '"IHash" instance is uninitialized';
+  SEmptyPassword = 'Password can''t be empty';
+  SEmptySalt = 'Salt can''t be empty';
+  SIterationtooSmall = 'Iteration must be greater than zero.';
+
+type
+
+  TPBKDF2_HMACNotBuildInAdapter = class sealed(TKDF, IPBKDF2_HMAC,
+    IPBKDF2_HMACNotBuildIn)
+
+  strict private
+    FHash: IHash;
+    FHMAC: IHMAC;
+    FPassword, FSalt, Fbuffer: THashLibByteArray;
+    FIterationCount, FBlock: UInt32;
+    FBlockSize, FstartIndex, FendIndex: Int32;
+
+    // initializes the state of the operation.
+    procedure Initialize();
+
+    // iterative hash function
+    function Func(): THashLibByteArray;
+
+    /// <summary>
+    /// Encodes an integer into a 4-byte array, in big endian.
+    /// </summary>
+    /// <param name="i">The integer to encode.</param>
+    /// <returns>array of bytes, in big endian.</returns>
+    class function GetBigEndianBytes(i: UInt32): THashLibByteArray;
+      static; inline;
+
+  public
+
+    constructor Create(a_underlyingHash: IHash;
+      a_password, a_salt: THashLibByteArray; a_iterations: UInt32);
+
+    /// <summary>
+    /// Returns the pseudo-random bytes for this object.
+    /// </summary>
+    /// <param name="bc">The number of pseudo-random key bytes to generate.</param>
+    /// <returns>A byte array filled with pseudo-random key bytes.</returns>
+    /// <exception cref="EArgumentOutOfRangeHashLibException">bc must be greater than zero.</exception>
+    /// <exception cref="EArgumentHashLibException">invalid start index or end index of internal buffer.</exception>
+    function GetBytes(bc: Int32): THashLibByteArray; override;
+
+  end;
+
+implementation
+
+uses
+  HlpHashFactory; // placed here because of circular dependency.
+
+{ TPBKDF2_HMACNotBuildInAdapter }
+
+constructor TPBKDF2_HMACNotBuildInAdapter.Create(a_underlyingHash: IHash;
+  a_password, a_salt: THashLibByteArray; a_iterations: UInt32);
+begin
+  Inherited Create();
+  FHash := a_underlyingHash;
+  FPassword := System.Copy(a_password);
+  FSalt := System.Copy(a_salt);
+  FIterationCount := a_iterations;
+  Initialize();
+end;
+
+class function TPBKDF2_HMACNotBuildInAdapter.GetBigEndianBytes(i: UInt32)
+  : THashLibByteArray;
+var
+  b, invertedBytes: THashLibByteArray;
+begin
+  b := TBitConverter.GetBytes(i);
+  invertedBytes := THashLibByteArray.Create(b[3], b[2], b[1], b[0]);
+  if TBitConverter.IsLittleEndian then
+    result := invertedBytes
+  else
+    result := b;
+end;
+
+function TPBKDF2_HMACNotBuildInAdapter.Func: THashLibByteArray;
+var
+  INT_block, temp, ret: THashLibByteArray;
+  i: UInt32;
+  j: Int32;
+begin
+
+  INT_block := TPBKDF2_HMACNotBuildInAdapter.GetBigEndianBytes(FBlock);
+  FHMAC.Initialize();
+
+  FHMAC.TransformBytes(FSalt, 0, System.Length(FSalt));
+  FHMAC.TransformBytes(INT_block, 0, System.Length(INT_block));
+
+  temp := FHMAC.TransformFinal().GetBytes();
+
+  ret := temp;
+
+  i := 2;
+  while i <= FIterationCount do
+  begin
+    temp := FHMAC.ComputeBytes(temp).GetBytes();
+    j := 0;
+    while j < FBlockSize do
+    begin
+      ret[j] := ret[j] xor temp[j];
+      System.Inc(j);
+    end;
+    System.Inc(i);
+  end;
+  System.Inc(FBlock);
+  result := ret;
+end;
+
+function TPBKDF2_HMACNotBuildInAdapter.GetBytes(bc: Int32): THashLibByteArray;
+var
+  LKey, LT_block: THashLibByteArray;
+  LOffset, LSize, LRemainder: Int32;
+begin
+
+  if (bc <= 0) then
+    raise EArgumentOutOfRangeHashLibException.CreateRes(@SInvalidArgument);
+
+  System.SetLength(LKey, bc);
+
+  LOffset := 0;
+  LSize := FendIndex - FstartIndex;
+  if (LSize > 0) then
+  begin
+    if (bc >= LSize) then
+    begin
+      System.Move(Fbuffer[FstartIndex], LKey[0], LSize);
+      FstartIndex := 0;
+      FendIndex := 0;
+      LOffset := LOffset + LSize;
+    end
+    else
+    begin
+      System.Move(Fbuffer[FstartIndex], LKey[0], bc);
+      FstartIndex := FstartIndex + bc;
+      result := LKey;
+      Exit;
+    end;
+  end;
+
+  if ((FstartIndex <> 0) and (FendIndex <> 0)) then
+    raise EArgumentHashLibException.CreateRes(@SInvalidIndex);
+
+  while (LOffset < bc) do
+  begin
+    LT_block := Func();
+    LRemainder := bc - LOffset;
+    if (LRemainder > FBlockSize) then
+    begin
+      System.Move(LT_block[0], LKey[LOffset], FBlockSize);
+      LOffset := LOffset + FBlockSize;
+    end
+    else
+    begin
+      System.Move(LT_block[0], LKey[LOffset], LRemainder);
+      System.Move(LT_block[LRemainder], Fbuffer[FstartIndex],
+        FBlockSize - LRemainder);
+      FendIndex := FendIndex + (FBlockSize - LRemainder);
+      result := LKey;
+      Exit;
+    end;
+  end;
+  result := LKey;
+
+end;
+
+procedure TPBKDF2_HMACNotBuildInAdapter.Initialize;
+begin
+  if (Fbuffer <> Nil) then
+    System.FillChar(Fbuffer[0], System.Length(Fbuffer) *
+      System.SizeOf(Byte), Byte(0));
+
+  FHMAC := THashFactory.THMAC.CreateHMAC(FHash);
+
+  FHMAC.Key := System.Copy(FPassword);
+  FBlockSize := FHMAC.HashSize;
+  System.SetLength(Fbuffer, FBlockSize);
+  FBlock := 1;
+  FstartIndex := 0;
+  FendIndex := 0;
+end;
+
+end.

+ 73 - 0
src/libraries/hashlib4pascal/HashLib/src/NullDigest/HlpNullDigest.pas

@@ -0,0 +1,73 @@
+unit HlpNullDigest;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+  Classes,
+  SysUtils,
+  HlpHashLibTypes,
+  HlpHash,
+  HlpIHashInfo,
+  HlpHashResult,
+  HlpIHashResult;
+
+type
+  TNullDigest = class sealed(THash, IBlockHash, ITransformBlock)
+  strict private
+  var
+    FbOut: TMemoryStream;
+
+  public
+    constructor Create();
+    destructor Destroy(); override;
+    procedure Initialize(); override;
+    procedure TransformBytes(a_data: THashLibByteArray;
+      a_index, a_length: Int32); override;
+    function TransformFinal(): IHashResult; override;
+  end;
+
+implementation
+
+{ TNullDigest }
+
+constructor TNullDigest.Create;
+begin
+  Inherited Create(-1, -1); // Dummy State
+  FbOut := TMemoryStream.Create();
+end;
+
+destructor TNullDigest.Destroy;
+begin
+  FbOut.Free;
+  inherited Destroy;
+end;
+
+procedure TNullDigest.Initialize;
+begin
+  FbOut.Position := 0;
+  FbOut.Size := 0;
+  HashSize := 0;
+  BlockSize := 0;
+end;
+
+procedure TNullDigest.TransformBytes(a_data: THashLibByteArray;
+  a_index, a_length: Int32);
+begin
+  FbOut.Write(a_data[a_index], a_length);
+  HashSize := Int32(FbOut.Size);
+end;
+
+function TNullDigest.TransformFinal: IHashResult;
+var
+  res: THashLibByteArray;
+begin
+  FbOut.Position := 0;
+  System.SetLength(res, FbOut.Size);
+  FbOut.Read(res[0], FbOut.Size);
+  result := THashResult.Create(res);
+  Initialize();
+end;
+
+end.

+ 246 - 0
src/libraries/hashlib4pascal/HashLib/src/Nullable/HlpNullable.pas

@@ -0,0 +1,246 @@
+unit HlpNullable;
+
+{$I ..\Include\HashLib.inc}
+{ /*  The "Nullable Types" found in this Unit were extracted from
+  https://github.com/jpluimers/Conferences/blob/master/2009/DelphiLive.2009/Nullable-types-in-Delphi-Win32/Delphi-generic/src/NullableTypes.pas
+  with some little modifications by me. */ }
+
+interface
+
+uses
+  HlpHashLibTypes,
+{$IFDEF HAS_UNITSCOPE}
+  System.TypInfo
+{$ELSE}
+  TypInfo
+{$ENDIF HAS_UNITSCOPE};
+
+resourcestring
+  SCannotAssignPointerToNullable =
+    'Cannot assign non-null pointer to nullable type.';
+  SUnsupportedType =
+    'Unsupported Type: Only supports Integers, Int64, Floats and Strings.';
+  SGetNullValue = 'Attempted to get a null value.';
+
+type
+
+  Nullable<T> = record
+  private
+  var
+    fValue: T;
+    class function CastBack(const aValue): T; static;
+    class function AddFloat(const aFloat, bFloat): T; static;
+    class function AddString(const aString, bString): T; static;
+    class function AddInt64(const aInt64, bInt64): T; static;
+    class function NewAddInt(const aInt, bInt): T; static;
+
+  var
+    fInitValue: string;
+
+  var
+    fDefault: T;
+
+  var
+    fInitDefault: string;
+    procedure SetValue(const aValue: T); inline;
+    procedure CheckValue; inline;
+    procedure CheckType; inline;
+    function GetValue: T; inline;
+    function GetIsNull: Boolean; inline;
+    function GetHasValue: Boolean; inline;
+    function GetHasDefault: Boolean; inline;
+  public
+    property Value: T read GetValue write SetValue;
+    property IsNull: Boolean read GetIsNull;
+    property HasValue: Boolean read GetHasValue;
+    property HasDefault: Boolean read GetHasDefault;
+    procedure ClearValue;
+    procedure SetDefault(const aDefault: T);
+
+    constructor Create(const aValue: T); overload;
+    constructor Create(const aValue: T; const aDefault: T); overload;
+
+    class operator Implicit(a: T): Nullable<T>;
+    class operator Implicit(a: Nullable<T>): T;
+    class operator Implicit(a: Pointer): Nullable<T>;
+    class operator Explicit(aValue: Nullable<T>): T;
+
+    class operator Add(a, b: Nullable<T>): Nullable<T>;
+  end;
+
+  /// <summary>
+  /// Represents a Nullable Integer.
+  /// </summary>
+  TNullableInteger = Nullable<Int32>;
+
+implementation
+
+{ Nullable<T> }
+
+function Nullable<T>.GetHasDefault: Boolean;
+begin
+  Result := fInitDefault = 'I';
+end;
+
+function Nullable<T>.GetHasValue: Boolean;
+begin
+  Result := not IsNull;
+end;
+
+function Nullable<T>.GetIsNull: Boolean;
+begin
+  Result := fInitValue <> 'I';
+end;
+
+procedure Nullable<T>.CheckType;
+var
+  info: PTypeInfo;
+begin
+  info := TypeInfo(T);
+  case info^.Kind of
+    tkInteger:
+      ;
+    tkFloat:
+      ;
+    tkString:
+      ;
+    tkInt64:
+      ;
+    tkUString:
+      ;
+  else
+    Raise EUnsupportedTypeHashLibException.CreateRes(@SUnsupportedType);
+  end;
+end;
+
+procedure Nullable<T>.CheckValue;
+begin
+  if IsNull then
+    if HasDefault then
+      fValue := fDefault
+    else
+      raise ENullReferenceHashLibException.CreateRes(@SGetNullValue);
+end;
+
+function Nullable<T>.GetValue: T;
+begin
+  CheckType;
+  CheckValue;
+  Result := fValue;
+end;
+
+procedure Nullable<T>.SetDefault(const aDefault: T);
+begin
+  fDefault := aDefault;
+  fInitDefault := 'I';
+  if IsNull then
+    fValue := aDefault;
+end;
+
+procedure Nullable<T>.SetValue(const aValue: T);
+begin
+  fInitValue := 'I';
+  fValue := aValue;
+end;
+
+class operator Nullable<T>.Implicit(a: Nullable<T>): T;
+begin
+  Result := a.Value;
+end;
+
+class operator Nullable<T>.Implicit(a: T): Nullable<T>;
+begin
+  Result.Value := a;
+end;
+
+class operator Nullable<T>.Implicit(a: Pointer): Nullable<T>;
+begin
+  if not System.Assigned(a) then
+    Result.ClearValue
+  else
+    raise EInvalidOperationHashLibException.CreateRes
+      (@SCannotAssignPointerToNullable);
+end;
+
+// got the idea from Andreas Hausladen
+class function Nullable<T>.CastBack(const aValue): T;
+begin
+  Result := T(aValue);
+end;
+
+class function Nullable<T>.AddInt64(const aInt64, bInt64): T;
+var
+  Value: Int64;
+begin
+  Value := Int64(aInt64) + Int64(bInt64);
+  Result := CastBack(Value);
+end;
+
+class function Nullable<T>.AddFloat(const aFloat, bFloat): T;
+var
+  Value: Double;
+begin
+  Value := Double(aFloat) + Double(bFloat);
+  Result := CastBack(Value);
+end;
+
+class function Nullable<T>.AddString(const aString, bString): T;
+var
+  Value: String;
+begin
+  Value := String(aString) + String(bString);
+  Result := CastBack(Value);
+end;
+
+class function Nullable<T>.NewAddInt(const aInt, bInt): T;
+var
+  Value: Int32;
+begin
+  Value := Int32(aInt) + Int32(bInt);
+  Result := CastBack(Value);
+end;
+
+class operator Nullable<T>.Add(a, b: Nullable<T>): Nullable<T>;
+var
+  info: PTypeInfo;
+begin
+  if a.IsNull or b.IsNull then
+    Result.ClearValue
+  else
+  begin
+    info := TypeInfo(T);
+    case info^.Kind of
+      tkInteger:
+        Result.Value := NewAddInt(a.fValue, b.fValue);
+      tkFloat:
+        Result.Value := AddFloat(a.fValue, b.fValue);
+      tkString:
+        Result.Value := AddString(a.fValue, b.fValue);
+      tkInt64:
+        Result.Value := AddInt64(a.fValue, b.fValue);
+    end;
+  end;
+end;
+
+procedure Nullable<T>.ClearValue;
+begin
+  fInitValue := '';
+end;
+
+constructor Nullable<T>.Create(const aValue: T);
+begin
+  SetValue(aValue);
+end;
+
+constructor Nullable<T>.Create(const aValue, aDefault: T);
+begin
+  SetValue(aValue);
+  SetDefault(aDefault);
+end;
+
+class operator Nullable<T>.Explicit(aValue: Nullable<T>): T;
+begin
+  Result := aValue.Value;
+end;
+
+end.

+ 138 - 0
src/libraries/hashlib4pascal/HashLib/src/Packages/Delphi/HashLib4PascalPackage.dpk

@@ -0,0 +1,138 @@
+package HashLib4PascalPackage;
+
+{$WARN DUPLICATE_CTOR_DTOR OFF}
+{$R *.res}
+{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
+{$ALIGN 8}
+{$ASSERTIONS ON}
+{$BOOLEVAL OFF}
+{$DEBUGINFO OFF}
+{$EXTENDEDSYNTAX ON}
+{$IMPORTEDDATA ON}
+{$IOCHECKS ON}
+{$LOCALSYMBOLS OFF}
+{$LONGSTRINGS ON}
+{$OPENSTRINGS ON}
+{$OPTIMIZATION ON}
+{$OVERFLOWCHECKS OFF}
+{$RANGECHECKS OFF}
+{$REFERENCEINFO OFF}
+{$SAFEDIVIDE OFF}
+{$STACKFRAMES OFF}
+{$TYPEDADDRESS OFF}
+{$VARSTRINGCHECKS ON}
+{$WRITEABLECONST OFF}
+{$MINENUMSIZE 1}
+{$IMAGEBASE $400000}
+{$DEFINE RELEASE}
+{$ENDIF IMPLICITBUILDING}
+{$RUNONLY}
+{$IMPLICITBUILD ON}
+
+requires
+  rtl,
+  soaprtl;
+
+contains
+  HlpHash in '..\..\Base\HlpHash.pas',
+  HlpHashBuffer in '..\..\Base\HlpHashBuffer.pas',
+  HlpHashCryptoNotBuildIn in '..\..\Base\HlpHashCryptoNotBuildIn.pas',
+  HlpHashFactory in '..\..\Base\HlpHashFactory.pas',
+  HlpHashResult in '..\..\Base\HlpHashResult.pas',
+  HlpHashRounds in '..\..\Base\HlpHashRounds.pas',
+  HlpHashSize in '..\..\Base\HlpHashSize.pas',
+  HlpHMACNotBuildInAdapter in '..\..\Base\HlpHMACNotBuildInAdapter.pas',
+  HlpKDF in '..\..\Base\HlpKDF.pas',
+  HlpMultipleTransformNonBlock in '..\..\Base\HlpMultipleTransformNonBlock.pas',
+  HlpAdler32 in '..\..\Checksum\HlpAdler32.pas',
+  HlpCRC in '..\..\Checksum\HlpCRC.pas',
+  HlpCRC16 in '..\..\Checksum\HlpCRC16.pas',
+  HlpCRC32 in '..\..\Checksum\HlpCRC32.pas',
+  HlpCRC64 in '..\..\Checksum\HlpCRC64.pas',
+  HlpBlake2B in '..\..\Crypto\HlpBlake2B.pas',
+  HlpBlake2S in '..\..\Crypto\HlpBlake2S.pas',
+  HlpGost in '..\..\Crypto\HlpGost.pas',
+  HlpGOST3411_2012 in '..\..\Crypto\HlpGOST3411_2012.pas',
+  HlpGrindahl256 in '..\..\Crypto\HlpGrindahl256.pas',
+  HlpGrindahl512 in '..\..\Crypto\HlpGrindahl512.pas',
+  HlpHAS160 in '..\..\Crypto\HlpHAS160.pas',
+  HlpHaval in '..\..\Crypto\HlpHaval.pas',
+  HlpMD2 in '..\..\Crypto\HlpMD2.pas',
+  HlpMD4 in '..\..\Crypto\HlpMD4.pas',
+  HlpMD5 in '..\..\Crypto\HlpMD5.pas',
+  HlpMDBase in '..\..\Crypto\HlpMDBase.pas',
+  HlpPanama in '..\..\Crypto\HlpPanama.pas',
+  HlpRadioGatun32 in '..\..\Crypto\HlpRadioGatun32.pas',
+  HlpRadioGatun64 in '..\..\Crypto\HlpRadioGatun64.pas',
+  HlpRIPEMD in '..\..\Crypto\HlpRIPEMD.pas',
+  HlpRIPEMD128 in '..\..\Crypto\HlpRIPEMD128.pas',
+  HlpRIPEMD160 in '..\..\Crypto\HlpRIPEMD160.pas',
+  HlpRIPEMD256 in '..\..\Crypto\HlpRIPEMD256.pas',
+  HlpRIPEMD320 in '..\..\Crypto\HlpRIPEMD320.pas',
+  HlpSHA0 in '..\..\Crypto\HlpSHA0.pas',
+  HlpSHA1 in '..\..\Crypto\HlpSHA1.pas',
+  HlpSHA2_224 in '..\..\Crypto\HlpSHA2_224.pas',
+  HlpSHA2_256 in '..\..\Crypto\HlpSHA2_256.pas',
+  HlpSHA2_256Base in '..\..\Crypto\HlpSHA2_256Base.pas',
+  HlpSHA2_384 in '..\..\Crypto\HlpSHA2_384.pas',
+  HlpSHA2_512 in '..\..\Crypto\HlpSHA2_512.pas',
+  HlpSHA2_512_224 in '..\..\Crypto\HlpSHA2_512_224.pas',
+  HlpSHA2_512_256 in '..\..\Crypto\HlpSHA2_512_256.pas',
+  HlpSHA2_512Base in '..\..\Crypto\HlpSHA2_512Base.pas',
+  HlpSHA3 in '..\..\Crypto\HlpSHA3.pas',
+  HlpSnefru in '..\..\Crypto\HlpSnefru.pas',
+  HlpTiger in '..\..\Crypto\HlpTiger.pas',
+  HlpTiger2 in '..\..\Crypto\HlpTiger2.pas',
+  HlpWhirlPool in '..\..\Crypto\HlpWhirlPool.pas',
+  HlpBlake2BConfig in '..\..\Crypto\Blake2BConfigurations\HlpBlake2BConfig.pas',
+  HlpBlake2BIvBuilder in '..\..\Crypto\Blake2BConfigurations\HlpBlake2BIvBuilder.pas',
+  HlpBlake2BTreeConfig in '..\..\Crypto\Blake2BConfigurations\HlpBlake2BTreeConfig.pas',
+  HlpBlake2SConfig in '..\..\Crypto\Blake2SConfigurations\HlpBlake2SConfig.pas',
+  HlpBlake2SIvBuilder in '..\..\Crypto\Blake2SConfigurations\HlpBlake2SIvBuilder.pas',
+  HlpBlake2STreeConfig in '..\..\Crypto\Blake2SConfigurations\HlpBlake2STreeConfig.pas',
+  HlpNullDigest in '..\..\NullDigest\HlpNullDigest.pas',
+  HlpAP in '..\..\Hash32\HlpAP.pas',
+  HlpBernstein in '..\..\Hash32\HlpBernstein.pas',
+  HlpBernstein1 in '..\..\Hash32\HlpBernstein1.pas',
+  HlpBKDR in '..\..\Hash32\HlpBKDR.pas',
+  HlpDEK in '..\..\Hash32\HlpDEK.pas',
+  HlpDJB in '..\..\Hash32\HlpDJB.pas',
+  HlpELF in '..\..\Hash32\HlpELF.pas',
+  HlpFNV in '..\..\Hash32\HlpFNV.pas',
+  HlpFNV1a in '..\..\Hash32\HlpFNV1a.pas',
+  HlpJenkins3 in '..\..\Hash32\HlpJenkins3.pas',
+  HlpJS in '..\..\Hash32\HlpJS.pas',
+  HlpMurmur2 in '..\..\Hash32\HlpMurmur2.pas',
+  HlpMurmurHash3_x86_32 in '..\..\Hash32\HlpMurmurHash3_x86_32.pas',
+  HlpOneAtTime in '..\..\Hash32\HlpOneAtTime.pas',
+  HlpPJW in '..\..\Hash32\HlpPJW.pas',
+  HlpRotating in '..\..\Hash32\HlpRotating.pas',
+  HlpRS in '..\..\Hash32\HlpRS.pas',
+  HlpSDBM in '..\..\Hash32\HlpSDBM.pas',
+  HlpShiftAndXor in '..\..\Hash32\HlpShiftAndXor.pas',
+  HlpSuperFast in '..\..\Hash32\HlpSuperFast.pas',
+  HlpXXHash32 in '..\..\Hash32\HlpXXHash32.pas',
+  HlpFNV1a64 in '..\..\Hash64\HlpFNV1a64.pas',
+  HlpFNV64 in '..\..\Hash64\HlpFNV64.pas',
+  HlpMurmur2_64 in '..\..\Hash64\HlpMurmur2_64.pas',
+  HlpSipHash in '..\..\Hash64\HlpSipHash.pas',
+  HlpXXHash64 in '..\..\Hash64\HlpXXHash64.pas',
+  HlpMurmurHash3_x64_128 in '..\..\Hash128\HlpMurmurHash3_x64_128.pas',
+  HlpMurmurHash3_x86_128 in '..\..\Hash128\HlpMurmurHash3_x86_128.pas',
+  HlpICRC in '..\..\Interfaces\HlpICRC.pas',
+  HlpIHash in '..\..\Interfaces\HlpIHash.pas',
+  HlpIHashInfo in '..\..\Interfaces\HlpIHashInfo.pas',
+  HlpIHashResult in '..\..\Interfaces\HlpIHashResult.pas',
+  HlpIKDF in '..\..\Interfaces\HlpIKDF.pas',
+  HlpIBlake2BConfig in '..\..\Interfaces\IBlake2BConfigurations\HlpIBlake2BConfig.pas',
+  HlpIBlake2BTreeConfig in '..\..\Interfaces\IBlake2BConfigurations\HlpIBlake2BTreeConfig.pas',
+  HlpIBlake2SConfig in '..\..\Interfaces\IBlake2SConfigurations\HlpIBlake2SConfig.pas',
+  HlpIBlake2STreeConfig in '..\..\Interfaces\IBlake2SConfigurations\HlpIBlake2STreeConfig.pas',
+  HlpPBKDF2_HMACNotBuildInAdapter in '..\..\KDF\HlpPBKDF2_HMACNotBuildInAdapter.pas',
+  HlpNullable in '..\..\Nullable\HlpNullable.pas',
+  HlpConverters in '..\..\Utils\HlpConverters.pas',
+  HlpBitConverter in '..\..\Utils\HlpBitConverter.pas',
+  HlpBits in '..\..\Utils\HlpBits.pas',
+  HlpHashLibTypes in '..\..\Utils\HlpHashLibTypes.pas';
+
+end.

+ 449 - 0
src/libraries/hashlib4pascal/HashLib/src/Packages/FPC/HashLib4PascalPackage.lpk

@@ -0,0 +1,449 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+  <Package Version="4">
+    <PathDelim Value="\"/>
+    <Name Value="HashLib4PascalPackage"/>
+    <Type Value="RunTimeOnly"/>
+    <Author Value="Xor-el (Ugochukwu Mmaduekwe)"/>
+    <CompilerOptions>
+      <Version Value="11"/>
+      <PathDelim Value="\"/>
+      <SearchPaths>
+        <IncludeFiles Value="..\..\..;..\..\Base;..\..\Checksum;..\..\Crypto;..\..\Crypto\Blake2BConfigurations;..\..\Crypto\Blake2SConfigurations;..\..\Hash32;..\..\Hash64;..\..\Hash128;..\..\Interfaces;..\..\Interfaces\IBlake2BConfigurations;..\..\Interfaces\IBlake2SConfigurations;..\..\KDF;..\..\Nullable;..\..\Utils"/>
+        <OtherUnitFiles Value="..\..\Base;..\..\Checksum;..\..\Crypto;..\..\Hash128;..\..\Hash32;..\..\Hash64;..\..\Interfaces;..\..\Nullable;..\..\Utils;..\..\KDF;..\..\Crypto\Blake2BConfigurations;..\..\Crypto\Blake2SConfigurations;..\..\Interfaces\IBlake2BConfigurations;..\..\Interfaces\IBlake2SConfigurations;..\..\NullDigest"/>
+        <UnitOutputDirectory Value="lib\HashLib4Pascal\$(TargetCPU)-$(TargetOS)"/>
+      </SearchPaths>
+      <CodeGeneration>
+        <Optimizations>
+          <OptimizationLevel Value="4"/>
+        </Optimizations>
+      </CodeGeneration>
+    </CompilerOptions>
+    <Description Value="HashLib4Pascal is a Delphi/FPC compatible library that provides an easy to use interface for computing hashes and checksums of strings (with a specified encoding), files, streams, byte arrays and untyped data to mention but a few.
+"/>
+    <License Value="MIT License"/>
+    <Version Major="2" Minor="4"/>
+    <Files Count="102">
+      <Item1>
+        <Filename Value="..\..\Base\HlpHash.pas"/>
+        <UnitName Value="HlpHash"/>
+      </Item1>
+      <Item2>
+        <Filename Value="..\..\Base\HlpHashBuffer.pas"/>
+        <UnitName Value="HlpHashBuffer"/>
+      </Item2>
+      <Item3>
+        <Filename Value="..\..\Base\HlpHashCryptoNotBuildIn.pas"/>
+        <UnitName Value="HlpHashCryptoNotBuildIn"/>
+      </Item3>
+      <Item4>
+        <Filename Value="..\..\Base\HlpHashFactory.pas"/>
+        <UnitName Value="HlpHashFactory"/>
+      </Item4>
+      <Item5>
+        <Filename Value="..\..\Base\HlpHashResult.pas"/>
+        <UnitName Value="HlpHashResult"/>
+      </Item5>
+      <Item6>
+        <Filename Value="..\..\Base\HlpHashRounds.pas"/>
+        <UnitName Value="HlpHashRounds"/>
+      </Item6>
+      <Item7>
+        <Filename Value="..\..\Base\HlpHashSize.pas"/>
+        <UnitName Value="HlpHashSize"/>
+      </Item7>
+      <Item8>
+        <Filename Value="..\..\Base\HlpHMACNotBuildInAdapter.pas"/>
+        <UnitName Value="HlpHMACNotBuildInAdapter"/>
+      </Item8>
+      <Item9>
+        <Filename Value="..\..\Base\HlpMultipleTransformNonBlock.pas"/>
+        <UnitName Value="HlpMultipleTransformNonBlock"/>
+      </Item9>
+      <Item10>
+        <Filename Value="..\..\Checksum\HlpAdler32.pas"/>
+        <UnitName Value="HlpAdler32"/>
+      </Item10>
+      <Item11>
+        <Filename Value="..\..\Checksum\HlpCRC.pas"/>
+        <UnitName Value="HlpCRC"/>
+      </Item11>
+      <Item12>
+        <Filename Value="..\..\Checksum\HlpCRC16.pas"/>
+        <UnitName Value="HlpCRC16"/>
+      </Item12>
+      <Item13>
+        <Filename Value="..\..\Checksum\HlpCRC32.pas"/>
+        <UnitName Value="HlpCRC32"/>
+      </Item13>
+      <Item14>
+        <Filename Value="..\..\Checksum\HlpCRC64.pas"/>
+        <UnitName Value="HlpCRC64"/>
+      </Item14>
+      <Item15>
+        <Filename Value="..\..\Crypto\HlpGost.pas"/>
+        <UnitName Value="HlpGost"/>
+      </Item15>
+      <Item16>
+        <Filename Value="..\..\Crypto\HlpGrindahl256.pas"/>
+        <UnitName Value="HlpGrindahl256"/>
+      </Item16>
+      <Item17>
+        <Filename Value="..\..\Crypto\HlpGrindahl512.pas"/>
+        <UnitName Value="HlpGrindahl512"/>
+      </Item17>
+      <Item18>
+        <Filename Value="..\..\Crypto\HlpHAS160.pas"/>
+        <UnitName Value="HlpHAS160"/>
+      </Item18>
+      <Item19>
+        <Filename Value="..\..\Crypto\HlpHaval.pas"/>
+        <UnitName Value="HlpHaval"/>
+      </Item19>
+      <Item20>
+        <Filename Value="..\..\Crypto\HlpMD2.pas"/>
+        <UnitName Value="HlpMD2"/>
+      </Item20>
+      <Item21>
+        <Filename Value="..\..\Crypto\HlpMD4.pas"/>
+        <UnitName Value="HlpMD4"/>
+      </Item21>
+      <Item22>
+        <Filename Value="..\..\Crypto\HlpMD5.pas"/>
+        <UnitName Value="HlpMD5"/>
+      </Item22>
+      <Item23>
+        <Filename Value="..\..\Crypto\HlpMDBase.pas"/>
+        <UnitName Value="HlpMDBase"/>
+      </Item23>
+      <Item24>
+        <Filename Value="..\..\Crypto\HlpPanama.pas"/>
+        <UnitName Value="HlpPanama"/>
+      </Item24>
+      <Item25>
+        <Filename Value="..\..\Crypto\HlpRadioGatun32.pas"/>
+        <UnitName Value="HlpRadioGatun32"/>
+      </Item25>
+      <Item26>
+        <Filename Value="..\..\Crypto\HlpRadioGatun64.pas"/>
+        <UnitName Value="HlpRadioGatun64"/>
+      </Item26>
+      <Item27>
+        <Filename Value="..\..\Crypto\HlpRIPEMD.pas"/>
+        <UnitName Value="HlpRIPEMD"/>
+      </Item27>
+      <Item28>
+        <Filename Value="..\..\Crypto\HlpRIPEMD128.pas"/>
+        <UnitName Value="HlpRIPEMD128"/>
+      </Item28>
+      <Item29>
+        <Filename Value="..\..\Crypto\HlpRIPEMD160.pas"/>
+        <UnitName Value="HlpRIPEMD160"/>
+      </Item29>
+      <Item30>
+        <Filename Value="..\..\Crypto\HlpRIPEMD256.pas"/>
+        <UnitName Value="HlpRIPEMD256"/>
+      </Item30>
+      <Item31>
+        <Filename Value="..\..\Crypto\HlpRIPEMD320.pas"/>
+        <UnitName Value="HlpRIPEMD320"/>
+      </Item31>
+      <Item32>
+        <Filename Value="..\..\Crypto\HlpSHA0.pas"/>
+        <UnitName Value="HlpSHA0"/>
+      </Item32>
+      <Item33>
+        <Filename Value="..\..\Crypto\HlpSHA1.pas"/>
+        <UnitName Value="HlpSHA1"/>
+      </Item33>
+      <Item34>
+        <Filename Value="..\..\Crypto\HlpSHA2_224.pas"/>
+        <UnitName Value="HlpSHA2_224"/>
+      </Item34>
+      <Item35>
+        <Filename Value="..\..\Crypto\HlpSHA2_256.pas"/>
+        <UnitName Value="HlpSHA2_256"/>
+      </Item35>
+      <Item36>
+        <Filename Value="..\..\Crypto\HlpSHA2_256Base.pas"/>
+        <UnitName Value="HlpSHA2_256Base"/>
+      </Item36>
+      <Item37>
+        <Filename Value="..\..\Crypto\HlpSHA2_384.pas"/>
+        <UnitName Value="HlpSHA2_384"/>
+      </Item37>
+      <Item38>
+        <Filename Value="..\..\Crypto\HlpSHA2_512.pas"/>
+        <UnitName Value="HlpSHA2_512"/>
+      </Item38>
+      <Item39>
+        <Filename Value="..\..\Crypto\HlpSHA2_512Base.pas"/>
+        <UnitName Value="HlpSHA2_512Base"/>
+      </Item39>
+      <Item40>
+        <Filename Value="..\..\Crypto\HlpSHA2_512_224.pas"/>
+        <UnitName Value="HlpSHA2_512_224"/>
+      </Item40>
+      <Item41>
+        <Filename Value="..\..\Crypto\HlpSHA2_512_256.pas"/>
+        <UnitName Value="HlpSHA2_512_256"/>
+      </Item41>
+      <Item42>
+        <Filename Value="..\..\Crypto\HlpSHA3.pas"/>
+        <UnitName Value="HlpSHA3"/>
+      </Item42>
+      <Item43>
+        <Filename Value="..\..\Crypto\HlpSnefru.pas"/>
+        <UnitName Value="HlpSnefru"/>
+      </Item43>
+      <Item44>
+        <Filename Value="..\..\Crypto\HlpTiger.pas"/>
+        <UnitName Value="HlpTiger"/>
+      </Item44>
+      <Item45>
+        <Filename Value="..\..\Crypto\HlpTiger2.pas"/>
+        <UnitName Value="HlpTiger2"/>
+      </Item45>
+      <Item46>
+        <Filename Value="..\..\Crypto\HlpWhirlPool.pas"/>
+        <UnitName Value="HlpWhirlPool"/>
+      </Item46>
+      <Item47>
+        <Filename Value="..\..\Hash128\HlpMurmurHash3_x64_128.pas"/>
+        <UnitName Value="HlpMurmurHash3_x64_128"/>
+      </Item47>
+      <Item48>
+        <Filename Value="..\..\NullDigest\HlpNullDigest.pas"/>
+        <UnitName Value="HlpNullDigest"/>
+      </Item48>
+      <Item49>
+        <Filename Value="..\..\Hash32\HlpAP.pas"/>
+        <UnitName Value="HlpAP"/>
+      </Item49>
+      <Item50>
+        <Filename Value="..\..\Hash32\HlpBernstein.pas"/>
+        <UnitName Value="HlpBernstein"/>
+      </Item50>
+      <Item51>
+        <Filename Value="..\..\Hash32\HlpBernstein1.pas"/>
+        <UnitName Value="HlpBernstein1"/>
+      </Item51>
+      <Item52>
+        <Filename Value="..\..\Hash32\HlpBKDR.pas"/>
+        <UnitName Value="HlpBKDR"/>
+      </Item52>
+      <Item53>
+        <Filename Value="..\..\Hash32\HlpDEK.pas"/>
+        <UnitName Value="HlpDEK"/>
+      </Item53>
+      <Item54>
+        <Filename Value="..\..\Hash32\HlpDJB.pas"/>
+        <UnitName Value="HlpDJB"/>
+      </Item54>
+      <Item55>
+        <Filename Value="..\..\Hash32\HlpELF.pas"/>
+        <UnitName Value="HlpELF"/>
+      </Item55>
+      <Item56>
+        <Filename Value="..\..\Hash32\HlpFNV.pas"/>
+        <UnitName Value="HlpFNV"/>
+      </Item56>
+      <Item57>
+        <Filename Value="..\..\Hash32\HlpFNV1a.pas"/>
+        <UnitName Value="HlpFNV1a"/>
+      </Item57>
+      <Item58>
+        <Filename Value="..\..\Hash32\HlpJenkins3.pas"/>
+        <UnitName Value="HlpJenkins3"/>
+      </Item58>
+      <Item59>
+        <Filename Value="..\..\Hash32\HlpJS.pas"/>
+        <UnitName Value="HlpJS"/>
+      </Item59>
+      <Item60>
+        <Filename Value="..\..\Hash32\HlpMurmur2.pas"/>
+        <UnitName Value="HlpMurmur2"/>
+      </Item60>
+      <Item61>
+        <Filename Value="..\..\Hash32\HlpMurmurHash3_x86_32.pas"/>
+        <UnitName Value="HlpMurmurHash3_x86_32"/>
+      </Item61>
+      <Item62>
+        <Filename Value="..\..\Hash32\HlpOneAtTime.pas"/>
+        <UnitName Value="HlpOneAtTime"/>
+      </Item62>
+      <Item63>
+        <Filename Value="..\..\Hash32\HlpPJW.pas"/>
+        <UnitName Value="HlpPJW"/>
+      </Item63>
+      <Item64>
+        <Filename Value="..\..\Hash32\HlpRotating.pas"/>
+        <UnitName Value="HlpRotating"/>
+      </Item64>
+      <Item65>
+        <Filename Value="..\..\Hash32\HlpRS.pas"/>
+        <UnitName Value="HlpRS"/>
+      </Item65>
+      <Item66>
+        <Filename Value="..\..\Hash32\HlpSDBM.pas"/>
+        <UnitName Value="HlpSDBM"/>
+      </Item66>
+      <Item67>
+        <Filename Value="..\..\Hash32\HlpShiftAndXor.pas"/>
+        <UnitName Value="HlpShiftAndXor"/>
+      </Item67>
+      <Item68>
+        <Filename Value="..\..\Hash32\HlpSuperFast.pas"/>
+        <UnitName Value="HlpSuperFast"/>
+      </Item68>
+      <Item69>
+        <Filename Value="..\..\Hash32\HlpXXHash32.pas"/>
+        <UnitName Value="HlpXXHash32"/>
+      </Item69>
+      <Item70>
+        <Filename Value="..\..\Hash64\HlpFNV1a64.pas"/>
+        <UnitName Value="HlpFNV1a64"/>
+      </Item70>
+      <Item71>
+        <Filename Value="..\..\Hash64\HlpFNV64.pas"/>
+        <UnitName Value="HlpFNV64"/>
+      </Item71>
+      <Item72>
+        <Filename Value="..\..\Hash64\HlpMurmur2_64.pas"/>
+        <UnitName Value="HlpMurmur2_64"/>
+      </Item72>
+      <Item73>
+        <Filename Value="..\..\Hash64\HlpSipHash.pas"/>
+        <UnitName Value="HlpSipHash"/>
+      </Item73>
+      <Item74>
+        <Filename Value="..\..\Hash64\HlpXXHash64.pas"/>
+        <UnitName Value="HlpXXHash64"/>
+      </Item74>
+      <Item75>
+        <Filename Value="..\..\Include\HashLib.inc"/>
+        <Type Value="Include"/>
+      </Item75>
+      <Item76>
+        <Filename Value="..\..\Include\HashLibHelper.inc"/>
+        <Type Value="Include"/>
+      </Item76>
+      <Item77>
+        <Filename Value="..\..\Interfaces\HlpIHash.pas"/>
+        <UnitName Value="HlpIHash"/>
+      </Item77>
+      <Item78>
+        <Filename Value="..\..\Interfaces\HlpIHashInfo.pas"/>
+        <UnitName Value="HlpIHashInfo"/>
+      </Item78>
+      <Item79>
+        <Filename Value="..\..\Interfaces\HlpIHashResult.pas"/>
+        <UnitName Value="HlpIHashResult"/>
+      </Item79>
+      <Item80>
+        <Filename Value="..\..\Nullable\HlpNullable.pas"/>
+        <UnitName Value="HlpNullable"/>
+      </Item80>
+      <Item81>
+        <Filename Value="..\..\Utils\HlpConverters.pas"/>
+        <UnitName Value="HlpConverters"/>
+      </Item81>
+      <Item82>
+        <Filename Value="..\..\Utils\HlpBitConverter.pas"/>
+        <UnitName Value="HlpBitConverter"/>
+      </Item82>
+      <Item83>
+        <Filename Value="..\..\Utils\HlpBits.pas"/>
+        <UnitName Value="HlpBits"/>
+      </Item83>
+      <Item84>
+        <Filename Value="..\..\Utils\HlpHashLibTypes.pas"/>
+        <UnitName Value="HlpHashLibTypes"/>
+      </Item84>
+      <Item85>
+        <Filename Value="..\..\Hash128\HlpMurmurHash3_x86_128.pas"/>
+        <UnitName Value="HlpMurmurHash3_x86_128"/>
+      </Item85>
+      <Item86>
+        <Filename Value="..\..\KDF\HlpPBKDF2_HMACNotBuildInAdapter.pas"/>
+        <UnitName Value="HlpPBKDF2_HMACNotBuildInAdapter"/>
+      </Item86>
+      <Item87>
+        <Filename Value="..\..\Interfaces\HlpIKDF.pas"/>
+        <UnitName Value="HlpIKDF"/>
+      </Item87>
+      <Item88>
+        <Filename Value="..\..\Base\HlpKDF.pas"/>
+        <UnitName Value="HlpKDF"/>
+      </Item88>
+      <Item89>
+        <Filename Value="..\..\Interfaces\HlpICRC.pas"/>
+        <UnitName Value="HlpICRC"/>
+      </Item89>
+      <Item90>
+        <Filename Value="..\..\Crypto\HlpBlake2B.pas"/>
+        <UnitName Value="HlpBlake2B"/>
+      </Item90>
+      <Item91>
+        <Filename Value="..\..\Crypto\HlpBlake2S.pas"/>
+        <UnitName Value="HlpBlake2S"/>
+      </Item91>
+      <Item92>
+        <Filename Value="..\..\Crypto\Blake2BConfigurations\HlpBlake2BConfig.pas"/>
+        <UnitName Value="HlpBlake2BConfig"/>
+      </Item92>
+      <Item93>
+        <Filename Value="..\..\Crypto\Blake2BConfigurations\HlpBlake2BIvBuilder.pas"/>
+        <UnitName Value="HlpBlake2BIvBuilder"/>
+      </Item93>
+      <Item94>
+        <Filename Value="..\..\Crypto\Blake2BConfigurations\HlpBlake2BTreeConfig.pas"/>
+        <UnitName Value="HlpBlake2BTreeConfig"/>
+      </Item94>
+      <Item95>
+        <Filename Value="..\..\Crypto\Blake2SConfigurations\HlpBlake2SConfig.pas"/>
+        <UnitName Value="HlpBlake2SConfig"/>
+      </Item95>
+      <Item96>
+        <Filename Value="..\..\Crypto\Blake2SConfigurations\HlpBlake2SIvBuilder.pas"/>
+        <UnitName Value="HlpBlake2SIvBuilder"/>
+      </Item96>
+      <Item97>
+        <Filename Value="..\..\Crypto\Blake2SConfigurations\HlpBlake2STreeConfig.pas"/>
+        <UnitName Value="HlpBlake2STreeConfig"/>
+      </Item97>
+      <Item98>
+        <Filename Value="..\..\Interfaces\IBlake2BConfigurations\HlpIBlake2BConfig.pas"/>
+        <UnitName Value="HlpIBlake2BConfig"/>
+      </Item98>
+      <Item99>
+        <Filename Value="..\..\Interfaces\IBlake2BConfigurations\HlpIBlake2BTreeConfig.pas"/>
+        <UnitName Value="HlpIBlake2BTreeConfig"/>
+      </Item99>
+      <Item100>
+        <Filename Value="..\..\Interfaces\IBlake2SConfigurations\HlpIBlake2SConfig.pas"/>
+        <UnitName Value="HlpIBlake2SConfig"/>
+      </Item100>
+      <Item101>
+        <Filename Value="..\..\Interfaces\IBlake2SConfigurations\HlpIBlake2STreeConfig.pas"/>
+        <UnitName Value="HlpIBlake2STreeConfig"/>
+      </Item101>
+      <Item102>
+        <Filename Value="..\..\Crypto\HlpGOST3411_2012.pas"/>
+        <UnitName Value="HlpGOST3411_2012"/>
+      </Item102>
+    </Files>
+    <LazDoc PackageName="(default)"/>
+    <RequiredPkgs Count="1">
+      <Item1>
+        <PackageName Value="FCL"/>
+      </Item1>
+    </RequiredPkgs>
+    <UsageOptions>
+      <UnitPath Value="$(PkgOutDir)"/>
+    </UsageOptions>
+    <PublishOptions>
+      <Version Value="2"/>
+    </PublishOptions>
+  </Package>
+</CONFIG>

Some files were not shown because too many files changed in this diff