Browse Source

Merge downstream

Herman Schoenfeld 7 years ago
parent
commit
89c6ae15c3
76 changed files with 1812 additions and 154 deletions
  1. 1 1
      src/libraries/hashlib4pascal/HashLib.inc
  2. 1 1
      src/libraries/hashlib4pascal/HashLibHelper.inc
  3. 13 0
      src/libraries/hashlib4pascal/HlpAP.pas
  4. 13 0
      src/libraries/hashlib4pascal/HlpAdler32.pas
  5. 12 0
      src/libraries/hashlib4pascal/HlpBKDR.pas
  6. 12 0
      src/libraries/hashlib4pascal/HlpBernstein.pas
  7. 12 0
      src/libraries/hashlib4pascal/HlpBernstein1.pas
  8. 4 0
      src/libraries/hashlib4pascal/HlpBits.pas
  9. 48 8
      src/libraries/hashlib4pascal/HlpBlake2B.pas
  10. 84 6
      src/libraries/hashlib4pascal/HlpBlake2BConfig.pas
  11. 1 1
      src/libraries/hashlib4pascal/HlpBlake2BTreeConfig.pas
  12. 48 8
      src/libraries/hashlib4pascal/HlpBlake2S.pas
  13. 84 6
      src/libraries/hashlib4pascal/HlpBlake2SConfig.pas
  14. 1 1
      src/libraries/hashlib4pascal/HlpBlake2STreeConfig.pas
  15. 31 5
      src/libraries/hashlib4pascal/HlpCRC.pas
  16. 19 2
      src/libraries/hashlib4pascal/HlpDEK.pas
  17. 12 0
      src/libraries/hashlib4pascal/HlpDJB.pas
  18. 12 0
      src/libraries/hashlib4pascal/HlpELF.pas
  19. 12 0
      src/libraries/hashlib4pascal/HlpFNV.pas
  20. 12 0
      src/libraries/hashlib4pascal/HlpFNV1a.pas
  21. 12 0
      src/libraries/hashlib4pascal/HlpFNV1a64.pas
  22. 12 0
      src/libraries/hashlib4pascal/HlpFNV64.pas
  23. 47 7
      src/libraries/hashlib4pascal/HlpGOST3411_2012.pas
  24. 18 2
      src/libraries/hashlib4pascal/HlpGost.pas
  25. 17 0
      src/libraries/hashlib4pascal/HlpGrindahl256.pas
  26. 17 0
      src/libraries/hashlib4pascal/HlpGrindahl512.pas
  27. 16 1
      src/libraries/hashlib4pascal/HlpHAS160.pas
  28. 17 4
      src/libraries/hashlib4pascal/HlpHMACNotBuildInAdapter.pas
  29. 8 3
      src/libraries/hashlib4pascal/HlpHash.pas
  30. 10 2
      src/libraries/hashlib4pascal/HlpHashBuffer.pas
  31. 230 3
      src/libraries/hashlib4pascal/HlpHaval.pas
  32. 12 0
      src/libraries/hashlib4pascal/HlpJS.pas
  33. 18 2
      src/libraries/hashlib4pascal/HlpJenkins3.pas
  34. 17 1
      src/libraries/hashlib4pascal/HlpMD2.pas
  35. 17 1
      src/libraries/hashlib4pascal/HlpMD4.pas
  36. 17 1
      src/libraries/hashlib4pascal/HlpMD5.pas
  37. 3 2
      src/libraries/hashlib4pascal/HlpMultipleTransformNonBlock.pas
  38. 19 3
      src/libraries/hashlib4pascal/HlpMurmur2.pas
  39. 18 3
      src/libraries/hashlib4pascal/HlpMurmur2_64.pas
  40. 17 0
      src/libraries/hashlib4pascal/HlpMurmurHash3_x64_128.pas
  41. 19 0
      src/libraries/hashlib4pascal/HlpMurmurHash3_x86_128.pas
  42. 1 1
      src/libraries/hashlib4pascal/HlpMurmurHash3_x86_32.pas
  43. 13 0
      src/libraries/hashlib4pascal/HlpNullDigest.pas
  44. 12 0
      src/libraries/hashlib4pascal/HlpOneAtTime.pas
  45. 12 0
      src/libraries/hashlib4pascal/HlpPJW.pas
  46. 38 1
      src/libraries/hashlib4pascal/HlpPanama.pas
  47. 17 1
      src/libraries/hashlib4pascal/HlpRIPEMD.pas
  48. 17 1
      src/libraries/hashlib4pascal/HlpRIPEMD128.pas
  49. 17 1
      src/libraries/hashlib4pascal/HlpRIPEMD160.pas
  50. 17 1
      src/libraries/hashlib4pascal/HlpRIPEMD256.pas
  51. 17 1
      src/libraries/hashlib4pascal/HlpRIPEMD320.pas
  52. 13 0
      src/libraries/hashlib4pascal/HlpRS.pas
  53. 24 2
      src/libraries/hashlib4pascal/HlpRadioGatun32.pas
  54. 23 1
      src/libraries/hashlib4pascal/HlpRadioGatun64.pas
  55. 12 0
      src/libraries/hashlib4pascal/HlpRotating.pas
  56. 12 0
      src/libraries/hashlib4pascal/HlpSDBM.pas
  57. 16 1
      src/libraries/hashlib4pascal/HlpSHA0.pas
  58. 19 2
      src/libraries/hashlib4pascal/HlpSHA1.pas
  59. 16 0
      src/libraries/hashlib4pascal/HlpSHA2_224.pas
  60. 16 0
      src/libraries/hashlib4pascal/HlpSHA2_256.pas
  61. 1 1
      src/libraries/hashlib4pascal/HlpSHA2_256Base.pas
  62. 16 0
      src/libraries/hashlib4pascal/HlpSHA2_384.pas
  63. 16 0
      src/libraries/hashlib4pascal/HlpSHA2_512.pas
  64. 1 1
      src/libraries/hashlib4pascal/HlpSHA2_512Base.pas
  65. 16 0
      src/libraries/hashlib4pascal/HlpSHA2_512_224.pas
  66. 16 0
      src/libraries/hashlib4pascal/HlpSHA2_512_256.pas
  67. 56 5
      src/libraries/hashlib4pascal/HlpSHA3.pas
  68. 12 0
      src/libraries/hashlib4pascal/HlpShiftAndXor.pas
  69. 28 8
      src/libraries/hashlib4pascal/HlpSipHash.pas
  70. 49 7
      src/libraries/hashlib4pascal/HlpSnefru.pas
  71. 18 2
      src/libraries/hashlib4pascal/HlpSuperFast.pas
  72. 93 10
      src/libraries/hashlib4pascal/HlpTiger.pas
  73. 94 11
      src/libraries/hashlib4pascal/HlpTiger2.pas
  74. 31 16
      src/libraries/hashlib4pascal/HlpWhirlPool.pas
  75. 30 3
      src/libraries/hashlib4pascal/HlpXXHash32.pas
  76. 30 3
      src/libraries/hashlib4pascal/HlpXXHash64.pas

+ 1 - 1
src/libraries/hashlib4pascal/HashLib.inc

@@ -1,6 +1,6 @@
 { *********************************************************** }
 { *********************************************************** }
 { *                     HashLib Library                     * }
 { *                     HashLib Library                     * }
-{ *      Copyright (c) Ugochukwu Mmaduekwe 2016 - 2017      * }
+{ *      Copyright (c) Ugochukwu Mmaduekwe 2016 - 2018      * }
 { *********************************************************** }
 { *********************************************************** }
 
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)

+ 1 - 1
src/libraries/hashlib4pascal/HashLibHelper.inc

@@ -1,6 +1,6 @@
 { *********************************************************** }
 { *********************************************************** }
 { *                     HashLib Library                     * }
 { *                     HashLib Library                     * }
-{ *      Copyright (c) Ugochukwu Mmaduekwe 2016 - 2017      * }
+{ *      Copyright (c) Ugochukwu Mmaduekwe 2016 - 2018      * }
 { *********************************************************** }
 { *********************************************************** }
 
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)

+ 13 - 0
src/libraries/hashlib4pascal/HlpAP.pas

@@ -7,6 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -24,6 +25,7 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -31,6 +33,17 @@ implementation
 
 
 { TAP }
 { TAP }
 
 
+function TAP.Clone(): IHash;
+var
+  HashInstance: TAP;
+begin
+  HashInstance := TAP.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  HashInstance.Fm_index := Fm_index;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TAP.Create;
 constructor TAP.Create;
 begin
 begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);

+ 13 - 0
src/libraries/hashlib4pascal/HlpAdler32.pas

@@ -8,6 +8,7 @@ uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
 
 
@@ -28,6 +29,7 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal: IHashResult; override;
     function TransformFinal: IHashResult; override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -35,6 +37,17 @@ implementation
 
 
 { TAdler32 }
 { TAdler32 }
 
 
+function TAdler32.Clone(): IHash;
+var
+  HashInstance: TAdler32;
+begin
+  HashInstance := TAdler32.Create();
+  HashInstance.Fm_a := Fm_a;
+  HashInstance.Fm_b := Fm_b;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TAdler32.Create;
 constructor TAdler32.Create;
 begin
 begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);

+ 12 - 0
src/libraries/hashlib4pascal/HlpBKDR.pas

@@ -7,6 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -27,12 +28,23 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TBKDR }
 { TBKDR }
 
 
+function TBKDR.Clone(): IHash;
+var
+  HashInstance: TBKDR;
+begin
+  HashInstance := TBKDR.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TBKDR.Create;
 constructor TBKDR.Create;
 begin
 begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);

+ 12 - 0
src/libraries/hashlib4pascal/HlpBernstein.pas

@@ -7,6 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -23,12 +24,23 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TBernstein }
 { TBernstein }
 
 
+function TBernstein.Clone(): IHash;
+var
+  HashInstance: TBernstein;
+begin
+  HashInstance := TBernstein.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TBernstein.Create;
 constructor TBernstein.Create;
 begin
 begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);

+ 12 - 0
src/libraries/hashlib4pascal/HlpBernstein1.pas

@@ -7,6 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -23,12 +24,23 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TBernstein1 }
 { TBernstein1 }
 
 
+function TBernstein1.Clone(): IHash;
+var
+  HashInstance: TBernstein1;
+begin
+  HashInstance := TBernstein1.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TBernstein1.Create;
 constructor TBernstein1.Create;
 begin
 begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);

+ 4 - 0
src/libraries/hashlib4pascal/HlpBits.pas

@@ -150,9 +150,11 @@ begin
 {$ELSE}
 {$ELSE}
   Result := Value shr ShiftBits;
   Result := Value shr ShiftBits;
   if (Value and $80000000) > 0 then
   if (Value and $80000000) > 0 then
+  begin
     // if you don't want to cast ($FFFFFFFF) to an Int32,
     // if you don't want to cast ($FFFFFFFF) to an Int32,
     // simply replace it with (-1) to avoid range check error.
     // simply replace it with (-1) to avoid range check error.
     Result := Result or (Int32($FFFFFFFF) shl (32 - ShiftBits));
     Result := Result or (Int32($FFFFFFFF) shl (32 - ShiftBits));
+  end;
 
 
   /// ++++++ Alternative Variant ++++++ ///
   /// ++++++ Alternative Variant ++++++ ///
 
 
@@ -168,7 +170,9 @@ begin
 {$ELSE}
 {$ELSE}
   Result := Value shr ShiftBits;
   Result := Value shr ShiftBits;
   if (Value and $8000000000000000) > 0 then
   if (Value and $8000000000000000) > 0 then
+  begin
     Result := Result or ($FFFFFFFFFFFFFFFF shl (64 - ShiftBits));
     Result := Result or ($FFFFFFFFFFFFFFFF shl (64 - ShiftBits));
+  end;
 
 
   /// ++++++ Alternative Variant ++++++ ///
   /// ++++++ Alternative Variant ++++++ ///
 
 

+ 48 - 8
src/libraries/hashlib4pascal/HlpBlake2B.pas

@@ -20,7 +20,9 @@ uses
   HlpIHashResult,
   HlpIHashResult,
   HlpIBlake2BConfig,
   HlpIBlake2BConfig,
   HlpBlake2BConfig,
   HlpBlake2BConfig,
+  HlpIBlake2BTreeConfig,
   HlpBlake2BIvBuilder,
   HlpBlake2BIvBuilder,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpConverters,
   HlpConverters,
   HlpHashLibTypes;
   HlpHashLibTypes;
@@ -67,14 +69,13 @@ type
       FDefaultConfig: IBlake2BConfig;
       FDefaultConfig: IBlake2BConfig;
 
 
   var
   var
+    F_m: array [0 .. 15] of UInt64;
     FrawConfig, Fm_state: THashLibUInt64Array;
     FrawConfig, Fm_state: THashLibUInt64Array;
     FKey, F_buf: THashLibByteArray;
     FKey, F_buf: THashLibByteArray;
-    F_m: array [0 .. 15] of UInt64;
 {$IFNDEF USE_UNROLLED_VARIANT}
 {$IFNDEF USE_UNROLLED_VARIANT}
     F_v: array [0 .. 15] of UInt64;
     F_v: array [0 .. 15] of UInt64;
 {$ENDIF USE_UNROLLED_VARIANT}
 {$ENDIF USE_UNROLLED_VARIANT}
-    F_bufferFilled: Int32;
-
+    F_bufferFilled, FHashSize, FBlockSize: Int32;
     F_counter0, F_counter1, F_finalizationFlag0, F_finalizationFlag1: UInt64;
     F_counter0, F_counter1, F_finalizationFlag0, F_finalizationFlag1: UInt64;
 
 
     class constructor Blake2BConfig();
     class constructor Blake2BConfig();
@@ -88,16 +89,18 @@ type
 
 
   strict protected
   strict protected
 
 
-    FHashSize, FBlockSize: Int32;
     function GetName: String; override;
     function GetName: String; override;
 
 
   public
   public
     constructor Create(); overload;
     constructor Create(); overload;
     constructor Create(const config: IBlake2BConfig); overload;
     constructor Create(const config: IBlake2BConfig); overload;
+    constructor Create(const config: IBlake2BConfig;
+      const treeConfig: IBlake2BTreeConfig); overload;
     procedure Initialize; override;
     procedure Initialize; override;
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_data_length: Int32); override;
       a_index, a_data_length: Int32); override;
     function TransformFinal: IHashResult; override;
     function TransformFinal: IHashResult; override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -137,6 +140,29 @@ end;
 
 
 {$ENDIF USE_UNROLLED_VARIANT}
 {$ENDIF USE_UNROLLED_VARIANT}
 
 
+function TBlake2B.Clone(): IHash;
+var
+  HashInstance: TBlake2B;
+begin
+  HashInstance := TBlake2B.Create(TBlake2BConfig.Create(FHashSize)
+    as IBlake2BConfig);
+  System.Move(F_m, HashInstance.F_m, System.SizeOf(F_m));
+  HashInstance.FrawConfig := System.Copy(FrawConfig);
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.FKey := System.Copy(FKey);
+  HashInstance.F_buf := System.Copy(F_buf);
+{$IFNDEF USE_UNROLLED_VARIANT}
+  System.Move(F_v, HashInstance.F_v, System.SizeOf(F_v));
+{$ENDIF USE_UNROLLED_VARIANT}
+  HashInstance.F_bufferFilled := F_bufferFilled;
+  HashInstance.F_counter0 := F_counter0;
+  HashInstance.F_counter1 := F_counter1;
+  HashInstance.F_finalizationFlag0 := F_finalizationFlag0;
+  HashInstance.F_finalizationFlag1 := F_finalizationFlag1;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
+end;
+
 procedure TBlake2B.Compress(block: PByte; start: Int32);
 procedure TBlake2B.Compress(block: PByte; start: Int32);
 var
 var
 {$IFDEF USE_UNROLLED_VARIANT}
 {$IFDEF USE_UNROLLED_VARIANT}
@@ -1597,6 +1623,12 @@ begin
 end;
 end;
 
 
 constructor TBlake2B.Create(const config: IBlake2BConfig);
 constructor TBlake2B.Create(const config: IBlake2BConfig);
+begin
+  Create(config, Nil);
+end;
+
+constructor TBlake2B.Create(const config: IBlake2BConfig;
+  const treeConfig: IBlake2BTreeConfig);
 var
 var
   Lconfig: IBlake2BConfig;
   Lconfig: IBlake2BConfig;
 begin
 begin
@@ -1609,7 +1641,7 @@ begin
     Lconfig := FDefaultConfig;
     Lconfig := FDefaultConfig;
   end;
   end;
 
 
-  FrawConfig := TBlake2BIvBuilder.ConfigB(Lconfig, Nil);
+  FrawConfig := TBlake2BIvBuilder.ConfigB(Lconfig, treeConfig);
   if ((Lconfig.Key <> Nil) and (System.Length(Lconfig.Key) <> 0)) then
   if ((Lconfig.Key <> Nil) and (System.Length(Lconfig.Key) <> 0)) then
   begin
   begin
 
 
@@ -1646,7 +1678,7 @@ end;
 
 
 procedure TBlake2B.Initialize;
 procedure TBlake2B.Initialize;
 var
 var
-  i: Integer;
+  i: Int32;
 begin
 begin
   if (FrawConfig = Nil) then
   if (FrawConfig = Nil) then
     raise EArgumentNilHashLibException.Create('config');
     raise EArgumentNilHashLibException.Create('config');
@@ -1673,6 +1705,14 @@ begin
 
 
   System.SetLength(F_buf, BlockSizeInBytes);
   System.SetLength(F_buf, BlockSizeInBytes);
 
 
+  System.FillChar(F_buf[0], (System.Length(F_buf) * System.SizeOf(Byte)
+    ), Byte(0));
+
+  System.FillChar(F_m, System.SizeOf(F_m), UInt64(0));
+
+{$IFNDEF USE_UNROLLED_VARIANT}
+  System.FillChar(F_v, System.SizeOf(F_v), UInt64(0));
+{$ENDIF USE_UNROLLED_VARIANT}
   for i := 0 to 7 do
   for i := 0 to 7 do
   begin
   begin
     Fm_state[i] := Fm_state[i] xor FrawConfig[i];
     Fm_state[i] := Fm_state[i] xor FrawConfig[i];
@@ -1745,7 +1785,7 @@ begin
   TConverters.le64_copy(PUInt64(Fm_state), 0, PByte(tempRes), 0,
   TConverters.le64_copy(PUInt64(Fm_state), 0, PByte(tempRes), 0,
     System.Length(tempRes));
     System.Length(tempRes));
 
 
-  result := THashResult.Create(tempRes);
+  Result := THashResult.Create(tempRes);
 
 
   Initialize();
   Initialize();
 
 
