diff --git a/HashLib.Benchmark/Delphi/PerformanceBenchmarkConsole.dpr b/HashLib.Benchmark/Delphi/PerformanceBenchmarkConsole.dpr
index 1d4c5744..990185ab 100644
--- a/HashLib.Benchmark/Delphi/PerformanceBenchmarkConsole.dpr
+++ b/HashLib.Benchmark/Delphi/PerformanceBenchmarkConsole.dpr
@@ -6,77 +6,32 @@ uses
Classes,
SysUtils,
uPerformanceBenchmark in '..\src\Core\uPerformanceBenchmark.pas',
- HlpCRC in '..\..\HashLib\src\Checksum\HlpCRC.pas',
- HlpICRC in '..\..\HashLib\src\Interfaces\HlpICRC.pas',
- HlpBitConverter in '..\..\HashLib\src\Utils\HlpBitConverter.pas',
- HlpGrindahl512 in '..\..\HashLib\src\Crypto\HlpGrindahl512.pas',
- HlpGrindahl256 in '..\..\HashLib\src\Crypto\HlpGrindahl256.pas',
- HlpHashFactory in '..\..\HashLib\src\Base\HlpHashFactory.pas',
- HlpCRC32Fast in '..\..\HashLib\src\Checksum\HlpCRC32Fast.pas',
- HlpCRC64 in '..\..\HashLib\src\Checksum\HlpCRC64.pas',
- HlpCRC32 in '..\..\HashLib\src\Checksum\HlpCRC32.pas',
- HlpBlake2B in '..\..\HashLib\src\Crypto\HlpBlake2B.pas',
- HlpFNV64 in '..\..\HashLib\src\Hash64\HlpFNV64.pas',
- HlpBits in '..\..\HashLib\src\Utils\HlpBits.pas',
- HlpConverters in '..\..\HashLib\src\Utils\HlpConverters.pas',
- HlpSHA3 in '..\..\HashLib\src\Crypto\HlpSHA3.pas',
- HlpIHashInfo in '..\..\HashLib\src\Interfaces\HlpIHashInfo.pas',
- HlpHashBuffer in '..\..\HashLib\src\Base\HlpHashBuffer.pas',
- HlpSnefru in '..\..\HashLib\src\Crypto\HlpSnefru.pas',
HlpHash in '..\..\HashLib\src\Base\HlpHash.pas',
- HlpXXHash32 in '..\..\HashLib\src\Hash32\HlpXXHash32.pas',
- HlpXXHash64 in '..\..\HashLib\src\Hash64\HlpXXHash64.pas',
+ HlpKDF in '..\..\HashLib\src\Base\HlpKDF.pas',
+ HlpHashBuffer in '..\..\HashLib\src\Base\HlpHashBuffer.pas',
HlpHashCryptoNotBuildIn in '..\..\HashLib\src\Base\HlpHashCryptoNotBuildIn.pas',
+ HlpHashFactory in '..\..\HashLib\src\Base\HlpHashFactory.pas',
+ HlpHashResult in '..\..\HashLib\src\Base\HlpHashResult.pas',
+ HlpHashRounds in '..\..\HashLib\src\Base\HlpHashRounds.pas',
+ HlpHashSize in '..\..\HashLib\src\Base\HlpHashSize.pas',
HlpHMACNotBuildInAdapter in '..\..\HashLib\src\Base\HlpHMACNotBuildInAdapter.pas',
- HlpPBKDF2_HMACNotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF2_HMACNotBuildInAdapter.pas',
- HlpPBKDF_Argon2NotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF_Argon2NotBuildInAdapter.pas',
- HlpArgon2TypeAndVersion in '..\..\HashLib\src\KDF\HlpArgon2TypeAndVersion.pas',
- HlpPBKDF_ScryptNotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF_ScryptNotBuildInAdapter.pas',
- HlpPanama in '..\..\HashLib\src\Crypto\HlpPanama.pas',
+ HlpMultipleTransformNonBlock in '..\..\HashLib\src\Base\HlpMultipleTransformNonBlock.pas',
HlpAdler32 in '..\..\HashLib\src\Checksum\HlpAdler32.pas',
- HlpAP in '..\..\HashLib\src\Hash32\HlpAP.pas',
- HlpBernstein in '..\..\HashLib\src\Hash32\HlpBernstein.pas',
- HlpBernstein1 in '..\..\HashLib\src\Hash32\HlpBernstein1.pas',
- HlpBKDR in '..\..\HashLib\src\Hash32\HlpBKDR.pas',
- HlpBlake2S in '..\..\HashLib\src\Crypto\HlpBlake2S.pas',
+ HlpCRC in '..\..\HashLib\src\Checksum\HlpCRC.pas',
HlpCRC16 in '..\..\HashLib\src\Checksum\HlpCRC16.pas',
- HlpDEK in '..\..\HashLib\src\Hash32\HlpDEK.pas',
- HlpDJB in '..\..\HashLib\src\Hash32\HlpDJB.pas',
- HlpELF in '..\..\HashLib\src\Hash32\HlpELF.pas',
- HlpFNV in '..\..\HashLib\src\Hash32\HlpFNV.pas',
- HlpFNV1a in '..\..\HashLib\src\Hash32\HlpFNV1a.pas',
- HlpFNV1a64 in '..\..\HashLib\src\Hash64\HlpFNV1a64.pas',
+ HlpCRC32 in '..\..\HashLib\src\Checksum\HlpCRC32.pas',
+ HlpCRC32Fast in '..\..\HashLib\src\Checksum\HlpCRC32Fast.pas',
+ HlpCRC64 in '..\..\HashLib\src\Checksum\HlpCRC64.pas',
HlpGost in '..\..\HashLib\src\Crypto\HlpGost.pas',
- HlpGOST3411_2012 in '..\..\HashLib\src\Crypto\HlpGOST3411_2012.pas',
+ HlpGrindahl256 in '..\..\HashLib\src\Crypto\HlpGrindahl256.pas',
+ HlpGrindahl512 in '..\..\HashLib\src\Crypto\HlpGrindahl512.pas',
HlpHAS160 in '..\..\HashLib\src\Crypto\HlpHAS160.pas',
- HlpHashLibTypes in '..\..\HashLib\src\Utils\HlpHashLibTypes.pas',
- HlpHashResult in '..\..\HashLib\src\Base\HlpHashResult.pas',
- HlpHashRounds in '..\..\HashLib\src\Base\HlpHashRounds.pas',
- HlpHashSize in '..\..\HashLib\src\Base\HlpHashSize.pas',
HlpHaval in '..\..\HashLib\src\Crypto\HlpHaval.pas',
- HlpBlake2BP in '..\..\HashLib\src\Crypto\HlpBlake2BP.pas',
- HlpBlake2SP in '..\..\HashLib\src\Crypto\HlpBlake2SP.pas',
- HlpBlake3 in '..\..\HashLib\src\Crypto\HlpBlake3.pas',
- HlpIHash in '..\..\HashLib\src\Interfaces\HlpIHash.pas',
- HlpIHashResult in '..\..\HashLib\src\Interfaces\HlpIHashResult.pas',
- HlpIKDF in '..\..\HashLib\src\Interfaces\HlpIKDF.pas',
- HlpJenkins3 in '..\..\HashLib\src\Hash32\HlpJenkins3.pas',
- HlpJS in '..\..\HashLib\src\Hash32\HlpJS.pas',
- HlpKDF in '..\..\HashLib\src\Base\HlpKDF.pas',
HlpMD2 in '..\..\HashLib\src\Crypto\HlpMD2.pas',
HlpMD4 in '..\..\HashLib\src\Crypto\HlpMD4.pas',
HlpMD5 in '..\..\HashLib\src\Crypto\HlpMD5.pas',
HlpMDBase in '..\..\HashLib\src\Crypto\HlpMDBase.pas',
- HlpMultipleTransformNonBlock in '..\..\HashLib\src\Base\HlpMultipleTransformNonBlock.pas',
- HlpMurmur2 in '..\..\HashLib\src\Hash32\HlpMurmur2.pas',
- HlpMurmur2_64 in '..\..\HashLib\src\Hash64\HlpMurmur2_64.pas',
- HlpMurmurHash3_x64_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x64_128.pas',
- HlpMurmurHash3_x86_32 in '..\..\HashLib\src\Hash32\HlpMurmurHash3_x86_32.pas',
- HlpMurmurHash3_x86_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x86_128.pas',
- HlpSipHash128 in '..\..\HashLib\src\Hash128\HlpSipHash128.pas',
- HlpNullDigest in '..\..\HashLib\src\NullDigest\HlpNullDigest.pas',
- HlpOneAtTime in '..\..\HashLib\src\Hash32\HlpOneAtTime.pas',
- HlpPJW in '..\..\HashLib\src\Hash32\HlpPJW.pas',
+ HlpPanama in '..\..\HashLib\src\Crypto\HlpPanama.pas',
HlpRadioGatun32 in '..\..\HashLib\src\Crypto\HlpRadioGatun32.pas',
HlpRadioGatun64 in '..\..\HashLib\src\Crypto\HlpRadioGatun64.pas',
HlpRIPEMD in '..\..\HashLib\src\Crypto\HlpRIPEMD.pas',
@@ -84,9 +39,6 @@ uses
HlpRIPEMD160 in '..\..\HashLib\src\Crypto\HlpRIPEMD160.pas',
HlpRIPEMD256 in '..\..\HashLib\src\Crypto\HlpRIPEMD256.pas',
HlpRIPEMD320 in '..\..\HashLib\src\Crypto\HlpRIPEMD320.pas',
- HlpRotating in '..\..\HashLib\src\Hash32\HlpRotating.pas',
- HlpRS in '..\..\HashLib\src\Hash32\HlpRS.pas',
- HlpSDBM in '..\..\HashLib\src\Hash32\HlpSDBM.pas',
HlpSHA0 in '..\..\HashLib\src\Crypto\HlpSHA0.pas',
HlpSHA1 in '..\..\HashLib\src\Crypto\HlpSHA1.pas',
HlpSHA2_224 in '..\..\HashLib\src\Crypto\HlpSHA2_224.pas',
@@ -97,17 +49,67 @@ uses
HlpSHA2_512_224 in '..\..\HashLib\src\Crypto\HlpSHA2_512_224.pas',
HlpSHA2_512_256 in '..\..\HashLib\src\Crypto\HlpSHA2_512_256.pas',
HlpSHA2_512Base in '..\..\HashLib\src\Crypto\HlpSHA2_512Base.pas',
- HlpShiftAndXor in '..\..\HashLib\src\Hash32\HlpShiftAndXor.pas',
- HlpSipHash in '..\..\HashLib\src\Hash64\HlpSipHash.pas',
- HlpSuperFast in '..\..\HashLib\src\Hash32\HlpSuperFast.pas',
+ HlpSHA3 in '..\..\HashLib\src\Crypto\HlpSHA3.pas',
+ HlpSnefru in '..\..\HashLib\src\Crypto\HlpSnefru.pas',
HlpTiger in '..\..\HashLib\src\Crypto\HlpTiger.pas',
HlpTiger2 in '..\..\HashLib\src\Crypto\HlpTiger2.pas',
HlpWhirlPool in '..\..\HashLib\src\Crypto\HlpWhirlPool.pas',
- HlpArrayUtils in '..\..\HashLib\src\Utils\HlpArrayUtils.pas',
- HlpBlake2SParams in '..\..\HashLib\src\Crypto\Blake2SParams\HlpBlake2SParams.pas',
+ HlpGOST3411_2012 in '..\..\HashLib\src\Crypto\HlpGOST3411_2012.pas',
+ HlpBlake2B in '..\..\HashLib\src\Crypto\HlpBlake2B.pas',
+ HlpBlake2S in '..\..\HashLib\src\Crypto\HlpBlake2S.pas',
HlpBlake2BParams in '..\..\HashLib\src\Crypto\Blake2BParams\HlpBlake2BParams.pas',
+ HlpBlake2SParams in '..\..\HashLib\src\Crypto\Blake2SParams\HlpBlake2SParams.pas',
+ HlpNullDigest in '..\..\HashLib\src\NullDigest\HlpNullDigest.pas',
+ HlpAP in '..\..\HashLib\src\Hash32\HlpAP.pas',
+ HlpBernstein in '..\..\HashLib\src\Hash32\HlpBernstein.pas',
+ HlpBernstein1 in '..\..\HashLib\src\Hash32\HlpBernstein1.pas',
+ HlpBKDR in '..\..\HashLib\src\Hash32\HlpBKDR.pas',
+ HlpDEK in '..\..\HashLib\src\Hash32\HlpDEK.pas',
+ HlpDJB in '..\..\HashLib\src\Hash32\HlpDJB.pas',
+ HlpELF in '..\..\HashLib\src\Hash32\HlpELF.pas',
+ HlpFNV in '..\..\HashLib\src\Hash32\HlpFNV.pas',
+ HlpFNV1a in '..\..\HashLib\src\Hash32\HlpFNV1a.pas',
+ HlpJenkins3 in '..\..\HashLib\src\Hash32\HlpJenkins3.pas',
+ HlpJS in '..\..\HashLib\src\Hash32\HlpJS.pas',
+ HlpMurmur2 in '..\..\HashLib\src\Hash32\HlpMurmur2.pas',
+ HlpMurmurHash3_x86_32 in '..\..\HashLib\src\Hash32\HlpMurmurHash3_x86_32.pas',
+ HlpOneAtTime in '..\..\HashLib\src\Hash32\HlpOneAtTime.pas',
+ HlpPJW in '..\..\HashLib\src\Hash32\HlpPJW.pas',
+ HlpRotating in '..\..\HashLib\src\Hash32\HlpRotating.pas',
+ HlpRS in '..\..\HashLib\src\Hash32\HlpRS.pas',
+ HlpSDBM in '..\..\HashLib\src\Hash32\HlpSDBM.pas',
+ HlpShiftAndXor in '..\..\HashLib\src\Hash32\HlpShiftAndXor.pas',
+ HlpSuperFast in '..\..\HashLib\src\Hash32\HlpSuperFast.pas',
+ HlpXXHash32 in '..\..\HashLib\src\Hash32\HlpXXHash32.pas',
+ HlpFNV1a64 in '..\..\HashLib\src\Hash64\HlpFNV1a64.pas',
+ HlpFNV64 in '..\..\HashLib\src\Hash64\HlpFNV64.pas',
+ HlpMurmur2_64 in '..\..\HashLib\src\Hash64\HlpMurmur2_64.pas',
+ HlpSipHash in '..\..\HashLib\src\Hash64\HlpSipHash.pas',
+ HlpXXHash64 in '..\..\HashLib\src\Hash64\HlpXXHash64.pas',
+ HlpXXHash3 in '..\..\HashLib\src\Hash64\HlpXXHash3.pas',
+ HlpMurmurHash3_x86_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x86_128.pas',
+ HlpMurmurHash3_x64_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x64_128.pas',
+ HlpSipHash128 in '..\..\HashLib\src\Hash128\HlpSipHash128.pas',
+ HlpXXHash128 in '..\..\HashLib\src\Hash128\HlpXXHash128.pas',
+ HlpIHash in '..\..\HashLib\src\Interfaces\HlpIHash.pas',
+ HlpIKDF in '..\..\HashLib\src\Interfaces\HlpIKDF.pas',
+ HlpICRC in '..\..\HashLib\src\Interfaces\HlpICRC.pas',
+ HlpIHashInfo in '..\..\HashLib\src\Interfaces\HlpIHashInfo.pas',
+ HlpIHashResult in '..\..\HashLib\src\Interfaces\HlpIHashResult.pas',
+ HlpIBlake2BParams in '..\..\HashLib\src\Interfaces\IBlake2BParams\HlpIBlake2BParams.pas',
HlpIBlake2SParams in '..\..\HashLib\src\Interfaces\IBlake2SParams\HlpIBlake2SParams.pas',
- HlpIBlake2BParams in '..\..\HashLib\src\Interfaces\IBlake2BParams\HlpIBlake2BParams.pas';
+ HlpBlake2BP in '..\..\HashLib\src\Crypto\HlpBlake2BP.pas',
+ HlpBlake2SP in '..\..\HashLib\src\Crypto\HlpBlake2SP.pas',
+ HlpBlake3 in '..\..\HashLib\src\Crypto\HlpBlake3.pas',
+ HlpPBKDF2_HMACNotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF2_HMACNotBuildInAdapter.pas',
+ HlpPBKDF_Argon2NotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF_Argon2NotBuildInAdapter.pas',
+ HlpArgon2TypeAndVersion in '..\..\HashLib\src\KDF\HlpArgon2TypeAndVersion.pas',
+ HlpPBKDF_ScryptNotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF_ScryptNotBuildInAdapter.pas',
+ HlpConverters in '..\..\HashLib\src\Utils\HlpConverters.pas',
+ HlpBitConverter in '..\..\HashLib\src\Utils\HlpBitConverter.pas',
+ HlpBits in '..\..\HashLib\src\Utils\HlpBits.pas',
+ HlpHashLibTypes in '..\..\HashLib\src\Utils\HlpHashLibTypes.pas',
+ HlpArrayUtils in '..\..\HashLib\src\Utils\HlpArrayUtils.pas';
var
StringList: TStringList;
diff --git a/HashLib.Benchmark/Delphi/PerformanceBenchmarkFMX.dpr b/HashLib.Benchmark/Delphi/PerformanceBenchmarkFMX.dpr
index b374140b..66026a6a 100644
--- a/HashLib.Benchmark/Delphi/PerformanceBenchmarkFMX.dpr
+++ b/HashLib.Benchmark/Delphi/PerformanceBenchmarkFMX.dpr
@@ -5,77 +5,32 @@ uses
FMX.Forms,
fmxMainForm in '..\src\Forms\FMX\fmxMainForm.pas' {MainForm},
uPerformanceBenchmark in '..\src\Core\uPerformanceBenchmark.pas',
- HlpCRC in '..\..\HashLib\src\Checksum\HlpCRC.pas',
- HlpICRC in '..\..\HashLib\src\Interfaces\HlpICRC.pas',
- HlpBitConverter in '..\..\HashLib\src\Utils\HlpBitConverter.pas',
- HlpGrindahl512 in '..\..\HashLib\src\Crypto\HlpGrindahl512.pas',
- HlpGrindahl256 in '..\..\HashLib\src\Crypto\HlpGrindahl256.pas',
- HlpHashFactory in '..\..\HashLib\src\Base\HlpHashFactory.pas',
- HlpCRC32Fast in '..\..\HashLib\src\Checksum\HlpCRC32Fast.pas',
- HlpCRC64 in '..\..\HashLib\src\Checksum\HlpCRC64.pas',
- HlpCRC32 in '..\..\HashLib\src\Checksum\HlpCRC32.pas',
- HlpBlake2B in '..\..\HashLib\src\Crypto\HlpBlake2B.pas',
- HlpFNV64 in '..\..\HashLib\src\Hash64\HlpFNV64.pas',
- HlpBits in '..\..\HashLib\src\Utils\HlpBits.pas',
- HlpConverters in '..\..\HashLib\src\Utils\HlpConverters.pas',
- HlpSHA3 in '..\..\HashLib\src\Crypto\HlpSHA3.pas',
- HlpIHashInfo in '..\..\HashLib\src\Interfaces\HlpIHashInfo.pas',
- HlpHashBuffer in '..\..\HashLib\src\Base\HlpHashBuffer.pas',
- HlpSnefru in '..\..\HashLib\src\Crypto\HlpSnefru.pas',
HlpHash in '..\..\HashLib\src\Base\HlpHash.pas',
- HlpXXHash32 in '..\..\HashLib\src\Hash32\HlpXXHash32.pas',
- HlpXXHash64 in '..\..\HashLib\src\Hash64\HlpXXHash64.pas',
+ HlpKDF in '..\..\HashLib\src\Base\HlpKDF.pas',
+ HlpHashBuffer in '..\..\HashLib\src\Base\HlpHashBuffer.pas',
HlpHashCryptoNotBuildIn in '..\..\HashLib\src\Base\HlpHashCryptoNotBuildIn.pas',
+ HlpHashFactory in '..\..\HashLib\src\Base\HlpHashFactory.pas',
+ HlpHashResult in '..\..\HashLib\src\Base\HlpHashResult.pas',
+ HlpHashRounds in '..\..\HashLib\src\Base\HlpHashRounds.pas',
+ HlpHashSize in '..\..\HashLib\src\Base\HlpHashSize.pas',
HlpHMACNotBuildInAdapter in '..\..\HashLib\src\Base\HlpHMACNotBuildInAdapter.pas',
- HlpPBKDF2_HMACNotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF2_HMACNotBuildInAdapter.pas',
- HlpPBKDF_Argon2NotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF_Argon2NotBuildInAdapter.pas',
- HlpArgon2TypeAndVersion in '..\..\HashLib\src\KDF\HlpArgon2TypeAndVersion.pas',
- HlpPBKDF_ScryptNotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF_ScryptNotBuildInAdapter.pas',
- HlpPanama in '..\..\HashLib\src\Crypto\HlpPanama.pas',
+ HlpMultipleTransformNonBlock in '..\..\HashLib\src\Base\HlpMultipleTransformNonBlock.pas',
HlpAdler32 in '..\..\HashLib\src\Checksum\HlpAdler32.pas',
- HlpAP in '..\..\HashLib\src\Hash32\HlpAP.pas',
- HlpBernstein in '..\..\HashLib\src\Hash32\HlpBernstein.pas',
- HlpBernstein1 in '..\..\HashLib\src\Hash32\HlpBernstein1.pas',
- HlpBKDR in '..\..\HashLib\src\Hash32\HlpBKDR.pas',
- HlpBlake2S in '..\..\HashLib\src\Crypto\HlpBlake2S.pas',
+ HlpCRC in '..\..\HashLib\src\Checksum\HlpCRC.pas',
HlpCRC16 in '..\..\HashLib\src\Checksum\HlpCRC16.pas',
- HlpDEK in '..\..\HashLib\src\Hash32\HlpDEK.pas',
- HlpDJB in '..\..\HashLib\src\Hash32\HlpDJB.pas',
- HlpELF in '..\..\HashLib\src\Hash32\HlpELF.pas',
- HlpFNV in '..\..\HashLib\src\Hash32\HlpFNV.pas',
- HlpFNV1a in '..\..\HashLib\src\Hash32\HlpFNV1a.pas',
- HlpFNV1a64 in '..\..\HashLib\src\Hash64\HlpFNV1a64.pas',
+ HlpCRC32 in '..\..\HashLib\src\Checksum\HlpCRC32.pas',
+ HlpCRC32Fast in '..\..\HashLib\src\Checksum\HlpCRC32Fast.pas',
+ HlpCRC64 in '..\..\HashLib\src\Checksum\HlpCRC64.pas',
HlpGost in '..\..\HashLib\src\Crypto\HlpGost.pas',
- HlpGOST3411_2012 in '..\..\HashLib\src\Crypto\HlpGOST3411_2012.pas',
+ HlpGrindahl256 in '..\..\HashLib\src\Crypto\HlpGrindahl256.pas',
+ HlpGrindahl512 in '..\..\HashLib\src\Crypto\HlpGrindahl512.pas',
HlpHAS160 in '..\..\HashLib\src\Crypto\HlpHAS160.pas',
- HlpHashLibTypes in '..\..\HashLib\src\Utils\HlpHashLibTypes.pas',
- HlpHashResult in '..\..\HashLib\src\Base\HlpHashResult.pas',
- HlpHashRounds in '..\..\HashLib\src\Base\HlpHashRounds.pas',
- HlpHashSize in '..\..\HashLib\src\Base\HlpHashSize.pas',
HlpHaval in '..\..\HashLib\src\Crypto\HlpHaval.pas',
- HlpBlake2BP in '..\..\HashLib\src\Crypto\HlpBlake2BP.pas',
- HlpBlake2SP in '..\..\HashLib\src\Crypto\HlpBlake2SP.pas',
- HlpBlake3 in '..\..\HashLib\src\Crypto\HlpBlake3.pas',
- HlpIHash in '..\..\HashLib\src\Interfaces\HlpIHash.pas',
- HlpIHashResult in '..\..\HashLib\src\Interfaces\HlpIHashResult.pas',
- HlpIKDF in '..\..\HashLib\src\Interfaces\HlpIKDF.pas',
- HlpJenkins3 in '..\..\HashLib\src\Hash32\HlpJenkins3.pas',
- HlpJS in '..\..\HashLib\src\Hash32\HlpJS.pas',
- HlpKDF in '..\..\HashLib\src\Base\HlpKDF.pas',
HlpMD2 in '..\..\HashLib\src\Crypto\HlpMD2.pas',
HlpMD4 in '..\..\HashLib\src\Crypto\HlpMD4.pas',
HlpMD5 in '..\..\HashLib\src\Crypto\HlpMD5.pas',
HlpMDBase in '..\..\HashLib\src\Crypto\HlpMDBase.pas',
- HlpMultipleTransformNonBlock in '..\..\HashLib\src\Base\HlpMultipleTransformNonBlock.pas',
- HlpMurmur2 in '..\..\HashLib\src\Hash32\HlpMurmur2.pas',
- HlpMurmur2_64 in '..\..\HashLib\src\Hash64\HlpMurmur2_64.pas',
- HlpMurmurHash3_x64_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x64_128.pas',
- HlpMurmurHash3_x86_32 in '..\..\HashLib\src\Hash32\HlpMurmurHash3_x86_32.pas',
- HlpMurmurHash3_x86_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x86_128.pas',
- HlpSipHash128 in '..\..\HashLib\src\Hash128\HlpSipHash128.pas',
- HlpNullDigest in '..\..\HashLib\src\NullDigest\HlpNullDigest.pas',
- HlpOneAtTime in '..\..\HashLib\src\Hash32\HlpOneAtTime.pas',
- HlpPJW in '..\..\HashLib\src\Hash32\HlpPJW.pas',
+ HlpPanama in '..\..\HashLib\src\Crypto\HlpPanama.pas',
HlpRadioGatun32 in '..\..\HashLib\src\Crypto\HlpRadioGatun32.pas',
HlpRadioGatun64 in '..\..\HashLib\src\Crypto\HlpRadioGatun64.pas',
HlpRIPEMD in '..\..\HashLib\src\Crypto\HlpRIPEMD.pas',
@@ -83,9 +38,6 @@ uses
HlpRIPEMD160 in '..\..\HashLib\src\Crypto\HlpRIPEMD160.pas',
HlpRIPEMD256 in '..\..\HashLib\src\Crypto\HlpRIPEMD256.pas',
HlpRIPEMD320 in '..\..\HashLib\src\Crypto\HlpRIPEMD320.pas',
- HlpRotating in '..\..\HashLib\src\Hash32\HlpRotating.pas',
- HlpRS in '..\..\HashLib\src\Hash32\HlpRS.pas',
- HlpSDBM in '..\..\HashLib\src\Hash32\HlpSDBM.pas',
HlpSHA0 in '..\..\HashLib\src\Crypto\HlpSHA0.pas',
HlpSHA1 in '..\..\HashLib\src\Crypto\HlpSHA1.pas',
HlpSHA2_224 in '..\..\HashLib\src\Crypto\HlpSHA2_224.pas',
@@ -96,17 +48,67 @@ uses
HlpSHA2_512_224 in '..\..\HashLib\src\Crypto\HlpSHA2_512_224.pas',
HlpSHA2_512_256 in '..\..\HashLib\src\Crypto\HlpSHA2_512_256.pas',
HlpSHA2_512Base in '..\..\HashLib\src\Crypto\HlpSHA2_512Base.pas',
- HlpShiftAndXor in '..\..\HashLib\src\Hash32\HlpShiftAndXor.pas',
- HlpSipHash in '..\..\HashLib\src\Hash64\HlpSipHash.pas',
- HlpSuperFast in '..\..\HashLib\src\Hash32\HlpSuperFast.pas',
+ HlpSHA3 in '..\..\HashLib\src\Crypto\HlpSHA3.pas',
+ HlpSnefru in '..\..\HashLib\src\Crypto\HlpSnefru.pas',
HlpTiger in '..\..\HashLib\src\Crypto\HlpTiger.pas',
HlpTiger2 in '..\..\HashLib\src\Crypto\HlpTiger2.pas',
HlpWhirlPool in '..\..\HashLib\src\Crypto\HlpWhirlPool.pas',
- HlpArrayUtils in '..\..\HashLib\src\Utils\HlpArrayUtils.pas',
- HlpBlake2SParams in '..\..\HashLib\src\Crypto\Blake2SParams\HlpBlake2SParams.pas',
+ HlpGOST3411_2012 in '..\..\HashLib\src\Crypto\HlpGOST3411_2012.pas',
+ HlpBlake2B in '..\..\HashLib\src\Crypto\HlpBlake2B.pas',
+ HlpBlake2S in '..\..\HashLib\src\Crypto\HlpBlake2S.pas',
HlpBlake2BParams in '..\..\HashLib\src\Crypto\Blake2BParams\HlpBlake2BParams.pas',
+ HlpBlake2SParams in '..\..\HashLib\src\Crypto\Blake2SParams\HlpBlake2SParams.pas',
+ HlpNullDigest in '..\..\HashLib\src\NullDigest\HlpNullDigest.pas',
+ HlpAP in '..\..\HashLib\src\Hash32\HlpAP.pas',
+ HlpBernstein in '..\..\HashLib\src\Hash32\HlpBernstein.pas',
+ HlpBernstein1 in '..\..\HashLib\src\Hash32\HlpBernstein1.pas',
+ HlpBKDR in '..\..\HashLib\src\Hash32\HlpBKDR.pas',
+ HlpDEK in '..\..\HashLib\src\Hash32\HlpDEK.pas',
+ HlpDJB in '..\..\HashLib\src\Hash32\HlpDJB.pas',
+ HlpELF in '..\..\HashLib\src\Hash32\HlpELF.pas',
+ HlpFNV in '..\..\HashLib\src\Hash32\HlpFNV.pas',
+ HlpFNV1a in '..\..\HashLib\src\Hash32\HlpFNV1a.pas',
+ HlpJenkins3 in '..\..\HashLib\src\Hash32\HlpJenkins3.pas',
+ HlpJS in '..\..\HashLib\src\Hash32\HlpJS.pas',
+ HlpMurmur2 in '..\..\HashLib\src\Hash32\HlpMurmur2.pas',
+ HlpMurmurHash3_x86_32 in '..\..\HashLib\src\Hash32\HlpMurmurHash3_x86_32.pas',
+ HlpOneAtTime in '..\..\HashLib\src\Hash32\HlpOneAtTime.pas',
+ HlpPJW in '..\..\HashLib\src\Hash32\HlpPJW.pas',
+ HlpRotating in '..\..\HashLib\src\Hash32\HlpRotating.pas',
+ HlpRS in '..\..\HashLib\src\Hash32\HlpRS.pas',
+ HlpSDBM in '..\..\HashLib\src\Hash32\HlpSDBM.pas',
+ HlpShiftAndXor in '..\..\HashLib\src\Hash32\HlpShiftAndXor.pas',
+ HlpSuperFast in '..\..\HashLib\src\Hash32\HlpSuperFast.pas',
+ HlpXXHash32 in '..\..\HashLib\src\Hash32\HlpXXHash32.pas',
+ HlpFNV1a64 in '..\..\HashLib\src\Hash64\HlpFNV1a64.pas',
+ HlpFNV64 in '..\..\HashLib\src\Hash64\HlpFNV64.pas',
+ HlpMurmur2_64 in '..\..\HashLib\src\Hash64\HlpMurmur2_64.pas',
+ HlpSipHash in '..\..\HashLib\src\Hash64\HlpSipHash.pas',
+ HlpXXHash64 in '..\..\HashLib\src\Hash64\HlpXXHash64.pas',
+ HlpXXHash3 in '..\..\HashLib\src\Hash64\HlpXXHash3.pas',
+ HlpMurmurHash3_x86_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x86_128.pas',
+ HlpMurmurHash3_x64_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x64_128.pas',
+ HlpSipHash128 in '..\..\HashLib\src\Hash128\HlpSipHash128.pas',
+ HlpXXHash128 in '..\..\HashLib\src\Hash128\HlpXXHash128.pas',
+ HlpIHash in '..\..\HashLib\src\Interfaces\HlpIHash.pas',
+ HlpIKDF in '..\..\HashLib\src\Interfaces\HlpIKDF.pas',
+ HlpICRC in '..\..\HashLib\src\Interfaces\HlpICRC.pas',
+ HlpIHashInfo in '..\..\HashLib\src\Interfaces\HlpIHashInfo.pas',
+ HlpIHashResult in '..\..\HashLib\src\Interfaces\HlpIHashResult.pas',
+ HlpIBlake2BParams in '..\..\HashLib\src\Interfaces\IBlake2BParams\HlpIBlake2BParams.pas',
HlpIBlake2SParams in '..\..\HashLib\src\Interfaces\IBlake2SParams\HlpIBlake2SParams.pas',
- HlpIBlake2BParams in '..\..\HashLib\src\Interfaces\IBlake2BParams\HlpIBlake2BParams.pas';
+ HlpBlake2BP in '..\..\HashLib\src\Crypto\HlpBlake2BP.pas',
+ HlpBlake2SP in '..\..\HashLib\src\Crypto\HlpBlake2SP.pas',
+ HlpBlake3 in '..\..\HashLib\src\Crypto\HlpBlake3.pas',
+ HlpPBKDF2_HMACNotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF2_HMACNotBuildInAdapter.pas',
+ HlpPBKDF_Argon2NotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF_Argon2NotBuildInAdapter.pas',
+ HlpArgon2TypeAndVersion in '..\..\HashLib\src\KDF\HlpArgon2TypeAndVersion.pas',
+ HlpPBKDF_ScryptNotBuildInAdapter in '..\..\HashLib\src\KDF\HlpPBKDF_ScryptNotBuildInAdapter.pas',
+ HlpConverters in '..\..\HashLib\src\Utils\HlpConverters.pas',
+ HlpBitConverter in '..\..\HashLib\src\Utils\HlpBitConverter.pas',
+ HlpBits in '..\..\HashLib\src\Utils\HlpBits.pas',
+ HlpHashLibTypes in '..\..\HashLib\src\Utils\HlpHashLibTypes.pas',
+ HlpArrayUtils in '..\..\HashLib\src\Utils\HlpArrayUtils.pas';
{$R *.res}
diff --git a/HashLib.Benchmark/src/Core/uPerformanceBenchmark.pas b/HashLib.Benchmark/src/Core/uPerformanceBenchmark.pas
index af2882a2..ede96475 100644
--- a/HashLib.Benchmark/src/Core/uPerformanceBenchmark.pas
+++ b/HashLib.Benchmark/src/Core/uPerformanceBenchmark.pas
@@ -128,12 +128,17 @@ class procedure TPerformanceBenchmark.DoBenchmark(var AStringList: TStringList);
AStringList.Append(Calculate(THashFactory.THash64.CreateXXHash64));
+ AStringList.Append(Calculate(THashFactory.THash64.CreateXXHash3));
+
AStringList.Append
(Calculate(THashFactory.THash128.CreateMurmurHash3_x86_128));
AStringList.Append
(Calculate(THashFactory.THash128.CreateMurmurHash3_x64_128));
+ AStringList.Append
+ (Calculate(THashFactory.THash128.CreateXXHash128));
+
AStringList.Append(Calculate(THashFactory.TCrypto.CreateMD5));
AStringList.Append(Calculate(THashFactory.TCrypto.CreateSHA1));
diff --git a/HashLib.Tests/Delphi.Tests/HashLib.Tests.dpr b/HashLib.Tests/Delphi.Tests/HashLib.Tests.dpr
index edc61084..4e61f05e 100644
--- a/HashLib.Tests/Delphi.Tests/HashLib.Tests.dpr
+++ b/HashLib.Tests/Delphi.Tests/HashLib.Tests.dpr
@@ -107,9 +107,11 @@ uses
HlpMurmur2_64 in '..\..\HashLib\src\Hash64\HlpMurmur2_64.pas',
HlpSipHash in '..\..\HashLib\src\Hash64\HlpSipHash.pas',
HlpXXHash64 in '..\..\HashLib\src\Hash64\HlpXXHash64.pas',
+ HlpXXHash3 in '..\..\HashLib\src\Hash64\HlpXXHash3.pas',
HlpMurmurHash3_x86_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x86_128.pas',
HlpMurmurHash3_x64_128 in '..\..\HashLib\src\Hash128\HlpMurmurHash3_x64_128.pas',
HlpSipHash128 in '..\..\HashLib\src\Hash128\HlpSipHash128.pas',
+ HlpXXHash128 in '..\..\HashLib\src\Hash128\HlpXXHash128.pas',
HlpIHash in '..\..\HashLib\src\Interfaces\HlpIHash.pas',
HlpIKDF in '..\..\HashLib\src\Interfaces\HlpIKDF.pas',
HlpICRC in '..\..\HashLib\src\Interfaces\HlpICRC.pas',
diff --git a/HashLib.Tests/src/Hash128Tests.pas b/HashLib.Tests/src/Hash128Tests.pas
index e096e4f8..1375c4f0 100644
--- a/HashLib.Tests/src/Hash128Tests.pas
+++ b/HashLib.Tests/src/Hash128Tests.pas
@@ -41,6 +41,15 @@ TTestSipHash128_2_4 = class(THashWithExternalKeyAlgorithmTestCase)
end;
+type
+ TTestXXHash128 = class(THashWithUInt64AsKeyAlgorithmTestCase)
+
+ protected
+ procedure SetUp; override;
+ procedure TearDown; override;
+
+ end;
+
implementation
// Hash128
@@ -102,6 +111,25 @@ procedure TTestSipHash128_2_4.TearDown;
inherited;
end;
+{ TTestXXHash128 }
+
+procedure TTestXXHash128.SetUp;
+begin
+ inherited;
+ HashInstance := THashFactory.THash128.CreateXXHash128();
+ HashOfEmptyData := '99AA06D3014798D86001C324468D497F';
+ HashOfDefaultData := 'E99DB8BBAB352CA352BAC9DD9D645426';
+ HashOfOnetoNine := '33119477EDE5DCD5E9716427681D5860';
+ HashOfABCDE := '3043C78169F25C3F97D5A48EF320EEC2';
+ HashOfDefaultDataWithMaxUInt64AsKey := '326119F2B7085D0BD48D1321CAA1B5CF';
+end;
+
+procedure TTestXXHash128.TearDown;
+begin
+ HashInstance := nil;
+ inherited;
+end;
+
initialization
// Register any test cases with the test runner
@@ -111,11 +139,13 @@ initialization
RegisterTest(TTestMurmurHash3_x86_128);
RegisterTest(TTestMurmurHash3_x64_128);
RegisterTest(TTestSipHash128_2_4);
+RegisterTest(TTestXXHash128);
{$ELSE}
// Hash128
RegisterTest(TTestMurmurHash3_x86_128.Suite);
RegisterTest(TTestMurmurHash3_x64_128.Suite);
RegisterTest(TTestSipHash128_2_4.Suite);
+RegisterTest(TTestXXHash128.Suite);
{$ENDIF FPC}
end.
diff --git a/HashLib.Tests/src/Hash64Tests.pas b/HashLib.Tests/src/Hash64Tests.pas
index f9270fed..265998ce 100644
--- a/HashLib.Tests/src/Hash64Tests.pas
+++ b/HashLib.Tests/src/Hash64Tests.pas
@@ -62,6 +62,16 @@ TTestXXHash64 = class(THashWithUInt64AsKeyAlgorithmTestCase)
end;
+type
+
+ TTestXXHash3 = class(THashWithUInt64AsKeyAlgorithmTestCase)
+
+ protected
+ procedure SetUp; override;
+ procedure TearDown; override;
+
+ end;
+
implementation
// Hash64
@@ -159,6 +169,25 @@ procedure TTestXXHash64.TearDown;
inherited;
end;
+{ TTestXXHash3 }
+
+procedure TTestXXHash3.SetUp;
+begin
+ inherited;
+ HashInstance := THashFactory.THash64.CreateXXHash3();
+ HashOfEmptyData := '2D06800538D394C2';
+ HashOfDefaultData := '73B9276A6BAC2B49';
+ HashOfOnetoNine := '72DCB18B67A17DFF';
+ HashOfABCDE := '55C65158EE9E652D';
+ HashOfDefaultDataWithMaxUInt64AsKey := '153E26503A9470AF';
+end;
+
+procedure TTestXXHash3.TearDown;
+begin
+ HashInstance := nil;
+ inherited;
+end;
+
initialization
// Register any test cases with the test runner
@@ -170,6 +199,7 @@ initialization
RegisterTest(TTestMurmur2_64);
RegisterTest(TTestSipHash2_4);
RegisterTest(TTestXXHash64);
+RegisterTest(TTestXXHash3);
{$ELSE}
// Hash64
RegisterTest(TTestFNV64.Suite);
@@ -177,6 +207,7 @@ initialization
RegisterTest(TTestMurmur2_64.Suite);
RegisterTest(TTestSipHash2_4.Suite);
RegisterTest(TTestXXHash64.Suite);
+RegisterTest(TTestXXHash3.Suite);
{$ENDIF FPC}
end.
diff --git a/HashLib/src/Base/HlpHashFactory.pas b/HashLib/src/Base/HlpHashFactory.pas
index fdf46a59..5323212b 100644
--- a/HashLib/src/Base/HlpHashFactory.pas
+++ b/HashLib/src/Base/HlpHashFactory.pas
@@ -49,9 +49,11 @@ interface
HlpSipHash,
HlpSipHash128,
HlpXXHash64,
+ HlpXXHash3,
// Hash128 Units //
HlpMurmurHash3_x86_128,
HlpMurmurHash3_x64_128,
+ HlpXXHash128,
// Crypto Units
HlpTiger,
HlpTiger2,
@@ -238,6 +240,8 @@ THash64 = class sealed(TObject)
class function CreateXXHash64(): IHashWithKey; static;
+ class function CreateXXHash3(): IHashWithKey; static;
+
end;
// ====================== THash128 ====================== //
@@ -251,6 +255,8 @@ THash128 = class sealed(TObject)
class function CreateMurmurHash3_x86_128(): IHashWithKey; static;
class function CreateMurmurHash3_x64_128(): IHashWithKey; static;
+ class function CreateXXHash128(): IHashWithKey; static;
+
end;
// ====================== TCrypto ====================== //
@@ -843,6 +849,11 @@ class function THashFactory.THash64.CreateXXHash64: IHashWithKey;
Result := TXXHash64.Create();
end;
+class function THashFactory.THash64.CreateXXHash3: IHashWithKey;
+begin
+ Result := TXXHash3.Create();
+end;
+
{ THashFactory.THash128 }
class function THashFactory.THash128.CreateMurmurHash3_x86_128: IHashWithKey;
@@ -860,6 +871,11 @@ class function THashFactory.THash128.CreateMurmurHash3_x64_128: IHashWithKey;
Result := TMurmurHash3_x64_128.Create();
end;
+class function THashFactory.THash128.CreateXXHash128: IHashWithKey;
+begin
+ Result := TXXHash128.Create();
+end;
+
{ THashFactory.TCrypto }
class function THashFactory.TCrypto.CreateGost(ASBoxType: TGostSBox): IHash;
diff --git a/HashLib/src/Hash128/HlpXXHash128.pas b/HashLib/src/Hash128/HlpXXHash128.pas
new file mode 100644
index 00000000..6b91ab2a
--- /dev/null
+++ b/HashLib/src/Hash128/HlpXXHash128.pas
@@ -0,0 +1,543 @@
+unit HlpXXHash128;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+ HlpHashLibTypes,
+ HlpHash,
+ HlpIHash,
+ HlpConverters,
+ HlpIHashInfo,
+ HlpHashResult,
+ HlpIHashResult,
+ HlpBits,
+ HlpXXHash3;
+
+resourcestring
+ SInvalidKeyLength = 'KeyLength Must Be Equal to %d';
+
+type
+
+ TXXHash128 = class sealed(THash, IHash128, IHashWithKey, ITransformBlock)
+
+ strict private
+ var
+ FKey: UInt64;
+ FHashLow, FHashHigh: UInt64;
+
+ const
+ CKEY = UInt64(0);
+
+ function GetKeyLength(): Int32;
+ function GetKey: THashLibByteArray; inline;
+ procedure SetKey(const AValue: THashLibByteArray); inline;
+
+ type
+
+ TXXH128_State = record
+
+ private
+ var
+ FAcc: TXXH3AccArray;
+ FCustomSecret: THashLibByteArray;
+ FBuffer: THashLibByteArray;
+ FBufferedSize: UInt32;
+ FNbStripesSoFar: Int32;
+ FTotalLength: UInt64;
+
+ function Clone(): TXXH128_State;
+
+ end;
+
+ strict private
+ var
+ FState: TXXH128_State;
+
+ class procedure XXH128_mix32B(var ALow, AHigh: UInt64;
+ AInput1, AInput2, ASecret: PByte; ASeed: UInt64); static;
+ class procedure XXH3_len_1to3_128b(AInput, ASecret: PByte;
+ ALen: Int32; ASeed: UInt64; out ALow, AHigh: UInt64); static;
+ class procedure XXH3_len_4to8_128b(AInput, ASecret: PByte;
+ ALen: Int32; ASeed: UInt64; out ALow, AHigh: UInt64); static;
+ class procedure XXH3_len_9to16_128b(AInput, ASecret: PByte;
+ ALen: Int32; ASeed: UInt64; out ALow, AHigh: UInt64); static;
+ class procedure XXH3_len_0to16_128b(AInput, ASecret: PByte;
+ ALen: Int32; ASeed: UInt64; out ALow, AHigh: UInt64); static;
+ class procedure XXH3_len_17to128_128b(AInput, ASecret: PByte;
+ ALen, ASecretSize: Int32; ASeed: UInt64;
+ out ALow, AHigh: UInt64); static;
+ class procedure XXH3_len_129to240_128b(AInput, ASecret: PByte;
+ ALen, ASecretSize: Int32; ASeed: UInt64;
+ out ALow, AHigh: UInt64); static;
+ class procedure XXH3_hashLong_128b_internal(AInput: PByte; ALen: Int32;
+ ASecret: PByte; ASecretSize: Int32;
+ out ALow, AHigh: UInt64); static;
+ class procedure XXH3_hashLong_128b_withSeed(AInput: PByte; ALen: Int32;
+ ASeed: UInt64; out ALow, AHigh: UInt64); static;
+ class procedure XXH3_128bits_internal(AInput: PByte; ALen: Int32;
+ ASeed: UInt64; ASecret: PByte; ASecretLen: Int32;
+ out ALow, AHigh: UInt64); static;
+
+ procedure DigestLong(var AAcc: TXXH3AccArray);
+
+ public
+ constructor Create();
+ procedure Initialize(); override;
+ procedure TransformBytes(const AData: THashLibByteArray;
+ AIndex, ALength: Int32); override;
+ function TransformFinal(): IHashResult; override;
+ function Clone(): IHash; override;
+ property KeyLength: Int32 read GetKeyLength;
+ property Key: THashLibByteArray read GetKey write SetKey;
+
+ end;
+
+implementation
+
+{ TXXHash128.TXXH128_State }
+
+function TXXHash128.TXXH128_State.Clone(): TXXH128_State;
+begin
+ Result := Default(TXXH128_State);
+ System.Move(FAcc, Result.FAcc, System.SizeOf(TXXH3AccArray));
+ Result.FCustomSecret := System.Copy(FCustomSecret);
+ Result.FBuffer := System.Copy(FBuffer);
+ Result.FBufferedSize := FBufferedSize;
+ Result.FNbStripesSoFar := FNbStripesSoFar;
+ Result.FTotalLength := FTotalLength;
+end;
+
+{ TXXHash128 }
+
+constructor TXXHash128.Create;
+begin
+ inherited Create(16, 64);
+ FKey := CKEY;
+ System.SetLength(FState.FBuffer, TXXH3Core.XXH3_INTERNALBUFFER_SIZE);
+ System.SetLength(FState.FCustomSecret, TXXH3Core.XXH3_SECRET_DEFAULT_SIZE);
+end;
+
+function TXXHash128.Clone(): IHash;
+var
+ LHashInstance: TXXHash128;
+begin
+ LHashInstance := TXXHash128.Create();
+ LHashInstance.FKey := FKey;
+ LHashInstance.FHashLow := FHashLow;
+ LHashInstance.FHashHigh := FHashHigh;
+ LHashInstance.FState := FState.Clone();
+ Result := LHashInstance;
+ Result.BufferSize := BufferSize;
+end;
+
+function TXXHash128.GetKey: THashLibByteArray;
+begin
+ Result := TConverters.ReadUInt64AsBytesLE(FKey);
+end;
+
+function TXXHash128.GetKeyLength: Int32;
+begin
+ Result := 8;
+end;
+
+procedure TXXHash128.SetKey(const AValue: THashLibByteArray);
+begin
+ if (AValue = nil) then
+ begin
+ FKey := CKEY;
+ end
+ else
+ begin
+ if System.Length(AValue) <> KeyLength then
+ begin
+ raise EArgumentHashLibException.CreateResFmt(@SInvalidKeyLength,
+ [KeyLength]);
+ end;
+ FKey := TConverters.ReadBytesAsUInt64LE(PByte(AValue), 0);
+ end;
+end;
+
+procedure TXXHash128.Initialize;
+begin
+ FHashLow := 0;
+ FHashHigh := 0;
+ System.Move(TXXH3Core.XXH3_INIT_ACC, FState.FAcc,
+ System.SizeOf(TXXH3AccArray));
+
+ if FKey <> 0 then
+ TXXH3Core.XXH3_initCustomSecret(PByte(FState.FCustomSecret), FKey)
+ else
+ System.Move(TXXH3Core.XXH3_SECRET[0], FState.FCustomSecret[0],
+ TXXH3Core.XXH3_SECRET_DEFAULT_SIZE);
+
+ FState.FTotalLength := 0;
+ FState.FBufferedSize := 0;
+ FState.FNbStripesSoFar := 0;
+end;
+
+class procedure TXXHash128.XXH128_mix32B(var ALow, AHigh: UInt64;
+ AInput1, AInput2, ASecret: PByte; ASeed: UInt64);
+begin
+ ALow := ALow + TXXH3Core.XXH3_mix16B(AInput1, ASecret, ASeed);
+ ALow := ALow xor (TConverters.ReadBytesAsUInt64LE(AInput2, 0) +
+ TConverters.ReadBytesAsUInt64LE(AInput2, 8));
+ AHigh := AHigh + TXXH3Core.XXH3_mix16B(AInput2, ASecret + 16, ASeed);
+ AHigh := AHigh xor (TConverters.ReadBytesAsUInt64LE(AInput1, 0) +
+ TConverters.ReadBytesAsUInt64LE(AInput1, 8));
+end;
+
+class procedure TXXHash128.XXH3_len_1to3_128b(AInput, ASecret: PByte;
+ ALen: Int32; ASeed: UInt64; out ALow, AHigh: UInt64);
+var
+ LC1, LC2, LC3: Byte;
+ LCombinedL, LCombinedH: UInt32;
+ LBitflipL, LBitflipH: UInt64;
+begin
+ LC1 := AInput[0];
+ LC2 := AInput[TBits.Asr32(ALen, 1)];
+ LC3 := AInput[ALen - 1];
+
+ LCombinedL := (UInt32(LC1) shl 16) or (UInt32(LC2) shl 24) or
+ (UInt32(LC3) shl 0) or (UInt32(ALen) shl 8);
+ LCombinedH := TBits.RotateLeft32(TBits.ReverseBytesUInt32(LCombinedL), 13);
+
+ LBitflipL := UInt64(TConverters.ReadBytesAsUInt32LE(ASecret, 0) xor
+ TConverters.ReadBytesAsUInt32LE(ASecret, 4)) + ASeed;
+ LBitflipH := UInt64(TConverters.ReadBytesAsUInt32LE(ASecret, 8) xor
+ TConverters.ReadBytesAsUInt32LE(ASecret, 12)) - ASeed;
+
+ ALow := TXXH3Core.XXH64_avalanche(UInt64(LCombinedL) xor LBitflipL);
+ AHigh := TXXH3Core.XXH64_avalanche(UInt64(LCombinedH) xor LBitflipH);
+end;
+
+class procedure TXXHash128.XXH3_len_4to8_128b(AInput, ASecret: PByte;
+ ALen: Int32; ASeed: UInt64; out ALow, AHigh: UInt64);
+var
+ LInputLo, LInputHi: UInt32;
+ LInput64, LBitflip, LKeyed: UInt64;
+ LMLow, LMHigh: UInt64;
+begin
+ ASeed := ASeed xor (UInt64(TBits.ReverseBytesUInt32(UInt32(ASeed))) shl 32);
+
+ LInputLo := TConverters.ReadBytesAsUInt32LE(AInput, 0);
+ LInputHi := TConverters.ReadBytesAsUInt32LE(AInput, ALen - 4);
+ LInput64 := UInt64(LInputLo) + (UInt64(LInputHi) shl 32);
+ LBitflip := (TConverters.ReadBytesAsUInt64LE(ASecret, 16) xor
+ TConverters.ReadBytesAsUInt64LE(ASecret, 24)) + ASeed;
+ LKeyed := LInput64 xor LBitflip;
+
+ TXXH3Core.XXH_mult64to128(LKeyed, TXXH3Core.XXH_PRIME64_1 +
+ (UInt64(ALen) shl 2), LMLow, LMHigh);
+
+ LMHigh := LMHigh + (LMLow shl 1);
+ LMLow := LMLow xor (LMHigh shr 3);
+
+ LMLow := LMLow xor (LMLow shr 35);
+ LMLow := LMLow * UInt64($9FB21C651E98DF25);
+ LMLow := LMLow xor (LMLow shr 28);
+ LMHigh := TXXH3Core.XXH3_avalanche(LMHigh);
+
+ ALow := LMLow;
+ AHigh := LMHigh;
+end;
+
+class procedure TXXHash128.XXH3_len_9to16_128b(AInput, ASecret: PByte;
+ ALen: Int32; ASeed: UInt64; out ALow, AHigh: UInt64);
+var
+ LBitflipL, LBitflipH, LInputLo, LInputHi: UInt64;
+ LMLow, LMHigh, LHLow, LHHigh: UInt64;
+begin
+ LBitflipL := (TConverters.ReadBytesAsUInt64LE(ASecret, 32) xor
+ TConverters.ReadBytesAsUInt64LE(ASecret, 40)) - ASeed;
+ LBitflipH := (TConverters.ReadBytesAsUInt64LE(ASecret, 48) xor
+ TConverters.ReadBytesAsUInt64LE(ASecret, 56)) + ASeed;
+ LInputLo := TConverters.ReadBytesAsUInt64LE(AInput, 0);
+ LInputHi := TConverters.ReadBytesAsUInt64LE(AInput, ALen - 8);
+
+ TXXH3Core.XXH_mult64to128(LInputLo xor LInputHi xor LBitflipL,
+ TXXH3Core.XXH_PRIME64_1, LMLow, LMHigh);
+
+ LMLow := LMLow + (UInt64(ALen - 1) shl 54);
+ LInputHi := LInputHi xor LBitflipH;
+
+ LMHigh := LMHigh + LInputHi +
+ TXXH3Core.XXH_mult32to64(UInt32(LInputHi),
+ TXXH3Core.XXH_PRIME32_2 - 1);
+ LMLow := LMLow xor TBits.ReverseBytesUInt64(LMHigh);
+
+ TXXH3Core.XXH_mult64to128(LMLow, TXXH3Core.XXH_PRIME64_2, LHLow, LHHigh);
+ LHHigh := LHHigh + LMHigh * TXXH3Core.XXH_PRIME64_2;
+
+ ALow := TXXH3Core.XXH3_avalanche(LHLow);
+ AHigh := TXXH3Core.XXH3_avalanche(LHHigh);
+end;
+
+class procedure TXXHash128.XXH3_len_0to16_128b(AInput, ASecret: PByte;
+ ALen: Int32; ASeed: UInt64; out ALow, AHigh: UInt64);
+var
+ LBitflipL, LBitflipH: UInt64;
+begin
+ if ALen > 8 then
+ XXH3_len_9to16_128b(AInput, ASecret, ALen, ASeed, ALow, AHigh)
+ else if ALen >= 4 then
+ XXH3_len_4to8_128b(AInput, ASecret, ALen, ASeed, ALow, AHigh)
+ else if ALen <> 0 then
+ XXH3_len_1to3_128b(AInput, ASecret, ALen, ASeed, ALow, AHigh)
+ else
+ begin
+ LBitflipL := TConverters.ReadBytesAsUInt64LE(ASecret, 64) xor
+ TConverters.ReadBytesAsUInt64LE(ASecret, 72);
+ LBitflipH := TConverters.ReadBytesAsUInt64LE(ASecret, 80) xor
+ TConverters.ReadBytesAsUInt64LE(ASecret, 88);
+ ALow := TXXH3Core.XXH64_avalanche(ASeed xor LBitflipL);
+ AHigh := TXXH3Core.XXH64_avalanche(ASeed xor LBitflipH);
+ end;
+end;
+
+class procedure TXXHash128.XXH3_len_17to128_128b(AInput, ASecret: PByte;
+ ALen, ASecretSize: Int32; ASeed: UInt64; out ALow, AHigh: UInt64);
+var
+ LAccLow, LAccHigh: UInt64;
+begin
+ LAccLow := UInt64(ALen) * TXXH3Core.XXH_PRIME64_1;
+ LAccHigh := 0;
+
+ if ALen > 32 then
+ begin
+ if ALen > 64 then
+ begin
+ if ALen > 96 then
+ XXH128_mix32B(LAccLow, LAccHigh, AInput + 48, AInput + ALen - 64,
+ ASecret + 96, ASeed);
+ XXH128_mix32B(LAccLow, LAccHigh, AInput + 32, AInput + ALen - 48,
+ ASecret + 64, ASeed);
+ end;
+ XXH128_mix32B(LAccLow, LAccHigh, AInput + 16, AInput + ALen - 32,
+ ASecret + 32, ASeed);
+ end;
+ XXH128_mix32B(LAccLow, LAccHigh, AInput, AInput + ALen - 16,
+ ASecret, ASeed);
+
+ ALow := TXXH3Core.XXH3_avalanche(LAccLow + LAccHigh);
+ AHigh := UInt64(0) - TXXH3Core.XXH3_avalanche(
+ LAccLow * TXXH3Core.XXH_PRIME64_1 +
+ LAccHigh * TXXH3Core.XXH_PRIME64_4 +
+ (UInt64(ALen) - ASeed) * TXXH3Core.XXH_PRIME64_2);
+end;
+
+class procedure TXXHash128.XXH3_len_129to240_128b(AInput, ASecret: PByte;
+ ALen, ASecretSize: Int32; ASeed: UInt64; out ALow, AHigh: UInt64);
+var
+ LAccLow, LAccHigh: UInt64;
+ LNbRounds, I: Int32;
+begin
+ LAccLow := UInt64(ALen) * TXXH3Core.XXH_PRIME64_1;
+ LAccHigh := 0;
+ LNbRounds := ALen div 32;
+
+ for I := 0 to 3 do
+ XXH128_mix32B(LAccLow, LAccHigh, AInput + (32 * I),
+ AInput + (32 * I) + 16, ASecret + (32 * I), ASeed);
+
+ LAccLow := TXXH3Core.XXH3_avalanche(LAccLow);
+ LAccHigh := TXXH3Core.XXH3_avalanche(LAccHigh);
+
+ for I := 4 to LNbRounds - 1 do
+ XXH128_mix32B(LAccLow, LAccHigh, AInput + (32 * I),
+ AInput + (32 * I) + 16,
+ ASecret + TXXH3Core.XXH3_MIDSIZE_STARTOFFSET + (32 * (I - 4)), ASeed);
+
+ XXH128_mix32B(LAccLow, LAccHigh, AInput + ALen - 16, AInput + ALen - 32,
+ ASecret + TXXH3Core.XXH3_SECRET_SIZE_MIN -
+ TXXH3Core.XXH3_MIDSIZE_LASTOFFSET - 16, UInt64(0) - ASeed);
+
+ ALow := TXXH3Core.XXH3_avalanche(LAccLow + LAccHigh);
+ AHigh := UInt64(0) - TXXH3Core.XXH3_avalanche(
+ LAccLow * TXXH3Core.XXH_PRIME64_1 +
+ LAccHigh * TXXH3Core.XXH_PRIME64_4 +
+ (UInt64(ALen) - ASeed) * TXXH3Core.XXH_PRIME64_2);
+end;
+
+class procedure TXXHash128.XXH3_hashLong_128b_internal(AInput: PByte;
+ ALen: Int32; ASecret: PByte; ASecretSize: Int32;
+ out ALow, AHigh: UInt64);
+var
+ LAcc: TXXH3AccArray;
+begin
+ System.Move(TXXH3Core.XXH3_INIT_ACC, LAcc, System.SizeOf(TXXH3AccArray));
+
+ TXXH3Core.XXH3_hashLong_internal_loop(LAcc, AInput, ALen,
+ ASecret, ASecretSize);
+
+ ALow := TXXH3Core.XXH3_mergeAccs(LAcc,
+ ASecret + TXXH3Core.XXH_SECRET_MERGEACCS_START,
+ UInt64(ALen) * TXXH3Core.XXH_PRIME64_1);
+ AHigh := TXXH3Core.XXH3_mergeAccs(LAcc,
+ ASecret + ASecretSize - TXXH3Core.XXH3_ACC_SIZE -
+ TXXH3Core.XXH_SECRET_MERGEACCS_START,
+ not (UInt64(ALen) * TXXH3Core.XXH_PRIME64_2));
+end;
+
+class procedure TXXHash128.XXH3_hashLong_128b_withSeed(AInput: PByte;
+ ALen: Int32; ASeed: UInt64; out ALow, AHigh: UInt64);
+var
+ LSecret: array [0 .. 191] of Byte;
+begin
+ if ASeed = 0 then
+ begin
+ XXH3_hashLong_128b_internal(AInput, ALen,
+ PByte(@TXXH3Core.XXH3_SECRET[0]),
+ TXXH3Core.XXH3_SECRET_DEFAULT_SIZE, ALow, AHigh);
+ Exit;
+ end;
+
+ TXXH3Core.XXH3_initCustomSecret(PByte(@LSecret[0]), ASeed);
+ XXH3_hashLong_128b_internal(AInput, ALen, PByte(@LSecret[0]),
+ TXXH3Core.XXH3_SECRET_DEFAULT_SIZE, ALow, AHigh);
+end;
+
+class procedure TXXHash128.XXH3_128bits_internal(AInput: PByte;
+ ALen: Int32; ASeed: UInt64; ASecret: PByte; ASecretLen: Int32;
+ out ALow, AHigh: UInt64);
+begin
+ if ALen <= 16 then
+ XXH3_len_0to16_128b(AInput, ASecret, ALen, ASeed, ALow, AHigh)
+ else if ALen <= 128 then
+ XXH3_len_17to128_128b(AInput, ASecret, ALen, ASecretLen, ASeed,
+ ALow, AHigh)
+ else if ALen <= TXXH3Core.XXH3_MIDSIZE_MAX then
+ XXH3_len_129to240_128b(AInput, ASecret, ALen, ASecretLen, ASeed,
+ ALow, AHigh)
+ else
+ XXH3_hashLong_128b_withSeed(AInput, ALen, ASeed, ALow, AHigh);
+end;
+
+procedure TXXHash128.DigestLong(var AAcc: TXXH3AccArray);
+var
+ LSecret: PByte;
+ LNbStripes, LNbStripesSoFar: Int32;
+ LLastStripe: array [0 .. 63] of Byte;
+ LCatchupSize: Int32;
+begin
+ LSecret := PByte(FState.FCustomSecret);
+
+ if FState.FBufferedSize >= TXXH3Core.XXH_STRIPE_LEN then
+ begin
+ LNbStripes := Int32((FState.FBufferedSize - 1) div
+ TXXH3Core.XXH_STRIPE_LEN);
+ LNbStripesSoFar := FState.FNbStripesSoFar;
+ TXXH3Core.XXH3_consumeStripes(AAcc, LNbStripesSoFar,
+ TXXH3Core.XXH3_STRIPES_PER_BLOCK, PByte(FState.FBuffer), LSecret,
+ LNbStripes, TXXH3Core.XXH3_SECRET_LIMIT);
+
+ TXXH3Core.XXH3_accumulate_512(AAcc,
+ PByte(FState.FBuffer) + FState.FBufferedSize -
+ TXXH3Core.XXH_STRIPE_LEN,
+ LSecret + TXXH3Core.XXH3_SECRET_LIMIT -
+ TXXH3Core.XXH_SECRET_LASTACC_START);
+ end
+ else
+ begin
+ LCatchupSize := TXXH3Core.XXH_STRIPE_LEN - Int32(FState.FBufferedSize);
+ System.Move(FState.FBuffer[TXXH3Core.XXH3_INTERNALBUFFER_SIZE -
+ LCatchupSize], LLastStripe[0], LCatchupSize);
+ System.Move(FState.FBuffer[0], LLastStripe[LCatchupSize],
+ FState.FBufferedSize);
+
+ TXXH3Core.XXH3_accumulate_512(AAcc, PByte(@LLastStripe[0]),
+ LSecret + TXXH3Core.XXH3_SECRET_LIMIT -
+ TXXH3Core.XXH_SECRET_LASTACC_START);
+ end;
+end;
+
+procedure TXXHash128.TransformBytes(const AData: THashLibByteArray;
+ AIndex, ALength: Int32);
+var
+ LPtrInput, LPtrEnd: PByte;
+ LLoadSize, LRemaining: Int32;
+begin
+{$IFDEF DEBUG}
+ System.Assert(AIndex >= 0);
+ System.Assert(ALength >= 0);
+ System.Assert(AIndex + ALength <= System.Length(AData));
+{$ENDIF DEBUG}
+ LPtrInput := PByte(AData) + AIndex;
+ LPtrEnd := LPtrInput + UInt32(ALength);
+ FState.FTotalLength := FState.FTotalLength + UInt64(ALength);
+
+ if FState.FBufferedSize + UInt32(ALength) <=
+ UInt32(TXXH3Core.XXH3_INTERNALBUFFER_SIZE) then
+ begin
+ System.Move(LPtrInput^, FState.FBuffer[FState.FBufferedSize], ALength);
+ FState.FBufferedSize := FState.FBufferedSize + UInt32(ALength);
+ Exit;
+ end;
+
+ LLoadSize := TXXH3Core.XXH3_INTERNALBUFFER_SIZE -
+ Int32(FState.FBufferedSize);
+ System.Move(LPtrInput^, FState.FBuffer[FState.FBufferedSize], LLoadSize);
+ LPtrInput := LPtrInput + LLoadSize;
+
+ TXXH3Core.XXH3_consumeStripes(FState.FAcc, FState.FNbStripesSoFar,
+ TXXH3Core.XXH3_STRIPES_PER_BLOCK, PByte(FState.FBuffer),
+ PByte(FState.FCustomSecret), TXXH3Core.XXH3_INTERNALBUFFER_STRIPES,
+ TXXH3Core.XXH3_SECRET_LIMIT);
+ FState.FBufferedSize := 0;
+
+ if LPtrEnd - LPtrInput > TXXH3Core.XXH3_INTERNALBUFFER_SIZE then
+ begin
+ repeat
+ TXXH3Core.XXH3_consumeStripes(FState.FAcc, FState.FNbStripesSoFar,
+ TXXH3Core.XXH3_STRIPES_PER_BLOCK, LPtrInput,
+ PByte(FState.FCustomSecret), TXXH3Core.XXH3_INTERNALBUFFER_STRIPES,
+ TXXH3Core.XXH3_SECRET_LIMIT);
+ LPtrInput := LPtrInput + TXXH3Core.XXH3_INTERNALBUFFER_SIZE;
+ until not(LPtrEnd - LPtrInput > TXXH3Core.XXH3_INTERNALBUFFER_SIZE);
+
+ System.Move((LPtrInput - TXXH3Core.XXH_STRIPE_LEN)^,
+ FState.FBuffer[TXXH3Core.XXH3_INTERNALBUFFER_SIZE -
+ TXXH3Core.XXH_STRIPE_LEN], TXXH3Core.XXH_STRIPE_LEN);
+ end;
+
+ LRemaining := LPtrEnd - LPtrInput;
+ System.Move(LPtrInput^, FState.FBuffer[0], LRemaining);
+ FState.FBufferedSize := UInt32(LRemaining);
+end;
+
+function TXXHash128.TransformFinal: IHashResult;
+var
+ LAcc: TXXH3AccArray;
+ LBufferBytes: THashLibByteArray;
+begin
+ if FState.FTotalLength > UInt64(TXXH3Core.XXH3_MIDSIZE_MAX) then
+ begin
+ System.Move(FState.FAcc, LAcc, System.SizeOf(TXXH3AccArray));
+ DigestLong(LAcc);
+ FHashLow := TXXH3Core.XXH3_mergeAccs(LAcc,
+ PByte(FState.FCustomSecret) + TXXH3Core.XXH_SECRET_MERGEACCS_START,
+ FState.FTotalLength * TXXH3Core.XXH_PRIME64_1);
+ FHashHigh := TXXH3Core.XXH3_mergeAccs(LAcc,
+ PByte(FState.FCustomSecret) + TXXH3Core.XXH3_SECRET_DEFAULT_SIZE -
+ TXXH3Core.XXH3_ACC_SIZE - TXXH3Core.XXH_SECRET_MERGEACCS_START,
+ not (FState.FTotalLength * TXXH3Core.XXH_PRIME64_2));
+ end
+ else
+ begin
+ XXH3_128bits_internal(PByte(FState.FBuffer),
+ Int32(FState.FTotalLength), FKey,
+ PByte(@TXXH3Core.XXH3_SECRET[0]),
+ TXXH3Core.XXH3_SECRET_DEFAULT_SIZE,
+ FHashLow, FHashHigh);
+ end;
+
+ System.SetLength(LBufferBytes, HashSize);
+ TConverters.ReadUInt64AsBytesBE(FHashHigh, LBufferBytes, 0);
+ TConverters.ReadUInt64AsBytesBE(FHashLow, LBufferBytes, 8);
+
+ Result := THashResult.Create(LBufferBytes);
+ Initialize();
+end;
+
+end.
diff --git a/HashLib/src/Hash64/HlpXXHash3.pas b/HashLib/src/Hash64/HlpXXHash3.pas
new file mode 100644
index 00000000..7851d39c
--- /dev/null
+++ b/HashLib/src/Hash64/HlpXXHash3.pas
@@ -0,0 +1,767 @@
+unit HlpXXHash3;
+
+{$I ..\Include\HashLib.inc}
+
+interface
+
+uses
+ HlpHashLibTypes,
+ HlpHash,
+ HlpIHash,
+ HlpConverters,
+ HlpIHashInfo,
+ HlpHashResult,
+ HlpIHashResult,
+ HlpBits;
+
+resourcestring
+ SInvalidKeyLength = 'KeyLength Must Be Equal to %d';
+
+type
+ TXXH3AccArray = array [0 .. 7] of UInt64;
+
+ TXXH3Core = class sealed(TObject)
+
+ public
+
+ const
+
+ XXH3_SECRET_DEFAULT_SIZE = Int32(192);
+ XXH3_SECRET_SIZE_MIN = Int32(136);
+ XXH_STRIPE_LEN = Int32(64);
+ XXH_ACC_NB = Int32(8);
+ XXH_SECRET_CONSUME_RATE = Int32(8);
+ XXH_SECRET_MERGEACCS_START = Int32(11);
+ XXH_SECRET_LASTACC_START = Int32(7);
+ XXH3_MIDSIZE_MAX = Int32(240);
+ XXH3_MIDSIZE_STARTOFFSET = Int32(3);
+ XXH3_MIDSIZE_LASTOFFSET = Int32(17);
+ XXH3_INTERNALBUFFER_SIZE = Int32(256);
+ XXH3_INTERNALBUFFER_STRIPES = Int32(4);
+ XXH3_ACC_SIZE = Int32(64);
+
+ XXH_PRIME32_1 = UInt32($9E3779B1);
+ XXH_PRIME32_2 = UInt32($85EBCA77);
+ XXH_PRIME32_3 = UInt32($C2B2AE3D);
+
+ XXH3_STRIPES_PER_BLOCK =
+ (XXH3_SECRET_DEFAULT_SIZE - XXH_STRIPE_LEN) div XXH_SECRET_CONSUME_RATE;
+ XXH3_SECRET_LIMIT = XXH3_SECRET_DEFAULT_SIZE - XXH_STRIPE_LEN;
+
+ XXH3_SECRET: array [0 .. 191] of Byte = ($B8, $FE, $6C, $39, $23, $A4,
+ $4B, $BE, $7C, $01, $81, $2C, $F7, $21, $AD, $1C, $DE, $D4, $6D, $E9,
+ $83, $90, $97, $DB, $72, $40, $A4, $A4, $B7, $B3, $67, $1F, $CB, $79,
+ $E6, $4E, $CC, $C0, $E5, $78, $82, $5A, $D0, $7D, $CC, $FF, $72, $21,
+ $B8, $08, $46, $74, $F7, $43, $24, $8E, $E0, $35, $90, $E6, $81, $3A,
+ $26, $4C, $3C, $28, $52, $BB, $91, $C3, $00, $CB, $88, $D0, $65, $8B,
+ $1B, $53, $2E, $A3, $71, $64, $48, $97, $A2, $0D, $F9, $4E, $38, $19,
+ $EF, $46, $A9, $DE, $AC, $D8, $A8, $FA, $76, $3F, $E3, $9C, $34, $3F,
+ $F9, $DC, $BB, $C7, $C7, $0B, $4F, $1D, $8A, $51, $E0, $4B, $CD, $B4,
+ $59, $31, $C8, $9F, $7E, $C9, $D9, $78, $73, $64, $EA, $C5, $AC, $83,
+ $34, $D3, $EB, $C3, $C5, $81, $A0, $FF, $FA, $13, $63, $EB, $17, $0D,
+ $DD, $51, $B7, $F0, $DA, $49, $D3, $16, $55, $26, $29, $D4, $68, $9E,
+ $2B, $16, $BE, $58, $7D, $47, $A1, $FC, $8F, $F8, $B8, $D1, $7A, $D0,
+ $31, $CE, $45, $CB, $3A, $8F, $95, $16, $04, $28, $AF, $D7, $FB, $CA,
+ $BB, $4B, $40, $7E);
+
+ // to bypass Internal error (200706094) on FPC, We use "Typed Constant".
+ XXH_PRIME64_1: UInt64 = UInt64($9E3779B185EBCA87);
+ XXH_PRIME64_2: UInt64 = UInt64($C2B2AE3D27D4EB4F);
+ XXH_PRIME64_3: UInt64 = UInt64($165667B19E3779F9);
+ XXH_PRIME64_4: UInt64 = UInt64($85EBCA77C2B2AE63);
+ XXH_PRIME64_5: UInt64 = UInt64($27D4EB2F165667C5);
+
+ XXH3_INIT_ACC: array [0 .. 7] of UInt64 = (UInt64($C2B2AE3D),
+ UInt64($9E3779B185EBCA87), UInt64($C2B2AE3D27D4EB4F),
+ UInt64($165667B19E3779F9), UInt64($85EBCA77C2B2AE63),
+ UInt64($85EBCA77), UInt64($27D4EB2F165667C5), UInt64($9E3779B1));
+
+ class function XXH_mult32to64(AX, AY: UInt32): UInt64; static; inline;
+ class procedure XXH_mult64to128(ALhs, ARhs: UInt64;
+ out ALow, AHigh: UInt64); static; inline;
+ class function XXH3_mul128_fold64(ALhs, ARhs: UInt64): UInt64;
+ static; inline;
+ class function XXH3_avalanche(AH64: UInt64): UInt64; static; inline;
+ class function XXH3_rrmxmx(AH64: UInt64; ALen: Int32): UInt64;
+ static; inline;
+ class function XXH64_avalanche(AH64: UInt64): UInt64; static; inline;
+ class function XXH3_mix16B(AInput, ASecret: PByte; ASeed: UInt64): UInt64;
+ static; inline;
+ class function XXH3_mix2Accs(const AAcc: TXXH3AccArray;
+ ALaneStart: Int32; ASecret: PByte): UInt64; static; inline;
+ class function XXH3_mergeAccs(const AAcc: TXXH3AccArray; ASecret: PByte;
+ AStart: UInt64): UInt64; static;
+ class procedure XXH3_scalarRound(var AAcc: TXXH3AccArray;
+ AInput, ASecret: PByte; ALane: Int32); static; inline;
+ class procedure XXH3_accumulate_512(var AAcc: TXXH3AccArray;
+ AInput, ASecret: PByte); static; inline;
+ class procedure XXH3_scalarScrambleRound(var AAcc: TXXH3AccArray;
+ ASecret: PByte; ALane: Int32); static; inline;
+ class procedure XXH3_scrambleAcc(var AAcc: TXXH3AccArray;
+ ASecret: PByte); static; inline;
+ class procedure XXH3_accumulate(var AAcc: TXXH3AccArray;
+ AInput, ASecret: PByte; ANbStripes: Int32); static;
+ class procedure XXH3_hashLong_internal_loop(var AAcc: TXXH3AccArray;
+ AInput: PByte; ALen: Int32; ASecret: PByte; ASecretSize: Int32); static;
+ class procedure XXH3_initCustomSecret(ACustomSecret: PByte;
+ ASeed: UInt64); static;
+ class procedure XXH3_consumeStripes(var AAcc: TXXH3AccArray;
+ var ANbStripesSoFar: Int32; ANbStripesPerBlock: Int32;
+ AInput, ASecret: PByte; ANbStripes, ASecretLimit: Int32); static;
+ end;
+
+ TXXHash3 = class sealed(THash, IHash64, IHashWithKey, ITransformBlock)
+
+ strict private
+ var
+ FKey, FHash: UInt64;
+
+ const
+ CKEY = UInt64(0);
+
+ function GetKeyLength(): Int32;
+ function GetKey: THashLibByteArray; inline;
+ procedure SetKey(const AValue: THashLibByteArray); inline;
+
+ type
+
+ TXXH3_State = record
+
+ private
+ var
+ FAcc: TXXH3AccArray;
+ FCustomSecret: THashLibByteArray;
+ FBuffer: THashLibByteArray;
+ FBufferedSize: UInt32;
+ FNbStripesSoFar: Int32;
+ FTotalLength: UInt64;
+
+ function Clone(): TXXH3_State;
+
+ end;
+
+ strict private
+ var
+ FState: TXXH3_State;
+
+ class function XXH3_len_1to3_64b(AInput, ASecret: PByte; ALen: Int32;
+ ASeed: UInt64): UInt64; static;
+ class function XXH3_len_4to8_64b(AInput, ASecret: PByte; ALen: Int32;
+ ASeed: UInt64): UInt64; static;
+ class function XXH3_len_9to16_64b(AInput, ASecret: PByte; ALen: Int32;
+ ASeed: UInt64): UInt64; static;
+ class function XXH3_len_0to16_64b(AInput, ASecret: PByte; ALen: Int32;
+ ASeed: UInt64): UInt64; static;
+ class function XXH3_len_17to128_64b(AInput, ASecret: PByte;
+ ALen, ASecretSize: Int32; ASeed: UInt64): UInt64; static;
+ class function XXH3_len_129to240_64b(AInput, ASecret: PByte;
+ ALen, ASecretSize: Int32; ASeed: UInt64): UInt64; static;
+ class function XXH3_hashLong_64b_internal(AInput: PByte; ALen: Int32;
+ ASecret: PByte; ASecretSize: Int32): UInt64; static;
+ class function XXH3_hashLong_64b_withSeed(AInput: PByte; ALen: Int32;
+ ASeed: UInt64): UInt64; static;
+ class function XXH3_64bits_internal(AInput: PByte; ALen: Int32;
+ ASeed: UInt64; ASecret: PByte; ASecretLen: Int32): UInt64; static;
+
+ procedure DigestLong(var AAcc: TXXH3AccArray);
+
+ public
+ constructor Create();
+ procedure Initialize(); override;
+ procedure TransformBytes(const AData: THashLibByteArray;
+ AIndex, ALength: Int32); override;
+ function TransformFinal(): IHashResult; override;
+ function Clone(): IHash; override;
+ property KeyLength: Int32 read GetKeyLength;
+ property Key: THashLibByteArray read GetKey write SetKey;
+
+ end;
+
+implementation
+
+{ TXXH3Core }
+
+class function TXXH3Core.XXH_mult32to64(AX, AY: UInt32): UInt64;
+begin
+ Result := UInt64(AX) * UInt64(AY);
+end;
+
+class procedure TXXH3Core.XXH_mult64to128(ALhs, ARhs: UInt64;
+ out ALow, AHigh: UInt64);
+var
+ LLoLo, LHiLo, LLoHi, LHiHi, LCross: UInt64;
+begin
+ LLoLo := UInt64(UInt32(ALhs)) * UInt64(UInt32(ARhs));
+ LHiLo := UInt64(UInt32(ALhs shr 32)) * UInt64(UInt32(ARhs));
+ LLoHi := UInt64(UInt32(ALhs)) * UInt64(UInt32(ARhs shr 32));
+ LHiHi := UInt64(UInt32(ALhs shr 32)) * UInt64(UInt32(ARhs shr 32));
+
+ LCross := (LLoLo shr 32) + (LHiLo and $FFFFFFFF) + LLoHi;
+ AHigh := (LHiLo shr 32) + (LCross shr 32) + LHiHi;
+ ALow := (LCross shl 32) or (LLoLo and $FFFFFFFF);
+end;
+
+class function TXXH3Core.XXH3_mul128_fold64(ALhs, ARhs: UInt64): UInt64;
+var
+ LLow, LHigh: UInt64;
+begin
+ XXH_mult64to128(ALhs, ARhs, LLow, LHigh);
+ Result := LLow xor LHigh;
+end;
+
+class function TXXH3Core.XXH3_avalanche(AH64: UInt64): UInt64;
+begin
+ AH64 := AH64 xor (AH64 shr 37);
+ AH64 := AH64 * UInt64($165667919E3779F9);
+ AH64 := AH64 xor (AH64 shr 32);
+ Result := AH64;
+end;
+
+class function TXXH3Core.XXH3_rrmxmx(AH64: UInt64; ALen: Int32): UInt64;
+begin
+ AH64 := AH64 xor (TBits.RotateLeft64(AH64, 49) xor
+ TBits.RotateLeft64(AH64, 24));
+ AH64 := AH64 * UInt64($9FB21C651E98DF25);
+ AH64 := AH64 xor ((AH64 shr 35) + UInt64(ALen));
+ AH64 := AH64 * UInt64($9FB21C651E98DF25);
+ AH64 := AH64 xor (AH64 shr 28);
+ Result := AH64;
+end;
+
+class function TXXH3Core.XXH64_avalanche(AH64: UInt64): UInt64;
+begin
+ AH64 := AH64 xor (AH64 shr 33);
+ AH64 := AH64 * XXH_PRIME64_2;
+ AH64 := AH64 xor (AH64 shr 29);
+ AH64 := AH64 * XXH_PRIME64_3;
+ AH64 := AH64 xor (AH64 shr 32);
+ Result := AH64;
+end;
+
+class function TXXH3Core.XXH3_mix16B(AInput, ASecret: PByte;
+ ASeed: UInt64): UInt64;
+var
+ LInputLo, LInputHi: UInt64;
+begin
+ LInputLo := TConverters.ReadBytesAsUInt64LE(AInput, 0);
+ LInputHi := TConverters.ReadBytesAsUInt64LE(AInput, 8);
+ Result := XXH3_mul128_fold64(LInputLo xor
+ (TConverters.ReadBytesAsUInt64LE(ASecret, 0) + ASeed),
+ LInputHi xor (TConverters.ReadBytesAsUInt64LE(ASecret, 8) - ASeed));
+end;
+
+class function TXXH3Core.XXH3_mix2Accs(const AAcc: TXXH3AccArray;
+ ALaneStart: Int32; ASecret: PByte): UInt64;
+begin
+ Result := XXH3_mul128_fold64(AAcc[ALaneStart] xor
+ TConverters.ReadBytesAsUInt64LE(ASecret, 0),
+ AAcc[ALaneStart + 1] xor TConverters.ReadBytesAsUInt64LE(ASecret, 8));
+end;
+
+class function TXXH3Core.XXH3_mergeAccs(const AAcc: TXXH3AccArray;
+ ASecret: PByte; AStart: UInt64): UInt64;
+var
+ I: Int32;
+begin
+ Result := AStart;
+ for I := 0 to 3 do
+ Result := Result + XXH3_mix2Accs(AAcc, 2 * I, ASecret + 16 * I);
+ Result := XXH3_avalanche(Result);
+end;
+
+class procedure TXXH3Core.XXH3_scalarRound(var AAcc: TXXH3AccArray;
+ AInput, ASecret: PByte; ALane: Int32);
+var
+ LDataVal, LDataKey: UInt64;
+begin
+ LDataVal := TConverters.ReadBytesAsUInt64LE(AInput, ALane * 8);
+ LDataKey := LDataVal xor TConverters.ReadBytesAsUInt64LE(ASecret, ALane * 8);
+ AAcc[ALane xor 1] := AAcc[ALane xor 1] + LDataVal;
+ AAcc[ALane] := AAcc[ALane] + XXH_mult32to64(UInt32(LDataKey),
+ UInt32(LDataKey shr 32));
+end;
+
+class procedure TXXH3Core.XXH3_accumulate_512(var AAcc: TXXH3AccArray;
+ AInput, ASecret: PByte);
+var
+ I: Int32;
+begin
+ for I := 0 to XXH_ACC_NB - 1 do
+ XXH3_scalarRound(AAcc, AInput, ASecret, I);
+end;
+
+class procedure TXXH3Core.XXH3_scalarScrambleRound(var AAcc: TXXH3AccArray;
+ ASecret: PByte; ALane: Int32);
+var
+ LKey64, LAcc64: UInt64;
+begin
+ LKey64 := TConverters.ReadBytesAsUInt64LE(ASecret, ALane * 8);
+ LAcc64 := AAcc[ALane];
+ LAcc64 := LAcc64 xor (LAcc64 shr 47);
+ LAcc64 := LAcc64 xor LKey64;
+ LAcc64 := LAcc64 * XXH_PRIME32_1;
+ AAcc[ALane] := LAcc64;
+end;
+
+class procedure TXXH3Core.XXH3_scrambleAcc(var AAcc: TXXH3AccArray;
+ ASecret: PByte);
+var
+ I: Int32;
+begin
+ for I := 0 to XXH_ACC_NB - 1 do
+ XXH3_scalarScrambleRound(AAcc, ASecret, I);
+end;
+
+class procedure TXXH3Core.XXH3_accumulate(var AAcc: TXXH3AccArray;
+ AInput, ASecret: PByte; ANbStripes: Int32);
+var
+ N: Int32;
+begin
+ for N := 0 to ANbStripes - 1 do
+ XXH3_accumulate_512(AAcc, AInput + N * XXH_STRIPE_LEN,
+ ASecret + N * XXH_SECRET_CONSUME_RATE);
+end;
+
+class procedure TXXH3Core.XXH3_hashLong_internal_loop(
+ var AAcc: TXXH3AccArray; AInput: PByte; ALen: Int32; ASecret: PByte;
+ ASecretSize: Int32);
+var
+ LNbStripesPerBlock, LBlockLen, LNbBlocks, LNbStripes, N: Int32;
+ LP: PByte;
+begin
+ LNbStripesPerBlock := (ASecretSize - XXH_STRIPE_LEN) div
+ XXH_SECRET_CONSUME_RATE;
+ LBlockLen := XXH_STRIPE_LEN * LNbStripesPerBlock;
+ LNbBlocks := (ALen - 1) div LBlockLen;
+
+ for N := 0 to LNbBlocks - 1 do
+ begin
+ XXH3_accumulate(AAcc, AInput + N * LBlockLen, ASecret,
+ LNbStripesPerBlock);
+ XXH3_scrambleAcc(AAcc, ASecret + ASecretSize - XXH_STRIPE_LEN);
+ end;
+
+ LNbStripes := ((ALen - 1) - (LBlockLen * LNbBlocks)) div XXH_STRIPE_LEN;
+ XXH3_accumulate(AAcc, AInput + LNbBlocks * LBlockLen, ASecret, LNbStripes);
+
+ LP := AInput + ALen - XXH_STRIPE_LEN;
+ XXH3_accumulate_512(AAcc, LP, ASecret + ASecretSize - XXH_STRIPE_LEN -
+ XXH_SECRET_LASTACC_START);
+end;
+
+class procedure TXXH3Core.XXH3_initCustomSecret(ACustomSecret: PByte;
+ ASeed: UInt64);
+var
+ I: Int32;
+ LLo, LHi: UInt64;
+begin
+ for I := 0 to (XXH3_SECRET_DEFAULT_SIZE div 16) - 1 do
+ begin
+ LLo := TConverters.ReadBytesAsUInt64LE(PByte(@XXH3_SECRET[0]),
+ 16 * I) + ASeed;
+ LHi := TConverters.ReadBytesAsUInt64LE(PByte(@XXH3_SECRET[0]),
+ 16 * I + 8) - ASeed;
+ PUInt64(ACustomSecret + 16 * I)^ := LLo;
+ PUInt64(ACustomSecret + 16 * I + 8)^ := LHi;
+ end;
+end;
+
+class procedure TXXH3Core.XXH3_consumeStripes(var AAcc: TXXH3AccArray;
+ var ANbStripesSoFar: Int32; ANbStripesPerBlock: Int32;
+ AInput, ASecret: PByte; ANbStripes, ASecretLimit: Int32);
+var
+ LNbStripesToEnd: Int32;
+begin
+ if ANbStripesPerBlock - ANbStripesSoFar <= ANbStripes then
+ begin
+ LNbStripesToEnd := ANbStripesPerBlock - ANbStripesSoFar;
+ XXH3_accumulate(AAcc, AInput,
+ ASecret + ANbStripesSoFar * XXH_SECRET_CONSUME_RATE, LNbStripesToEnd);
+ XXH3_scrambleAcc(AAcc, ASecret + ASecretLimit);
+ ANbStripesSoFar := 0;
+ AInput := AInput + LNbStripesToEnd * XXH_STRIPE_LEN;
+ ANbStripes := ANbStripes - LNbStripesToEnd;
+
+ while ANbStripes >= ANbStripesPerBlock do
+ begin
+ XXH3_accumulate(AAcc, AInput, ASecret, ANbStripesPerBlock);
+ XXH3_scrambleAcc(AAcc, ASecret + ASecretLimit);
+ AInput := AInput + ANbStripesPerBlock * XXH_STRIPE_LEN;
+ ANbStripes := ANbStripes - ANbStripesPerBlock;
+ end;
+
+ XXH3_accumulate(AAcc, AInput, ASecret, ANbStripes);
+ ANbStripesSoFar := ANbStripes;
+ end
+ else
+ begin
+ XXH3_accumulate(AAcc, AInput,
+ ASecret + ANbStripesSoFar * XXH_SECRET_CONSUME_RATE, ANbStripes);
+ ANbStripesSoFar := ANbStripesSoFar + ANbStripes;
+ end;
+end;
+
+{ TXXHash3.TXXH3_State }
+
+function TXXHash3.TXXH3_State.Clone(): TXXH3_State;
+begin
+ Result := Default(TXXH3_State);
+ System.Move(FAcc, Result.FAcc, System.SizeOf(TXXH3AccArray));
+ Result.FCustomSecret := System.Copy(FCustomSecret);
+ Result.FBuffer := System.Copy(FBuffer);
+ Result.FBufferedSize := FBufferedSize;
+ Result.FNbStripesSoFar := FNbStripesSoFar;
+ Result.FTotalLength := FTotalLength;
+end;
+
+{ TXXHash3 }
+
+constructor TXXHash3.Create;
+begin
+ inherited Create(8, 64);
+ FKey := CKEY;
+ System.SetLength(FState.FBuffer, TXXH3Core.XXH3_INTERNALBUFFER_SIZE);
+ System.SetLength(FState.FCustomSecret, TXXH3Core.XXH3_SECRET_DEFAULT_SIZE);
+end;
+
+function TXXHash3.Clone(): IHash;
+var
+ LHashInstance: TXXHash3;
+begin
+ LHashInstance := TXXHash3.Create();
+ LHashInstance.FKey := FKey;
+ LHashInstance.FHash := FHash;
+ LHashInstance.FState := FState.Clone();
+ Result := LHashInstance;
+ Result.BufferSize := BufferSize;
+end;
+
+function TXXHash3.GetKey: THashLibByteArray;
+begin
+ Result := TConverters.ReadUInt64AsBytesLE(FKey);
+end;
+
+function TXXHash3.GetKeyLength: Int32;
+begin
+ Result := 8;
+end;
+
+procedure TXXHash3.SetKey(const AValue: THashLibByteArray);
+begin
+ if (AValue = nil) then
+ begin
+ FKey := CKEY;
+ end
+ else
+ begin
+ if System.Length(AValue) <> KeyLength then
+ begin
+ raise EArgumentHashLibException.CreateResFmt(@SInvalidKeyLength,
+ [KeyLength]);
+ end;
+ FKey := TConverters.ReadBytesAsUInt64LE(PByte(AValue), 0);
+ end;
+end;
+
+procedure TXXHash3.Initialize;
+begin
+ FHash := 0;
+ System.Move(TXXH3Core.XXH3_INIT_ACC, FState.FAcc,
+ System.SizeOf(TXXH3AccArray));
+
+ if FKey <> 0 then
+ TXXH3Core.XXH3_initCustomSecret(PByte(FState.FCustomSecret), FKey)
+ else
+ System.Move(TXXH3Core.XXH3_SECRET[0], FState.FCustomSecret[0],
+ TXXH3Core.XXH3_SECRET_DEFAULT_SIZE);
+
+ FState.FTotalLength := 0;
+ FState.FBufferedSize := 0;
+ FState.FNbStripesSoFar := 0;
+end;
+
+class function TXXHash3.XXH3_len_1to3_64b(AInput, ASecret: PByte;
+ ALen: Int32; ASeed: UInt64): UInt64;
+var
+ LC1, LC2, LC3: Byte;
+ LCombined: UInt32;
+ LBitflip, LKeyed: UInt64;
+begin
+ LC1 := AInput[0];
+ LC2 := AInput[TBits.Asr32(ALen, 1)];
+ LC3 := AInput[ALen - 1];
+ LCombined := (UInt32(LC1) shl 16) or (UInt32(LC2) shl 24) or
+ (UInt32(LC3) shl 0) or (UInt32(ALen) shl 8);
+ LBitflip := UInt64(TConverters.ReadBytesAsUInt32LE(ASecret, 0) xor
+ TConverters.ReadBytesAsUInt32LE(ASecret, 4)) + ASeed;
+ LKeyed := UInt64(LCombined) xor LBitflip;
+ Result := TXXH3Core.XXH64_avalanche(LKeyed);
+end;
+
+class function TXXHash3.XXH3_len_4to8_64b(AInput, ASecret: PByte;
+ ALen: Int32; ASeed: UInt64): UInt64;
+var
+ LInput1, LInput2: UInt32;
+ LBitflip, LInput64, LKeyed: UInt64;
+begin
+ ASeed := ASeed xor (UInt64(TBits.ReverseBytesUInt32(UInt32(ASeed))) shl 32);
+ LInput1 := TConverters.ReadBytesAsUInt32LE(AInput, 0);
+ LInput2 := TConverters.ReadBytesAsUInt32LE(AInput, ALen - 4);
+ LBitflip := (TConverters.ReadBytesAsUInt64LE(ASecret, 8) xor
+ TConverters.ReadBytesAsUInt64LE(ASecret, 16)) - ASeed;
+ LInput64 := UInt64(LInput2) + (UInt64(LInput1) shl 32);
+ LKeyed := LInput64 xor LBitflip;
+ Result := TXXH3Core.XXH3_rrmxmx(LKeyed, ALen);
+end;
+
+class function TXXHash3.XXH3_len_9to16_64b(AInput, ASecret: PByte;
+ ALen: Int32; ASeed: UInt64): UInt64;
+var
+ LBitflip1, LBitflip2, LInputLo, LInputHi, LAcc: UInt64;
+begin
+ LBitflip1 := (TConverters.ReadBytesAsUInt64LE(ASecret, 24) xor
+ TConverters.ReadBytesAsUInt64LE(ASecret, 32)) + ASeed;
+ LBitflip2 := (TConverters.ReadBytesAsUInt64LE(ASecret, 40) xor
+ TConverters.ReadBytesAsUInt64LE(ASecret, 48)) - ASeed;
+ LInputLo := TConverters.ReadBytesAsUInt64LE(AInput, 0) xor LBitflip1;
+ LInputHi := TConverters.ReadBytesAsUInt64LE(AInput, ALen - 8) xor LBitflip2;
+ LAcc := UInt64(ALen) + TBits.ReverseBytesUInt64(LInputLo) + LInputHi +
+ TXXH3Core.XXH3_mul128_fold64(LInputLo, LInputHi);
+ Result := TXXH3Core.XXH3_avalanche(LAcc);
+end;
+
+class function TXXHash3.XXH3_len_0to16_64b(AInput, ASecret: PByte;
+ ALen: Int32; ASeed: UInt64): UInt64;
+begin
+ if ALen > 8 then
+ Result := XXH3_len_9to16_64b(AInput, ASecret, ALen, ASeed)
+ else if ALen >= 4 then
+ Result := XXH3_len_4to8_64b(AInput, ASecret, ALen, ASeed)
+ else if ALen <> 0 then
+ Result := XXH3_len_1to3_64b(AInput, ASecret, ALen, ASeed)
+ else
+ Result := TXXH3Core.XXH64_avalanche(ASeed xor
+ (TConverters.ReadBytesAsUInt64LE(ASecret, 56) xor
+ TConverters.ReadBytesAsUInt64LE(ASecret, 64)));
+end;
+
+class function TXXHash3.XXH3_len_17to128_64b(AInput, ASecret: PByte;
+ ALen, ASecretSize: Int32; ASeed: UInt64): UInt64;
+var
+ LAcc: UInt64;
+begin
+ LAcc := UInt64(ALen) * TXXH3Core.XXH_PRIME64_1;
+
+ if ALen > 32 then
+ begin
+ if ALen > 64 then
+ begin
+ if ALen > 96 then
+ begin
+ LAcc := LAcc + TXXH3Core.XXH3_mix16B(AInput + 48,
+ ASecret + 96, ASeed);
+ LAcc := LAcc + TXXH3Core.XXH3_mix16B(AInput + ALen - 64,
+ ASecret + 112, ASeed);
+ end;
+ LAcc := LAcc + TXXH3Core.XXH3_mix16B(AInput + 32,
+ ASecret + 64, ASeed);
+ LAcc := LAcc + TXXH3Core.XXH3_mix16B(AInput + ALen - 48,
+ ASecret + 80, ASeed);
+ end;
+ LAcc := LAcc + TXXH3Core.XXH3_mix16B(AInput + 16, ASecret + 32, ASeed);
+ LAcc := LAcc + TXXH3Core.XXH3_mix16B(AInput + ALen - 32,
+ ASecret + 48, ASeed);
+ end;
+
+ LAcc := LAcc + TXXH3Core.XXH3_mix16B(AInput + 0, ASecret + 0, ASeed);
+ LAcc := LAcc + TXXH3Core.XXH3_mix16B(AInput + ALen - 16,
+ ASecret + 16, ASeed);
+ Result := TXXH3Core.XXH3_avalanche(LAcc);
+end;
+
+class function TXXHash3.XXH3_len_129to240_64b(AInput, ASecret: PByte;
+ ALen, ASecretSize: Int32; ASeed: UInt64): UInt64;
+var
+ LAcc: UInt64;
+ LNbRounds, I: Int32;
+begin
+ LAcc := UInt64(ALen) * TXXH3Core.XXH_PRIME64_1;
+ LNbRounds := ALen div 16;
+
+ for I := 0 to 7 do
+ LAcc := LAcc + TXXH3Core.XXH3_mix16B(AInput + (16 * I),
+ ASecret + (16 * I), ASeed);
+ LAcc := TXXH3Core.XXH3_avalanche(LAcc);
+
+ for I := 8 to LNbRounds - 1 do
+ LAcc := LAcc + TXXH3Core.XXH3_mix16B(AInput + (16 * I),
+ ASecret + (16 * (I - 8)) + TXXH3Core.XXH3_MIDSIZE_STARTOFFSET, ASeed);
+
+ LAcc := LAcc + TXXH3Core.XXH3_mix16B(AInput + ALen - 16,
+ ASecret + TXXH3Core.XXH3_SECRET_SIZE_MIN -
+ TXXH3Core.XXH3_MIDSIZE_LASTOFFSET, ASeed);
+ Result := TXXH3Core.XXH3_avalanche(LAcc);
+end;
+
+class function TXXHash3.XXH3_hashLong_64b_internal(AInput: PByte;
+ ALen: Int32; ASecret: PByte; ASecretSize: Int32): UInt64;
+var
+ LAcc: TXXH3AccArray;
+begin
+ System.Move(TXXH3Core.XXH3_INIT_ACC, LAcc, System.SizeOf(TXXH3AccArray));
+
+ TXXH3Core.XXH3_hashLong_internal_loop(LAcc, AInput, ALen,
+ ASecret, ASecretSize);
+
+ Result := TXXH3Core.XXH3_mergeAccs(LAcc,
+ ASecret + TXXH3Core.XXH_SECRET_MERGEACCS_START,
+ UInt64(ALen) * TXXH3Core.XXH_PRIME64_1);
+end;
+
+class function TXXHash3.XXH3_hashLong_64b_withSeed(AInput: PByte;
+ ALen: Int32; ASeed: UInt64): UInt64;
+var
+ LSecret: array [0 .. 191] of Byte;
+begin
+ if ASeed = 0 then
+ begin
+ Result := XXH3_hashLong_64b_internal(AInput, ALen,
+ PByte(@TXXH3Core.XXH3_SECRET[0]), TXXH3Core.XXH3_SECRET_DEFAULT_SIZE);
+ Exit;
+ end;
+
+ TXXH3Core.XXH3_initCustomSecret(PByte(@LSecret[0]), ASeed);
+ Result := XXH3_hashLong_64b_internal(AInput, ALen, PByte(@LSecret[0]),
+ TXXH3Core.XXH3_SECRET_DEFAULT_SIZE);
+end;
+
+class function TXXHash3.XXH3_64bits_internal(AInput: PByte; ALen: Int32;
+ ASeed: UInt64; ASecret: PByte; ASecretLen: Int32): UInt64;
+begin
+ if ALen <= 16 then
+ Result := XXH3_len_0to16_64b(AInput, ASecret, ALen, ASeed)
+ else if ALen <= 128 then
+ Result := XXH3_len_17to128_64b(AInput, ASecret, ALen, ASecretLen, ASeed)
+ else if ALen <= TXXH3Core.XXH3_MIDSIZE_MAX then
+ Result := XXH3_len_129to240_64b(AInput, ASecret, ALen, ASecretLen, ASeed)
+ else
+ Result := XXH3_hashLong_64b_withSeed(AInput, ALen, ASeed);
+end;
+
+procedure TXXHash3.DigestLong(var AAcc: TXXH3AccArray);
+var
+ LSecret: PByte;
+ LNbStripes, LNbStripesSoFar: Int32;
+ LLastStripe: array [0 .. 63] of Byte;
+ LCatchupSize: Int32;
+begin
+ LSecret := PByte(FState.FCustomSecret);
+
+ if FState.FBufferedSize >= TXXH3Core.XXH_STRIPE_LEN then
+ begin
+ LNbStripes := Int32((FState.FBufferedSize - 1) div
+ TXXH3Core.XXH_STRIPE_LEN);
+ LNbStripesSoFar := FState.FNbStripesSoFar;
+ TXXH3Core.XXH3_consumeStripes(AAcc, LNbStripesSoFar,
+ TXXH3Core.XXH3_STRIPES_PER_BLOCK, PByte(FState.FBuffer), LSecret,
+ LNbStripes, TXXH3Core.XXH3_SECRET_LIMIT);
+
+ TXXH3Core.XXH3_accumulate_512(AAcc,
+ PByte(FState.FBuffer) + FState.FBufferedSize -
+ TXXH3Core.XXH_STRIPE_LEN,
+ LSecret + TXXH3Core.XXH3_SECRET_LIMIT -
+ TXXH3Core.XXH_SECRET_LASTACC_START);
+ end
+ else
+ begin
+ LCatchupSize := TXXH3Core.XXH_STRIPE_LEN - Int32(FState.FBufferedSize);
+ System.Move(FState.FBuffer[TXXH3Core.XXH3_INTERNALBUFFER_SIZE -
+ LCatchupSize], LLastStripe[0], LCatchupSize);
+ System.Move(FState.FBuffer[0], LLastStripe[LCatchupSize],
+ FState.FBufferedSize);
+
+ TXXH3Core.XXH3_accumulate_512(AAcc, PByte(@LLastStripe[0]),
+ LSecret + TXXH3Core.XXH3_SECRET_LIMIT -
+ TXXH3Core.XXH_SECRET_LASTACC_START);
+ end;
+end;
+
+procedure TXXHash3.TransformBytes(const AData: THashLibByteArray;
+ AIndex, ALength: Int32);
+var
+ LPtrInput, LPtrEnd: PByte;
+ LLoadSize, LRemaining: Int32;
+begin
+{$IFDEF DEBUG}
+ System.Assert(AIndex >= 0);
+ System.Assert(ALength >= 0);
+ System.Assert(AIndex + ALength <= System.Length(AData));
+{$ENDIF DEBUG}
+ LPtrInput := PByte(AData) + AIndex;
+ LPtrEnd := LPtrInput + UInt32(ALength);
+ FState.FTotalLength := FState.FTotalLength + UInt64(ALength);
+
+ if FState.FBufferedSize + UInt32(ALength) <=
+ UInt32(TXXH3Core.XXH3_INTERNALBUFFER_SIZE) then
+ begin
+ System.Move(LPtrInput^, FState.FBuffer[FState.FBufferedSize], ALength);
+ FState.FBufferedSize := FState.FBufferedSize + UInt32(ALength);
+ Exit;
+ end;
+
+ LLoadSize := TXXH3Core.XXH3_INTERNALBUFFER_SIZE -
+ Int32(FState.FBufferedSize);
+ System.Move(LPtrInput^, FState.FBuffer[FState.FBufferedSize], LLoadSize);
+ LPtrInput := LPtrInput + LLoadSize;
+
+ TXXH3Core.XXH3_consumeStripes(FState.FAcc, FState.FNbStripesSoFar,
+ TXXH3Core.XXH3_STRIPES_PER_BLOCK, PByte(FState.FBuffer),
+ PByte(FState.FCustomSecret), TXXH3Core.XXH3_INTERNALBUFFER_STRIPES,
+ TXXH3Core.XXH3_SECRET_LIMIT);
+ FState.FBufferedSize := 0;
+
+ if LPtrEnd - LPtrInput > TXXH3Core.XXH3_INTERNALBUFFER_SIZE then
+ begin
+ repeat
+ TXXH3Core.XXH3_consumeStripes(FState.FAcc, FState.FNbStripesSoFar,
+ TXXH3Core.XXH3_STRIPES_PER_BLOCK, LPtrInput,
+ PByte(FState.FCustomSecret), TXXH3Core.XXH3_INTERNALBUFFER_STRIPES,
+ TXXH3Core.XXH3_SECRET_LIMIT);
+ LPtrInput := LPtrInput + TXXH3Core.XXH3_INTERNALBUFFER_SIZE;
+ until not(LPtrEnd - LPtrInput > TXXH3Core.XXH3_INTERNALBUFFER_SIZE);
+
+ System.Move((LPtrInput - TXXH3Core.XXH_STRIPE_LEN)^,
+ FState.FBuffer[TXXH3Core.XXH3_INTERNALBUFFER_SIZE -
+ TXXH3Core.XXH_STRIPE_LEN], TXXH3Core.XXH_STRIPE_LEN);
+ end;
+
+ LRemaining := LPtrEnd - LPtrInput;
+ System.Move(LPtrInput^, FState.FBuffer[0], LRemaining);
+ FState.FBufferedSize := UInt32(LRemaining);
+end;
+
+function TXXHash3.TransformFinal: IHashResult;
+var
+ LAcc: TXXH3AccArray;
+begin
+ if FState.FTotalLength > UInt64(TXXH3Core.XXH3_MIDSIZE_MAX) then
+ begin
+ System.Move(FState.FAcc, LAcc, System.SizeOf(TXXH3AccArray));
+ DigestLong(LAcc);
+ FHash := TXXH3Core.XXH3_mergeAccs(LAcc,
+ PByte(FState.FCustomSecret) + TXXH3Core.XXH_SECRET_MERGEACCS_START,
+ FState.FTotalLength * TXXH3Core.XXH_PRIME64_1);
+ end
+ else
+ begin
+ FHash := XXH3_64bits_internal(PByte(FState.FBuffer),
+ Int32(FState.FTotalLength), FKey,
+ PByte(@TXXH3Core.XXH3_SECRET[0]),
+ TXXH3Core.XXH3_SECRET_DEFAULT_SIZE);
+ end;
+
+ Result := THashResult.Create(FHash);
+ Initialize();
+end;
+
+end.
diff --git a/HashLib/src/Packages/Delphi/HashLib4PascalPackage.dpk b/HashLib/src/Packages/Delphi/HashLib4PascalPackage.dpk
index 95309ad7..d796bde8 100644
--- a/HashLib/src/Packages/Delphi/HashLib4PascalPackage.dpk
+++ b/HashLib/src/Packages/Delphi/HashLib4PascalPackage.dpk
@@ -113,9 +113,11 @@ contains
HlpMurmur2_64 in '..\..\Hash64\HlpMurmur2_64.pas',
HlpSipHash in '..\..\Hash64\HlpSipHash.pas',
HlpXXHash64 in '..\..\Hash64\HlpXXHash64.pas',
+ HlpXXHash3 in '..\..\Hash64\HlpXXHash3.pas',
HlpMurmurHash3_x64_128 in '..\..\Hash128\HlpMurmurHash3_x64_128.pas',
HlpMurmurHash3_x86_128 in '..\..\Hash128\HlpMurmurHash3_x86_128.pas',
HlpSipHash128 in '..\..\Hash128\HlpSipHash128.pas',
+ HlpXXHash128 in '..\..\Hash128\HlpXXHash128.pas',
HlpICRC in '..\..\Interfaces\HlpICRC.pas',
HlpIHash in '..\..\Interfaces\HlpIHash.pas',
HlpIHashInfo in '..\..\Interfaces\HlpIHashInfo.pas',
diff --git a/HashLib/src/Packages/FPC/HashLib4PascalPackage.lpk b/HashLib/src/Packages/FPC/HashLib4PascalPackage.lpk
index db1ec2e2..1bc9c978 100644
--- a/HashLib/src/Packages/FPC/HashLib4PascalPackage.lpk
+++ b/HashLib/src/Packages/FPC/HashLib4PascalPackage.lpk
@@ -23,7 +23,7 @@
"/>
-
+
@@ -440,6 +440,14 @@
+
+
+
+
+
+
+
+
diff --git a/HashLib/src/Packages/FPC/HashLib4PascalPackage.pas b/HashLib/src/Packages/FPC/HashLib4PascalPackage.pas
index 946a2330..6c7c82e9 100644
--- a/HashLib/src/Packages/FPC/HashLib4PascalPackage.pas
+++ b/HashLib/src/Packages/FPC/HashLib4PascalPackage.pas
@@ -22,13 +22,13 @@ interface
HlpMurmur2, HlpMurmurHash3_x86_32, HlpOneAtTime, HlpPJW, HlpRotating, HlpRS,
HlpSDBM, HlpShiftAndXor, HlpSuperFast, HlpXXHash32, HlpFNV1a64, HlpFNV64,
HlpMurmur2_64, HlpSipHash, HlpXXHash64, HlpIHash, HlpIHashInfo,
- HlpIHashResult, HlpConverters, HlpBitConverter, HlpBits,
- HlpHashLibTypes, HlpMurmurHash3_x86_128, HlpPBKDF2_HMACNotBuildInAdapter,
- HlpIKDF, HlpKDF, HlpICRC, HlpBlake2B, HlpBlake2S, HlpGOST3411_2012,
- HlpCRC32Fast, HlpArgon2TypeAndVersion, HlpPBKDF_Argon2NotBuildInAdapter,
+ HlpIHashResult, HlpConverters, HlpBitConverter, HlpBits, HlpHashLibTypes,
+ HlpMurmurHash3_x86_128, HlpPBKDF2_HMACNotBuildInAdapter, HlpIKDF, HlpKDF,
+ HlpICRC, HlpBlake2B, HlpBlake2S, HlpGOST3411_2012, HlpCRC32Fast,
+ HlpArgon2TypeAndVersion, HlpPBKDF_Argon2NotBuildInAdapter,
HlpPBKDF_ScryptNotBuildInAdapter, HlpArrayUtils, HlpBlake2BP, HlpBlake2SP,
HlpSipHash128, HlpBlake2SParams, HlpBlake2BParams, HlpIBlake2SParams,
- HlpIBlake2BParams, HlpBlake3;
+ HlpIBlake2BParams, HlpBlake3, HlpXXHash3, HlpXXHash128;
implementation
diff --git a/README.md b/README.md
index 6e65a21e..2cdc5e7f 100644
--- a/README.md
+++ b/README.md
@@ -50,10 +50,10 @@ HashLib4Pascal is a comprehensive hashing library for Object Pascal, providing a
`AP` | `BKDR` | `Bernstein` | `Bernstein1` | `DEK` | `DJB` | `ELF` | `FNV` | `FNV1a` | `Jenkins3` | `JS` | `Murmur2` | `MurmurHash3_x86_32` | `OneAtTime` | `PJW` | `Rotating` | `RS` | `SDBM` | `ShiftAndXor` | `SuperFast` | `XXHash32`
#### 64-bit
-`FNV64` | `FNV1a64` | `Murmur2_64` | `SipHash2_4` | `XXHash64`
+`FNV64` | `FNV1a64` | `Murmur2_64` | `SipHash2_4` | `XXHash64` | `XXHash3`
#### 128-bit
-`SipHash128_2_4` | `MurmurHash3_x86_128` | `MurmurHash3_x64_128`
+`SipHash128_2_4` | `MurmurHash3_x86_128` | `MurmurHash3_x64_128` | `XXHash128`