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`