@@ -1753,7 +1793,7 @@ end;
 
 
 function TBlake2B.GetName: String;
 function TBlake2B.GetName: String;
 begin
 begin
-  result := Format('%s_%u', [Self.ClassName, Self.HashSize * 8]);
+  Result := Format('%s_%u', [Self.ClassName, Self.HashSize * 8]);
 end;
 end;
 
 
 end.
 end.

+ 84 - 6
src/libraries/hashlib4pascal/HlpBlake2BConfig.pas

@@ -11,7 +11,11 @@ uses
 
 
 resourcestring
 resourcestring
   SInvalidHashSize =
   SInvalidHashSize =
-    'BLAKE2B HashSize must be restricted to one of the following [20, 32, 48, 64]';
+    'BLAKE2B HashSize must be restricted to one of the following [1 .. 64], "%d"';
+  SInvalidKeyLength = '"Key" Length Must Not Be Greater Than 64, "%d"';
+  SInvalidPersonalisationLength =
+    '"Personalisation" Length Must Be Equal To 16, "%d"';
+  SInvalidSaltLength = '"Salt" Length Must Be Equal To 16, "%d"';
 
 
 type
 type
 
 
@@ -24,6 +28,12 @@ type
     FHashSize: Int32;
     FHashSize: Int32;
     FPersonalisation, FSalt, FKey: THashLibByteArray;
     FPersonalisation, FSalt, FKey: THashLibByteArray;
 
 
+    procedure ValidateHashSize(AHashSize: Int32); inline;
+    procedure ValidateKeyLength(const AKey: THashLibByteArray); inline;
+    procedure ValidatePersonalisationLength(const APersonalisation
+      : THashLibByteArray); inline;
+    procedure ValidateSaltLength(const ASalt: THashLibByteArray); inline;
+
     function GetPersonalisation: THashLibByteArray; inline;
     function GetPersonalisation: THashLibByteArray; inline;
     procedure SetPersonalisation(const value: THashLibByteArray); inline;
     procedure SetPersonalisation(const value: THashLibByteArray); inline;
 
 
@@ -38,6 +48,8 @@ type
 
 
   public
   public
     constructor Create(AHashSize: THashSize = THashSize.hsHashSize512);
     constructor Create(AHashSize: THashSize = THashSize.hsHashSize512);
+      overload;
+    constructor Create(AHashSize: Int32); overload;
     property Personalisation: THashLibByteArray read GetPersonalisation
     property Personalisation: THashLibByteArray read GetPersonalisation
       write SetPersonalisation;
       write SetPersonalisation;
     property Salt: THashLibByteArray read GetSalt write SetSalt;
     property Salt: THashLibByteArray read GetSalt write SetSalt;
@@ -50,6 +62,61 @@ implementation
 
 
 { TBlake2BConfig }
 { TBlake2BConfig }
 
 
+procedure TBlake2BConfig.ValidateHashSize(AHashSize: Int32);
+begin
+  if not((AHashSize) in [1 .. 64]) or (((AHashSize * 8) and 7) <> 0) then
+  begin
+    raise EArgumentHashLibException.CreateResFmt(@SInvalidHashSize,
+      [AHashSize]);
+  end;
+end;
+
+procedure TBlake2BConfig.ValidateKeyLength(const AKey: THashLibByteArray);
+var
+  KeyLength: Int32;
+begin
+  if (AKey <> Nil) then
+  begin
+    KeyLength := System.Length(AKey);
+    if (KeyLength > 64) then
+    begin
+      raise EArgumentOutOfRangeHashLibException.CreateResFmt(@SInvalidKeyLength,
+        [KeyLength]);
+    end;
+  end;
+end;
+
+procedure TBlake2BConfig.ValidatePersonalisationLength(const APersonalisation
+  : THashLibByteArray);
+var
+  PersonalisationLength: Int32;
+begin
+  if (APersonalisation <> Nil) then
+  begin
+    PersonalisationLength := System.Length(APersonalisation);
+    if (PersonalisationLength <> 16) then
+    begin
+      raise EArgumentOutOfRangeHashLibException.CreateResFmt
+        (@SInvalidPersonalisationLength, [PersonalisationLength]);
+    end;
+  end;
+end;
+
+procedure TBlake2BConfig.ValidateSaltLength(const ASalt: THashLibByteArray);
+var
+  SaltLength: Int32;
+begin
+  if (ASalt <> Nil) then
+  begin
+    SaltLength := System.Length(ASalt);
+    if (SaltLength <> 16) then
+    begin
+      raise EArgumentOutOfRangeHashLibException.CreateResFmt
+        (@SInvalidSaltLength, [SaltLength]);
+    end;
+  end;
+end;
+
 function TBlake2BConfig.GetHashSize: Int32;
 function TBlake2BConfig.GetHashSize: Int32;
 begin
 begin
   result := FHashSize;
   result := FHashSize;
@@ -72,32 +139,43 @@ end;
 
 
 procedure TBlake2BConfig.SetHashSize(value: Int32);
 procedure TBlake2BConfig.SetHashSize(value: Int32);
 begin
 begin
+  ValidateHashSize(value);
   FHashSize := value;
   FHashSize := value;
 end;
 end;
 
 
 procedure TBlake2BConfig.SetKey(const value: THashLibByteArray);
 procedure TBlake2BConfig.SetKey(const value: THashLibByteArray);
 begin
 begin
+  ValidateKeyLength(value);
   FKey := value;
   FKey := value;
 end;
 end;
 
 
 procedure TBlake2BConfig.SetPersonalisation(const value: THashLibByteArray);
 procedure TBlake2BConfig.SetPersonalisation(const value: THashLibByteArray);
 begin
 begin
+  ValidatePersonalisationLength(value);
   FPersonalisation := value;
   FPersonalisation := value;
 end;
 end;
 
 
 procedure TBlake2BConfig.SetSalt(const value: THashLibByteArray);
 procedure TBlake2BConfig.SetSalt(const value: THashLibByteArray);
 begin
 begin
+  ValidateSaltLength(value);
   FSalt := value;
   FSalt := value;
 end;
 end;
 
 
 constructor TBlake2BConfig.Create(AHashSize: THashSize);
 constructor TBlake2BConfig.Create(AHashSize: THashSize);
+var
+  LHashSize: Int32;
 begin
 begin
   Inherited Create();
   Inherited Create();
-  if not(Int32(AHashSize) in [20, 32, 48, 64]) then
-  begin
-    raise EArgumentHashLibException.CreateRes(@SInvalidHashSize);
-  end;
-  HashSize := Int32(AHashSize);
+  LHashSize := Int32(AHashSize);
+  ValidateHashSize(LHashSize);
+  FHashSize := LHashSize;
+end;
+
+constructor TBlake2BConfig.Create(AHashSize: Int32);
+begin
+  Inherited Create();
+  ValidateHashSize(AHashSize);
+  FHashSize := AHashSize;
 end;
 end;
 
 
 end.
 end.

+ 1 - 1
src/libraries/hashlib4pascal/HlpBlake2BTreeConfig.pas

@@ -95,7 +95,7 @@ end;
 constructor TBlake2BTreeConfig.Create;
 constructor TBlake2BTreeConfig.Create;
 begin
 begin
   Inherited Create();
   Inherited Create();
-  IntermediateHashSize := 64;
+  FIntermediateHashSize := 64;
 end;
 end;
 
 
 end.
 end.

+ 48 - 8
src/libraries/hashlib4pascal/HlpBlake2S.pas

@@ -20,7 +20,9 @@ uses
   HlpIHashResult,
   HlpIHashResult,
   HlpIBlake2SConfig,
   HlpIBlake2SConfig,
   HlpBlake2SConfig,
   HlpBlake2SConfig,
+  HlpIBlake2STreeConfig,
   HlpBlake2SIvBuilder,
   HlpBlake2SIvBuilder,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpConverters,
   HlpConverters,
   HlpHashLibTypes;
   HlpHashLibTypes;
@@ -67,14 +69,13 @@ type
       FDefaultConfig: IBlake2SConfig;
       FDefaultConfig: IBlake2SConfig;
 
 
   var
   var
+    F_m: array [0 .. 15] of UInt32;
     FrawConfig, Fm_state: THashLibUInt32Array;
     FrawConfig, Fm_state: THashLibUInt32Array;
     FKey, F_buf: THashLibByteArray;
     FKey, F_buf: THashLibByteArray;
-    F_m: array [0 .. 15] of UInt32;
 {$IFNDEF USE_UNROLLED_VARIANT}
 {$IFNDEF USE_UNROLLED_VARIANT}
     F_v: array [0 .. 15] of UInt32;
     F_v: array [0 .. 15] of UInt32;
 {$ENDIF USE_UNROLLED_VARIANT}
 {$ENDIF USE_UNROLLED_VARIANT}
-    F_bufferFilled: Int32;
-
+    F_bufferFilled, FHashSize, FBlockSize: Int32;
     F_counter0, F_counter1, F_finalizationFlag0, F_finalizationFlag1: UInt32;
     F_counter0, F_counter1, F_finalizationFlag0, F_finalizationFlag1: UInt32;
 
 
     class constructor Blake2SConfig();
     class constructor Blake2SConfig();
@@ -88,16 +89,18 @@ type
 
 
   strict protected
   strict protected
 
 
-    FHashSize, FBlockSize: Int32;
     function GetName: String; override;
     function GetName: String; override;
 
 
   public
   public
     constructor Create(); overload;
     constructor Create(); overload;
     constructor Create(const config: IBlake2SConfig); overload;
     constructor Create(const config: IBlake2SConfig); overload;
+    constructor Create(const config: IBlake2SConfig;
+      const treeConfig: IBlake2STreeConfig); overload;
     procedure Initialize; override;
     procedure Initialize; override;
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_data_length: Int32); override;
       a_index, a_data_length: Int32); override;
     function TransformFinal: IHashResult; override;
     function TransformFinal: IHashResult; override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -132,6 +135,29 @@ end;
 
 
 {$ENDIF USE_UNROLLED_VARIANT}
 {$ENDIF USE_UNROLLED_VARIANT}
 
 
+function TBlake2S.Clone(): IHash;
+var
+  HashInstance: TBlake2S;
+begin
+  HashInstance := TBlake2S.Create(TBlake2SConfig.Create(FHashSize)
+    as IBlake2SConfig);
+  System.Move(F_m, HashInstance.F_m, System.SizeOf(F_m));
+  HashInstance.FrawConfig := System.Copy(FrawConfig);
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.FKey := System.Copy(FKey);
+  HashInstance.F_buf := System.Copy(F_buf);
+{$IFNDEF USE_UNROLLED_VARIANT}
+  System.Move(F_v, HashInstance.F_v, System.SizeOf(F_v));
+{$ENDIF USE_UNROLLED_VARIANT}
+  HashInstance.F_bufferFilled := F_bufferFilled;
+  HashInstance.F_counter0 := F_counter0;
+  HashInstance.F_counter1 := F_counter1;
+  HashInstance.F_finalizationFlag0 := F_finalizationFlag0;
+  HashInstance.F_finalizationFlag1 := F_finalizationFlag1;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
+end;
+
 procedure TBlake2S.Compress(block: PByte; start: Int32);
 procedure TBlake2S.Compress(block: PByte; start: Int32);
 var
 var
 {$IFDEF USE_UNROLLED_VARIANT}
 {$IFDEF USE_UNROLLED_VARIANT}
@@ -1378,6 +1404,12 @@ begin
 end;
 end;
 
 
 constructor TBlake2S.Create(const config: IBlake2SConfig);
 constructor TBlake2S.Create(const config: IBlake2SConfig);
+begin
+  Create(config, Nil);
+end;
+
+constructor TBlake2S.Create(const config: IBlake2SConfig;
+  const treeConfig: IBlake2STreeConfig);
 var
 var
   Lconfig: IBlake2SConfig;
   Lconfig: IBlake2SConfig;
 begin
 begin
@@ -1390,7 +1422,7 @@ begin
     Lconfig := FDefaultConfig;
     Lconfig := FDefaultConfig;
   end;
   end;
 
 
-  FrawConfig := TBlake2SIvBuilder.ConfigS(Lconfig, Nil);
+  FrawConfig := TBlake2SIvBuilder.ConfigS(Lconfig, treeConfig);
   if ((Lconfig.Key <> Nil) and (System.Length(Lconfig.Key) <> 0)) then
   if ((Lconfig.Key <> Nil) and (System.Length(Lconfig.Key) <> 0)) then
   begin
   begin
 
 
@@ -1427,7 +1459,7 @@ end;
 
 
 procedure TBlake2S.Initialize;
 procedure TBlake2S.Initialize;
 var
 var
-  i: Integer;
+  i: Int32;
 begin
 begin
   if (FrawConfig = Nil) then
   if (FrawConfig = Nil) then
     raise EArgumentNilHashLibException.Create('config');
     raise EArgumentNilHashLibException.Create('config');
@@ -1454,6 +1486,14 @@ begin
 
 
   System.SetLength(F_buf, BlockSizeInBytes);
   System.SetLength(F_buf, BlockSizeInBytes);
 
 
+  System.FillChar(F_buf[0], (System.Length(F_buf) * System.SizeOf(Byte)
+    ), Byte(0));
+
+  System.FillChar(F_m, System.SizeOf(F_m), UInt32(0));
+
+{$IFNDEF USE_UNROLLED_VARIANT}
+  System.FillChar(F_v, System.SizeOf(F_v), UInt32(0));
+{$ENDIF USE_UNROLLED_VARIANT}
   for i := 0 to 7 do
   for i := 0 to 7 do
   begin
   begin
     Fm_state[i] := Fm_state[i] xor FrawConfig[i];
     Fm_state[i] := Fm_state[i] xor FrawConfig[i];
@@ -1526,7 +1566,7 @@ begin
   TConverters.le32_copy(PCardinal(Fm_state), 0, PByte(tempRes), 0,
   TConverters.le32_copy(PCardinal(Fm_state), 0, PByte(tempRes), 0,
     System.Length(tempRes));
     System.Length(tempRes));
 
 
-  result := THashResult.Create(tempRes);
+  Result := THashResult.Create(tempRes);
 
 
   Initialize();
   Initialize();
 
 
@@ -1534,7 +1574,7 @@ end;
 
 
 function TBlake2S.GetName: String;
 function TBlake2S.GetName: String;
 begin
 begin
-  result := Format('%s_%u', [Self.ClassName, Self.HashSize * 8]);
+  Result := Format('%s_%u', [Self.ClassName, Self.HashSize * 8]);
 end;
 end;
 
 
 end.
 end.

+ 84 - 6
src/libraries/hashlib4pascal/HlpBlake2SConfig.pas

@@ -11,7 +11,11 @@ uses
 
 
 resourcestring
 resourcestring
   SInvalidHashSize =
   SInvalidHashSize =
-    'BLAKE2S HashSize must be restricted to one of the following [16, 20, 28, 32]';
+    'BLAKE2S HashSize must be restricted to one of the following [1 .. 32], "%d"';
+  SInvalidKeyLength = '"Key" Length Must Not Be Greater Than 32, "%d"';
+  SInvalidPersonalisationLength =
+    '"Personalisation" Length Must Be Equal To 8, "%d"';
+  SInvalidSaltLength = '"Salt" Length Must Be Equal To 8, "%d"';
 
 
 type
 type
 
 
@@ -24,6 +28,12 @@ type
     FHashSize: Int32;
     FHashSize: Int32;
     FPersonalisation, FSalt, FKey: THashLibByteArray;
     FPersonalisation, FSalt, FKey: THashLibByteArray;
 
 
+    procedure ValidateHashSize(AHashSize: Int32); inline;
+    procedure ValidateKeyLength(const AKey: THashLibByteArray); inline;
+    procedure ValidatePersonalisationLength(const APersonalisation
+      : THashLibByteArray); inline;
+    procedure ValidateSaltLength(const ASalt: THashLibByteArray); inline;
+
     function GetPersonalisation: THashLibByteArray; inline;
     function GetPersonalisation: THashLibByteArray; inline;
     procedure SetPersonalisation(const value: THashLibByteArray); inline;
     procedure SetPersonalisation(const value: THashLibByteArray); inline;
 
 
@@ -38,6 +48,8 @@ type
 
 
   public
   public
     constructor Create(AHashSize: THashSize = THashSize.hsHashSize256);
     constructor Create(AHashSize: THashSize = THashSize.hsHashSize256);
+      overload;
+    constructor Create(AHashSize: Int32); overload;
     property Personalisation: THashLibByteArray read GetPersonalisation
     property Personalisation: THashLibByteArray read GetPersonalisation
       write SetPersonalisation;
       write SetPersonalisation;
     property Salt: THashLibByteArray read GetSalt write SetSalt;
     property Salt: THashLibByteArray read GetSalt write SetSalt;
@@ -50,6 +62,61 @@ implementation
 
 
 { TBlake2SConfig }
 { TBlake2SConfig }
 
 
+procedure TBlake2SConfig.ValidateHashSize(AHashSize: Int32);
+begin
+  if not((AHashSize) in [1 .. 32]) or (((AHashSize * 8) and 7) <> 0) then
+  begin
+    raise EArgumentHashLibException.CreateResFmt(@SInvalidHashSize,
+      [AHashSize]);
+  end;
+end;
+
+procedure TBlake2SConfig.ValidateKeyLength(const AKey: THashLibByteArray);
+var
+  KeyLength: Int32;
+begin
+  if (AKey <> Nil) then
+  begin
+    KeyLength := System.Length(AKey);
+    if (KeyLength > 32) then
+    begin
+      raise EArgumentOutOfRangeHashLibException.CreateResFmt(@SInvalidKeyLength,
+        [KeyLength]);
+    end;
+  end;
+end;
+
+procedure TBlake2SConfig.ValidatePersonalisationLength(const APersonalisation
+  : THashLibByteArray);
+var
+  PersonalisationLength: Int32;
+begin
+  if (APersonalisation <> Nil) then
+  begin
+    PersonalisationLength := System.Length(APersonalisation);
+    if (PersonalisationLength <> 8) then
+    begin
+      raise EArgumentOutOfRangeHashLibException.CreateResFmt
+        (@SInvalidPersonalisationLength, [PersonalisationLength]);
+    end;
+  end;
+end;
+
+procedure TBlake2SConfig.ValidateSaltLength(const ASalt: THashLibByteArray);
+var
+  SaltLength: Int32;
+begin
+  if (ASalt <> Nil) then
+  begin
+    SaltLength := System.Length(ASalt);
+    if (SaltLength <> 8) then
+    begin
+      raise EArgumentOutOfRangeHashLibException.CreateResFmt
+        (@SInvalidSaltLength, [SaltLength]);
+    end;
+  end;
+end;
+
 function TBlake2SConfig.GetHashSize: Int32;
 function TBlake2SConfig.GetHashSize: Int32;
 begin
 begin
   result := FHashSize;
   result := FHashSize;
