Skip to content

Commit

Permalink
Merge pull request #4 from cmazakas/feature/sha-224
Browse files Browse the repository at this point in the history
add sha-224 impl
  • Loading branch information
pdimov authored Sep 26, 2024
2 parents 2ffd620 + 2bc2b2d commit eb570e7
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 24 deletions.
103 changes: 80 additions & 23 deletions include/boost/hash2/sha2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
#include <boost/hash2/detail/rot.hpp>
#include <boost/hash2/detail/write.hpp>
#include <boost/assert.hpp>
#include <boost/cstdint.hpp>
#include <array>
#include <cstddef>
#include <cstdint>
#include <cstring>

Expand All @@ -23,10 +21,11 @@ namespace boost
namespace hash2
{

class sha2_256
namespace detail
{
private:

struct sha2_256_base
{
std::uint32_t state_[ 8 ];

static const int N = 64;
Expand All @@ -36,18 +35,8 @@ class sha2_256

std::uint64_t n_;

private:

void init()
sha2_256_base(): m_( 0 ), n_( 0 )
{
state_[ 0 ] = 0x6a09e667;
state_[ 1 ] = 0xbb67ae85;
state_[ 2 ] = 0x3c6ef372;
state_[ 3 ] = 0xa54ff53a;
state_[ 4 ] = 0x510e527f;
state_[ 5 ] = 0x9b05688c;
state_[ 6 ] = 0x1f83d9ab;
state_[ 7 ] = 0x5be0cd19;
}

static std::uint32_t Sigma0( std::uint32_t x ) noexcept
Expand Down Expand Up @@ -140,14 +129,6 @@ class sha2_256
state_[7] += h;
}

public:
using result_type = std::array<unsigned char, 32>;

sha2_256(): m_( 0 ), n_( 0 )
{
init();
}

void update( void const * pv, std::size_t n )
{
unsigned char const* p = static_cast<unsigned char const*>( pv );
Expand Down Expand Up @@ -201,6 +182,35 @@ class sha2_256

BOOST_ASSERT( m_ == n_ % N );
}
};

} // namespace detail

class sha2_256 : detail::sha2_256_base
{
private:

void init()
{
state_[ 0 ] = 0x6a09e667;
state_[ 1 ] = 0xbb67ae85;
state_[ 2 ] = 0x3c6ef372;
state_[ 3 ] = 0xa54ff53a;
state_[ 4 ] = 0x510e527f;
state_[ 5 ] = 0x9b05688c;
state_[ 6 ] = 0x1f83d9ab;
state_[ 7 ] = 0x5be0cd19;
}

public:
using result_type = std::array<unsigned char, 32>;

sha2_256()
{
init();
}

using detail::sha2_256_base::update;

result_type result()
{
Expand All @@ -223,6 +233,53 @@ class sha2_256
}
};

class sha2_224 : detail::sha2_256_base
{
private:

void init()
{
state_[ 0 ] = 0xc1059ed8;
state_[ 1 ] = 0x367cd507;
state_[ 2 ] = 0x3070dd17;
state_[ 3 ] = 0xf70e5939;
state_[ 4 ] = 0xffc00b31;
state_[ 5 ] = 0x68581511;
state_[ 6 ] = 0x64f98fa7;
state_[ 7 ] = 0xbefa4fa4;
}

public:
using result_type = std::array<unsigned char, 28>;

sha2_224()
{
init();
}

using detail::sha2_256_base::update;

result_type result()
{
unsigned char bits[ 8 ];
detail::write64be( bits, n_ * 8 );

std::size_t k = m_ < 56 ? 56 - m_ : 64 + 56 - m_;
unsigned char padding[ 64 ] = { 0x80 };

update( padding, k );
update( bits, 8 );
BOOST_ASSERT( m_ == 0 );

result_type digest;
for( int i = 0; i < 7; ++i ) {
detail::write32be( &digest[ i * 4 ], state_[ i ] );
}

return digest;
}
};

} // namespace hash2
} // namespace boost

Expand Down
53 changes: 52 additions & 1 deletion test/sha2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ template<class H> std::string digest( std::vector<char> const & v )
}

using boost::hash2::sha2_256;
using boost::hash2::sha2_224;

int main()
static
void sha_256()
{
// https://en.wikipedia.org/wiki/SHA-2#Test_vectors

Expand Down Expand Up @@ -106,6 +108,55 @@ int main()
std::vector<char> buf(1000000, 0x00);
BOOST_TEST_EQ( digest<sha2_256>( buf ), std::string( "d29751f2649b32ff572b5e0a9f541ea660a50f94ff0beedfb0b692b924cc8025" ) );
}
}

static
void sha_224()
{
// https://en.wikipedia.org/wiki/SHA-2#Test_vectors

BOOST_TEST_EQ( digest<sha2_224>( "" ), std::string( "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f" ) );

// https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA224.pdf
BOOST_TEST_EQ( digest<sha2_224>( "abc" ), std::string( "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7" ) );
BOOST_TEST_EQ( digest<sha2_224>( "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ), std::string( "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525" ) );

// https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA2_Additional.pdf
BOOST_TEST_EQ( digest<sha2_224>( "\xff" ), std::string( "e33f9d75e6ae1369dbabf81b96b4591ae46bba30b591a6b6c62542b5" ) );
BOOST_TEST_EQ( digest<sha2_224>( "\xe5\xe0\x99\x24" ), std::string( "fd19e74690d291467ce59f077df311638f1c3a46e510d0e49a67062d" ) );

{
char buf[ 56 ] = { 0 };
BOOST_TEST_EQ( digest<sha2_224>( buf ), std::string( "5c3e25b69d0ea26f260cfae87e23759e1eca9d1ecc9fbf3c62266804" ) );
}

{
char buf[ 1000 ] = {};
for( auto& c : buf ) c = 'Q';
BOOST_TEST_EQ( digest<sha2_224>( buf ), std::string( "3706197f66890a41779dc8791670522e136fafa24874685715bd0a8a" ) );
}

{
char buf[ 1000 ] = {};
for( auto& c : buf ) c = 'A';
BOOST_TEST_EQ( digest<sha2_224>( buf ), std::string( "a8d0c66b5c6fdfd836eb3c6d04d32dfe66c3b1f168b488bf4c9c66ce" ) );
}

{
char buf[ 1005 ] = {};
for( auto& c : buf ) c = '\x99';
BOOST_TEST_EQ( digest<sha2_224>( buf ), std::string( "cb00ecd03788bf6c0908401e0eb053ac61f35e7e20a2cfd7bd96d640" ) );
}

{
std::vector<char> buf(1000000, 0x00);
BOOST_TEST_EQ( digest<sha2_224>( buf ), std::string( "3a5d74b68f14f3a4b2be9289b8d370672d0b3d2f53bc303c59032df3" ) );
}
}

int main()
{
sha_256();
sha_224();
return boost::report_errors();
}

0 comments on commit eb570e7

Please sign in to comment.