From 837eb184e69b83fa30d5bc80a800995c7acb4866 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Nov 2024 18:26:38 +0200 Subject: [PATCH 01/20] Update README --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 096266f..8d0ed3a 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,6 @@ are being tested on [Github Actions](https://github.com/pdimov/hash2/actions/) a ## Planned Additions -* Support for endian-independent hashing * A `std::hash`-compatible adaptor ## License From 07073f4ce46c02954351677134e73286c8d47d90 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Nov 2024 19:24:42 +0200 Subject: [PATCH 02/20] Update documentation --- doc/hash2/hashing_bytes.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/hash2/hashing_bytes.adoc b/doc/hash2/hashing_bytes.adoc index e774142..deabd0d 100644 --- a/doc/hash2/hashing_bytes.adoc +++ b/doc/hash2/hashing_bytes.adoc @@ -59,8 +59,8 @@ Normally, non-cryptographic hash functions have an integer `result_type`, and cryptographic hash functions have an array-like `result_type`, but that's not required. -The provided utility function `get_integral_result_type` can be used to -obtain an integer hash value from any valid `result_type`. +The provided utility function `get_integral_result` can be used to obtain +an integer hash value from any valid `result_type`. ### block_size From aa1a679ba1081978dad88a974c0b9bf7cb681fb1 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Nov 2024 19:30:11 +0200 Subject: [PATCH 03/20] Update test/concept.cpp --- test/concept.cpp | 122 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 95 insertions(+), 27 deletions(-) diff --git a/test/concept.cpp b/test/concept.cpp index c45b28b..afea8b8 100644 --- a/test/concept.cpp +++ b/test/concept.cpp @@ -264,47 +264,115 @@ template void test_copy_constructible() template void test_update() { - unsigned char const data[ 3 ] = {}; - { - H h1; + unsigned char const data[ 3 ] = { 0x01, 0x02, 0x03 }; - H h2; - h2.update( data, 3 ); + { + H h1; - BOOST_TEST( h1.result() != h2.result() ); + H h2; + h2.update( data, 3 ); + + BOOST_TEST( h1.result() != h2.result() ); + } + + { + H h1; + h1.update( data, 3 ); + + H h2; + h2.update( data, 3 ); + + BOOST_TEST( h1.result() == h2.result() ); + } + + { + H h1; + h1.update( data, 3 ); + + H h2; + h2.update( data, 2 ); + + BOOST_TEST( h1.result() != h2.result() ); + } + + { + H h1; + h1.update( data, 3 ); + + H h2( h1 ); + + h1.update( data, 3 ); + h2.update( data, 3 ); + + BOOST_TEST( h1.result() == h2.result() ); + } + + { + H h1; + h1.update( data, 3 ); + + H h2; + h2.update( data + 0, 1 ); + h2.update( data + 1, 1 ); + h2.update( data + 2, 1 ); + + BOOST_TEST( h1.result() == h2.result() ); + } + + { + H h1; + h1.update( data, 3 ); + + H h2; + h2.update( data + 0, 1 ); + h2.update( data + 1, 1 ); + h2.update( data + 2, 1 ); + + BOOST_TEST( h1.result() == h2.result() ); + } + + { + H h1; + h1.update( data, 3 ); + + H h2; + h2.update( data, 1 ); + h2.update( data + 1, 2 ); + + BOOST_TEST( h1.result() == h2.result() ); + } } { - H h1; - h1.update( data, 3 ); + int const N = 95; - H h2; - h2.update( data, 3 ); + unsigned char const data[ N ] = {}; - BOOST_TEST( h1.result() == h2.result() ); - } + { + H h1; + h1.update( data, N ); - { - H h1; - h1.update( data, 3 ); + H h2; + h2.update( data, N / 3 ); + h2.update( data + N / 3, N - N / 3 ); - H h2; - h2.update( data, 2 ); + BOOST_TEST( h1.result() == h2.result() ); + } - BOOST_TEST( h1.result() != h2.result() ); - } + { + H h1; + h1.update( data, N ); - { - H h1; - h1.update( data, 3 ); + H h2; - H h2( h1 ); + for( int i = 0; i < N / 5; ++i ) + { + h2.update( data + i * 5, 5 ); + } - h1.update( data, 3 ); - h2.update( data, 3 ); - - BOOST_TEST( h1.result() == h2.result() ); + BOOST_TEST( h1.result() == h2.result() ); + } } } From 44a8f9c845b3c8136004996d6db41472348792e1 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Nov 2024 19:31:43 +0200 Subject: [PATCH 04/20] Update test/multiple_result.cpp --- test/multiple_result.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/multiple_result.cpp b/test/multiple_result.cpp index a937ab0..93b26fd 100644 --- a/test/multiple_result.cpp +++ b/test/multiple_result.cpp @@ -21,13 +21,16 @@ template void test() typename H::result_type r1 = h.result(); typename H::result_type r2 = h.result(); - BOOST_TEST( r1 != r2 ); + BOOST_TEST( r2 != r1 ); typename H::result_type r3 = h.result(); - BOOST_TEST( r2 != r3 ); + BOOST_TEST( r3 != r2 ); + BOOST_TEST( r3 != r1 ); typename H::result_type r4 = h.result(); - BOOST_TEST( r3 != r4 ); + BOOST_TEST( r4 != r3 ); + BOOST_TEST( r4 != r2 ); + BOOST_TEST( r4 != r1 ); } { From 98f7aed26601d20d50abbc8034434688a5310731 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Nov 2024 20:48:32 +0200 Subject: [PATCH 05/20] Add test/quality.cpp --- test/Jamfile | 1 + test/quality.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 test/quality.cpp diff --git a/test/Jamfile b/test/Jamfile index ca1d527..3918030 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -131,6 +131,7 @@ run concept.cpp ; run plaintext_leak.cpp ; run multiple_result.cpp ; run integral_result.cpp ; +run quality.cpp ; # benchmarks diff --git a/test/quality.cpp b/test/quality.cpp new file mode 100644 index 0000000..f80e6f0 --- /dev/null +++ b/test/quality.cpp @@ -0,0 +1,87 @@ +// Copyright 2024 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include +#include +#include + +template void test_bit_flip( unsigned char ch ) +{ + int const N = 32; + + std::vector v( N, static_cast( ch ) ); + + for( int n = 1; n <= N; ++n ) + { + typename H::result_type r1 = {}; + + { + H h; + h.update( v.data(), n ); + + r1 = h.result(); + } + + for( int j = 0; j < n * 8; ++j ) + { + v[ j / 8 ] ^= 1 << ( j % 8 ); + + H h; + h.update( v.data(), n ); + + typename H::result_type r2 = h.result(); + + v[ j / 8 ] ^= 1 << ( j % 8 ); + + BOOST_TEST( r1 != r2 ) || std::fprintf( stderr, "Hash collision with bit %d flipped in %d * 0x%02X\n", j, n, ch ); + } + } +} + +template void test_seq_length( unsigned char ch ) +{ + int const N = 1024; + + std::vector v( N, static_cast( ch ) ); + + typename H::result_type r[ N ] = {}; + + for( int n = 0; n < N; ++n ) + { + H h; + h.update( v.data(), n ); + + r[ n ] = h.result(); + + for( int j = 0; j < n; ++j ) + { + BOOST_TEST( r[j] != r[n] ) || std::fprintf( stderr, "Hash collision between %d * 0x%02X and %d * 0x%02X\n", j, ch, n, ch ); + } + } +} + +template void test() +{ + for( int ch = 0; ch <= 0xFF; ++ch ) + { + test_bit_flip( static_cast( ch ) ); + test_seq_length( static_cast( ch ) ); + } +} + +int main() +{ + test(); + test(); + test(); + test(); + test(); + test(); + + return boost::report_errors(); +} From a6c9abf58fee797501414ef310d9f552664939ec Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Mon, 4 Nov 2024 15:33:05 -0800 Subject: [PATCH 06/20] update ripemd-160 to be constexpr --- include/boost/hash2/ripemd.hpp | 65 +++++++++++++----------- test/Jamfile | 1 + test/hmac_ripemd.cpp | 16 ------ test/ripemd.cpp | 16 ------ test/ripemd_cx.cpp | 93 ++++++++++++++++++++++++++++++++++ 5 files changed, 129 insertions(+), 62 deletions(-) create mode 100644 test/ripemd_cx.cpp diff --git a/include/boost/hash2/ripemd.hpp b/include/boost/hash2/ripemd.hpp index 4ad4974..6ab659b 100644 --- a/include/boost/hash2/ripemd.hpp +++ b/include/boost/hash2/ripemd.hpp @@ -9,13 +9,14 @@ // RIPEMD-160 message digest algorithm, https://www.esat.kuleuven.be/cosic/publications/article-317.pdf #include +#include #include #include #include +#include #include #include #include -#include #include #include @@ -39,83 +40,83 @@ private: private: - static BOOST_FORCEINLINE std::uint32_t F1( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return x ^ y ^ z; } - static BOOST_FORCEINLINE std::uint32_t F2( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return (x & y) | (~x & z); } - static BOOST_FORCEINLINE std::uint32_t F3( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return (x | ~y) ^ z; } - static BOOST_FORCEINLINE std::uint32_t F4( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return (x & z) | (y & ~z); } - static BOOST_FORCEINLINE std::uint32_t F5( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return x ^ (y | ~z); } + static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR std::uint32_t F1( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return x ^ y ^ z; } + static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR std::uint32_t F2( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return (x & y) | (~x & z); } + static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR std::uint32_t F3( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return (x | ~y) ^ z; } + static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR std::uint32_t F4( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return (x & z) | (y & ~z); } + static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR std::uint32_t F5( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return x ^ (y | ~z); } - static BOOST_FORCEINLINE void R1( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) + static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void R1( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) { a += F1(b, c, d) + x; a = detail::rotl(a, s) + e; c = detail::rotl(c, 10); } - static BOOST_FORCEINLINE void R2( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) + static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void R2( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) { a += F2(b, c, d) + x + 0x5a827999u; a = detail::rotl(a, s) + e; c = detail::rotl(c, 10); } - static BOOST_FORCEINLINE void R3( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) + static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void R3( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) { a += F3(b, c, d) + x + 0x6ed9eba1u; a = detail::rotl(a, s) + e; c = detail::rotl(c, 10); } - static BOOST_FORCEINLINE void R4( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) + static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void R4( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) { a += F4(b, c, d) + x + 0x8f1bbcdcu; a = detail::rotl(a, s) + e; c = detail::rotl(c, 10); } - static BOOST_FORCEINLINE void R5( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) + static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void R5( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) { a += F5(b, c, d) + x + 0xa953fd4eu; a = detail::rotl(a, s) + e; c = detail::rotl(c, 10); } - static BOOST_FORCEINLINE void RR1( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) + static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void RR1( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) { a += F5(b, c, d) + x + 0x50a28be6u; a = detail::rotl(a, s) + e; c = detail::rotl(c, 10); } - static BOOST_FORCEINLINE void RR2( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) + static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void RR2( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) { a += F4(b, c, d) + x + 0x5c4dd124u; a = detail::rotl(a, s) + e; c = detail::rotl(c, 10); } - static BOOST_FORCEINLINE void RR3( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) + static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void RR3( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) { a += F3(b, c, d) + x + 0x6d703ef3u; a = detail::rotl(a, s) + e; c = detail::rotl(c, 10); } - static BOOST_FORCEINLINE void RR4( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) + static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void RR4( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) { a += F2(b, c, d) + x + 0x7a6d76e9u; a = detail::rotl(a, s) + e; c = detail::rotl(c, 10); } - static BOOST_FORCEINLINE void RR5( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) + static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void RR5( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s ) { a += F1(b, c, d) + x; a = detail::rotl(a, s) + e; c = detail::rotl(c, 10); } - void transform( unsigned char const block[ 64 ] ) + BOOST_CXX14_CONSTEXPR void transform( unsigned char const block[ 64 ] ) { std::uint32_t aa = state_[ 0 ]; std::uint32_t bb = state_[ 1 ]; @@ -129,7 +130,7 @@ private: std::uint32_t ddd = state_[ 3 ]; std::uint32_t eee = state_[ 4 ]; - std::uint32_t X[ 16 ]; + std::uint32_t X[ 16 ] = {}; for( int i = 0; i < 16; ++i ) { @@ -328,17 +329,17 @@ private: public: - typedef std::array result_type; + typedef digest<20> result_type; static constexpr int block_size = 64; ripemd_160() = default; - explicit ripemd_160( std::uint64_t seed ) + explicit BOOST_CXX14_CONSTEXPR ripemd_160( std::uint64_t seed ) { if( seed != 0 ) { - unsigned char tmp[ 8 ]; + unsigned char tmp[ 8 ] = {}; detail::write64le( tmp, seed ); update( tmp, 8 ); @@ -346,7 +347,7 @@ public: } } - ripemd_160( unsigned char const * p, std::size_t n ) + BOOST_CXX14_CONSTEXPR ripemd_160( unsigned char const * p, std::size_t n ) { if( n != 0 ) { @@ -355,10 +356,8 @@ public: } } - void update( void const * pv, std::size_t n ) + BOOST_CXX14_CONSTEXPR void update( unsigned char const* p, std::size_t n ) { - unsigned char const* p = static_cast( pv ); - BOOST_ASSERT( m_ == n_ % N ); if( n == 0 ) return; @@ -374,7 +373,7 @@ public: k = n; } - std::memcpy( buffer_ + m_, p, k ); + detail::memcpy( buffer_ + m_, p, k ); p += k; n -= k; @@ -387,7 +386,7 @@ public: transform( buffer_ ); m_ = 0; - std::memset( buffer_, 0, N ); + detail::memset( buffer_, 0, N ); } BOOST_ASSERT( m_ == 0 ); @@ -404,18 +403,24 @@ public: if( n > 0 ) { - std::memcpy( buffer_, p, n ); + detail::memcpy( buffer_, p, n ); m_ = n; } BOOST_ASSERT( m_ == n_ % N ); } - result_type result() + void update( void const * pv, std::size_t n ) + { + unsigned char const* p = static_cast( pv ); + update( p, n ); + } + + BOOST_CXX14_CONSTEXPR result_type result() { BOOST_ASSERT( m_ == n_ % N ); - unsigned char bits[ 8 ]; + unsigned char bits[ 8 ] = {}; detail::write64le( bits, n_ * 8 ); diff --git a/test/Jamfile b/test/Jamfile index 3918030..af37747 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -118,6 +118,7 @@ run hmac_sha2.cpp ; run ripemd.cpp ; run hmac_ripemd.cpp ; +run ripemd_cx.cpp ; # legacy diff --git a/test/hmac_ripemd.cpp b/test/hmac_ripemd.cpp index ede3c3a..b81609f 100644 --- a/test/hmac_ripemd.cpp +++ b/test/hmac_ripemd.cpp @@ -14,22 +14,6 @@ #include #include -template std::string to_string( std::array const & v ) -{ - std::string r; - - for( std::size_t i = 0; i < N; ++i ) - { - char buffer[ 8 ]; - - std::snprintf( buffer, sizeof( buffer ), "%02x", static_cast( v[ i ] ) ); - - r += buffer; - } - - return r; -} - template std::string digest( std::string const k, std::string const & s ) { H h( reinterpret_cast( k.data() ), k.size() ); diff --git a/test/ripemd.cpp b/test/ripemd.cpp index cd61c39..64f447d 100644 --- a/test/ripemd.cpp +++ b/test/ripemd.cpp @@ -12,22 +12,6 @@ #include #include -template std::string to_string( std::array const & v ) -{ - std::string r; - - for( std::size_t i = 0; i < N; ++i ) - { - char buffer[ 8 ]; - - std::snprintf( buffer, sizeof( buffer ), "%02x", static_cast( v[ i ] ) ); - - r += buffer; - } - - return r; -} - template std::string digest( std::string const & s ) { H h; diff --git a/test/ripemd_cx.cpp b/test/ripemd_cx.cpp new file mode 100644 index 0000000..7895331 --- /dev/null +++ b/test/ripemd_cx.cpp @@ -0,0 +1,93 @@ +// Copyright 2024 Christian Mazakas +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_MSVC) && BOOST_MSVC < 1920 +# pragma warning(disable: 4307) // integral constant overflow +#endif + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +template BOOST_CXX14_CONSTEXPR typename H::result_type test( std::uint64_t seed, boost::hash2::digest const& dgst ) +{ + H h( seed ); + + h.update( dgst.data(), N / 3 ); + h.update( dgst.data() + N / 3, N - N / 3 ); + + return h.result(); +} + +BOOST_CXX14_CONSTEXPR unsigned char to_byte( char c ) +{ + if (c >= '0' && c <= '9') return c - '0'; + if (c >= 'a' && c <= 'f') return c - 'a' + 10; + if (c >= 'A' && c <= 'F') return c - 'A' + 10; + return 0xff; +} + +BOOST_CXX14_CONSTEXPR boost::hash2::digest<20> digest_from_hex( char const* str ) +{ + boost::hash2::digest<20> dgst = {}; + auto* p = dgst.data(); + for( int i = 0; i < 20; ++i ) { + auto c1 = to_byte( str[ 2 * i ] ); + auto c2 = to_byte( str[ 2 * i + 1 ] ); + p[ i ] = (c1 << 4) | c2; + } + return dgst; +} + +template BOOST_CXX14_CONSTEXPR boost::hash2::digest digest_from_str( char const (&str)[N] ) +{ + boost::hash2::digest dgst; + for( std::size_t i = 0; i < N - 1; ++i ) { + dgst.data()[ i ] = static_cast( str[ i ] ); + } + return dgst; +} + +int main() +{ + using namespace boost::hash2; + + BOOST_TEST_EQ( test( 0, digest_from_str( "a" ) ), digest_from_hex( "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe" ) ); + BOOST_TEST_EQ( test( 0, digest_from_str( "abc" ) ), digest_from_hex( "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc" ) ); + BOOST_TEST_EQ( test( 0, digest_from_str( "message digest" ) ), digest_from_hex( "5d0689ef49d2fae572b881b123a85ffa21595f36" ) ); + BOOST_TEST_EQ( test( 0, digest_from_str( "abcdefghijklmnopqrstuvwxyz" ) ), digest_from_hex( "f71c27109c692c1b56bbdceb5b9d2865b3708dbc" ) ); + BOOST_TEST_EQ( test( 0, digest_from_str( "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) ), digest_from_hex( "12a053384a9c0c88e405a06c27dcf49ada62eb2b" ) ); + BOOST_TEST_EQ( test( 0, digest_from_str( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) ), digest_from_hex( "b0e20b6e3116640286ed3a87a5713079b21f5189" ) ); + + BOOST_TEST_EQ( test( 7, digest_from_str( "a" ) ), digest_from_hex( "7580d81d5ed1467317ce3ab9199088764a518b9d" ) ); + BOOST_TEST_EQ( test( 7, digest_from_str( "abc" ) ), digest_from_hex( "f5a724fe56b405db4edcb1ea46707ad78753a2e4" ) ); + BOOST_TEST_EQ( test( 7, digest_from_str( "message digest" ) ), digest_from_hex( "da6a32ce82c07de14ac5c2be1be3775201f07941" ) ); + BOOST_TEST_EQ( test( 7, digest_from_str( "abcdefghijklmnopqrstuvwxyz" ) ), digest_from_hex( "221e3b3af0671febf816397ded6f05c8a5c540d3" ) ); + BOOST_TEST_EQ( test( 7, digest_from_str( "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) ), digest_from_hex( "4578ce76d4ddec5a75288306da83f65eb963973c" ) ); + BOOST_TEST_EQ( test( 7, digest_from_str( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) ), digest_from_hex( "868f80dffc5c55612afdd5f8c7c4948410134dc5" ) ); + +#if !defined(BOOST_NO_CXX14_CONSTEXPR) + + STATIC_ASSERT( test( 0, digest_from_str( "a" ) ) == digest_from_hex( "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe" ) ); + STATIC_ASSERT( test( 0, digest_from_str( "abc" ) ) == digest_from_hex( "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc" ) ); + STATIC_ASSERT( test( 0, digest_from_str( "message digest" ) ) == digest_from_hex( "5d0689ef49d2fae572b881b123a85ffa21595f36" ) ); + STATIC_ASSERT( test( 0, digest_from_str( "abcdefghijklmnopqrstuvwxyz" ) ) == digest_from_hex( "f71c27109c692c1b56bbdceb5b9d2865b3708dbc" ) ); + STATIC_ASSERT( test( 0, digest_from_str( "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) ) == digest_from_hex( "12a053384a9c0c88e405a06c27dcf49ada62eb2b" ) ); + STATIC_ASSERT( test( 0, digest_from_str( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) ) == digest_from_hex( "b0e20b6e3116640286ed3a87a5713079b21f5189" ) ); + + STATIC_ASSERT( test( 7, digest_from_str( "a" ) ) == digest_from_hex( "7580d81d5ed1467317ce3ab9199088764a518b9d" ) ); + STATIC_ASSERT( test( 7, digest_from_str( "abc" ) ) == digest_from_hex( "f5a724fe56b405db4edcb1ea46707ad78753a2e4" ) ); + STATIC_ASSERT( test( 7, digest_from_str( "message digest" ) ) == digest_from_hex( "da6a32ce82c07de14ac5c2be1be3775201f07941" ) ); + STATIC_ASSERT( test( 7, digest_from_str( "abcdefghijklmnopqrstuvwxyz" ) ) == digest_from_hex( "221e3b3af0671febf816397ded6f05c8a5c540d3" ) ); + STATIC_ASSERT( test( 7, digest_from_str( "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) ) == digest_from_hex( "4578ce76d4ddec5a75288306da83f65eb963973c" ) ); + STATIC_ASSERT( test( 7, digest_from_str( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) ) == digest_from_hex( "868f80dffc5c55612afdd5f8c7c4948410134dc5" ) ); + +#endif + + return boost::report_errors(); +} From cdc11e21cdf123065489585ae95f0eed42361c43 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Nov 2024 21:05:15 +0200 Subject: [PATCH 07/20] Constexpr-ify hmac.hpp --- include/boost/hash2/hmac.hpp | 37 ++++++++++++++++------------ test/Jamfile | 1 + test/hmac_md5_cx.cpp | 47 ++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 test/hmac_md5_cx.cpp diff --git a/include/boost/hash2/hmac.hpp b/include/boost/hash2/hmac.hpp index 96a421d..d2f506e 100644 --- a/include/boost/hash2/hmac.hpp +++ b/include/boost/hash2/hmac.hpp @@ -8,7 +8,9 @@ // HMAC message authentication algorithm, https://tools.ietf.org/html/rfc2104 #include +#include #include +#include #include #include #include @@ -22,9 +24,8 @@ template class hmac { public: - typedef typename H::result_type result_type; - - static const int block_size = H::block_size; + using result_type = typename H::result_type; + static constexpr int block_size = H::block_size; private: @@ -33,9 +34,9 @@ private: private: - void init( unsigned char const * p, std::size_t n ) + BOOST_CXX14_CONSTEXPR void init( unsigned char const* p, std::size_t n ) { - int const m = block_size; + constexpr std::size_t m = block_size; unsigned char key[ m ] = {}; @@ -45,27 +46,26 @@ private: } else if( n <= m ) { - std::memcpy( key, p, n ); + detail::memcpy( key, p, n ); } else { H h; - h.update( p, n ); result_type r = h.result(); - std::memcpy( key, &r[0], r.size() ); + detail::memcpy( key, &r[0], m < r.size()? m: r.size() ); } - for( int i = 0; i < m; ++i ) + for( std::size_t i = 0; i < m; ++i ) { key[ i ] = static_cast( key[ i ] ^ 0x36 ); } inner_.update( key, m ); - for( int i = 0; i < m; ++i ) + for( std::size_t i = 0; i < m; ++i ) { key[ i ] = static_cast( key[ i ] ^ 0x36 ^ 0x5C ); } @@ -75,12 +75,12 @@ private: public: - hmac() + BOOST_CXX14_CONSTEXPR hmac() { init( 0, 0 ); } - explicit hmac( std::uint64_t seed ) + explicit BOOST_CXX14_CONSTEXPR hmac( std::uint64_t seed ) { if( seed == 0 ) { @@ -88,24 +88,29 @@ public: } else { - unsigned char tmp[ 8 ]; + unsigned char tmp[ 8 ] = {}; detail::write64le( tmp, seed ); init( tmp, 8 ); } } - hmac( unsigned char const * p, std::size_t n ) + BOOST_CXX14_CONSTEXPR hmac( unsigned char const* p, std::size_t n ) { init( p, n ); } - void update( void const * pv, std::size_t n ) + BOOST_CXX14_CONSTEXPR void update( unsigned char const* p, std::size_t n ) + { + inner_.update( p, n ); + } + + void update( void const* pv, std::size_t n ) { inner_.update( pv, n ); } - result_type result() + BOOST_CXX14_CONSTEXPR result_type result() { result_type r = inner_.result(); diff --git a/test/Jamfile b/test/Jamfile index af37747..03f64c4 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -108,6 +108,7 @@ run siphash_cx.cpp ; run md5.cpp ; run hmac_md5.cpp ; run md5_cx.cpp ; +run hmac_md5_cx.cpp ; run sha1.cpp ; run hmac_sha1.cpp ; diff --git a/test/hmac_md5_cx.cpp b/test/hmac_md5_cx.cpp new file mode 100644 index 0000000..9743e62 --- /dev/null +++ b/test/hmac_md5_cx.cpp @@ -0,0 +1,47 @@ +// Copyright 2024 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_MSVC) && BOOST_MSVC < 1920 +# pragma warning(disable: 4307) // integral constant overflow +#endif + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +template BOOST_CXX14_CONSTEXPR typename H::result_type test( std::uint64_t seed, unsigned char const (&v)[ N ] ) +{ + H h( seed ); + + h.update( v, N / 3 ); + h.update( v, N - N / 3 ); + + return h.result(); +} + +int main() +{ + using namespace boost::hash2; + + constexpr unsigned char v[ 95 ] = {}; + + BOOST_CXX14_CONSTEXPR digest<16> r1 = {{ 0x6F, 0x37, 0xD7, 0x4E, 0xD7, 0x97, 0xC2, 0x55, 0xEA, 0x1E, 0x4A, 0x46, 0xC3, 0x52, 0x39, 0xD7 }}; + BOOST_CXX14_CONSTEXPR digest<16> r2 = {{ 0x68, 0xD4, 0xDF, 0x36, 0x73, 0x64, 0x42, 0xC0, 0xED, 0xE2, 0xA6, 0x15, 0x85, 0x10, 0xA4, 0x5E }}; + + BOOST_TEST_EQ( test( 0, v ), r1 ); + BOOST_TEST_EQ( test( 7, v ), r2 ); + +#if !defined(BOOST_NO_CXX14_CONSTEXPR) + + STATIC_ASSERT( test( 0, v ) == r1 ); + STATIC_ASSERT( test( 7, v ) == r2 ); + +#endif + + return boost::report_errors(); +} From 6621b819f01be00fa8a4aced455ce910650bc49b Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 6 Nov 2024 02:32:43 +0200 Subject: [PATCH 08/20] Avoid GCC 5 internal compiler errors --- include/boost/hash2/hmac.hpp | 23 +++++++++++++++++++---- test/hmac_md5_cx.cpp | 2 +- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/include/boost/hash2/hmac.hpp b/include/boost/hash2/hmac.hpp index d2f506e..318c703 100644 --- a/include/boost/hash2/hmac.hpp +++ b/include/boost/hash2/hmac.hpp @@ -11,10 +11,25 @@ #include #include #include +#include #include #include #include +#if !defined(BOOST_NO_CXX14_CONSTEXPR) || BOOST_WORKAROUND(BOOST_GCC, < 60000) + +# define BOOST_HASH2_HMAC_CONSTEXPR constexpr + +#else + +// libs/hash2/test/concept.cpp:45:7: in constexpr expansion of 'h1.boost::hash2::hmac::hmac()' +// ./boost/hash2/hmac.hpp:80:13: in constexpr expansion of 'boost::hash2::hmac::init(0u, 0u)' +// libs/hash2/test/concept.cpp:45:7: internal compiler error: in fold_binary_loc, at fold-const.c:9925 + +# define BOOST_HASH2_HMAC_CONSTEXPR + +#endif + namespace boost { namespace hash2 @@ -34,7 +49,7 @@ private: private: - BOOST_CXX14_CONSTEXPR void init( unsigned char const* p, std::size_t n ) + BOOST_HASH2_HMAC_CONSTEXPR void init( unsigned char const* p, std::size_t n ) { constexpr std::size_t m = block_size; @@ -75,12 +90,12 @@ private: public: - BOOST_CXX14_CONSTEXPR hmac() + BOOST_HASH2_HMAC_CONSTEXPR hmac() { init( 0, 0 ); } - explicit BOOST_CXX14_CONSTEXPR hmac( std::uint64_t seed ) + explicit BOOST_HASH2_HMAC_CONSTEXPR hmac( std::uint64_t seed ) { if( seed == 0 ) { @@ -95,7 +110,7 @@ public: } } - BOOST_CXX14_CONSTEXPR hmac( unsigned char const* p, std::size_t n ) + BOOST_HASH2_HMAC_CONSTEXPR hmac( unsigned char const* p, std::size_t n ) { init( p, n ); } diff --git a/test/hmac_md5_cx.cpp b/test/hmac_md5_cx.cpp index 9743e62..6e53940 100644 --- a/test/hmac_md5_cx.cpp +++ b/test/hmac_md5_cx.cpp @@ -36,7 +36,7 @@ int main() BOOST_TEST_EQ( test( 0, v ), r1 ); BOOST_TEST_EQ( test( 7, v ), r2 ); -#if !defined(BOOST_NO_CXX14_CONSTEXPR) +#if !defined(BOOST_NO_CXX14_CONSTEXPR) && !( defined(BOOST_GCC) && BOOST_GCC < 60000 ) STATIC_ASSERT( test( 0, v ) == r1 ); STATIC_ASSERT( test( 7, v ) == r2 ); From 9b348ebd0cce5750713d34e91b74ad6f7f1abf6b Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 6 Nov 2024 02:42:45 +0200 Subject: [PATCH 09/20] Update test/fnv1a_cx.cpp --- test/fnv1a_cx.cpp | 46 ++++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/test/fnv1a_cx.cpp b/test/fnv1a_cx.cpp index 7c85718..bb2662c 100644 --- a/test/fnv1a_cx.cpp +++ b/test/fnv1a_cx.cpp @@ -11,8 +11,6 @@ # pragma warning(disable: 4307) // integral constant overflow #endif -#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) - template BOOST_CXX14_CONSTEXPR typename H::result_type test( std::uint64_t seed, unsigned char const (&v)[ N ] ) { H h( seed ); @@ -22,6 +20,18 @@ template BOOST_CXX14_CONSTEXPR typename H::result_type t return h.result(); } +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +#if defined(BOOST_NO_CXX14_CONSTEXPR) + +# define TEST_EQ(x1, x2) BOOST_TEST_EQ(x1, x2) + +#else + +# define TEST_EQ(x1, x2) BOOST_TEST_EQ(x1, x2); STATIC_ASSERT(x1 == x2) + +#endif + int main() { using namespace boost::hash2; @@ -29,33 +39,17 @@ int main() constexpr unsigned char v1[] = { 0 }; constexpr unsigned char v4[] = { 0, 1, 2, 3 }; - BOOST_TEST_EQ( test( 0, v1 ), 84696351 ); - BOOST_TEST_EQ( test( 0, v4 ), 3282719153 ); + TEST_EQ( test( 0, v1 ), 84696351 ); + TEST_EQ( test( 0, v4 ), 3282719153 ); - BOOST_TEST_EQ( test( 0, v1 ), 12638153115695167455ull ); - BOOST_TEST_EQ( test( 0, v4 ), 4932904490461320209 ); + TEST_EQ( test( 0, v1 ), 12638153115695167455ull ); + TEST_EQ( test( 0, v4 ), 4932904490461320209 ); - BOOST_TEST_EQ( test( 7, v1 ), 1695235878 ); - BOOST_TEST_EQ( test( 7, v4 ), 4085431250 ); + TEST_EQ( test( 7, v1 ), 1695235878 ); + TEST_EQ( test( 7, v4 ), 4085431250 ); - BOOST_TEST_EQ( test( 7, v1 ), 3154070194012243846 ); - BOOST_TEST_EQ( test( 7, v4 ), 9028993744456876338 ); - -#if !defined(BOOST_NO_CXX14_CONSTEXPR) - - STATIC_ASSERT( test( 0, v1 ) == 84696351 ); - STATIC_ASSERT( test( 0, v4 ) == 3282719153 ); - - STATIC_ASSERT( test( 0, v1 ) == 12638153115695167455ull ); - STATIC_ASSERT( test( 0, v4 ) == 4932904490461320209 ); - - STATIC_ASSERT( test( 7, v1 ) == 1695235878 ); - STATIC_ASSERT( test( 7, v4 ) == 4085431250 ); - - STATIC_ASSERT( test( 7, v1 ) == 3154070194012243846 ); - STATIC_ASSERT( test( 7, v4 ) == 9028993744456876338 ); - -#endif + TEST_EQ( test( 7, v1 ), 3154070194012243846 ); + TEST_EQ( test( 7, v4 ), 9028993744456876338 ); return boost::report_errors(); } From e52e92691157267f395ad093ece9b3c7c3c324ed Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 6 Nov 2024 02:45:02 +0200 Subject: [PATCH 10/20] Update test/xxhash_cx.cpp --- test/xxhash_cx.cpp | 48 ++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/test/xxhash_cx.cpp b/test/xxhash_cx.cpp index 88cbca6..52a81bb 100644 --- a/test/xxhash_cx.cpp +++ b/test/xxhash_cx.cpp @@ -12,18 +12,28 @@ # pragma warning(disable: 4307) // integral constant overflow #endif -#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) - template BOOST_CXX14_CONSTEXPR typename H::result_type test( std::uint64_t seed, unsigned char const (&v)[ N ] ) { H h( seed ); h.update( v, N / 3 ); - h.update( v, N - N / 3 ); + h.update( v + N / 3, N - N / 3 ); return h.result(); } +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +#if defined(BOOST_NO_CXX14_CONSTEXPR) + +# define TEST_EQ(x1, x2) BOOST_TEST_EQ(x1, x2) + +#else + +# define TEST_EQ(x1, x2) BOOST_TEST_EQ(x1, x2); STATIC_ASSERT(x1 == x2) + +#endif + int main() { using namespace boost::hash2; @@ -31,33 +41,17 @@ int main() constexpr unsigned char v21[ 21 ] = {}; constexpr unsigned char v45[ 45 ] = {}; - BOOST_TEST_EQ( test( 0, v21 ), 86206869 ); - BOOST_TEST_EQ( test( 0, v45 ), 747548280 ); + TEST_EQ( test( 0, v21 ), 86206869 ); + TEST_EQ( test( 0, v45 ), 747548280 ); - BOOST_TEST_EQ( test( 0, v21 ), 8680240691998137788 ); - BOOST_TEST_EQ( test( 0, v45 ), 4352694002423811028 ); + TEST_EQ( test( 0, v21 ), 8680240691998137788 ); + TEST_EQ( test( 0, v45 ), 4352694002423811028 ); - BOOST_TEST_EQ( test( 7, v21 ), 2135174986 ); - BOOST_TEST_EQ( test( 7, v45 ), 1547773082 ); + TEST_EQ( test( 7, v21 ), 2135174986 ); + TEST_EQ( test( 7, v45 ), 1547773082 ); - BOOST_TEST_EQ( test( 7, v21 ), 16168826474312362322ull ); - BOOST_TEST_EQ( test( 7, v45 ), 14120916949766558435ull ); - -#if !defined(BOOST_NO_CXX14_CONSTEXPR) - - STATIC_ASSERT( test( 0, v21 ) == 86206869 ); - STATIC_ASSERT( test( 0, v45 ) == 747548280 ); - - STATIC_ASSERT( test( 0, v21 ) == 8680240691998137788 ); - STATIC_ASSERT( test( 0, v45 ) == 4352694002423811028 ); - - STATIC_ASSERT( test( 7, v21 ) == 2135174986 ); - STATIC_ASSERT( test( 7, v45 ) == 1547773082 ); - - STATIC_ASSERT( test( 7, v21 ) == 16168826474312362322ull ); - STATIC_ASSERT( test( 7, v45 ) == 14120916949766558435ull ); - -#endif + TEST_EQ( test( 7, v21 ), 16168826474312362322ull ); + TEST_EQ( test( 7, v45 ), 14120916949766558435ull ); return boost::report_errors(); } From 5724c5a714b1ea12dae379511b1596898002de6d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 6 Nov 2024 02:47:12 +0200 Subject: [PATCH 11/20] Update test/spihash_cx.cpp --- test/siphash_cx.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/test/siphash_cx.cpp b/test/siphash_cx.cpp index 9e97715..5044f7c 100644 --- a/test/siphash_cx.cpp +++ b/test/siphash_cx.cpp @@ -12,18 +12,28 @@ # pragma warning(disable: 4307) // integral constant overflow #endif -#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) - template BOOST_CXX14_CONSTEXPR typename H::result_type test( unsigned char const (&seed)[ 16 ], unsigned char const (&v)[ N ] ) { H h( seed, 16 ); h.update( v, N / 3 ); - h.update( v, N - N / 3 ); + h.update( v + N / 3, N - N / 3 ); return h.result(); } +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +#if defined(BOOST_NO_CXX14_CONSTEXPR) + +# define TEST_EQ(x1, x2) BOOST_TEST_EQ(x1, x2) + +#else + +# define TEST_EQ(x1, x2) BOOST_TEST_EQ(x1, x2); STATIC_ASSERT(x1 == x2) + +#endif + int main() { using namespace boost::hash2; @@ -33,21 +43,11 @@ int main() constexpr unsigned char v21[ 21 ] = {}; constexpr unsigned char v45[ 45 ] = {}; - BOOST_TEST_EQ( test( seed, v21 ), 3273912247 ); - BOOST_TEST_EQ( test( seed, v45 ), 3389005632 ); + TEST_EQ( test( seed, v21 ), 3273912247 ); + TEST_EQ( test( seed, v45 ), 3389005632 ); - BOOST_TEST_EQ( test( seed, v21 ), 17634937937087799533ull ); - BOOST_TEST_EQ( test( seed, v45 ), 7083435387605517692 ); - -#if !defined(BOOST_NO_CXX14_CONSTEXPR) - - STATIC_ASSERT( test( seed, v21 ) == 3273912247 ); - STATIC_ASSERT( test( seed, v45 ) == 3389005632 ); - - STATIC_ASSERT( test( seed, v21 ) == 17634937937087799533ull ); - STATIC_ASSERT( test( seed, v45 ) == 7083435387605517692 ); - -#endif + TEST_EQ( test( seed, v21 ), 17634937937087799533ull ); + TEST_EQ( test( seed, v45 ), 7083435387605517692 ); return boost::report_errors(); } From b976e6544ec49e3428d7a56827d614bcd657c0a7 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 6 Nov 2024 02:49:32 +0200 Subject: [PATCH 12/20] Update test/md5_cx.cpp --- test/md5_cx.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/test/md5_cx.cpp b/test/md5_cx.cpp index 69d7b3d..68707ee 100644 --- a/test/md5_cx.cpp +++ b/test/md5_cx.cpp @@ -12,18 +12,28 @@ # pragma warning(disable: 4307) // integral constant overflow #endif -#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) - template BOOST_CXX14_CONSTEXPR typename H::result_type test( std::uint64_t seed, unsigned char const (&v)[ N ] ) { H h( seed ); h.update( v, N / 3 ); - h.update( v, N - N / 3 ); + h.update( v + N / 3, N - N / 3 ); return h.result(); } +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +#if defined(BOOST_NO_CXX14_CONSTEXPR) + +# define TEST_EQ(x1, x2) BOOST_TEST_EQ(x1, x2) + +#else + +# define TEST_EQ(x1, x2) BOOST_TEST_EQ(x1, x2); STATIC_ASSERT(x1 == x2) + +#endif + int main() { using namespace boost::hash2; @@ -33,15 +43,8 @@ int main() BOOST_CXX14_CONSTEXPR digest<16> r1 = {{ 10, 29, 252, 24, 200, 200, 56, 31, 5, 248, 173, 157, 43, 69, 9, 181 }}; BOOST_CXX14_CONSTEXPR digest<16> r2 = {{ 181, 92, 80, 91, 73, 60, 132, 154, 25, 168, 65, 211, 8, 142, 193, 207 }}; - BOOST_TEST_EQ( test( 0, v ), r1 ); - BOOST_TEST_EQ( test( 7, v ), r2 ); - -#if !defined(BOOST_NO_CXX14_CONSTEXPR) - - STATIC_ASSERT( test( 0, v ) == r1 ); - STATIC_ASSERT( test( 7, v ) == r2 ); - -#endif + TEST_EQ( test( 0, v ), r1 ); + TEST_EQ( test( 7, v ), r2 ); return boost::report_errors(); } From d6b5b094e12017a67276b5821f86ba996d59bf15 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 6 Nov 2024 02:52:12 +0200 Subject: [PATCH 13/20] Update test/sha1_cx.cpp --- test/sha1_cx.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/test/sha1_cx.cpp b/test/sha1_cx.cpp index 9ef8267..1f99d2e 100644 --- a/test/sha1_cx.cpp +++ b/test/sha1_cx.cpp @@ -12,18 +12,28 @@ # pragma warning(disable: 4307) // integral constant overflow #endif -#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) - template BOOST_CXX14_CONSTEXPR typename H::result_type test( std::uint64_t seed, unsigned char const (&v)[ N ] ) { H h( seed ); h.update( v, N / 3 ); - h.update( v, N - N / 3 ); + h.update( v + N / 3, N - N / 3 ); return h.result(); } +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +#if defined(BOOST_NO_CXX14_CONSTEXPR) + +# define TEST_EQ(x1, x2) BOOST_TEST_EQ(x1, x2) + +#else + +# define TEST_EQ(x1, x2) BOOST_TEST_EQ(x1, x2); STATIC_ASSERT(x1 == x2) + +#endif + int main() { using namespace boost::hash2; @@ -33,15 +43,8 @@ int main() BOOST_CXX14_CONSTEXPR digest<20> r1 = {{ 0xBD, 0x05, 0x7D, 0x7F, 0x49, 0x14, 0x38, 0x24, 0xE4, 0x52, 0x63, 0x14, 0x7A, 0x02, 0xA5, 0x80, 0x13, 0x7F, 0xAB, 0xEF }}; BOOST_CXX14_CONSTEXPR digest<20> r2 = {{ 0xB8, 0x90, 0x42, 0x8C, 0x88, 0xBB, 0x53, 0xD1, 0x19, 0xB9, 0x34, 0x18, 0x0D, 0xA6, 0x26, 0x5B, 0xB1, 0xEF, 0xF7, 0x58 }}; - BOOST_TEST_EQ( test( 0, v ), r1 ); - BOOST_TEST_EQ( test( 7, v ), r2 ); - -#if !defined(BOOST_NO_CXX14_CONSTEXPR) - - STATIC_ASSERT( test( 0, v ) == r1 ); - STATIC_ASSERT( test( 7, v ) == r2 ); - -#endif + TEST_EQ( test( 0, v ), r1 ); + TEST_EQ( test( 7, v ), r2 ); return boost::report_errors(); } From 7aad2abda419a2342afce5bca1fcad6f8f5cb70b Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 6 Nov 2024 02:53:48 +0200 Subject: [PATCH 14/20] Remove unnecessary includes --- test/md5_cx.cpp | 1 - test/sha1_cx.cpp | 1 - test/siphash_cx.cpp | 1 - test/xxhash_cx.cpp | 1 - 4 files changed, 4 deletions(-) diff --git a/test/md5_cx.cpp b/test/md5_cx.cpp index 68707ee..3d03a96 100644 --- a/test/md5_cx.cpp +++ b/test/md5_cx.cpp @@ -3,7 +3,6 @@ // https://www.boost.org/LICENSE_1_0.txt #include -#include #include #include #include diff --git a/test/sha1_cx.cpp b/test/sha1_cx.cpp index 1f99d2e..3d2ac96 100644 --- a/test/sha1_cx.cpp +++ b/test/sha1_cx.cpp @@ -3,7 +3,6 @@ // https://www.boost.org/LICENSE_1_0.txt #include -#include #include #include #include diff --git a/test/siphash_cx.cpp b/test/siphash_cx.cpp index 5044f7c..63fdf45 100644 --- a/test/siphash_cx.cpp +++ b/test/siphash_cx.cpp @@ -3,7 +3,6 @@ // https://www.boost.org/LICENSE_1_0.txt #include -#include #include #include #include diff --git a/test/xxhash_cx.cpp b/test/xxhash_cx.cpp index 52a81bb..7a23e7b 100644 --- a/test/xxhash_cx.cpp +++ b/test/xxhash_cx.cpp @@ -3,7 +3,6 @@ // https://www.boost.org/LICENSE_1_0.txt #include -#include #include #include #include From f1cbe459e988b34207097f47887feba82df2bd1c Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 6 Nov 2024 02:56:08 +0200 Subject: [PATCH 15/20] Update test/hmac_md5_cx.cpp --- test/hmac_md5_cx.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/test/hmac_md5_cx.cpp b/test/hmac_md5_cx.cpp index 6e53940..ec9badf 100644 --- a/test/hmac_md5_cx.cpp +++ b/test/hmac_md5_cx.cpp @@ -3,7 +3,6 @@ // https://www.boost.org/LICENSE_1_0.txt #include -#include #include #include #include @@ -12,18 +11,28 @@ # pragma warning(disable: 4307) // integral constant overflow #endif -#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) - template BOOST_CXX14_CONSTEXPR typename H::result_type test( std::uint64_t seed, unsigned char const (&v)[ N ] ) { H h( seed ); h.update( v, N / 3 ); - h.update( v, N - N / 3 ); + h.update( v + N / 3, N - N / 3 ); return h.result(); } +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +#if defined(BOOST_NO_CXX14_CONSTEXPR) || ( defined(BOOST_GCC) && BOOST_GCC < 60000 ) + +# define TEST_EQ(x1, x2) BOOST_TEST_EQ(x1, x2) + +#else + +# define TEST_EQ(x1, x2) BOOST_TEST_EQ(x1, x2); STATIC_ASSERT(x1 == x2) + +#endif + int main() { using namespace boost::hash2; @@ -33,15 +42,8 @@ int main() BOOST_CXX14_CONSTEXPR digest<16> r1 = {{ 0x6F, 0x37, 0xD7, 0x4E, 0xD7, 0x97, 0xC2, 0x55, 0xEA, 0x1E, 0x4A, 0x46, 0xC3, 0x52, 0x39, 0xD7 }}; BOOST_CXX14_CONSTEXPR digest<16> r2 = {{ 0x68, 0xD4, 0xDF, 0x36, 0x73, 0x64, 0x42, 0xC0, 0xED, 0xE2, 0xA6, 0x15, 0x85, 0x10, 0xA4, 0x5E }}; - BOOST_TEST_EQ( test( 0, v ), r1 ); - BOOST_TEST_EQ( test( 7, v ), r2 ); - -#if !defined(BOOST_NO_CXX14_CONSTEXPR) && !( defined(BOOST_GCC) && BOOST_GCC < 60000 ) - - STATIC_ASSERT( test( 0, v ) == r1 ); - STATIC_ASSERT( test( 7, v ) == r2 ); - -#endif + TEST_EQ( test( 0, v ), r1 ); + TEST_EQ( test( 7, v ), r2 ); return boost::report_errors(); } From 2f5fc32113cf4715985324967551df540e3248f7 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 6 Nov 2024 03:13:57 +0200 Subject: [PATCH 16/20] Fix GCC 5 workaround --- include/boost/hash2/hmac.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/hash2/hmac.hpp b/include/boost/hash2/hmac.hpp index 318c703..797d1c3 100644 --- a/include/boost/hash2/hmac.hpp +++ b/include/boost/hash2/hmac.hpp @@ -16,7 +16,7 @@ #include #include -#if !defined(BOOST_NO_CXX14_CONSTEXPR) || BOOST_WORKAROUND(BOOST_GCC, < 60000) +#if !defined(BOOST_NO_CXX14_CONSTEXPR) && !BOOST_WORKAROUND(BOOST_GCC, < 60000) # define BOOST_HASH2_HMAC_CONSTEXPR constexpr From 20b01a9fdcd4d413cba7a7d0e94c451d280883b2 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 6 Nov 2024 03:18:24 +0200 Subject: [PATCH 17/20] Update test/sha1.cpp --- test/sha1.cpp | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/test/sha1.cpp b/test/sha1.cpp index 2027d6f..64a9783 100644 --- a/test/sha1.cpp +++ b/test/sha1.cpp @@ -6,31 +6,11 @@ #include #include -#include #include -#include -#include - -template std::string to_string( std::array const & v ) -{ - std::string r; - - for( std::size_t i = 0; i < N; ++i ) - { - char buffer[ 8 ]; - - std::snprintf( buffer, sizeof( buffer ), "%02x", static_cast( v[ i ] ) ); - - r += buffer; - } - - return r; -} template std::string digest( std::string const & s ) { H h; - h.update( s.data(), s.size() ); return to_string( h.result() ); From 742e5724d65637bae668bc9f0a45ed4e365e1afa Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 6 Nov 2024 03:21:38 +0200 Subject: [PATCH 18/20] Update test/hmac_sha1.cpp --- test/hmac_sha1.cpp | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/test/hmac_sha1.cpp b/test/hmac_sha1.cpp index 7412d0f..211568f 100644 --- a/test/hmac_sha1.cpp +++ b/test/hmac_sha1.cpp @@ -10,26 +10,7 @@ #include #include -#include #include -#include -#include - -template std::string to_string( std::array const & v ) -{ - std::string r; - - for( std::size_t i = 0; i < N; ++i ) - { - char buffer[ 8 ]; - - std::snprintf( buffer, sizeof( buffer ), "%02x", static_cast( v[ i ] ) ); - - r += buffer; - } - - return r; -} template std::string digest( std::string const & k, std::string const & s ) { From 3999960c65f5c65ce8e82ec4325cee0cf4fbab4d Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Wed, 6 Nov 2024 10:05:37 -0800 Subject: [PATCH 19/20] add reference docs for ripemd-160 --- doc/hash2/reference/ripemd.adoc | 83 +++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/doc/hash2/reference/ripemd.adoc b/doc/hash2/reference/ripemd.adoc index 63e97cf..2d8673f 100644 --- a/doc/hash2/reference/ripemd.adoc +++ b/doc/hash2/reference/ripemd.adoc @@ -22,5 +22,88 @@ using hmac_ripemd_160 = hmac; } // namespace boost ``` +This header implements the https://homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf[RIPEMD-160] algorithm. + ## ripemd_160 +``` +class ripemd_160 +{ + using result_type = digest<20>; + + static constexpr int block_size = 64; + + constexpr ripemd_160(); + explicit constexpr ripemd_160( std::uint64_t seed ); + constexpr ripemd_160( unsigned char const* p, std::size_t n ); + + void update( void const * pv, std::size_t n ); + constexpr void update( unsigned char const* p, std::size_t n ); + + constexpr result_type result(); +}; +``` + +### Constructors + +``` +constexpr ripemd_160(); +``` + +Default constructor. + +Effects: :: + Initializes the internal state of the RIPEMD-160 algorithm to its initial values. + +``` +explicit constexpr ripemd_160( std::uint64_t seed ); +``` + +Constructor taking an integral seed value. + +Effects: :: + Initializes the state as if by default construction, then if `seed` is not zero, performs `update(p, 8); result();` where `p` points to a little-endian representation of the value of `seed`. + +Remarks: :: + By convention, if `seed` is zero, the effect of this constructor is the same as default construction. + +``` +constexpr ripemd_160( unsigned char const* p, std::size_t n ); +``` + +Constructor taking a byte sequence seed. + +Effects: :: + Initializes the state as if by default construction, then if `n` is not zero, performs `update(p, n); result()`. + +Remarks: :: + By convention, if `n` is zero, the effect of this constructor is the same as default construction. + +### update + +``` +void update( void const* p, std::size_t n ); +constexpr void update( unsigned char const* p, std::size_t n ); +``` + +Effects: :: + Updates the internal state of the RIPEMD-160 algorithm from the byte sequence `[p, p+n)`. + +Remarks: :: + Consecutive calls to `update` are equivalent to a single call with the concatenated byte sequences of the individual calls. + +### result + +``` +constexpr result_type result(); +``` + +Effects: :: + Pads the accumulated message and finalizes the RIPEMD-160 digest. + +Returns: :: + The RIPEMD-160 digest of the message formed from the byte sequences of the preceding calls to `update`. + +Remarks: :: + Repeated calls to `result()` return a pseudorandom sequence of `result_type` values, effectively extending the output. + From f45b248c09735ad57a32a039f0e3de594c744a00 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Wed, 6 Nov 2024 10:13:44 -0800 Subject: [PATCH 20/20] cleanup ripemd-160 constexpr tests --- test/ripemd_cx.cpp | 48 +++++++++++++++++----------------------------- 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/test/ripemd_cx.cpp b/test/ripemd_cx.cpp index 7895331..032691f 100644 --- a/test/ripemd_cx.cpp +++ b/test/ripemd_cx.cpp @@ -14,6 +14,12 @@ #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) +#if defined(BOOST_NO_CXX14_CONSTEXPR) +# define TEST_EQ(x1, x2) BOOST_TEST_EQ(x1, x2) +#else +# define TEST_EQ(x1, x2) BOOST_TEST_EQ(x1, x2); STATIC_ASSERT(x1 == x2) +#endif + template BOOST_CXX14_CONSTEXPR typename H::result_type test( std::uint64_t seed, boost::hash2::digest const& dgst ) { H h( seed ); @@ -57,37 +63,19 @@ int main() { using namespace boost::hash2; - BOOST_TEST_EQ( test( 0, digest_from_str( "a" ) ), digest_from_hex( "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe" ) ); - BOOST_TEST_EQ( test( 0, digest_from_str( "abc" ) ), digest_from_hex( "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc" ) ); - BOOST_TEST_EQ( test( 0, digest_from_str( "message digest" ) ), digest_from_hex( "5d0689ef49d2fae572b881b123a85ffa21595f36" ) ); - BOOST_TEST_EQ( test( 0, digest_from_str( "abcdefghijklmnopqrstuvwxyz" ) ), digest_from_hex( "f71c27109c692c1b56bbdceb5b9d2865b3708dbc" ) ); - BOOST_TEST_EQ( test( 0, digest_from_str( "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) ), digest_from_hex( "12a053384a9c0c88e405a06c27dcf49ada62eb2b" ) ); - BOOST_TEST_EQ( test( 0, digest_from_str( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) ), digest_from_hex( "b0e20b6e3116640286ed3a87a5713079b21f5189" ) ); + TEST_EQ( test( 0, digest_from_str( "a" ) ), digest_from_hex( "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe" ) ); + TEST_EQ( test( 0, digest_from_str( "abc" ) ), digest_from_hex( "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc" ) ); + TEST_EQ( test( 0, digest_from_str( "message digest" ) ), digest_from_hex( "5d0689ef49d2fae572b881b123a85ffa21595f36" ) ); + TEST_EQ( test( 0, digest_from_str( "abcdefghijklmnopqrstuvwxyz" ) ), digest_from_hex( "f71c27109c692c1b56bbdceb5b9d2865b3708dbc" ) ); + TEST_EQ( test( 0, digest_from_str( "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) ), digest_from_hex( "12a053384a9c0c88e405a06c27dcf49ada62eb2b" ) ); + TEST_EQ( test( 0, digest_from_str( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) ), digest_from_hex( "b0e20b6e3116640286ed3a87a5713079b21f5189" ) ); - BOOST_TEST_EQ( test( 7, digest_from_str( "a" ) ), digest_from_hex( "7580d81d5ed1467317ce3ab9199088764a518b9d" ) ); - BOOST_TEST_EQ( test( 7, digest_from_str( "abc" ) ), digest_from_hex( "f5a724fe56b405db4edcb1ea46707ad78753a2e4" ) ); - BOOST_TEST_EQ( test( 7, digest_from_str( "message digest" ) ), digest_from_hex( "da6a32ce82c07de14ac5c2be1be3775201f07941" ) ); - BOOST_TEST_EQ( test( 7, digest_from_str( "abcdefghijklmnopqrstuvwxyz" ) ), digest_from_hex( "221e3b3af0671febf816397ded6f05c8a5c540d3" ) ); - BOOST_TEST_EQ( test( 7, digest_from_str( "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) ), digest_from_hex( "4578ce76d4ddec5a75288306da83f65eb963973c" ) ); - BOOST_TEST_EQ( test( 7, digest_from_str( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) ), digest_from_hex( "868f80dffc5c55612afdd5f8c7c4948410134dc5" ) ); - -#if !defined(BOOST_NO_CXX14_CONSTEXPR) - - STATIC_ASSERT( test( 0, digest_from_str( "a" ) ) == digest_from_hex( "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe" ) ); - STATIC_ASSERT( test( 0, digest_from_str( "abc" ) ) == digest_from_hex( "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc" ) ); - STATIC_ASSERT( test( 0, digest_from_str( "message digest" ) ) == digest_from_hex( "5d0689ef49d2fae572b881b123a85ffa21595f36" ) ); - STATIC_ASSERT( test( 0, digest_from_str( "abcdefghijklmnopqrstuvwxyz" ) ) == digest_from_hex( "f71c27109c692c1b56bbdceb5b9d2865b3708dbc" ) ); - STATIC_ASSERT( test( 0, digest_from_str( "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) ) == digest_from_hex( "12a053384a9c0c88e405a06c27dcf49ada62eb2b" ) ); - STATIC_ASSERT( test( 0, digest_from_str( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) ) == digest_from_hex( "b0e20b6e3116640286ed3a87a5713079b21f5189" ) ); - - STATIC_ASSERT( test( 7, digest_from_str( "a" ) ) == digest_from_hex( "7580d81d5ed1467317ce3ab9199088764a518b9d" ) ); - STATIC_ASSERT( test( 7, digest_from_str( "abc" ) ) == digest_from_hex( "f5a724fe56b405db4edcb1ea46707ad78753a2e4" ) ); - STATIC_ASSERT( test( 7, digest_from_str( "message digest" ) ) == digest_from_hex( "da6a32ce82c07de14ac5c2be1be3775201f07941" ) ); - STATIC_ASSERT( test( 7, digest_from_str( "abcdefghijklmnopqrstuvwxyz" ) ) == digest_from_hex( "221e3b3af0671febf816397ded6f05c8a5c540d3" ) ); - STATIC_ASSERT( test( 7, digest_from_str( "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) ) == digest_from_hex( "4578ce76d4ddec5a75288306da83f65eb963973c" ) ); - STATIC_ASSERT( test( 7, digest_from_str( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) ) == digest_from_hex( "868f80dffc5c55612afdd5f8c7c4948410134dc5" ) ); - -#endif + TEST_EQ( test( 7, digest_from_str( "a" ) ), digest_from_hex( "7580d81d5ed1467317ce3ab9199088764a518b9d" ) ); + TEST_EQ( test( 7, digest_from_str( "abc" ) ), digest_from_hex( "f5a724fe56b405db4edcb1ea46707ad78753a2e4" ) ); + TEST_EQ( test( 7, digest_from_str( "message digest" ) ), digest_from_hex( "da6a32ce82c07de14ac5c2be1be3775201f07941" ) ); + TEST_EQ( test( 7, digest_from_str( "abcdefghijklmnopqrstuvwxyz" ) ), digest_from_hex( "221e3b3af0671febf816397ded6f05c8a5c540d3" ) ); + TEST_EQ( test( 7, digest_from_str( "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ) ), digest_from_hex( "4578ce76d4ddec5a75288306da83f65eb963973c" ) ); + TEST_EQ( test( 7, digest_from_str( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) ), digest_from_hex( "868f80dffc5c55612afdd5f8c7c4948410134dc5" ) ); return boost::report_errors(); }