@@ -72,32 +139,43 @@ end;
 
 
 procedure TBlake2SConfig.SetHashSize(value: Int32);
 procedure TBlake2SConfig.SetHashSize(value: Int32);
 begin
 begin
+  ValidateHashSize(value);
   FHashSize := value;
   FHashSize := value;
 end;
 end;
 
 
 procedure TBlake2SConfig.SetKey(const value: THashLibByteArray);
 procedure TBlake2SConfig.SetKey(const value: THashLibByteArray);
 begin
 begin
+  ValidateKeyLength(value);
   FKey := value;
   FKey := value;
 end;
 end;
 
 
 procedure TBlake2SConfig.SetPersonalisation(const value: THashLibByteArray);
 procedure TBlake2SConfig.SetPersonalisation(const value: THashLibByteArray);
 begin
 begin
+  ValidatePersonalisationLength(value);
   FPersonalisation := value;
   FPersonalisation := value;
 end;
 end;
 
 
 procedure TBlake2SConfig.SetSalt(const value: THashLibByteArray);
 procedure TBlake2SConfig.SetSalt(const value: THashLibByteArray);
 begin
 begin
+  ValidateSaltLength(value);
   FSalt := value;
   FSalt := value;
 end;
 end;
 
 
 constructor TBlake2SConfig.Create(AHashSize: THashSize);
 constructor TBlake2SConfig.Create(AHashSize: THashSize);
+var
+  LHashSize: Int32;
 begin
 begin
   Inherited Create();
   Inherited Create();
-  if not(Int32(AHashSize) in [16, 20, 28, 32]) then
-  begin
-    raise EArgumentHashLibException.CreateRes(@SInvalidHashSize);
-  end;
-  HashSize := Int32(AHashSize);
+  LHashSize := Int32(AHashSize);
+  ValidateHashSize(LHashSize);
+  FHashSize := LHashSize;
+end;
+
+constructor TBlake2SConfig.Create(AHashSize: Int32);
+begin
+  Inherited Create();
+  ValidateHashSize(AHashSize);
+  FHashSize := AHashSize;
 end;
 end;
 
 
 end.
 end.

+ 1 - 1
src/libraries/hashlib4pascal/HlpBlake2STreeConfig.pas

@@ -95,7 +95,7 @@ end;
 constructor TBlake2STreeConfig.Create;
 constructor TBlake2STreeConfig.Create;
 begin
 begin
   Inherited Create();
   Inherited Create();
-  IntermediateHashSize := 32;
+  FIntermediateHashSize := 32;
 end;
 end;
 
 
 end.
 end.

+ 31 - 5
src/libraries/hashlib4pascal/HlpCRC.pas

@@ -9,12 +9,15 @@ interface
 
 
 uses
 uses
 {$IFDEF HAS_UNITSCOPE}
 {$IFDEF HAS_UNITSCOPE}
+  System.SysUtils,
   System.TypInfo,
   System.TypInfo,
 {$ELSE}
 {$ELSE}
+  SysUtils,
   TypInfo,
   TypInfo,
 {$ENDIF HAS_UNITSCOPE}
 {$ENDIF HAS_UNITSCOPE}
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult,
   HlpIHashResult,
@@ -550,7 +553,6 @@ type
     FReflectIn, FReflectOut, FIsTableGenerated: Boolean;
     FReflectIn, FReflectOut, FIsTableGenerated: Boolean;
 
 
     Fm_CRCTable: THashLibUInt64Array;
     Fm_CRCTable: THashLibUInt64Array;
-    Fptr_Fm_CRCTable: PUInt64;
 
 
   const
   const
     Delta = Int32(7);
     Delta = Int32(7);
@@ -591,6 +593,9 @@ type
     property XOROut: UInt64 read GetXOROut write SetXOROut;
     property XOROut: UInt64 read GetXOROut write SetXOROut;
     property CheckValue: UInt64 read GetCheckValue write SetCheckValue;
     property CheckValue: UInt64 read GetCheckValue write SetCheckValue;
 
 
+  strict protected
+    function GetName: String; override;
+
   public
   public
 
 
     constructor Create(_Width: Int32; _poly, _Init: UInt64;
     constructor Create(_Width: Int32; _poly, _Init: UInt64;
@@ -602,6 +607,8 @@ type
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
 
 
+    function Clone(): IHash; override;
+
     class function CreateCRCObject(a_value: TCRCStandard): ICRC; static;
     class function CreateCRCObject(a_value: TCRCStandard): ICRC; static;
 
 
   end;
   end;
@@ -690,6 +697,11 @@ begin
   FXorOut := value;
   FXorOut := value;
 end;
 end;
 
 
+function TCRC.GetName: String;
+begin
+  result := Format('T%s', [(Self as ICRC).Names[0]]);
+end;
+
 procedure TCRC.CalculateCRCbyTable(a_data: PByte;
 procedure TCRC.CalculateCRCbyTable(a_data: PByte;
   a_data_length, a_index: Int32);
   a_data_length, a_index: Int32);
 var
 var
@@ -705,7 +717,7 @@ begin
   begin
   begin
     while Length > 0 do
     while Length > 0 do
     begin
     begin
-      tmp := (tmp shr 8) xor Fptr_Fm_CRCTable[Byte(tmp xor a_data[i])];
+      tmp := (tmp shr 8) xor Fm_CRCTable[Byte(tmp xor a_data[i])];
       System.Inc(i);
       System.Inc(i);
       System.Dec(Length);
       System.Dec(Length);
     end;
     end;
@@ -716,7 +728,7 @@ begin
 
 
     while Length > 0 do
     while Length > 0 do
     begin
     begin
-      tmp := (tmp shl 8) xor Fptr_Fm_CRCTable
+      tmp := (tmp shl 8) xor Fm_CRCTable
         [Byte((tmp shr (Width - 8)) xor a_data[i])];
         [Byte((tmp shr (Width - 8)) xor a_data[i])];
       System.Inc(i);
       System.Inc(i);
       System.Dec(Length);
       System.Dec(Length);
@@ -761,6 +773,21 @@ begin
 
 
 end;
 end;
 
 
+function TCRC.Clone(): IHash;
+var
+  HashInstance: TCRC;
+begin
+  HashInstance := TCRC.Create(Width, Polynomial, Init, ReflectIn, ReflectOut,
+    XOROut, CheckValue, System.Copy(Names));
+  HashInstance.Fm_CRCMask := Fm_CRCMask;
+  HashInstance.Fm_CRCHighBitMask := Fm_CRCHighBitMask;
+  HashInstance.Fm_hash := Fm_hash;
+  HashInstance.FIsTableGenerated := FIsTableGenerated;
+  HashInstance.Fm_CRCTable := System.Copy(Fm_CRCTable);
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TCRC.Create(_Width: Int32; _poly, _Init: UInt64;
 constructor TCRC.Create(_Width: Int32; _poly, _Init: UInt64;
   _refIn, _refOut: Boolean; _XorOut, _check: UInt64;
   _refIn, _refOut: Boolean; _XorOut, _check: UInt64;
   const _Names: THashLibStringArray);
   const _Names: THashLibStringArray);
@@ -1244,7 +1271,6 @@ var
   i, j: Int32;
   i, j: Int32;
 begin
 begin
   System.SetLength(Fm_CRCTable, 256);
   System.SetLength(Fm_CRCTable, 256);
-  Fptr_Fm_CRCTable := PUInt64(Fm_CRCTable);
   i := 0;
   i := 0;
   while i < 256 do
   while i < 256 do
   begin
   begin
@@ -1270,7 +1296,7 @@ begin
       crc := Reflect(crc, Width);
       crc := Reflect(crc, Width);
     end;
     end;
     crc := crc and Fm_CRCMask;
     crc := crc and Fm_CRCMask;
-    Fptr_Fm_CRCTable[i] := crc;
+    Fm_CRCTable[i] := crc;
     System.Inc(i);
     System.Inc(i);
   end;
   end;
 
 

+ 19 - 2
src/libraries/hashlib4pascal/HlpDEK.pas

@@ -6,7 +6,11 @@ interface
 
 
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpHash,
+{$ENDIF DELPHI}
   HlpBits,
   HlpBits,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult,
   HlpIHashResult,
@@ -17,10 +21,11 @@ type
   TDEK = class sealed(TMultipleTransformNonBlock, IHash32, ITransformBlock)
   TDEK = class sealed(TMultipleTransformNonBlock, IHash32, ITransformBlock)
 
 
   strict protected
   strict protected
-    function ComputeAggregatedBytes(a_data: THashLibByteArray)
+    function ComputeAggregatedBytes(const a_data: THashLibByteArray)
       : IHashResult; override;
       : IHashResult; override;
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -33,7 +38,19 @@ begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);
 end;
 end;
 
 
-function TDEK.ComputeAggregatedBytes(a_data: THashLibByteArray): IHashResult;
+function TDEK.Clone(): IHash;
+var
+  HashInstance: TDEK;
+begin
+  HashInstance := TDEK.Create();
+  FBuffer.Position := 0;
+  HashInstance.FBuffer.CopyFrom(FBuffer, FBuffer.Size);
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
+function TDEK.ComputeAggregatedBytes(const a_data: THashLibByteArray)
+  : IHashResult;
 var
 var
   hash: UInt32;
   hash: UInt32;
   i: Int32;
   i: Int32;

+ 12 - 0
src/libraries/hashlib4pascal/HlpDJB.pas

@@ -7,6 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -23,12 +24,23 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TDJB }
 { TDJB }
 
 
+function TDJB.Clone(): IHash;
+var
+  HashInstance: TDJB;
+begin
+  HashInstance := TDJB.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TDJB.Create;
 constructor TDJB.Create;
 begin
 begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);

+ 12 - 0
src/libraries/hashlib4pascal/HlpELF.pas

@@ -7,6 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -23,12 +24,23 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TELF }
 { TELF }
 
 
+function TELF.Clone(): IHash;
+var
+  HashInstance: TELF;
+begin
+  HashInstance := TELF.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TELF.Create;
 constructor TELF.Create;
 begin
 begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);

+ 12 - 0
src/libraries/hashlib4pascal/HlpFNV.pas

@@ -7,6 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -23,12 +24,23 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TFNV }
 { TFNV }
 
 
+function TFNV.Clone(): IHash;
+var
+  HashInstance: TFNV;
+begin
+  HashInstance := TFNV.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TFNV.Create;
 constructor TFNV.Create;
 begin
 begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);

+ 12 - 0
src/libraries/hashlib4pascal/HlpFNV1a.pas

@@ -7,6 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -23,12 +24,23 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TFNV1a }
 { TFNV1a }
 
 
+function TFNV1a.Clone(): IHash;
+var
+  HashInstance: TFNV1a;
+begin
+  HashInstance := TFNV1a.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TFNV1a.Create;
 constructor TFNV1a.Create;
 begin
 begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);

+ 12 - 0
src/libraries/hashlib4pascal/HlpFNV1a64.pas

@@ -7,6 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -23,12 +24,23 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TFNV1a64 }
 { TFNV1a64 }
 
 
+function TFNV1a64.Clone(): IHash;
+var
+  HashInstance: TFNV1a64;
+begin
+  HashInstance := TFNV1a64.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TFNV1a64.Create;
 constructor TFNV1a64.Create;
 begin
 begin
   Inherited Create(8, 1);
   Inherited Create(8, 1);

+ 12 - 0
src/libraries/hashlib4pascal/HlpFNV64.pas

@@ -7,6 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -23,12 +24,23 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TFNV64 }
 { TFNV64 }
 
 
+function TFNV64.Clone(): IHash;
+var
+  HashInstance: TFNV64;
+begin
+  HashInstance := TFNV64.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TFNV64.Create;
 constructor TFNV64.Create;
 begin
 begin
   Inherited Create(8, 1);
   Inherited Create(8, 1);

+ 47 - 7
src/libraries/hashlib4pascal/HlpGOST3411_2012.pas

@@ -6,6 +6,7 @@ interface
 
 
 uses
 uses
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult,
   HlpIHashResult,
@@ -20,11 +21,6 @@ type
     FC: THashLibMatrixByteArray;
     FC: THashLibMatrixByteArray;
     FT: THashLibMatrixUInt64Array;
     FT: THashLibMatrixUInt64Array;
 
 
-  var
-    FIV, FN, FSigma, FKi, Fm, Fh, Ftmp, Fblock: THashLibByteArray;
-
-    FbOff: Int32;
-
     procedure InternalUpdate(input: Byte); inline;
     procedure InternalUpdate(input: Byte); inline;
     procedure xor512(const A, B: THashLibByteArray); inline;
     procedure xor512(const A, B: THashLibByteArray); inline;
     procedure E(const K, a_m: THashLibByteArray);
     procedure E(const K, a_m: THashLibByteArray);
@@ -37,6 +33,12 @@ type
     class constructor GOST3411_2012();
     class constructor GOST3411_2012();
 
 
   strict protected
   strict protected
+
+  var
+    FIV, FN, FSigma, FKi, Fm, Fh, Ftmp, Fblock: THashLibByteArray;
+
+    FbOff: Int32;
+
     constructor Create(a_hash_size: Int32; const IV: THashLibByteArray);
     constructor Create(a_hash_size: Int32; const IV: THashLibByteArray);
 
 
   public
   public
@@ -59,6 +61,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     function TransformFinal: IHashResult; override;
     function TransformFinal: IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 type
 type
@@ -72,6 +75,7 @@ type
     class constructor TGOST3411_2012_512();
     class constructor TGOST3411_2012_512();
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
@@ -80,7 +84,7 @@ implementation
 
 
 procedure TGOST3411_2012.xor512(const A, B: THashLibByteArray);
 procedure TGOST3411_2012.xor512(const A, B: THashLibByteArray);
 var
 var
-  i: Integer;
+  i: Int32;
 begin
 begin
   for i := 0 to System.Pred(64) do
   for i := 0 to System.Pred(64) do
   begin
   begin
@@ -338,7 +342,7 @@ begin
   V[57] := Byte(r shr 8);
   V[57] := Byte(r shr 8);
   V[56] := Byte(r);
   V[56] := Byte(r);
 
 
-  System.FillChar(res, System.SizeOf(res), 0);
+  System.FillChar(res, System.SizeOf(res), UInt64(0));
 end;
 end;
 
 
 class constructor TGOST3411_2012.GOST3411_2012;
 class constructor TGOST3411_2012.GOST3411_2012;
@@ -1627,6 +1631,24 @@ end;
 
 
 { TGOST3411_2012_256 }
 { TGOST3411_2012_256 }
 
 
+function TGOST3411_2012_256.Clone(): IHash;
+var
+  HashInstance: TGOST3411_2012_256;
+begin
+  HashInstance := TGOST3411_2012_256.Create();
+  HashInstance.FIV := System.Copy(FIV);
+  HashInstance.FN := System.Copy(FN);
+  HashInstance.FSigma := System.Copy(FSigma);
+  HashInstance.FKi := System.Copy(FKi);
+  HashInstance.Fm := System.Copy(Fm);
+  HashInstance.Fh := System.Copy(Fh);
+  HashInstance.Ftmp := System.Copy(Ftmp);
+  HashInstance.Fblock := System.Copy(Fblock);
+  HashInstance.FbOff := FbOff;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TGOST3411_2012_256.Create();
 constructor TGOST3411_2012_256.Create();
 begin
 begin
   inherited Create(32, FIV_256);
   inherited Create(32, FIV_256);
@@ -1653,6 +1675,24 @@ end;
 
 
 { TGOST3411_2012_512 }
 { TGOST3411_2012_512 }
 
 
+function TGOST3411_2012_512.Clone(): IHash;
+var
+  HashInstance: TGOST3411_2012_512;
+begin
+  HashInstance := TGOST3411_2012_512.Create();
+  HashInstance.FIV := System.Copy(FIV);
+  HashInstance.FN := System.Copy(FN);
+  HashInstance.FSigma := System.Copy(FSigma);
+  HashInstance.FKi := System.Copy(FKi);
+  HashInstance.Fm := System.Copy(Fm);
+  HashInstance.Fh := System.Copy(Fh);
+  HashInstance.Ftmp := System.Copy(Ftmp);
+  HashInstance.Fblock := System.Copy(Fblock);
+  HashInstance.FbOff := FbOff;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TGOST3411_2012_512.Create();
 constructor TGOST3411_2012_512.Create();
 begin
 begin
   inherited Create(64, FIV_512);
   inherited Create(64, FIV_512);

+ 18 - 2
src/libraries/hashlib4pascal/HlpGost.pas

@@ -7,11 +7,13 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
+  HlpHash,
   HlpHashBuffer,
   HlpHashBuffer,
   HlpBitConverter,
   HlpBitConverter,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpBits,
   HlpBits,
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashCryptoNotBuildIn;
   HlpHashCryptoNotBuildIn;
 
 
@@ -39,6 +41,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -46,6 +49,19 @@ implementation
 
 
 { TGost }
 { TGost }
 
 
+function TGost.Clone(): IHash;
+var
+  HashInstance: TGost;
+begin
+  HashInstance := TGost.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 procedure TGost.Compress(a_m: PCardinal);
 procedure TGost.Compress(a_m: PCardinal);
 var
 var
   u0, u1, u2, u3, u4, u5, u6, u7, v0, v1, v2, v3, v4, v5, v6, v7, w0, w1, w2,
   u0, u1, u2, u3, u4, u5, u6, u7, v0, v1, v2, v3, v4, v5, v6, v7, w0, w1, w2,
@@ -452,8 +468,8 @@ begin
 
 
   Compress(@(m[0]));
   Compress(@(m[0]));
 
 
-  System.FillChar(m, System.SizeOf(m), 0);
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(m, System.SizeOf(m), UInt32(0));
+  System.FillChar(data, System.SizeOf(data), UInt32(0));
 
 
 end;
 end;
 
 

+ 17 - 0
src/libraries/hashlib4pascal/HlpGrindahl256.pas

@@ -10,9 +10,12 @@ uses
 {$ENDIF DELPHI2010}
 {$ENDIF DELPHI2010}
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
+  HlpHash,
+  HlpHashBuffer,
   HlpBitConverter,
   HlpBitConverter,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashCryptoNotBuildIn;
   HlpHashCryptoNotBuildIn;
 
 
@@ -92,6 +95,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -113,6 +117,19 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TGrindahl256.Clone(): IHash;
+var
+  HashInstance: TGrindahl256;
+begin
+  HashInstance := TGrindahl256.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_temp := System.Copy(Fm_temp);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TGrindahl256.Create;
 constructor TGrindahl256.Create;
 begin
 begin
   Inherited Create(32, 4);
   Inherited Create(32, 4);

+ 17 - 0
src/libraries/hashlib4pascal/HlpGrindahl512.pas

