2
0
mirror of https://github.com/boostorg/hash2.git synced 2026-01-19 04:12:12 +00:00

Handle the case where n is less than the minimum secret size; this is a precondition violation in XXH3, but we want to do something reasonable

This commit is contained in:
Peter Dimov
2025-04-30 19:46:57 +03:00
parent 154abf359b
commit 05317d5030
2 changed files with 42 additions and 6 deletions

View File

@@ -544,22 +544,58 @@ public:
{
with_secret_ = true;
secret_len_ = std::min( default_secret_len, n );
if( n < min_secret_len )
{
// this is a precondition violation for XXH3, but we try to do something reasonable
detail::memcpy( secret_, xxh3_128_constants<>::default_secret, default_secret_len );
secret_len_ = default_secret_len;
}
else
{
secret_len_ = std::min( default_secret_len, n );
}
// incorporate passed secret into secret_
// in the case where min_secret_len <= n <= default_secret_len,
// this is a simple copy because the initial secret_ is {}
while( n >= default_secret_len )
{
for( std::size_t i = 0; i < default_secret_len; ++i )
for( std::size_t i = 0; i < default_secret_len / 8; ++i )
{
secret_[ i ] ^= p[ i ];
std::uint64_t v1 = detail::read64le( p + i * 8 );
std::uint64_t v2 = detail::read64le( secret_ + i * 8 );
detail::write64le( secret_ + i * 8, v1 + v2 );
}
p += default_secret_len;
n -= default_secret_len;
}
for( std::size_t i = 0; i < n; ++i )
{
secret_[ i ] ^= p[ i ];
std::size_t i = 0;
for( ; i < n / 8; ++i )
{
std::uint64_t v1 = detail::read64le( p + i * 8 );
std::uint64_t v2 = detail::read64le( secret_ + i * 8 );
detail::write64le( secret_ + i * 8, v1 + v2 );
}
n = n % 8;
if( n > 0 )
{
unsigned char w[ 8 ] = {};
detail::memcpy( w, p + i * 8, n );
std::uint64_t v1 = detail::read64le( w );
std::uint64_t v2 = detail::read64le( secret_ + i * 8 );
detail::write64le( secret_ + i * 8, v1 + v2 );
}
}
}

View File

@@ -223,7 +223,7 @@ int main()
constexpr digest<16> d = {};
// TEST_NE( hash<xxh3_128>( 0, secret, 1 ), d );
TEST_NE( hash<xxh3_128>( 0, secret, 1 ), d );
TEST_NE( hash<xxh3_128>( 0, secret, 135 ), d );
return boost::report_errors();