@@ -10,10 +10,13 @@ uses
 {$ENDIF DELPHI2010}
 {$ENDIF DELPHI2010}
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
+  HlpHash,
+  HlpHashBuffer,
   HlpBitConverter,
   HlpBitConverter,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpBits,
   HlpBits,
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashCryptoNotBuildIn;
   HlpHashCryptoNotBuildIn;
 
 
@@ -179,6 +182,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -199,6 +203,19 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TGrindahl512.Clone(): IHash;
+var
+  HashInstance: TGrindahl512;
+begin
+  HashInstance := TGrindahl512.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_temp := System.Copy(Fm_temp);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TGrindahl512.Create;
 constructor TGrindahl512.Create;
 begin
 begin
   Inherited Create(64, 8);
   Inherited Create(64, 8);

+ 16 - 1
src/libraries/hashlib4pascal/HlpHAS160.pas

@@ -10,10 +10,12 @@ uses
 {$ENDIF DELPHI2010}
 {$ENDIF DELPHI2010}
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
+  HlpHash,
   HlpHashBuffer,
   HlpHashBuffer,
   HlpBitConverter,
   HlpBitConverter,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashCryptoNotBuildIn;
   HlpHashCryptoNotBuildIn;
 
 
@@ -50,12 +52,25 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { THAS160 }
 { THAS160 }
 
 
+function THAS160.Clone(): IHash;
+var
+  HashInstance: THAS160;
+begin
+  HashInstance := THAS160.Create();
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THAS160.Create;
 constructor THAS160.Create;
 begin
 begin
   Inherited Create(20, 64);
   Inherited Create(20, 64);
@@ -202,7 +217,7 @@ begin
   Fm_hash[3] := Fm_hash[3] + D;
   Fm_hash[3] := Fm_hash[3] + D;
   Fm_hash[4] := Fm_hash[4] + E;
   Fm_hash[4] := Fm_hash[4] + E;
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt32(0));
 
 
 end;
 end;
 
 

+ 17 - 4
src/libraries/hashlib4pascal/HlpHMACNotBuildInAdapter.pas

@@ -44,6 +44,7 @@ type
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
+    function Clone(): IHash; override;
     property Key: THashLibByteArray read GetKey write SetKey;
     property Key: THashLibByteArray read GetKey write SetKey;
     property Name: String read GetName;
     property Name: String read GetName;
     property KeyLength: TNullableInteger read GetKeyLength;
     property KeyLength: TNullableInteger read GetKeyLength;
@@ -54,6 +55,19 @@ implementation
 
 
 { THMACNotBuildInAdapter }
 { THMACNotBuildInAdapter }
 
 
+function THMACNotBuildInAdapter.Clone(): IHash;
+var
+  HmacInstance: THMACNotBuildInAdapter;
+begin
+  HmacInstance := THMACNotBuildInAdapter.Create(Fm_hash.Clone());
+  HmacInstance.Fm_opad := System.Copy(Fm_opad);
+  HmacInstance.Fm_ipad := System.Copy(Fm_ipad);
+  HmacInstance.Fm_key := System.Copy(Fm_key);
+  HmacInstance.Fm_blocksize := Fm_blocksize;
+  result := HmacInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THMACNotBuildInAdapter.Create(const a_underlyingHash: IHash);
 constructor THMACNotBuildInAdapter.Create(const a_underlyingHash: IHash);
 begin
 begin
   Inherited Create(a_underlyingHash.HashSize, a_underlyingHash.BlockSize);
   Inherited Create(a_underlyingHash.HashSize, a_underlyingHash.BlockSize);
@@ -102,8 +116,8 @@ begin
     LKey := Key;
     LKey := Key;
   end;
   end;
 
 
-  System.FillChar(Fm_ipad[0], LBlockSize * System.SizeOf(Byte), $36);
-  System.FillChar(Fm_opad[0], LBlockSize * System.SizeOf(Byte), $5C);
+  System.FillChar(Fm_ipad[0], LBlockSize * System.SizeOf(Byte), Byte($36));
+  System.FillChar(Fm_opad[0], LBlockSize * System.SizeOf(Byte), Byte($5C));
 
 
   Idx := 0;
   Idx := 0;
   while (Idx < System.Length(LKey)) and (Idx < LBlockSize) do
   while (Idx < System.Length(LKey)) and (Idx < LBlockSize) do
@@ -145,8 +159,7 @@ end;
 
 
 function THMACNotBuildInAdapter.GetName: String;
 function THMACNotBuildInAdapter.GetName: String;
 begin
 begin
-  result := Format('%s(%s)', [Self.ClassName, (Self.Fm_hash as THash)
-    .ClassName]);
+  result := Format('%s(%s)', ['THMAC', Fm_hash.Name]);
 
 
 end;
 end;
 
 

+ 8 - 3
src/libraries/hashlib4pascal/HlpHash.pas

@@ -24,7 +24,7 @@ resourcestring
   // SInvalidHashSize = '"HashSize" Must Be Greater Than Zero';
   // SInvalidHashSize = '"HashSize" Must Be Greater Than Zero';
   SUnAssignedStream = 'Input Stream Is Unassigned';
   SUnAssignedStream = 'Input Stream Is Unassigned';
   SFileNotExist = 'Specified File Not Found';
   SFileNotExist = 'Specified File Not Found';
-  SNotYetImplemented = 'Not Yet Implemented For "%s"';
+  SCloneNotYetImplemented = 'Clone Not Yet Implemented For "%s"';
 
 
 type
 type
   THash = class abstract(TInterfacedObject, IHash)
   THash = class abstract(TInterfacedObject, IHash)
@@ -236,7 +236,7 @@ end;
 function THash.Clone(): IHash;
 function THash.Clone(): IHash;
 begin
 begin
   raise ENotImplementedHashLibException.CreateResFmt
   raise ENotImplementedHashLibException.CreateResFmt
-    (@SNotYetImplemented, [Name]);
+    (@SCloneNotYetImplemented, [Name]);
 end;
 end;
 
 
 function THash.ComputeBytes(const a_data: THashLibByteArray): IHashResult;
 function THash.ComputeBytes(const a_data: THashLibByteArray): IHashResult;
@@ -287,13 +287,16 @@ begin
   begin
   begin
     if (a_length > -1) then
     if (a_length > -1) then
     begin
     begin
-
       if ((a_stream.Position + a_length) > a_stream.Size) then
       if ((a_stream.Position + a_length) > a_stream.Size) then
+      begin
         raise EIndexOutOfRangeHashLibException.CreateRes(@SIndexOutOfRange);
         raise EIndexOutOfRangeHashLibException.CreateRes(@SIndexOutOfRange);
+      end;
     end;
     end;
 
 
     if (a_stream.Position >= a_stream.Size) then
     if (a_stream.Position >= a_stream.Size) then
+    begin
       Exit;
       Exit;
+    end;
   end
   end
   else
   else
   begin
   begin
@@ -365,7 +368,9 @@ begin
   System.Assert((a_length = -1) or (a_length > 0));
   System.Assert((a_length = -1) or (a_length > 0));
 {$ENDIF DEBUG}
 {$ENDIF DEBUG}
   if not FileExists(a_file_name) then
   if not FileExists(a_file_name) then
+  begin
     raise EArgumentHashLibException.CreateRes(@SFileNotExist);
     raise EArgumentHashLibException.CreateRes(@SFileNotExist);
+  end;
 
 
   MyFileStream := TFileStream.Create(a_file_name, fmOpenRead or
   MyFileStream := TFileStream.Create(a_file_name, fmOpenRead or
     fmShareDenyWrite);
     fmShareDenyWrite);

+ 10 - 2
src/libraries/hashlib4pascal/HlpHashBuffer.pas

@@ -36,6 +36,7 @@ type
     function Feed(a_data: PByte; a_length_a_data: Int32; a_length: Int32)
     function Feed(a_data: PByte; a_length_a_data: Int32; a_length: Int32)
       : Boolean; overload;
       : Boolean; overload;
     function ToString(): String;
     function ToString(): String;
+    function Clone(): THashBuffer; inline;
 
 
     property IsEmpty: Boolean read GetIsEmpty;
     property IsEmpty: Boolean read GetIsEmpty;
     property IsFull: Boolean read GetIsFull;
     property IsFull: Boolean read GetIsFull;
@@ -47,6 +48,13 @@ implementation
 
 
 { THashBuffer }
 { THashBuffer }
 
 
+function THashBuffer.Clone(): THashBuffer;
+begin
+  result := Default(THashBuffer);
+  result.Fm_data := System.Copy(Fm_data);
+  result.Fm_pos := Fm_pos;
+end;
+
 constructor THashBuffer.Create(a_length: Int32);
 constructor THashBuffer.Create(a_length: Int32);
 begin
 begin
 {$IFDEF DEBUG}
 {$IFDEF DEBUG}
@@ -148,7 +156,7 @@ end;
 function THashBuffer.GetBytesZeroPadded: THashLibByteArray;
 function THashBuffer.GetBytesZeroPadded: THashLibByteArray;
 begin
 begin
   System.FillChar(Fm_data[Fm_pos], (System.Length(Fm_data) - Fm_pos) *
   System.FillChar(Fm_data[Fm_pos], (System.Length(Fm_data) - Fm_pos) *
-    System.SizeOf(Byte), 0);
+    System.SizeOf(Byte), Byte(0));
   Fm_pos := 0;
   Fm_pos := 0;
   result := Fm_data;
   result := Fm_data;
 end;
 end;
@@ -171,7 +179,7 @@ end;
 procedure THashBuffer.Initialize;
 procedure THashBuffer.Initialize;
 begin
 begin
   Fm_pos := 0;
   Fm_pos := 0;
-  System.FillChar(Fm_data[0], System.Length(Fm_data) * System.SizeOf(Byte), 0);
+  System.FillChar(Fm_data[0], System.Length(Fm_data) * System.SizeOf(Byte), Byte(0));
 end;
 end;
 
 
 function THashBuffer.ToString: String;
 function THashBuffer.ToString: String;

+ 230 - 3
src/libraries/hashlib4pascal/HlpHaval.pas

@@ -10,6 +10,7 @@ uses
 {$ENDIF DELPHI2010}
 {$ENDIF DELPHI2010}
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
+  HlpHash,
   HlpHashBuffer,
   HlpHashBuffer,
   HlpBitConverter,
   HlpBitConverter,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
@@ -17,6 +18,7 @@ uses
   HlpHashSize,
   HlpHashSize,
   HlpHashRounds,
   HlpHashRounds,
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashCryptoNotBuildIn;
   HlpHashCryptoNotBuildIn;
 
 
@@ -93,6 +95,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -102,6 +105,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -111,6 +115,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -120,6 +125,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -129,6 +135,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -138,6 +145,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -147,6 +155,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -156,6 +165,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -165,6 +175,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -174,6 +185,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -183,6 +195,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -192,6 +205,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -201,6 +215,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -210,6 +225,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -219,6 +235,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -784,7 +801,7 @@ begin
   Fm_hash[6] := Fm_hash[6] + g;
   Fm_hash[6] := Fm_hash[6] + g;
   Fm_hash[7] := Fm_hash[7] + h;
   Fm_hash[7] := Fm_hash[7] + h;
 
 
-  System.FillChar(temp, System.SizeOf(temp), 0);
+  System.FillChar(temp, System.SizeOf(temp), UInt32(0));
 end;
 end;
 
 
 { THaval4 }
 { THaval4 }
@@ -1365,7 +1382,7 @@ begin
   Fm_hash[6] := Fm_hash[6] + g;
   Fm_hash[6] := Fm_hash[6] + g;
   Fm_hash[7] := Fm_hash[7] + h;
   Fm_hash[7] := Fm_hash[7] + h;
 
 
-  System.FillChar(temp, System.SizeOf(temp), 0);
+  System.FillChar(temp, System.SizeOf(temp), UInt32(0));
 
 
 end;
 end;
 
 
@@ -2074,12 +2091,26 @@ begin
   Fm_hash[6] := Fm_hash[6] + g;
   Fm_hash[6] := Fm_hash[6] + g;
   Fm_hash[7] := Fm_hash[7] + h;
   Fm_hash[7] := Fm_hash[7] + h;
 
 
-  System.FillChar(temp, System.SizeOf(temp), 0);
+  System.FillChar(temp, System.SizeOf(temp), UInt32(0));
 
 
 end;
 end;
 
 
 { THaval_3_128 }
 { THaval_3_128 }
 
 
+function THaval_3_128.Clone(): IHash;
+var
+  HashInstance: THaval_3_128;
+begin
+  HashInstance := THaval_3_128.Create();
+  HashInstance.Fm_rounds := Fm_rounds;
+  HashInstance.FHashSize := FHashSize;
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THaval_3_128.Create;
 constructor THaval_3_128.Create;
 begin
 begin
   inherited Create(THashSize.hsHashSize128);
   inherited Create(THashSize.hsHashSize128);
@@ -2087,6 +2118,20 @@ end;
 
 
 { THaval_4_128 }
 { THaval_4_128 }
 
 
+function THaval_4_128.Clone(): IHash;
+var
+  HashInstance: THaval_4_128;
+begin
+  HashInstance := THaval_4_128.Create();
+  HashInstance.Fm_rounds := Fm_rounds;
+  HashInstance.FHashSize := FHashSize;
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THaval_4_128.Create;
 constructor THaval_4_128.Create;
 begin
 begin
   inherited Create(THashSize.hsHashSize128);
   inherited Create(THashSize.hsHashSize128);
@@ -2094,6 +2139,20 @@ end;
 
 
 { THaval_5_128 }
 { THaval_5_128 }
 
 
+function THaval_5_128.Clone(): IHash;
+var
+  HashInstance: THaval_5_128;
+begin
+  HashInstance := THaval_5_128.Create();
+  HashInstance.Fm_rounds := Fm_rounds;
+  HashInstance.FHashSize := FHashSize;
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THaval_5_128.Create;
 constructor THaval_5_128.Create;
 begin
 begin
   inherited Create(THashSize.hsHashSize128);
   inherited Create(THashSize.hsHashSize128);
@@ -2101,6 +2160,20 @@ end;
 
 
 { THaval_3_160 }
 { THaval_3_160 }
 
 
+function THaval_3_160.Clone(): IHash;
+var
+  HashInstance: THaval_3_160;
+begin
+  HashInstance := THaval_3_160.Create();
+  HashInstance.Fm_rounds := Fm_rounds;
+  HashInstance.FHashSize := FHashSize;
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THaval_3_160.Create;
 constructor THaval_3_160.Create;
 begin
 begin
   inherited Create(THashSize.hsHashSize160);
   inherited Create(THashSize.hsHashSize160);
@@ -2108,6 +2181,20 @@ end;
 
 
 { THaval_4_160 }
 { THaval_4_160 }
 
 
+function THaval_4_160.Clone(): IHash;
+var
+  HashInstance: THaval_4_160;
+begin
+  HashInstance := THaval_4_160.Create();
+  HashInstance.Fm_rounds := Fm_rounds;
+  HashInstance.FHashSize := FHashSize;
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THaval_4_160.Create;
 constructor THaval_4_160.Create;
 begin
 begin
   inherited Create(THashSize.hsHashSize160);
   inherited Create(THashSize.hsHashSize160);
@@ -2115,6 +2202,20 @@ end;
 
 
 { THaval_5_160 }
 { THaval_5_160 }
 
 
+function THaval_5_160.Clone(): IHash;
+var
+  HashInstance: THaval_5_160;
+begin
+  HashInstance := THaval_5_160.Create();
+  HashInstance.Fm_rounds := Fm_rounds;
+  HashInstance.FHashSize := FHashSize;
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THaval_5_160.Create;
 constructor THaval_5_160.Create;
 begin
 begin
   inherited Create(THashSize.hsHashSize160);
   inherited Create(THashSize.hsHashSize160);
@@ -2122,6 +2223,20 @@ end;
 
 
 { THaval_3_192 }
 { THaval_3_192 }
 
 
+function THaval_3_192.Clone(): IHash;
+var
+  HashInstance: THaval_3_192;
+begin
+  HashInstance := THaval_3_192.Create();
+  HashInstance.Fm_rounds := Fm_rounds;
+  HashInstance.FHashSize := FHashSize;
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THaval_3_192.Create;
 constructor THaval_3_192.Create;
 begin
 begin
   inherited Create(THashSize.hsHashSize192);
   inherited Create(THashSize.hsHashSize192);
@@ -2129,6 +2244,20 @@ end;
 
 
 { THaval_4_192 }
 { THaval_4_192 }
 
 
+function THaval_4_192.Clone(): IHash;
+var
+  HashInstance: THaval_4_192;
+begin
+  HashInstance := THaval_4_192.Create();
+  HashInstance.Fm_rounds := Fm_rounds;
+  HashInstance.FHashSize := FHashSize;
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THaval_4_192.Create;
 constructor THaval_4_192.Create;
 begin
 begin
   inherited Create(THashSize.hsHashSize192);
   inherited Create(THashSize.hsHashSize192);
@@ -2136,6 +2265,20 @@ end;
 
 
 { THaval_5_192 }
 { THaval_5_192 }
 
 
+function THaval_5_192.Clone(): IHash;
+var
+  HashInstance: THaval_5_192;
+begin
+  HashInstance := THaval_5_192.Create();
+  HashInstance.Fm_rounds := Fm_rounds;
+  HashInstance.FHashSize := FHashSize;
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THaval_5_192.Create;
 constructor THaval_5_192.Create;
 begin
 begin
   inherited Create(THashSize.hsHashSize192);
   inherited Create(THashSize.hsHashSize192);
@@ -2143,6 +2286,20 @@ end;
 
 
 { THaval_3_224 }
 { THaval_3_224 }
 
 
+function THaval_3_224.Clone(): IHash;
+var
+  HashInstance: THaval_3_224;
+begin
+  HashInstance := THaval_3_224.Create();
+  HashInstance.Fm_rounds := Fm_rounds;
+  HashInstance.FHashSize := FHashSize;
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THaval_3_224.Create;
 constructor THaval_3_224.Create;
 begin
 begin
   inherited Create(THashSize.hsHashSize224);
   inherited Create(THashSize.hsHashSize224);
@@ -2150,6 +2307,20 @@ end;
 
 
 { THaval_4_224 }
 { THaval_4_224 }
 
 
+function THaval_4_224.Clone(): IHash;
+var
+  HashInstance: THaval_4_224;
+begin
+  HashInstance := THaval_4_224.Create();
+  HashInstance.Fm_rounds := Fm_rounds;
+  HashInstance.FHashSize := FHashSize;
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THaval_4_224.Create;
 constructor THaval_4_224.Create;
 begin
 begin
   inherited Create(THashSize.hsHashSize224);
   inherited Create(THashSize.hsHashSize224);
@@ -2157,6 +2328,20 @@ end;
 
 
 { THaval_5_224 }
 { THaval_5_224 }
 
 
+function THaval_5_224.Clone(): IHash;
+var
+  HashInstance: THaval_5_224;
+begin
+  HashInstance := THaval_5_224.Create();
+  HashInstance.Fm_rounds := Fm_rounds;
+  HashInstance.FHashSize := FHashSize;
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THaval_5_224.Create;
 constructor THaval_5_224.Create;
 begin
 begin
   inherited Create(THashSize.hsHashSize224);
   inherited Create(THashSize.hsHashSize224);
@@ -2164,6 +2349,20 @@ end;
 
 
 { THaval_3_256 }
 { THaval_3_256 }
 
 
+function THaval_3_256.Clone(): IHash;
+var
+  HashInstance: THaval_3_256;
+begin
+  HashInstance := THaval_3_256.Create();
+  HashInstance.Fm_rounds := Fm_rounds;
+  HashInstance.FHashSize := FHashSize;
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THaval_3_256.Create;
 constructor THaval_3_256.Create;
 begin
 begin
   inherited Create(THashSize.hsHashSize256);
   inherited Create(THashSize.hsHashSize256);
@@ -2171,6 +2370,20 @@ end;
 
 
 { THaval_4_256 }
 { THaval_4_256 }
 
 
+function THaval_4_256.Clone(): IHash;
+var
+  HashInstance: THaval_4_256;
+begin
+  HashInstance := THaval_4_256.Create();
+  HashInstance.Fm_rounds := Fm_rounds;
+  HashInstance.FHashSize := FHashSize;
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THaval_4_256.Create;
 constructor THaval_4_256.Create;
 begin
 begin
   inherited Create(THashSize.hsHashSize256);
   inherited Create(THashSize.hsHashSize256);
@@ -2178,6 +2391,20 @@ end;
 
 
 { THaval_5_256 }
 { THaval_5_256 }
 
 
+function THaval_5_256.Clone(): IHash;
+var
+  HashInstance: THaval_5_256;
+begin
+  HashInstance := THaval_5_256.Create();
+  HashInstance.Fm_rounds := Fm_rounds;
+  HashInstance.FHashSize := FHashSize;
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor THaval_5_256.Create;
 constructor THaval_5_256.Create;
 begin
 begin
   inherited Create(THashSize.hsHashSize256);
   inherited Create(THashSize.hsHashSize256);

+ 12 - 0
src/libraries/hashlib4pascal/HlpJS.pas

@@ -7,6 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -23,12 +24,23 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TJS }
 { TJS }
 
 
+function TJS.Clone(): IHash;
+var
+  HashInstance: TJS;
+begin
+  HashInstance := TJS.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TJS.Create;
 constructor TJS.Create;
 begin
 begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);

+ 18 - 2
src/libraries/hashlib4pascal/HlpJenkins3.pas

@@ -6,7 +6,11 @@ interface
 
 
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpHash,
+{$ENDIF DELPHI}
   HlpBits,
   HlpBits,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult,
   HlpIHashResult,
@@ -17,10 +21,11 @@ type
   TJenkins3 = class sealed(TMultipleTransformNonBlock, IHash32, ITransformBlock)
   TJenkins3 = class sealed(TMultipleTransformNonBlock, IHash32, ITransformBlock)
 
 
   strict protected
   strict protected
-    function ComputeAggregatedBytes(a_data: THashLibByteArray)
+    function ComputeAggregatedBytes(const a_data: THashLibByteArray)
       : IHashResult; override;
       : IHashResult; override;
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -33,7 +38,18 @@ begin
   Inherited Create(4, 12);
   Inherited Create(4, 12);
 end;
 end;
 
 
-function TJenkins3.ComputeAggregatedBytes(a_data: THashLibByteArray)
+function TJenkins3.Clone(): IHash;
+var
+  HashInstance: TJenkins3;
+begin
+  HashInstance := TJenkins3.Create();
+  FBuffer.Position := 0;
+  HashInstance.FBuffer.CopyFrom(FBuffer, FBuffer.Size);
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
+function TJenkins3.ComputeAggregatedBytes(const a_data: THashLibByteArray)
   : IHashResult;
   : IHashResult;
 var
 var
   &length, currentIndex, i1, i2, i3, i4: Int32;
   &length, currentIndex, i1, i2, i3, i4: Int32;

+ 17 - 1
src/libraries/hashlib4pascal/HlpMD2.pas

@@ -8,7 +8,9 @@ uses
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpHashBuffer,
   HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashCryptoNotBuildIn;
   HlpHashCryptoNotBuildIn;
 
 
@@ -68,6 +70,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -75,6 +78,19 @@ implementation
 
 
 { TMD2 }
 { TMD2 }
 
 
+function TMD2.Clone(): IHash;
+var
+  HashInstance: TMD2;
+begin
+  HashInstance := TMD2.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_checksum := System.Copy(Fm_checksum);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TMD2.Create;
 constructor TMD2.Create;
 begin
 begin
   Inherited Create(16, 16);
   Inherited Create(16, 16);
@@ -163,7 +179,7 @@ begin
     t := Fm_checksum[i];
     t := Fm_checksum[i];
   end;
   end;
 
 
-  System.FillChar(temp, System.SizeOf(temp), 0);
+  System.FillChar(temp, System.SizeOf(temp), Byte(0));
 
 
 end;
 end;
 
 

+ 17 - 1
src/libraries/hashlib4pascal/HlpMD4.pas

@@ -11,9 +11,12 @@ uses
   HlpMDBase,
   HlpMDBase,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
+  HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpBits,
   HlpBits,
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo;
   HlpIHashInfo;
 
 
 type
 type
@@ -25,6 +28,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -32,6 +36,18 @@ implementation
 
 
 { TMD4 }
 { TMD4 }
 
 
+function TMD4.Clone(): IHash;
+var
+  HashInstance: TMD4;
+begin
+  HashInstance := TMD4.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TMD4.Create;
 constructor TMD4.Create;
 begin
 begin
   Inherited Create(4, 16);
   Inherited Create(4, 16);
@@ -155,7 +171,7 @@ begin
   Fm_state[2] := Fm_state[2] + c;
   Fm_state[2] := Fm_state[2] + c;
   Fm_state[3] := Fm_state[3] + d;
   Fm_state[3] := Fm_state[3] + d;
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt32(0));
 end;
 end;
 
 
 end.
 end.

+ 17 - 1
src/libraries/hashlib4pascal/HlpMD5.pas

@@ -12,7 +12,10 @@ uses
   HlpMDBase,
   HlpMDBase,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
+  HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
+  HlpIHash,
   HlpConverters,
   HlpConverters,
   HlpIHashInfo;
   HlpIHashInfo;
 
 
@@ -25,6 +28,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -32,6 +36,18 @@ implementation
 
 
 { TMD5 }
 { TMD5 }
 
 
+function TMD5.Clone(): IHash;
+var
+  HashInstance: TMD5;
+begin
+  HashInstance := TMD5.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TMD5.Create;
 constructor TMD5.Create;
 begin
 begin
   Inherited Create(4, 16);
   Inherited Create(4, 16);
@@ -188,7 +204,7 @@ begin
   Fm_state[2] := Fm_state[2] + C;
   Fm_state[2] := Fm_state[2] + C;
   Fm_state[3] := Fm_state[3] + D;
   Fm_state[3] := Fm_state[3] + D;
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt32(0));
 
 
 end;
 end;
 
 

+ 3 - 2
src/libraries/hashlib4pascal/HlpMultipleTransformNonBlock.pas

@@ -20,12 +20,13 @@ type
   TMultipleTransformNonBlock = class abstract(THash, INonBlockHash)
   TMultipleTransformNonBlock = class abstract(THash, INonBlockHash)
 
 
   strict private
   strict private
-    FBuffer: TMemoryStream;
 
 
     function Aggregate(): THashLibByteArray;
     function Aggregate(): THashLibByteArray;
 
 
   strict protected
   strict protected
-    function ComputeAggregatedBytes(a_data: THashLibByteArray): IHashResult;
+    FBuffer: TMemoryStream;
+
+    function ComputeAggregatedBytes(const a_data: THashLibByteArray): IHashResult;
       virtual; abstract;
       virtual; abstract;
 
 
   public
   public

+ 19 - 3
src/libraries/hashlib4pascal/HlpMurmur2.pas

@@ -10,8 +10,9 @@ uses
 {$ENDIF DELPHI2010}
 {$ENDIF DELPHI2010}
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
-  HlpBitConverter,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
+  HlpIHash,
   HlpConverters,
   HlpConverters,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
@@ -43,12 +44,13 @@ type
     procedure SetKey(const value: THashLibByteArray); inline;
     procedure SetKey(const value: THashLibByteArray); inline;
 
 
   strict protected
   strict protected
-    function ComputeAggregatedBytes(a_data: THashLibByteArray)
+    function ComputeAggregatedBytes(const a_data: THashLibByteArray)
       : IHashResult; override;
       : IHashResult; override;
 
 
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
     property KeyLength: TNullableInteger read GetKeyLength;
     property KeyLength: TNullableInteger read GetKeyLength;
     property Key: THashLibByteArray read GetKey write SetKey;
     property Key: THashLibByteArray read GetKey write SetKey;
 
 
@@ -175,7 +177,21 @@ begin
   result := Int32(Fm_h);
   result := Int32(Fm_h);
 end;
 end;
 
 
-function TMurmur2.ComputeAggregatedBytes(a_data: THashLibByteArray)
+function TMurmur2.Clone(): IHash;
+var
+  HashInstance: TMurmur2;
+begin
+  HashInstance := TMurmur2.Create();
+  HashInstance.Fm_key := Fm_key;
+  HashInstance.Fm_working_key := Fm_working_key;
+  HashInstance.Fm_h := Fm_h;
+  FBuffer.Position := 0;
+  HashInstance.FBuffer.CopyFrom(FBuffer, FBuffer.Size);
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
+function TMurmur2.ComputeAggregatedBytes(const a_data: THashLibByteArray)
   : IHashResult;
   : IHashResult;
 
 
 begin
 begin

+ 18 - 3
src/libraries/hashlib4pascal/HlpMurmur2_64.pas

@@ -7,9 +7,10 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
-  HlpBitConverter,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult,
   HlpIHashResult,
@@ -45,12 +46,13 @@ type
     procedure SetKey(const value: THashLibByteArray); inline;
     procedure SetKey(const value: THashLibByteArray); inline;
 
 
   strict protected
   strict protected
-    function ComputeAggregatedBytes(a_data: THashLibByteArray)
+    function ComputeAggregatedBytes(const a_data: THashLibByteArray)
       : IHashResult; override;
       : IHashResult; override;
 
 
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
     property KeyLength: TNullableInteger read GetKeyLength;
     property KeyLength: TNullableInteger read GetKeyLength;
     property Key: THashLibByteArray read GetKey write SetKey;
     property Key: THashLibByteArray read GetKey write SetKey;
 
 
@@ -60,7 +62,20 @@ implementation
 
 
 { TMurmur2_64 }
 { TMurmur2_64 }
 
 
-function TMurmur2_64.ComputeAggregatedBytes(a_data: THashLibByteArray)
+function TMurmur2_64.Clone(): IHash;
+var
+  HashInstance: TMurmur2_64;
+begin
+  HashInstance := TMurmur2_64.Create();
+  HashInstance.Fm_key := Fm_key;
+  HashInstance.Fm_working_key := Fm_working_key;
+  FBuffer.Position := 0;
+  HashInstance.FBuffer.CopyFrom(FBuffer, FBuffer.Size);
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
+function TMurmur2_64.ComputeAggregatedBytes(const a_data: THashLibByteArray)
   : IHashResult;
   : IHashResult;
 var
 var
   &length, current_index: Int32;
   &length, current_index: Int32;

+ 17 - 0
src/libraries/hashlib4pascal/HlpMurmurHash3_x64_128.pas

@@ -16,6 +16,7 @@ uses
   HlpIHashInfo,
   HlpIHashInfo,
   HlpNullable,
   HlpNullable,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult,
   HlpIHashResult,
   HlpBits;
   HlpBits;
@@ -69,6 +70,7 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal: IHashResult; override;
     function TransformFinal: IHashResult; override;
+    function Clone(): IHash; override;
     property KeyLength: TNullableInteger read GetKeyLength;
     property KeyLength: TNullableInteger read GetKeyLength;
     property Key: THashLibByteArray read GetKey write SetKey;
     property Key: THashLibByteArray read GetKey write SetKey;
   end;
   end;
@@ -117,6 +119,21 @@ begin
   ProcessPendings();
   ProcessPendings();
 end;
 end;
 
 
+function TMurmurHash3_x64_128.Clone(): IHash;
+var
+  HashInstance: TMurmurHash3_x64_128;
+begin
+  HashInstance := TMurmurHash3_x64_128.Create();
+  HashInstance.Fm_h1 := Fm_h1;
+  HashInstance.Fm_h2 := Fm_h2;
+  HashInstance.Fm_total_length := Fm_total_length;
+  HashInstance.Fm_key := Fm_key;
+  HashInstance.Fm_idx := Fm_idx;
+  HashInstance.Fm_buf := System.Copy(Fm_buf);
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TMurmurHash3_x64_128.Create;
 constructor TMurmurHash3_x64_128.Create;
 begin
 begin
   Inherited Create(16, 16);
   Inherited Create(16, 16);

+ 19 - 0
src/libraries/hashlib4pascal/HlpMurmurHash3_x86_128.pas

@@ -16,6 +16,7 @@ uses
   HlpBitConverter,
   HlpBitConverter,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult,
   HlpIHashResult,
   HlpBits;
   HlpBits;
@@ -65,6 +66,7 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal: IHashResult; override;
     function TransformFinal: IHashResult; override;
+    function Clone(): IHash; override;
     property KeyLength: TNullableInteger read GetKeyLength;
     property KeyLength: TNullableInteger read GetKeyLength;
     property Key: THashLibByteArray read GetKey write SetKey;
     property Key: THashLibByteArray read GetKey write SetKey;
   end;
   end;
@@ -137,6 +139,23 @@ begin
   ProcessPendings();
   ProcessPendings();
 end;
 end;
 
 
+function TMurmurHash3_x86_128.Clone(): IHash;
+var
+  HashInstance: TMurmurHash3_x86_128;
+begin
+  HashInstance := TMurmurHash3_x86_128.Create();
+    HashInstance.Fm_key := Fm_key;
+  HashInstance.Fm_h1 := Fm_h1;
+  HashInstance.Fm_h2 := Fm_h2;
+  HashInstance.Fm_h3 := Fm_h3;
+  HashInstance.Fm_h4 := Fm_h4;
+  HashInstance.Fm_total_length := Fm_total_length;
+  HashInstance.Fm_idx := Fm_idx;
+  HashInstance.Fm_buf := System.Copy(Fm_buf);
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TMurmurHash3_x86_128.Create;
 constructor TMurmurHash3_x86_128.Create;
 begin
 begin
   Inherited Create(16, 16);
   Inherited Create(16, 16);

+ 1 - 1
src/libraries/hashlib4pascal/HlpMurmurHash3_x86_32.pas

@@ -68,7 +68,7 @@ implementation
 
 
 { TMurmurHash3_x86_32 }
 { TMurmurHash3_x86_32 }
 
 
-function TMurmurHash3_x86_32.Clone: IHash;
+function TMurmurHash3_x86_32.Clone(): IHash;
 var
 var
   HashInstance: TMurmurHash3_x86_32;
   HashInstance: TMurmurHash3_x86_32;
 begin
 begin

+ 13 - 0
src/libraries/hashlib4pascal/HlpNullDigest.pas

@@ -9,6 +9,7 @@ uses
   SysUtils,
   SysUtils,
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -26,12 +27,24 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TNullDigest }
 { TNullDigest }
 
 
+function TNullDigest.Clone(): IHash;
+var
+  HashInstance: TNullDigest;
+begin
+  HashInstance := TNullDigest.Create();
+  FbOut.Position := 0;
+  HashInstance.FbOut.CopyFrom(FbOut, FbOut.Size);
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TNullDigest.Create;
 constructor TNullDigest.Create;
 begin
 begin
   Inherited Create(-1, -1); // Dummy State
   Inherited Create(-1, -1); // Dummy State

+ 12 - 0
src/libraries/hashlib4pascal/HlpOneAtTime.pas

@@ -7,6 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -23,12 +24,23 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TOneAtTime }
 { TOneAtTime }
 
 
+function TOneAtTime.Clone(): IHash;
+var
+  HashInstance: TOneAtTime;
+begin
+  HashInstance := TOneAtTime.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TOneAtTime.Create;
 constructor TOneAtTime.Create;
 begin
 begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);

+ 12 - 0
src/libraries/hashlib4pascal/HlpPJW.pas

@@ -7,6 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -30,12 +31,23 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TPJW }
 { TPJW }
 
 
+function TPJW.Clone(): IHash;
+var
+  HashInstance: TPJW;
+begin
+  HashInstance := TPJW.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TPJW.Create;
 constructor TPJW.Create;
 begin
 begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);

+ 38 - 1
src/libraries/hashlib4pascal/HlpPanama.pas

@@ -9,8 +9,11 @@ uses
   HlpBits,
   HlpBits,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
+  HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashCryptoNotBuildIn;
   HlpHashCryptoNotBuildIn;
 
 
@@ -38,6 +41,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -45,6 +49,28 @@ implementation
 
 
 { TPanama }
 { TPanama }
 
 
+function TPanama.Clone(): IHash;
+var
+  HashInstance: TPanama;
+  Idx: Int32;
+begin
+  HashInstance := TPanama.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Ftheta := System.Copy(Ftheta);
+  HashInstance.Fgamma := System.Copy(Fgamma);
+  HashInstance.Fpi := System.Copy(Fpi);
+  // since System.Copy() does not support jagged arrays (multidimensional dynamic arrays, we improvise)
+  for Idx := System.Low(Fm_stages) to System.High(Fm_stages) do
+  begin
+    HashInstance.Fm_stages[Idx] := System.Copy(Fm_stages[Idx]);
+  end;
+  HashInstance.Fm_tap := Fm_tap;
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TPanama.Create;
 constructor TPanama.Create;
 var
 var
   i: Int32;
   i: Int32;
@@ -214,6 +240,17 @@ begin
   System.FillChar(Fm_state[0], System.Length(Fm_state) * System.SizeOf(UInt32),
   System.FillChar(Fm_state[0], System.Length(Fm_state) * System.SizeOf(UInt32),
     UInt32(0));
     UInt32(0));
 
 
+  System.FillChar(Ftheta[0], System.Length(Ftheta) * System.SizeOf(UInt32),
+    UInt32(0));
+
+  System.FillChar(Fgamma[0], System.Length(Fgamma) * System.SizeOf(UInt32),
+    UInt32(0));
+
+  System.FillChar(Fpi[0], System.Length(Fpi) * System.SizeOf(UInt32),
+    UInt32(0));
+
+  Fm_tap := 0;
+
   for i := System.Low(Fm_stages) to System.High(Fm_stages) do
   for i := System.Low(Fm_stages) to System.High(Fm_stages) do
   begin
   begin
     System.FillChar(Fm_stages[i, 0], System.Length(Fm_stages[i]) *
     System.FillChar(Fm_stages[i, 0], System.Length(Fm_stages[i]) *
@@ -276,7 +313,7 @@ begin
   Fm_state[15] := Ftheta[15] xor Fm_stages[tap16, 6];
   Fm_state[15] := Ftheta[15] xor Fm_stages[tap16, 6];
   Fm_state[16] := Ftheta[16] xor Fm_stages[tap16, 7];
   Fm_state[16] := Ftheta[16] xor Fm_stages[tap16, 7];
 
 
-  System.FillChar(work_buffer, System.SizeOf(work_buffer), 0);
+  System.FillChar(work_buffer, System.SizeOf(work_buffer), UInt32(0));
 
 
 end;
 end;
 
 

+ 17 - 1
src/libraries/hashlib4pascal/HlpRIPEMD.pas

@@ -11,9 +11,12 @@ uses
   HlpBits,
   HlpBits,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
+  HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpMDBase,
   HlpMDBase,
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo;
   HlpIHashInfo;
 
 
 type
 type
@@ -30,6 +33,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -37,6 +41,18 @@ implementation
 
 
 { TRIPEMD }
 { TRIPEMD }
 
 
+function TRIPEMD.Clone(): IHash;
+var
+  HashInstance: TRIPEMD;
+begin
+  HashInstance := TRIPEMD.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TRIPEMD.Create;
 constructor TRIPEMD.Create;
 begin
 begin
   Inherited Create(4, 16);
   Inherited Create(4, 16);
@@ -183,7 +199,7 @@ begin
   Fm_state[2] := Fm_state[3] + a + bb;
   Fm_state[2] := Fm_state[3] + a + bb;
   Fm_state[3] := cc;
   Fm_state[3] := cc;
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt32(0));
 
 
 end;
 end;
 
 

+ 17 - 1
src/libraries/hashlib4pascal/HlpRIPEMD128.pas

@@ -11,9 +11,12 @@ uses
   HlpMDBase,
   HlpMDBase,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
+  HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpBits,
   HlpBits,
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo;
   HlpIHashInfo;
 
 
 type
 type
@@ -25,6 +28,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -32,6 +36,18 @@ implementation
 
 
 { TRIPEMD128 }
 { TRIPEMD128 }
 
 
+function TRIPEMD128.Clone(): IHash;
+var
+  HashInstance: TRIPEMD128;
+begin
+  HashInstance := TRIPEMD128.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TRIPEMD128.Create;
 constructor TRIPEMD128.Create;
 begin
 begin
   Inherited Create(4, 16);
   Inherited Create(4, 16);
@@ -325,7 +341,7 @@ begin
   Fm_state[3] := Fm_state[0] + b + cc;
   Fm_state[3] := Fm_state[0] + b + cc;
   Fm_state[0] := dd;
   Fm_state[0] := dd;
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt32(0));
 
 
 end;
 end;
 
 

+ 17 - 1
src/libraries/hashlib4pascal/HlpRIPEMD160.pas

@@ -11,9 +11,12 @@ uses
   HlpMDBase,
   HlpMDBase,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
+  HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpBits,
   HlpBits,
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo;
   HlpIHashInfo;
 
 
 type
 type
@@ -26,6 +29,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -33,6 +37,18 @@ implementation
 
 
 { TRIPEMD160 }
 { TRIPEMD160 }
 
 
+function TRIPEMD160.Clone(): IHash;
+var
+  HashInstance: TRIPEMD160;
+begin
+  HashInstance := TRIPEMD160.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TRIPEMD160.Create;
 constructor TRIPEMD160.Create;
 begin
 begin
   Inherited Create(5, 20);
   Inherited Create(5, 20);
@@ -563,7 +579,7 @@ begin
   Fm_state[4] := Fm_state[0] + b + cc;
   Fm_state[4] := Fm_state[0] + b + cc;
   Fm_state[0] := dd;
   Fm_state[0] := dd;
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt32(0));
 
 
 end;
 end;
 
 

+ 17 - 1
src/libraries/hashlib4pascal/HlpRIPEMD256.pas

@@ -12,8 +12,11 @@ uses
   HlpBits,
   HlpBits,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
+  HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo;
   HlpIHashInfo;
 
 
 type
 type
@@ -26,6 +29,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -33,6 +37,18 @@ implementation
 
 
 { TRIPEMD256 }
 { TRIPEMD256 }
 
 
+function TRIPEMD256.Clone(): IHash;
+var
+  HashInstance: TRIPEMD256;
+begin
+  HashInstance := TRIPEMD256.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TRIPEMD256.Create;
 constructor TRIPEMD256.Create;
 begin
 begin
   Inherited Create(8, 32);
   Inherited Create(8, 32);
@@ -340,7 +356,7 @@ begin
   Fm_state[6] := Fm_state[6] + c;
   Fm_state[6] := Fm_state[6] + c;
   Fm_state[7] := Fm_state[7] + d;
   Fm_state[7] := Fm_state[7] + d;
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt32(0));
 
 
 end;
 end;
 
 

+ 17 - 1
src/libraries/hashlib4pascal/HlpRIPEMD320.pas

@@ -11,9 +11,12 @@ uses
   HlpMDBase,
   HlpMDBase,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
+  HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpBits,
   HlpBits,
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo;
   HlpIHashInfo;
 
 
 type
 type
@@ -26,6 +29,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -33,6 +37,18 @@ implementation
 
 
 { TRIPEMD320 }
 { TRIPEMD320 }
 
 
+function TRIPEMD320.Clone(): IHash;
+var
+  HashInstance: TRIPEMD320;
+begin
+  HashInstance := TRIPEMD320.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TRIPEMD320.Create;
 constructor TRIPEMD320.Create;
 begin
 begin
   Inherited Create(10, 40);
   Inherited Create(10, 40);
@@ -572,7 +588,7 @@ begin
   Fm_state[8] := Fm_state[8] + d;
   Fm_state[8] := Fm_state[8] + d;
   Fm_state[9] := Fm_state[9] + e;
   Fm_state[9] := Fm_state[9] + e;
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt32(0));
 
 
 end;
 end;
 
 

+ 13 - 0
src/libraries/hashlib4pascal/HlpRS.pas

@@ -7,6 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -26,12 +27,24 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TRS }
 { TRS }
 
 
+function TRS.Clone(): IHash;
+var
+  HashInstance: TRS;
+begin
+  HashInstance := TRS.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  HashInstance.Fm_a := Fm_a;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TRS.Create;
 constructor TRS.Create;
 begin
 begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);

+ 24 - 2
src/libraries/hashlib4pascal/HlpRadioGatun32.pas

@@ -8,9 +8,12 @@ uses
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
+  HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpBits,
   HlpBits,
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashCryptoNotBuildIn;
   HlpHashCryptoNotBuildIn;
 
 
@@ -34,6 +37,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -41,6 +45,24 @@ implementation
 
 
 { TRadioGatun32 }
 { TRadioGatun32 }
 
 
+function TRadioGatun32.Clone(): IHash;
+var
+  HashInstance: TRadioGatun32;
+  Idx: Int32;
+begin
+  HashInstance := TRadioGatun32.Create();
+  HashInstance.Fm_mill := System.Copy(Fm_mill);
+  // since System.Copy() does not support jagged arrays (multidimensional dynamic arrays, we improvise)
+  for Idx := System.Low(Fm_belt) to System.High(Fm_belt) do
+  begin
+    HashInstance.Fm_belt[Idx] := System.Copy(Fm_belt[Idx]);
+  end;
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TRadioGatun32.Create;
 constructor TRadioGatun32.Create;
 var
 var
   i: Int32;
   i: Int32;
@@ -100,7 +122,6 @@ begin
 
 
   TConverters.le32_copy(PCardinal(tempRes), 0, PByte(result), 0,
   TConverters.le32_copy(PCardinal(tempRes), 0, PByte(result), 0,
     System.Length(result));
     System.Length(result));
-
 end;
 end;
 
 
 procedure TRadioGatun32.Initialize;
 procedure TRadioGatun32.Initialize;
@@ -117,6 +138,7 @@ begin
 
 
     System.FillChar(Fm_belt[i][0], System.Length(Fm_belt[i]) *
     System.FillChar(Fm_belt[i][0], System.Length(Fm_belt[i]) *
       System.SizeOf(UInt32), UInt32(0));
       System.SizeOf(UInt32), UInt32(0));
+
     System.Inc(i);
     System.Inc(i);
   end;
   end;
 
 
@@ -207,7 +229,7 @@ begin
 
 
   RoundFunction();
   RoundFunction();
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt32(0));
 end;
 end;
 
 
 end.
 end.

+ 23 - 1
src/libraries/hashlib4pascal/HlpRadioGatun64.pas

@@ -8,9 +8,12 @@ uses
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
+  HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpBits,
   HlpBits,
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashCryptoNotBuildIn;
   HlpHashCryptoNotBuildIn;
 
 
@@ -34,6 +37,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -41,6 +45,24 @@ implementation
 
 
 { TRadioGatun64 }
 { TRadioGatun64 }
 
 
+function TRadioGatun64.Clone(): IHash;
+var
+  HashInstance: TRadioGatun64;
+  Idx: Int32;
+begin
+  HashInstance := TRadioGatun64.Create();
+  HashInstance.Fm_mill := System.Copy(Fm_mill);
+  // since System.Copy() does not support jagged arrays (multidimensional dynamic arrays, we improvise)
+  for Idx := System.Low(Fm_belt) to System.High(Fm_belt) do
+  begin
+    HashInstance.Fm_belt[Idx] := System.Copy(Fm_belt[Idx]);
+  end;
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TRadioGatun64.Create;
 constructor TRadioGatun64.Create;
 var
 var
   i: Int32;
   i: Int32;
@@ -205,7 +227,7 @@ begin
 
 
   RoundFunction();
   RoundFunction();
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt64(0));
 end;
 end;
 
 
 end.
 end.

+ 12 - 0
src/libraries/hashlib4pascal/HlpRotating.pas

@@ -8,6 +8,7 @@ uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpBits,
   HlpBits,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -24,12 +25,23 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TRotating }
 { TRotating }
 
 
+function TRotating.Clone(): IHash;
+var
+  HashInstance: TRotating;
+begin
+  HashInstance := TRotating.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TRotating.Create;
 constructor TRotating.Create;
 begin
 begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);

+ 12 - 0
src/libraries/hashlib4pascal/HlpSDBM.pas

@@ -7,6 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -23,12 +24,23 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TSDBM }
 { TSDBM }
 
 
+function TSDBM.Clone(): IHash;
+var
+  HashInstance: TSDBM;
+begin
+  HashInstance := TSDBM.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TSDBM.Create;
 constructor TSDBM.Create;
 begin
 begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);

+ 16 - 1
src/libraries/hashlib4pascal/HlpSHA0.pas

@@ -12,9 +12,11 @@ uses
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpHashBuffer,
   HlpHashBuffer,
   HlpBitConverter,
   HlpBitConverter,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashCryptoNotBuildIn;
   HlpHashCryptoNotBuildIn;
 
 
@@ -44,6 +46,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -51,6 +54,18 @@ implementation
 
 
 { TSHA0 }
 { TSHA0 }
 
 
+function TSHA0.Clone(): IHash;
+var
+  HashInstance: TSHA0;
+begin
+  HashInstance := TSHA0.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TSHA0.Create;
 constructor TSHA0.Create;
 begin
 begin
   Inherited Create(20, 64);
   Inherited Create(20, 64);
@@ -559,7 +574,7 @@ begin
   Fm_state[3] := Fm_state[3] + D;
   Fm_state[3] := Fm_state[3] + D;
   Fm_state[4] := Fm_state[4] + E;
   Fm_state[4] := Fm_state[4] + E;
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt32(0));
 
 
 end;
 end;
 
 

+ 19 - 2
src/libraries/hashlib4pascal/HlpSHA1.pas

@@ -5,9 +5,13 @@ unit HlpSHA1;
 interface
 interface
 
 
 uses
 uses
-
   HlpBits,
   HlpBits,
-  HlpSHA0;
+{$IFDEF DELPHI}
+  HlpHashBuffer,
+  HlpHash,
+{$ENDIF DELPHI}
+  HlpSHA0,
+  HlpIHash;
 
 
 type
 type
   TSHA1 = class sealed(TSHA0)
   TSHA1 = class sealed(TSHA0)
@@ -20,6 +24,7 @@ type
     // called for classes if none is defined by the developer but I just put it
     // called for classes if none is defined by the developer but I just put it
     // for readability reasons.
     // for readability reasons.
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -27,6 +32,18 @@ implementation
 
 
 { TSHA1 }
 { TSHA1 }
 
 
+function TSHA1.Clone(): IHash;
+var
+  HashInstance: TSHA1;
+begin
+  HashInstance := TSHA1.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TSHA1.Create;
 constructor TSHA1.Create;
 begin
 begin
   Inherited Create();
   Inherited Create();

+ 16 - 0
src/libraries/hashlib4pascal/HlpSHA2_224.pas

@@ -11,8 +11,11 @@ uses
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
+  HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpSHA2_256Base,
   HlpSHA2_256Base,
+  HlpIHash,
   HlpConverters;
   HlpConverters;
 
 
 type
 type
@@ -24,6 +27,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -31,6 +35,18 @@ implementation
 
 
 { TSHA2_224 }
 { TSHA2_224 }
 
 
+function TSHA2_224.Clone(): IHash;
+var
+  HashInstance: TSHA2_224;
+begin
+  HashInstance := TSHA2_224.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TSHA2_224.Create;
 constructor TSHA2_224.Create;
 begin
 begin
   Inherited Create(28);
   Inherited Create(28);

+ 16 - 0
src/libraries/hashlib4pascal/HlpSHA2_256.pas

@@ -11,7 +11,10 @@ uses
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
+  HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
+  HlpIHash,
   HlpSHA2_256Base,
   HlpSHA2_256Base,
   HlpConverters;
   HlpConverters;
 
 
@@ -24,6 +27,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -31,6 +35,18 @@ implementation
 
 
 { TSHA2_256 }
 { TSHA2_256 }
 
 
+function TSHA2_256.Clone(): IHash;
+var
+  HashInstance: TSHA2_256;
+begin
+  HashInstance := TSHA2_256.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TSHA2_256.Create;
 constructor TSHA2_256.Create;
 begin
 begin
   Inherited Create(32);
   Inherited Create(32);

+ 1 - 1
src/libraries/hashlib4pascal/HlpSHA2_256Base.pas

@@ -941,7 +941,7 @@ begin
   Fm_state[6] := Fm_state[6] + G;
   Fm_state[6] := Fm_state[6] + G;
   Fm_state[7] := Fm_state[7] + H;
   Fm_state[7] := Fm_state[7] + H;
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt32(0));
 
 
 end;
 end;
 
 

+ 16 - 0
src/libraries/hashlib4pascal/HlpSHA2_384.pas

@@ -11,7 +11,10 @@ uses
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
+  HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
+  HlpIHash,
   HlpSHA2_512Base,
   HlpSHA2_512Base,
   HlpConverters;
   HlpConverters;
 
 
@@ -24,6 +27,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -31,6 +35,18 @@ implementation
 
 
 { TSHA2_384 }
 { TSHA2_384 }
 
 
+function TSHA2_384.Clone(): IHash;
+var
+  HashInstance: TSHA2_384;
+begin
+  HashInstance := TSHA2_384.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TSHA2_384.Create;
 constructor TSHA2_384.Create;
 begin
 begin
   Inherited Create(48);
   Inherited Create(48);

+ 16 - 0
src/libraries/hashlib4pascal/HlpSHA2_512.pas

@@ -11,7 +11,10 @@ uses
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
+  HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
+  HlpIHash,
   HlpSHA2_512Base,
   HlpSHA2_512Base,
   HlpConverters;
   HlpConverters;
 
 
@@ -24,6 +27,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -31,6 +35,18 @@ implementation
 
 
 { TSHA2_512 }
 { TSHA2_512 }
 
 
+function TSHA2_512.Clone(): IHash;
+var
+  HashInstance: TSHA2_512;
+begin
+  HashInstance := TSHA2_512.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TSHA2_512.Create;
 constructor TSHA2_512.Create;
 begin
 begin
   Inherited Create(64);
   Inherited Create(64);

+ 1 - 1
src/libraries/hashlib4pascal/HlpSHA2_512Base.pas

@@ -1296,7 +1296,7 @@ begin
   Fm_state[6] := Fm_state[6] + g;
   Fm_state[6] := Fm_state[6] + g;
   Fm_state[7] := Fm_state[7] + h;
   Fm_state[7] := Fm_state[7] + h;
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt64(0));
 
 
 end;
 end;
 
 

+ 16 - 0
src/libraries/hashlib4pascal/HlpSHA2_512_224.pas

@@ -11,7 +11,10 @@ uses
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
+  HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
+  HlpIHash,
   HlpSHA2_512Base,
   HlpSHA2_512Base,
   HlpConverters;
   HlpConverters;
 
 
@@ -24,6 +27,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -31,6 +35,18 @@ implementation
 
 
 { TSHA2_512_224 }
 { TSHA2_512_224 }
 
 
+function TSHA2_512_224.Clone(): IHash;
+var
+  HashInstance: TSHA2_512_224;
+begin
+  HashInstance := TSHA2_512_224.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TSHA2_512_224.Create;
 constructor TSHA2_512_224.Create;
 begin
 begin
   Inherited Create(28);
   Inherited Create(28);

+ 16 - 0
src/libraries/hashlib4pascal/HlpSHA2_512_256.pas

@@ -11,7 +11,10 @@ uses
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
+  HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
+  HlpIHash,
   HlpSHA2_512Base,
   HlpSHA2_512Base,
   HlpConverters;
   HlpConverters;
 
 
@@ -24,6 +27,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -31,6 +35,18 @@ implementation
 
 
 { TSHA2_512_256 }
 { TSHA2_512_256 }
 
 
+function TSHA2_512_256.Clone(): IHash;
+var
+  HashInstance: TSHA2_512_256;
+begin
+  HashInstance := TSHA2_512_256.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TSHA2_512_256.Create;
 constructor TSHA2_512_256.Create;
 begin
 begin
   Inherited Create(32);
   Inherited Create(32);

+ 56 - 5
src/libraries/hashlib4pascal/HlpSHA3.pas

@@ -12,8 +12,10 @@ uses
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpHashBuffer,
   HlpHashBuffer,
   HlpBitConverter,
   HlpBitConverter,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpIHashInfo,
   HlpIHashInfo,
+  HlpIHash,
   HlpHashCryptoNotBuildIn,
   HlpHashCryptoNotBuildIn,
   HlpConverters,
   HlpConverters,
   HlpHashSize,
   HlpHashSize,
@@ -22,11 +24,8 @@ uses
 type
 type
   TSHA3 = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
   TSHA3 = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
 
 
-  strict private
-    Fm_state: THashLibUInt64Array;
-
   strict protected
   strict protected
-
+    Fm_state: THashLibUInt64Array;
     FHashSize, FBlockSize: Int32;
     FHashSize, FBlockSize: Int32;
 
 
     (*
     (*
@@ -65,6 +64,7 @@ type
   public
   public
 
 
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
   end;
   end;
 
 
 type
 type
@@ -74,6 +74,7 @@ type
   public
   public
 
 
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
   end;
   end;
 
 
 type
 type
@@ -83,6 +84,7 @@ type
   public
   public
 
 
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
   end;
   end;
 
 
 type
 type
@@ -92,6 +94,7 @@ type
   public
   public
 
 
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
@@ -2780,11 +2783,23 @@ begin
   Fm_state[23] := Aso;
   Fm_state[23] := Aso;
   Fm_state[24] := Asu;
   Fm_state[24] := Asu;
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt64(0));
 end;
 end;
 
 
 { TSHA3_224 }
 { TSHA3_224 }
 
 
+function TSHA3_224.Clone(): IHash;
+var
+  HashInstance: TSHA3_224;
+begin
+  HashInstance := TSHA3_224.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TSHA3_224.Create;
 constructor TSHA3_224.Create;
 begin
 begin
   Inherited Create(THashSize.hsHashSize224);
   Inherited Create(THashSize.hsHashSize224);
@@ -2792,6 +2807,18 @@ end;
 
 
 { TSHA3_256 }
 { TSHA3_256 }
 
 
+function TSHA3_256.Clone(): IHash;
+var
+  HashInstance: TSHA3_256;
+begin
+  HashInstance := TSHA3_256.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TSHA3_256.Create;
 constructor TSHA3_256.Create;
 begin
 begin
   Inherited Create(THashSize.hsHashSize256);
   Inherited Create(THashSize.hsHashSize256);
@@ -2799,6 +2826,18 @@ end;
 
 
 { TSHA3_384 }
 { TSHA3_384 }
 
 
+function TSHA3_384.Clone(): IHash;
+var
+  HashInstance: TSHA3_384;
+begin
+  HashInstance := TSHA3_384.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TSHA3_384.Create;
 constructor TSHA3_384.Create;
 begin
 begin
   Inherited Create(THashSize.hsHashSize384);
   Inherited Create(THashSize.hsHashSize384);
@@ -2806,6 +2845,18 @@ end;
 
 
 { TSHA3_512 }
 { TSHA3_512 }
 
 
+function TSHA3_512.Clone(): IHash;
+var
+  HashInstance: TSHA3_512;
+begin
+  HashInstance := TSHA3_512.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TSHA3_512.Create;
 constructor TSHA3_512.Create;
 begin
 begin
   Inherited Create(THashSize.hsHashSize512);
   Inherited Create(THashSize.hsHashSize512);

+ 12 - 0
src/libraries/hashlib4pascal/HlpShiftAndXor.pas

@@ -7,6 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult;
   HlpIHashResult;
@@ -23,12 +24,23 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
   end;
   end;
 
 
 implementation
 implementation
 
 
 { TShiftAndXor }
 { TShiftAndXor }
 
 
+function TShiftAndXor.Clone(): IHash;
+var
+  HashInstance: TShiftAndXor;
+begin
+  HashInstance := TShiftAndXor.Create();
+  HashInstance.Fm_hash := Fm_hash;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TShiftAndXor.Create;
 constructor TShiftAndXor.Create;
 begin
 begin
   Inherited Create(4, 1);
   Inherited Create(4, 1);

+ 28 - 8
src/libraries/hashlib4pascal/HlpSipHash.pas

@@ -13,10 +13,8 @@ uses
   HlpConverters,
   HlpConverters,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpNullable,
   HlpNullable,
-{$IFDEF DELPHI}
-  HlpBitConverter,
-{$ENDIF DELPHI}
   HlpHash,
   HlpHash,
+  HlpIHash,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult,
   HlpIHashResult,
   HlpBits;
   HlpBits;
@@ -29,12 +27,7 @@ type
 
 
   strict private
   strict private
 
 
-    Fm_v0, Fm_v1, Fm_v2, Fm_v3, Fm_key0, Fm_key1, Fm_total_length: UInt64;
-    F_cr, F_fr, Fm_idx: Int32;
-    Fm_buf: THashLibByteArray;
-
 {$REGION 'Consts'}
 {$REGION 'Consts'}
-
   const
   const
     V0 = UInt64($736F6D6570736575);
     V0 = UInt64($736F6D6570736575);
     V1 = UInt64($646F72616E646F6D);
     V1 = UInt64($646F72616E646F6D);
@@ -54,6 +47,12 @@ type
     function GetKey: THashLibByteArray;
     function GetKey: THashLibByteArray;
     procedure SetKey(const value: THashLibByteArray);
     procedure SetKey(const value: THashLibByteArray);
 
 
+  strict protected
+
+    Fm_v0, Fm_v1, Fm_v2, Fm_v3, Fm_key0, Fm_key1, Fm_total_length: UInt64;
+    F_cr, F_fr, Fm_idx: Int32;
+    Fm_buf: THashLibByteArray;
+
   public
   public
     constructor Create(a_compression_rounds: Int32 = 2;
     constructor Create(a_compression_rounds: Int32 = 2;
       a_finalization_rounds: Int32 = 4);
       a_finalization_rounds: Int32 = 4);
@@ -75,6 +74,7 @@ type
   public
   public
 
 
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -82,6 +82,26 @@ implementation
 
 
 { TSipHash2_4 }
 { TSipHash2_4 }
 
 
+function TSipHash2_4.Clone(): IHash;
+var
+  HashInstance: TSipHash2_4;
+begin
+  HashInstance := TSipHash2_4.Create();
+  HashInstance.Fm_v0 := Fm_v0;
+  HashInstance.Fm_v1 := Fm_v1;
+  HashInstance.Fm_v2 := Fm_v2;
+  HashInstance.Fm_v3 := Fm_v3;
+  HashInstance.Fm_key0 := Fm_key0;
+  HashInstance.Fm_key1 := Fm_key1;
+  HashInstance.Fm_total_length := Fm_total_length;
+  HashInstance.F_cr := F_cr;
+  HashInstance.F_fr := F_fr;
+  HashInstance.Fm_idx := Fm_idx;
+  HashInstance.Fm_buf := System.Copy(Fm_buf);
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TSipHash2_4.Create;
 constructor TSipHash2_4.Create;
 begin
 begin
   Inherited Create(2, 4);
   Inherited Create(2, 4);

+ 49 - 7
src/libraries/hashlib4pascal/HlpSnefru.pas

@@ -5,17 +5,21 @@ unit HlpSnefru;
 interface
 interface
 
 
 uses
 uses
-{$IFDEF DELPHI2010}
-  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
-{$ENDIF DELPHI2010}
+{$IFDEF HAS_UNITSCOPE}
+  System.SysUtils,
+{$ELSE}
+  SysUtils,
+{$ENDIF HAS_UNITSCOPE}
   HlpHashLibTypes,
   HlpHashLibTypes,
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
+  HlpHash,
   HlpHashBuffer,
   HlpHashBuffer,
   HlpBitConverter,
   HlpBitConverter,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpBits,
   HlpBits,
   HlpHashSize,
   HlpHashSize,
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashCryptoNotBuildIn;
   HlpHashCryptoNotBuildIn;
 
 
@@ -24,6 +28,7 @@ resourcestring
     'Snefru Security Level Cannot be Less than 1. Standard Level is 8';
     'Snefru Security Level Cannot be Less than 1. Standard Level is 8';
   SInvalidSnefruHashSize =
   SInvalidSnefruHashSize =
     'Snefru HashSize Must be Either 128 bit(16 byte) or 256 bit(32 byte)';
     'Snefru HashSize Must be Either 128 bit(16 byte) or 256 bit(32 byte)';
+  SInvalidHashSize = 'Specified HashSize Is Invalid or UnSupported "%d"';
 
 
 type
 type
 
 
@@ -43,7 +48,10 @@ type
 
 
     class constructor Snefru();
     class constructor Snefru();
 
 
+    function GetHashSize(AHashSize: Int32): THashSize; inline;
+
   strict protected
   strict protected
+    function GetName: String; override;
     function GetResult(): THashLibByteArray; override;
     function GetResult(): THashLibByteArray; override;
     procedure Finish(); override;
     procedure Finish(); override;
     procedure TransformBlock(a_data: PByte; a_data_length: Int32;
     procedure TransformBlock(a_data: PByte; a_data_length: Int32;
@@ -58,6 +66,7 @@ type
     /// <returns></returns>
     /// <returns></returns>
     constructor Create(a_security_level: Int32; a_hash_size: THashSize);
     constructor Create(a_security_level: Int32; a_hash_size: THashSize);
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -65,6 +74,33 @@ implementation
 
 
 { TSnefru }
 { TSnefru }
 
 
+function TSnefru.GetHashSize(AHashSize: Int32): THashSize;
+begin
+  case AHashSize of
+    16:
+      Result := THashSize.hsHashSize128;
+    32:
+      Result := THashSize.hsHashSize256
+  else
+    begin
+      raise EArgumentInvalidHashLibException.CreateResFmt(@SInvalidHashSize,
+        [AHashSize]);
+    end;
+  end;
+end;
+
+function TSnefru.Clone(): IHash;
+var
+  HashInstance: TSnefru;
+begin
+  HashInstance := TSnefru.Create(Fm_security_level, GetHashSize(FHashSize));
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
+end;
+
 constructor TSnefru.Create(a_security_level: Int32; a_hash_size: THashSize);
 constructor TSnefru.Create(a_security_level: Int32; a_hash_size: THashSize);
 begin
 begin
 
 
@@ -100,11 +136,17 @@ begin
 
 
 end;
 end;
 
 
+function TSnefru.GetName: String;
+begin
+  Result := Format('%s_%u_%u', [Self.ClassName, Fm_security_level,
+    Self.HashSize * 8]);
+end;
+
 function TSnefru.GetResult: THashLibByteArray;
 function TSnefru.GetResult: THashLibByteArray;
 begin
 begin
-  System.SetLength(result, System.Length(Fm_state) * System.SizeOf(UInt32));
-  TConverters.be32_copy(PCardinal(Fm_state), 0, PByte(result), 0,
-    System.Length(result));
+  System.SetLength(Result, System.Length(Fm_state) * System.SizeOf(UInt32));
+  TConverters.be32_copy(PCardinal(Fm_state), 0, PByte(Result), 0,
+    System.Length(Result));
 end;
 end;
 
 
 procedure TSnefru.Initialize;
 procedure TSnefru.Initialize;
@@ -206,7 +248,7 @@ begin
     Fm_state[7] := Fm_state[7] xor work[8];
     Fm_state[7] := Fm_state[7] xor work[8];
   end;
   end;
 
 
-  System.FillChar(work, System.SizeOf(work), 0);
+  System.FillChar(work, System.SizeOf(work), UInt32(0));
 
 
 end;
 end;
 
 

+ 18 - 2
src/libraries/hashlib4pascal/HlpSuperFast.pas

@@ -6,6 +6,10 @@ interface
 
 
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
+{$IFDEF DELPHI}
+  HlpHash,
+{$ENDIF DELPHI}
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult,
   HlpIHashResult,
@@ -17,10 +21,11 @@ type
     ITransformBlock)
     ITransformBlock)
 
 
   strict protected
   strict protected
-    function ComputeAggregatedBytes(a_data: THashLibByteArray)
+    function ComputeAggregatedBytes(const a_data: THashLibByteArray)
       : IHashResult; override;
       : IHashResult; override;
   public
   public
     constructor Create();
     constructor Create();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -33,7 +38,18 @@ begin
   Inherited Create(4, 4);
   Inherited Create(4, 4);
 end;
 end;
 
 
-function TSuperFast.ComputeAggregatedBytes(a_data: THashLibByteArray)
+function TSuperFast.Clone(): IHash;
+var
+  HashInstance: TSuperFast;
+begin
+  HashInstance := TSuperFast.Create();
+  FBuffer.Position := 0;
+  HashInstance.FBuffer.CopyFrom(FBuffer, FBuffer.Size);
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
+function TSuperFast.ComputeAggregatedBytes(const a_data: THashLibByteArray)
   : IHashResult;
   : IHashResult;
 var
 var
   hash, tmp, u1: UInt32;
   hash, tmp, u1: UInt32;

+ 93 - 10
src/libraries/hashlib4pascal/HlpTiger.pas

@@ -5,32 +5,34 @@ unit HlpTiger;
 interface
 interface
 
 
 uses
 uses
-{$IFDEF DELPHI2010}
-  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
-{$ENDIF DELPHI2010}
+{$IFDEF HAS_UNITSCOPE}
+  System.SysUtils,
+{$ELSE}
+  SysUtils,
+{$ENDIF HAS_UNITSCOPE}
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
   HlpHashBuffer,
   HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpConverters,
   HlpConverters,
   HlpHashRounds,
   HlpHashRounds,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashCryptoNotBuildIn;
   HlpHashCryptoNotBuildIn;
 
 
 resourcestring
 resourcestring
   SInvalidTigerHashSize =
   SInvalidTigerHashSize =
     'Tiger HashSize Must be Either 128 bit(16 byte), 160 bit(20 byte) or 192 bit(24 byte)';
     'Tiger HashSize Must be Either 128 bit(16 byte), 160 bit(20 byte) or 192 bit(24 byte)';
+  SInvalidHashRound = 'Specified HashRound Is Invalid or UnSupported "%d"';
 
 
 type
 type
   TTiger = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
   TTiger = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
 
 
   strict private
   strict private
 
 
-    Fm_rounds: Int32;
-
 {$REGION 'Consts'}
 {$REGION 'Consts'}
-
   const
   const
 
 
     C1 = UInt64($A5A5A5A5A5A5A5A5);
     C1 = UInt64($A5A5A5A5A5A5A5A5);
@@ -558,15 +560,19 @@ type
 
 
 {$ENDREGION}
 {$ENDREGION}
   strict protected
   strict protected
+    Fm_rounds: Int32;
     Fm_hash: THashLibUInt64Array;
     Fm_hash: THashLibUInt64Array;
 
 
     constructor Create(a_hash_size: Int32; a_rounds: THashRounds);
     constructor Create(a_hash_size: Int32; a_rounds: THashRounds);
 
 
+    function GetName: String; override;
     function GetResult(): THashLibByteArray; override;
     function GetResult(): THashLibByteArray; override;
     procedure Finish(); override;
     procedure Finish(); override;
     procedure TransformBlock(a_data: PByte; a_data_length: Int32;
     procedure TransformBlock(a_data: PByte; a_data_length: Int32;
       a_index: Int32); override;
       a_index: Int32); override;
 
 
+    function GetHashRound(AHashRound: Int32): THashRounds; inline;
+
   public
   public
     procedure Initialize(); override;
     procedure Initialize(); override;
 
 
@@ -578,6 +584,7 @@ type
 
 
   public
   public
     constructor Create(a_hash_size: Int32; a_rounds: THashRounds);
     constructor Create(a_hash_size: Int32; a_rounds: THashRounds);
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -589,6 +596,7 @@ type
     constructor CreateRound3();
     constructor CreateRound3();
     constructor CreateRound4();
     constructor CreateRound4();
     constructor CreateRound5();
     constructor CreateRound5();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -600,6 +608,7 @@ type
     constructor CreateRound3();
     constructor CreateRound3();
     constructor CreateRound4();
     constructor CreateRound4();
     constructor CreateRound5();
     constructor CreateRound5();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -610,6 +619,7 @@ type
     constructor CreateRound3();
     constructor CreateRound3();
     constructor CreateRound4();
     constructor CreateRound4();
     constructor CreateRound5();
     constructor CreateRound5();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -617,6 +627,25 @@ implementation
 
 
 { TTiger }
 { TTiger }
 
 
+function TTiger.GetHashRound(AHashRound: Int32): THashRounds;
+begin
+  case AHashRound of
+    3:
+      Result := THashRounds.hrRounds3;
+    4:
+      Result := THashRounds.hrRounds4;
+    5:
+      Result := THashRounds.hrRounds5;
+    8:
+      Result := THashRounds.hrRounds8
+  else
+    begin
+      raise EArgumentInvalidHashLibException.CreateResFmt(@SInvalidHashRound,
+        [AHashRound]);
+    end;
+  end;
+end;
+
 constructor TTiger.Create(a_hash_size: Int32; a_rounds: THashRounds);
 constructor TTiger.Create(a_hash_size: Int32; a_rounds: THashRounds);
 begin
 begin
   Inherited Create(a_hash_size, 64);
   Inherited Create(a_hash_size, 64);
@@ -650,11 +679,17 @@ begin
 
 
 end;
 end;
 
 
+function TTiger.GetName: String;
+begin
+  Result := Format('%s_%u_%u', [Self.ClassParent.ClassName, Fm_rounds,
+    Self.HashSize * 8]);
+end;
+
 function TTiger.GetResult: THashLibByteArray;
 function TTiger.GetResult: THashLibByteArray;
 begin
 begin
-  System.SetLength(result, HashSize);
-  TConverters.le64_copy(PUInt64(Fm_hash), 0, PByte(result), 0,
-    System.Length(result));
+  System.SetLength(Result, HashSize);
+  TConverters.le64_copy(PUInt64(Fm_hash), 0, PByte(Result), 0,
+    System.Length(Result));
 end;
 end;
 
 
 procedure TTiger.Initialize;
 procedure TTiger.Initialize;
@@ -973,12 +1008,24 @@ begin
   Fm_hash[1] := b - Fm_hash[1];
   Fm_hash[1] := b - Fm_hash[1];
   Fm_hash[2] := Fm_hash[2] + c;
   Fm_hash[2] := Fm_hash[2] + c;
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt64(0));
 
 
 end;
 end;
 
 
 { TTiger_128 }
 { TTiger_128 }
 
 
+function TTiger_128.Clone(): IHash;
+var
+  HashInstance: TTiger_128;
+begin
+  HashInstance := TTiger_128.Create(HashSize, GetHashRound(Fm_rounds));
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
+end;
+
 constructor TTiger_128.CreateRound3;
 constructor TTiger_128.CreateRound3;
 begin
 begin
   Inherited Create(16, THashRounds.hrRounds3);
   Inherited Create(16, THashRounds.hrRounds3);
@@ -996,6 +1043,18 @@ end;
 
 
 { TTiger_160 }
 { TTiger_160 }
 
 
+function TTiger_160.Clone(): IHash;
+var
+  HashInstance: TTiger_160;
+begin
+  HashInstance := TTiger_160.Create(HashSize, GetHashRound(Fm_rounds));
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
+end;
+
 constructor TTiger_160.CreateRound3;
 constructor TTiger_160.CreateRound3;
 begin
 begin
   Inherited Create(20, THashRounds.hrRounds3);
   Inherited Create(20, THashRounds.hrRounds3);
@@ -1013,6 +1072,18 @@ end;
 
 
 { TTiger_192 }
 { TTiger_192 }
 
 
+function TTiger_192.Clone(): IHash;
+var
+  HashInstance: TTiger_192;
+begin
+  HashInstance := TTiger_192.Create(HashSize, GetHashRound(Fm_rounds));
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
+end;
+
 constructor TTiger_192.CreateRound3;
 constructor TTiger_192.CreateRound3;
 begin
 begin
   Inherited Create(24, THashRounds.hrRounds3);
   Inherited Create(24, THashRounds.hrRounds3);
@@ -1030,6 +1101,18 @@ end;
 
 
 { TTiger_Base }
 { TTiger_Base }
 
 
+function TTiger_Base.Clone(): IHash;
+var
+  HashInstance: TTiger_Base;
+begin
+  HashInstance := TTiger_Base.Create(HashSize, GetHashRound(Fm_rounds));
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
+end;
+
 constructor TTiger_Base.Create(a_hash_size: Int32; a_rounds: THashRounds);
 constructor TTiger_Base.Create(a_hash_size: Int32; a_rounds: THashRounds);
 begin
 begin
   Inherited Create(a_hash_size, a_rounds);
   Inherited Create(a_hash_size, a_rounds);

+ 94 - 11
src/libraries/hashlib4pascal/HlpTiger2.pas

@@ -5,32 +5,34 @@ unit HlpTiger2;
 interface
 interface
 
 
 uses
 uses
-{$IFDEF DELPHI2010}
-  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
-{$ENDIF DELPHI2010}
-  HlpHashLibTypes,
+{$IFDEF HAS_UNITSCOPE}
+  System.SysUtils,
+{$ELSE}
+  SysUtils,
+{$ENDIF HAS_UNITSCOPE}
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
   HlpHashBuffer,
   HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
+  HlpHashLibTypes,
   HlpConverters,
   HlpConverters,
   HlpHashRounds,
   HlpHashRounds,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashCryptoNotBuildIn;
   HlpHashCryptoNotBuildIn;
 
 
 resourcestring
 resourcestring
   SInvalidTiger2HashSize =
   SInvalidTiger2HashSize =
     'Tiger2 HashSize Must be Either 128 bit(16 byte), 160 bit(20 byte) or 192 bit(24 byte)';
     'Tiger2 HashSize Must be Either 128 bit(16 byte), 160 bit(20 byte) or 192 bit(24 byte)';
+  SInvalidHashRound = 'Specified HashRound Is Invalid or UnSupported "%d"';
 
 
 type
 type
   TTiger2 = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
   TTiger2 = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
 
 
   strict private
   strict private
 
 
-    Fm_rounds: Int32;
-
 {$REGION 'Consts'}
 {$REGION 'Consts'}
-
   const
   const
 
 
     C1 = UInt64($A5A5A5A5A5A5A5A5);
     C1 = UInt64($A5A5A5A5A5A5A5A5);
@@ -558,15 +560,19 @@ type
 
 
 {$ENDREGION}
 {$ENDREGION}
   strict protected
   strict protected
+    Fm_rounds: Int32;
     Fm_hash: THashLibUInt64Array;
     Fm_hash: THashLibUInt64Array;
 
 
     constructor Create(a_hash_size: Int32; a_rounds: THashRounds);
     constructor Create(a_hash_size: Int32; a_rounds: THashRounds);
 
 
+    function GetName: String; override;
     function GetResult(): THashLibByteArray; override;
     function GetResult(): THashLibByteArray; override;
     procedure Finish(); override;
     procedure Finish(); override;
     procedure TransformBlock(a_data: PByte; a_data_length: Int32;
     procedure TransformBlock(a_data: PByte; a_data_length: Int32;
       a_index: Int32); override;
       a_index: Int32); override;
 
 
+    function GetHashRound(AHashRound: Int32): THashRounds; inline;
+
   public
   public
     procedure Initialize(); override;
     procedure Initialize(); override;
 
 
@@ -578,6 +584,7 @@ type
 
 
   public
   public
     constructor Create(a_hash_size: Int32; a_rounds: THashRounds);
     constructor Create(a_hash_size: Int32; a_rounds: THashRounds);
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -589,6 +596,7 @@ type
     constructor CreateRound3();
     constructor CreateRound3();
     constructor CreateRound4();
     constructor CreateRound4();
     constructor CreateRound5();
     constructor CreateRound5();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -600,6 +608,7 @@ type
     constructor CreateRound3();
     constructor CreateRound3();
     constructor CreateRound4();
     constructor CreateRound4();
     constructor CreateRound5();
     constructor CreateRound5();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -610,6 +619,7 @@ type
     constructor CreateRound3();
     constructor CreateRound3();
     constructor CreateRound4();
     constructor CreateRound4();
     constructor CreateRound5();
     constructor CreateRound5();
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -617,6 +627,25 @@ implementation
 
 
 { TTiger2 }
 { TTiger2 }
 
 
+function TTiger2.GetHashRound(AHashRound: Int32): THashRounds;
+begin
+  case AHashRound of
+    3:
+      Result := THashRounds.hrRounds3;
+    4:
+      Result := THashRounds.hrRounds4;
+    5:
+      Result := THashRounds.hrRounds5;
+    8:
+      Result := THashRounds.hrRounds8
+  else
+    begin
+      raise EArgumentInvalidHashLibException.CreateResFmt(@SInvalidHashRound,
+        [AHashRound]);
+    end;
+  end;
+end;
+
 constructor TTiger2.Create(a_hash_size: Int32; a_rounds: THashRounds);
 constructor TTiger2.Create(a_hash_size: Int32; a_rounds: THashRounds);
 begin
 begin
   Inherited Create(a_hash_size, 64);
   Inherited Create(a_hash_size, 64);
@@ -650,11 +679,17 @@ begin
 
 
 end;
 end;
 
 
+function TTiger2.GetName: String;
+begin
+  Result := Format('%s_%u_%u', [Self.ClassParent.ClassName, Fm_rounds,
+    Self.HashSize * 8]);
+end;
+
 function TTiger2.GetResult: THashLibByteArray;
 function TTiger2.GetResult: THashLibByteArray;
 begin
 begin
-  System.SetLength(result, HashSize);
-  TConverters.le64_copy(PUInt64(Fm_hash), 0, PByte(result), 0,
-    System.Length(result));
+  System.SetLength(Result, HashSize);
+  TConverters.le64_copy(PUInt64(Fm_hash), 0, PByte(Result), 0,
+    System.Length(Result));
 end;
 end;
 
 
 procedure TTiger2.Initialize;
 procedure TTiger2.Initialize;
@@ -973,12 +1008,24 @@ begin
   Fm_hash[1] := b - Fm_hash[1];
   Fm_hash[1] := b - Fm_hash[1];
   Fm_hash[2] := Fm_hash[2] + c;
   Fm_hash[2] := Fm_hash[2] + c;
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt64(0));
 
 
 end;
 end;
 
 
 { TTiger2_128 }
 { TTiger2_128 }
 
 
+function TTiger2_128.Clone(): IHash;
+var
+  HashInstance: TTiger2_128;
+begin
+  HashInstance := TTiger2_128.Create(HashSize, GetHashRound(Fm_rounds));
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
+end;
+
 constructor TTiger2_128.CreateRound3;
 constructor TTiger2_128.CreateRound3;
 begin
 begin
   Inherited Create(16, THashRounds.hrRounds3);
   Inherited Create(16, THashRounds.hrRounds3);
@@ -996,6 +1043,18 @@ end;
 
 
 { TTiger2_160 }
 { TTiger2_160 }
 
 
+function TTiger2_160.Clone(): IHash;
+var
+  HashInstance: TTiger2_160;
+begin
+  HashInstance := TTiger2_160.Create(HashSize, GetHashRound(Fm_rounds));
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
+end;
+
 constructor TTiger2_160.CreateRound3;
 constructor TTiger2_160.CreateRound3;
 begin
 begin
   Inherited Create(20, THashRounds.hrRounds3);
   Inherited Create(20, THashRounds.hrRounds3);
@@ -1013,6 +1072,18 @@ end;
 
 
 { TTiger2_192 }
 { TTiger2_192 }
 
 
+function TTiger2_192.Clone(): IHash;
+var
+  HashInstance: TTiger2_192;
+begin
+  HashInstance := TTiger2_192.Create(HashSize, GetHashRound(Fm_rounds));
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
+end;
+
 constructor TTiger2_192.CreateRound3;
 constructor TTiger2_192.CreateRound3;
 begin
 begin
   Inherited Create(24, THashRounds.hrRounds3);
   Inherited Create(24, THashRounds.hrRounds3);
@@ -1030,6 +1101,18 @@ end;
 
 
 { TTiger2_Base }
 { TTiger2_Base }
 
 
+function TTiger2_Base.Clone(): IHash;
+var
+  HashInstance: TTiger2_Base;
+begin
+  HashInstance := TTiger2_Base.Create(HashSize, GetHashRound(Fm_rounds));
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
+end;
+
 constructor TTiger2_Base.Create(a_hash_size: Int32; a_rounds: THashRounds);
 constructor TTiger2_Base.Create(a_hash_size: Int32; a_rounds: THashRounds);
 begin
 begin
   Inherited Create(a_hash_size, a_rounds);
   Inherited Create(a_hash_size, a_rounds);

+ 31 - 16
src/libraries/hashlib4pascal/HlpWhirlPool.pas

@@ -12,8 +12,10 @@ uses
 {$IFDEF DELPHI}
 {$IFDEF DELPHI}
   HlpBitConverter,
   HlpBitConverter,
   HlpHashBuffer,
   HlpHashBuffer,
+  HlpHash,
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
   HlpConverters,
   HlpConverters,
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashCryptoNotBuildIn;
   HlpHashCryptoNotBuildIn;
 
 
@@ -58,9 +60,9 @@ type
 {$ENDREGION}
 {$ENDREGION}
     class constructor WhirlPool;
     class constructor WhirlPool;
 
 
-    class function packIntoUInt64(b7, b6, b5, b4, b3, b2, b1, b0: UInt32)
+    class function PackIntoUInt64(b7, b6, b5, b4, b3, b2, b1, b0: UInt32)
       : UInt64; static; inline;
       : UInt64; static; inline;
-    class function maskWithReductionPolynomial(input: UInt32): UInt32;
+    class function MaskWithReductionPolynomial(input: UInt32): UInt32;
       static; inline;
       static; inline;
 
 
   strict protected
   strict protected
@@ -72,6 +74,7 @@ type
   public
   public
     constructor Create();
     constructor Create();
     procedure Initialize(); override;
     procedure Initialize(); override;
+    function Clone(): IHash; override;
 
 
   end;
   end;
 
 
@@ -79,6 +82,18 @@ implementation
 
 
 { TWhirlPool }
 { TWhirlPool }
 
 
+function TWhirlPool.Clone(): IHash;
+var
+  HashInstance: TWhirlPool;
+begin
+  HashInstance := TWhirlPool.Create();
+  HashInstance.Fm_hash := System.Copy(Fm_hash);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TWhirlPool.Create;
 constructor TWhirlPool.Create;
 begin
 begin
   Inherited Create(64, 64);
   Inherited Create(64, 64);
@@ -129,14 +144,14 @@ begin
   Inherited Initialize();
   Inherited Initialize();
 end;
 end;
 
 
-class function TWhirlPool.maskWithReductionPolynomial(input: UInt32): UInt32;
+class function TWhirlPool.MaskWithReductionPolynomial(input: UInt32): UInt32;
 begin
 begin
   if (input >= $100) then
   if (input >= $100) then
     input := input xor REDUCTION_POLYNOMIAL;
     input := input xor REDUCTION_POLYNOMIAL;
   result := input;
   result := input;
 end;
 end;
 
 
-class function TWhirlPool.packIntoUInt64(b7, b6, b5, b4, b3, b2, b1,
+class function TWhirlPool.PackIntoUInt64(b7, b6, b5, b4, b3, b2, b1,
   b0: UInt32): UInt64;
   b0: UInt32): UInt64;
 begin
 begin
   result := (UInt64(b7) shl 56) xor (UInt64(b6) shl 48) xor (UInt64(b5) shl 40)
   result := (UInt64(b7) shl 56) xor (UInt64(b6) shl 48) xor (UInt64(b5) shl 40)
@@ -223,7 +238,7 @@ begin
     System.Inc(i);
     System.Inc(i);
   end;
   end;
 
 
-  System.FillChar(data, System.SizeOf(data), 0);
+  System.FillChar(data, System.SizeOf(data), UInt64(0));
 
 
 end;
 end;
 
 
@@ -249,20 +264,20 @@ begin
 
 
   begin
   begin
     v1 := s_SBOX[i];
     v1 := s_SBOX[i];
-    v2 := maskWithReductionPolynomial(v1 shl 1);
-    v4 := maskWithReductionPolynomial(v2 shl 1);
+    v2 := MaskWithReductionPolynomial(v1 shl 1);
+    v4 := MaskWithReductionPolynomial(v2 shl 1);
     v5 := v4 xor v1;
     v5 := v4 xor v1;
-    v8 := maskWithReductionPolynomial(v4 shl 1);
+    v8 := MaskWithReductionPolynomial(v4 shl 1);
     v9 := v8 xor v1;
     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);
+    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);
     System.Inc(i);
   end;
   end;

+ 30 - 3
src/libraries/hashlib4pascal/HlpXXHash32.pas

@@ -7,9 +7,7 @@ interface
 uses
 uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
-{$IFDEF DELPHI}
-  HlpBitConverter,
-{$ENDIF DELPHI}
+  HlpIHash,
   HlpConverters,
   HlpConverters,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
@@ -52,6 +50,8 @@ type
       Fmemsize, Fv1, Fv2, Fv3, Fv4: UInt32;
       Fmemsize, Fv1, Fv2, Fv3, Fv4: UInt32;
       Fmemory: THashLibByteArray;
       Fmemory: THashLibByteArray;
 
 
+      function Clone(): TXXH_State; inline;
+
     end;
     end;
 
 
   strict private
   strict private
@@ -63,6 +63,7 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
     property KeyLength: TNullableInteger read GetKeyLength;
     property KeyLength: TNullableInteger read GetKeyLength;
     property Key: THashLibByteArray read GetKey write SetKey;
     property Key: THashLibByteArray read GetKey write SetKey;
 
 
@@ -70,8 +71,34 @@ type
 
 
 implementation
 implementation
 
 
+{ TXXHash32.TXXH_State }
+
+function TXXHash32.TXXH_State.Clone(): TXXH_State;
+begin
+  result := Default (TXXH_State);
+  result.Ftotal_len := Ftotal_len;
+  result.Fmemsize := Fmemsize;
+  result.Fv1 := Fv1;
+  result.Fv2 := Fv2;
+  result.Fv3 := Fv3;
+  result.Fv4 := Fv4;
+  result.Fmemory := System.Copy(Fmemory);
+end;
+
 { TXXHash32 }
 { TXXHash32 }
 
 
+function TXXHash32.Clone(): IHash;
+var
+  HashInstance: TXXHash32;
+begin
+  HashInstance := TXXHash32.Create();
+  HashInstance.Fm_key := Fm_key;
+  HashInstance.Fm_hash := Fm_hash;
+  HashInstance.F_state := F_state.Clone();
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TXXHash32.Create;
 constructor TXXHash32.Create;
 begin
 begin
   Inherited Create(4, 16);
   Inherited Create(4, 16);

+ 30 - 3
src/libraries/hashlib4pascal/HlpXXHash64.pas

@@ -8,9 +8,7 @@ uses
   HlpHashLibTypes,
   HlpHashLibTypes,
   HlpHash,
   HlpHash,
   HlpConverters,
   HlpConverters,
-{$IFDEF DELPHI}
-  HlpBitConverter,
-{$ENDIF DELPHI}
+  HlpIHash,
   HlpIHashInfo,
   HlpIHashInfo,
   HlpHashResult,
   HlpHashResult,
   HlpIHashResult,
   HlpIHashResult,
@@ -60,6 +58,8 @@ type
       Fmemsize: UInt32;
       Fmemsize: UInt32;
       Fmemory: THashLibByteArray;
       Fmemory: THashLibByteArray;
 
 
+      function Clone(): TXXH_State; inline;
+
     end;
     end;
 
 
   strict private
   strict private
@@ -71,6 +71,7 @@ type
     procedure TransformBytes(const a_data: THashLibByteArray;
     procedure TransformBytes(const a_data: THashLibByteArray;
       a_index, a_length: Int32); override;
       a_index, a_length: Int32); override;
     function TransformFinal(): IHashResult; override;
     function TransformFinal(): IHashResult; override;
+    function Clone(): IHash; override;
     property KeyLength: TNullableInteger read GetKeyLength;
     property KeyLength: TNullableInteger read GetKeyLength;
     property Key: THashLibByteArray read GetKey write SetKey;
     property Key: THashLibByteArray read GetKey write SetKey;
 
 
@@ -78,8 +79,34 @@ type
 
 
 implementation
 implementation
 
 
+{ TXXHash64.TXXH_State }
+
+function TXXHash64.TXXH_State.Clone(): TXXH_State;
+begin
+  result := Default (TXXH_State);
+  result.Ftotal_len := Ftotal_len;
+  result.Fmemsize := Fmemsize;
+  result.Fv1 := Fv1;
+  result.Fv2 := Fv2;
+  result.Fv3 := Fv3;
+  result.Fv4 := Fv4;
+  result.Fmemory := System.Copy(Fmemory);
+end;
+
 { TXXHash64 }
 { TXXHash64 }
 
 
+function TXXHash64.Clone(): IHash;
+var
+  HashInstance: TXXHash64;
+begin
+  HashInstance := TXXHash64.Create();
+  HashInstance.Fm_key := Fm_key;
+  HashInstance.Fm_hash := Fm_hash;
+  HashInstance.F_state := F_state.Clone();
+  result := HashInstance as IHash;
+  result.BufferSize := BufferSize;
+end;
+
 constructor TXXHash64.Create;
 constructor TXXHash64.Create;
 begin
 begin
   Inherited Create(8, 32);
   Inherited Create(8, 32);