hash: style

This commit is contained in:
Danny Robson 2016-06-17 16:20:09 +10:00
parent 5e6155a51a
commit ce26ce1238
15 changed files with 231 additions and 95 deletions

View File

@ -20,6 +20,8 @@
#include <cstdint>
#include <cstdlib>
///////////////////////////////////////////////////////////////////////////////
namespace util { namespace hash {
uint32_t adler32 (const void* restrict, size_t) noexcept;
uint32_t adler32 (const uint8_t *restrict first, const uint8_t *restrict last) noexcept;

View File

@ -38,7 +38,7 @@ util::hash::bsdsum (
}
///////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
uint16_t
util::hash::bsdsum (const void *restrict data, size_t size) noexcept
{

View File

@ -20,6 +20,8 @@
#include <cstdint>
#include <cstdlib>
///////////////////////////////////////////////////////////////////////////////
namespace util { namespace hash {
uint16_t bsdsum (const void *restrict data, size_t bytes) noexcept;
uint16_t bsdsum (const uint8_t *restrict first, const uint8_t *restrict last) noexcept;

View File

@ -20,6 +20,8 @@
#include <cstdint>
#include <cstdlib>
///////////////////////////////////////////////////////////////////////////////
namespace util { namespace hash {
uint32_t crc32 (const void *restrict data, size_t bytes) noexcept;
uint32_t crc32 (const uint8_t *restrict first, const uint8_t *restrict last) noexcept;

View File

@ -21,6 +21,7 @@
#include <cstdint>
///////////////////////////////////////////////////////////////////////////////
namespace util { namespace hash {
class MD2 {
public:

View File

@ -25,30 +25,44 @@
using util::hash::MD4;
using std::array;
///////////////////////////////////////////////////////////////////////////////
// Auxiliary functions for each set of rounds
static inline uint32_t
static constexpr
uint32_t
F (uint32_t X, uint32_t Y, uint32_t Z)
{ return (X & Y) | (~X & Z); }
{
return (X & Y) | (~X & Z);
}
static inline uint32_t
//-----------------------------------------------------------------------------
static constexpr
uint32_t
G (uint32_t X, uint32_t Y, uint32_t Z)
{ return (X & Y) | (X & Z) | (Y & Z); }
{
return (X & Y) | (X & Z) | (Y & Z);
}
static inline uint32_t
//-----------------------------------------------------------------------------
static constexpr
uint32_t
H (uint32_t X, uint32_t Y, uint32_t Z)
{ return X ^ Y ^ Z; }
{
return X ^ Y ^ Z;
}
// Constructors and setup functions
static const uint32_t DEFAULT_A = 0x67452301;
static const uint32_t DEFAULT_B = 0xefcdab89;
static const uint32_t DEFAULT_C = 0x98badcfe;
static const uint32_t DEFAULT_D = 0x10325476;
//-----------------------------------------------------------------------------
static constexpr uint32_t DEFAULT_A = 0x67452301;
static constexpr uint32_t DEFAULT_B = 0xefcdab89;
static constexpr uint32_t DEFAULT_C = 0x98badcfe;
static constexpr uint32_t DEFAULT_D = 0x10325476;
///////////////////////////////////////////////////////////////////////////////
MD4::MD4 ()
{
reset ();
@ -59,8 +73,10 @@ MD4::MD4 ()
}
//-----------------------------------------------------------------------------
void
MD4::reset (void) {
MD4::reset (void)
{
m_total = 0;
ABCD[0] = DEFAULT_A;
@ -72,6 +88,7 @@ MD4::reset (void) {
}
///////////////////////////////////////////////////////////////////////////////
void
MD4::update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept
{
@ -81,13 +98,18 @@ MD4::update (const uint8_t *restrict first, const uint8_t *restrict last) noexce
}
//-----------------------------------------------------------------------------
void
MD4::update (const void *restrict data, size_t size) noexcept
{ update (static_cast<const uint8_t*> (data), size); }
{
update (static_cast<const uint8_t*> (data), size);
}
//-----------------------------------------------------------------------------
void
MD4::update (const uint8_t *restrict data, size_t size) noexcept {
MD4::update (const uint8_t *restrict data, size_t size) noexcept
{
size_t offset = m_total % sizeof (Xb);
size_t remain = sizeof (Xb) - offset;
@ -116,16 +138,20 @@ MD4::update (const uint8_t *restrict data, size_t size) noexcept {
}
///////////////////////////////////////////////////////////////////////////////
MD4::digest_t
MD4::digest (void) const {
MD4::digest (void) const
{
digest_t d;
memcpy (d.data (), ABCD.data(), sizeof (ABCD));
return d;
}
///////////////////////////////////////////////////////////////////////////////
void
MD4::transform (void) {
MD4::transform (void)
{
uint32_t A = ABCD[0],
B = ABCD[1],
C = ABCD[2],
@ -213,8 +239,10 @@ MD4::transform (void) {
}
///////////////////////////////////////////////////////////////////////////////
void
MD4::finish (void) {
MD4::finish (void)
{
uint64_t bits = m_total * 8;
{
@ -246,4 +274,3 @@ MD4::finish (void) {
transform ();
}
}

View File

@ -20,6 +20,8 @@
#include <array>
#include <cstdint>
///////////////////////////////////////////////////////////////////////////////
namespace util { namespace hash {
class MD4 {
public:

View File

@ -24,29 +24,44 @@
using util::hash::MD5;
///////////////////////////////////////////////////////////////////////////////
// Per-round mixing functions
static inline uint32_t
static constexpr
uint32_t
F (uint32_t x, uint32_t y, uint32_t z)
//{ return (x & y) | (~x & z); }
{ return z ^ (x & (y ^ z)); }
{
return z ^ (x & (y ^ z));
}
static inline uint32_t
//-----------------------------------------------------------------------------
static constexpr
uint32_t
G (uint32_t x, uint32_t y, uint32_t z)
//{ return (x & z) | (y & ~z); }
{ return F (z, x, y); }
{
return F (z, x, y);
}
static inline uint32_t
//-----------------------------------------------------------------------------
static constexpr
uint32_t
H (uint32_t x, uint32_t y, uint32_t z)
{ return x ^ y ^ z; }
{
return x ^ y ^ z;
}
static inline uint32_t
//-----------------------------------------------------------------------------
static constexpr
uint32_t
I (uint32_t x, uint32_t y, uint32_t z)
{ return y ^ (x | ~z); }
{
return y ^ (x | ~z);
}
///////////////////////////////////////////////////////////////////////////////
// Mixing constants for all rounds. They are defined as 'abs(sin(i)) * max_uint32', but we use the
// literals to avoid any stupid maths issues during compilation.
const std::array<uint32_t, 65> T = { {
@ -78,21 +93,24 @@ const std::array<uint32_t, 65> T = { {
} };
//-----------------------------------------------------------------------------
static const uint32_t DEFAULT_A = 0x67452301;
static const uint32_t DEFAULT_B = 0xefcdab89;
static const uint32_t DEFAULT_C = 0x98badcfe;
static const uint32_t DEFAULT_D = 0x10325476;
///////////////////////////////////////////////////////////////////////////////
MD5::MD5()
{
reset ();
}
//-----------------------------------------------------------------------------
void
MD5::reset (void) {
MD5::reset (void)
{
m_total = 0;
ABCD[0] = DEFAULT_A;
@ -102,6 +120,7 @@ MD5::reset (void) {
}
///////////////////////////////////////////////////////////////////////////////
void
MD5::update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept
{
@ -111,13 +130,18 @@ MD5::update (const uint8_t *restrict first, const uint8_t *restrict last) noexce
}
//-----------------------------------------------------------------------------
void
MD5::update (const void *restrict data, size_t len) noexcept
{ MD5::update (static_cast<const uint8_t*> (data), len); }
{
MD5::update (static_cast<const uint8_t*> (data), len);
}
//-----------------------------------------------------------------------------
void
MD5::update (const uint8_t *restrict data, size_t size) noexcept {
MD5::update (const uint8_t *restrict data, size_t size) noexcept
{
size_t offset = m_total % sizeof (Xb);
size_t remain = sizeof (Xb) - offset;
@ -146,8 +170,10 @@ MD5::update (const uint8_t *restrict data, size_t size) noexcept {
}
///////////////////////////////////////////////////////////////////////////////
MD5::digest_t
MD5::digest (void) const {
MD5::digest (void) const
{
static_assert (sizeof (ABCD) == sizeof (digest_t),
"Hash state must be the same size as the final digest");
@ -157,8 +183,10 @@ MD5::digest (void) const {
}
///////////////////////////////////////////////////////////////////////////////
void
MD5::finish (void) {
MD5::finish (void)
{
uint64_t bits = m_total * 8;
{
@ -192,8 +220,10 @@ MD5::finish (void) {
}
///////////////////////////////////////////////////////////////////////////////
void
MD5::transform (void) {
MD5::transform (void)
{
uint32_t A = ABCD[0],
B = ABCD[1],
C = ABCD[2],

View File

@ -21,6 +21,8 @@
#include <cstdint>
#include <cstdlib>
///////////////////////////////////////////////////////////////////////////////
namespace util { namespace hash {
class MD5 {
public:

View File

@ -33,8 +33,10 @@ RIPEMD::RIPEMD()
}
//-----------------------------------------------------------------------------
void
RIPEMD::reset (void) {
RIPEMD::reset (void)
{
m_state[0] = 0x67452301u;
m_state[1] = 0xEFCDAB89u;
m_state[2] = 0x98BADCFEu;
@ -49,7 +51,9 @@ RIPEMD::reset (void) {
///////////////////////////////////////////////////////////////////////////////
void
RIPEMD::update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept
RIPEMD::update (
const uint8_t *restrict first,
const uint8_t *restrict last) noexcept
{
CHECK_LE (first, last);
@ -59,7 +63,8 @@ RIPEMD::update (const uint8_t *restrict first, const uint8_t *restrict last) noe
//-----------------------------------------------------------------------------
void
RIPEMD::update (const uint8_t *restrict data, size_t len) noexcept {
RIPEMD::update (const uint8_t *restrict data, size_t len) noexcept
{
CHECK (data);
size_t cursor = 0;
@ -82,31 +87,56 @@ RIPEMD::update (const uint8_t *restrict data, size_t len) noexcept {
throw std::length_error ("exceeded maximum message length");
}
///////////////////////////////////////////////////////////////////////////////
static constexpr
uint32_t
f1 (uint32_t x, uint32_t y, uint32_t z) { return x ^ y ^ z; }
f1 (uint32_t x, uint32_t y, uint32_t z)
{
return x ^ y ^ z;
}
//-----------------------------------------------------------------------------
static constexpr
uint32_t
f2 (uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (~x & z); }
f2 (uint32_t x, uint32_t y, uint32_t z)
{
return (x & y) | (~x & z);
}
//-----------------------------------------------------------------------------
static constexpr
uint32_t
f3 (uint32_t x, uint32_t y, uint32_t z) { return (x | ~y) ^ z; }
f3 (uint32_t x, uint32_t y, uint32_t z)
{
return (x | ~y) ^ z;
}
//-----------------------------------------------------------------------------
static constexpr
uint32_t
f4 (uint32_t x, uint32_t y, uint32_t z) { return (x & z) | (y & ~z); }
f4 (uint32_t x, uint32_t y, uint32_t z)
{
return (x & z) | (y & ~z);
}
//-----------------------------------------------------------------------------
static constexpr
uint32_t
f5 (uint32_t x, uint32_t y, uint32_t z) { return x ^ (y | ~z); }
f5 (uint32_t x, uint32_t y, uint32_t z)
{
return x ^ (y | ~z);
}
///////////////////////////////////////////////////////////////////////////////
void
RIPEMD::transform (void) {
RIPEMD::transform (void)
{
CHECK_EQ (m_buffer.size, sizeof (m_buffer.d32));
// Use: boolean function f
@ -338,7 +368,8 @@ RIPEMD::transform (void) {
///////////////////////////////////////////////////////////////////////////////
void
RIPEMD::finish (void) {
RIPEMD::finish (void)
{
// Ensure the length wouldn't overflow if converted to bits. We need to
// grab this before there's a chance it gets overwritten.
CHECK_EQ (m_length >> sizeof(m_length) * 8 - 3, 0u);
@ -377,7 +408,8 @@ RIPEMD::finish (void) {
///////////////////////////////////////////////////////////////////////////////
RIPEMD::digest_t
RIPEMD::digest (void) const {
RIPEMD::digest (void) const
{
digest_t d;
memcpy (d.data (), m_state, sizeof (m_state));
return d;

View File

@ -20,6 +20,8 @@
#include <array>
///////////////////////////////////////////////////////////////////////////////
namespace util { namespace hash {
class RIPEMD {
public:

View File

@ -29,14 +29,12 @@
using util::hash::SHA1;
using std::numeric_limits;
using std::begin;
using std::end;
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
std::ostream&
operator<< (std::ostream &os, SHA1::state_t t) {
operator<< (std::ostream &os, SHA1::state_t t)
{
switch (t) {
case SHA1::READY: os << "READY"; return os;
case SHA1::FINISHED: os << "FINISHED"; return os;
@ -46,37 +44,53 @@ operator<< (std::ostream &os, SHA1::state_t t) {
}
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
// Logical function for sequence of rounds
static inline uint32_t
static constexpr
uint32_t
f_00 (uint32_t B, uint32_t C, uint32_t D)
{ return (B & C) | (~B & D); }
static inline uint32_t
f_20 (uint32_t B, uint32_t C, uint32_t D)
{ return B ^ C ^ D; }
static inline uint32_t
f_40 (uint32_t B, uint32_t C, uint32_t D)
{ return (B & C) | (B & D) | (C & D); }
static inline uint32_t
f_60 (uint32_t B, uint32_t C, uint32_t D)
{ return B ^ C ^ D; }
{
return (B & C) | (~B & D);
}
//-----------------------------------------------------------------------------
static constexpr
uint32_t
f_20 (uint32_t B, uint32_t C, uint32_t D)
{
return B ^ C ^ D;
}
//-----------------------------------------------------------------------------
static constexpr
uint32_t
f_40 (uint32_t B, uint32_t C, uint32_t D)
{
return (B & C) | (B & D) | (C & D);
}
//-----------------------------------------------------------------------------
static constexpr
uint32_t
f_60 (uint32_t B, uint32_t C, uint32_t D)
{
return B ^ C ^ D;
}
///////////////////////////////////////////////////////////////////////////////
// Constant words for sequence of rounds
static const uint32_t K_00 = 0x5A827999;
static const uint32_t K_20 = 0x6ED9EBA1;
static const uint32_t K_40 = 0x8F1BBCDC;
static const uint32_t K_60 = 0xCA62C1D6;
static constexpr uint32_t K_00 = 0x5A827999;
static constexpr uint32_t K_20 = 0x6ED9EBA1;
static constexpr uint32_t K_40 = 0x8F1BBCDC;
static constexpr uint32_t K_60 = 0xCA62C1D6;
static const uint32_t DEFAULT_H[] = {
static
constexpr uint32_t DEFAULT_H[] = {
0x67452301,
0xEFCDAB89,
0x98BADCFE,
@ -84,19 +98,22 @@ static const uint32_t DEFAULT_H[] = {
0xC3D2E1F0
};
static const size_t BLOCK_WORDS = 16;
static const size_t BLOCK_BYTES = BLOCK_WORDS * sizeof (uint32_t);
static constexpr size_t BLOCK_WORDS = 16;
static constexpr size_t BLOCK_BYTES = BLOCK_WORDS * sizeof (uint32_t);
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
SHA1::SHA1()
{
reset ();
}
//-----------------------------------------------------------------------------
void
SHA1::reset (void) {
SHA1::reset (void)
{
total = 0;
state = READY;
@ -104,9 +121,11 @@ SHA1::reset (void) {
}
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
void
SHA1::update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept
SHA1::update (
const uint8_t *restrict first,
const uint8_t *restrict last) noexcept
{
CHECK_LE (first, last);
@ -116,9 +135,10 @@ SHA1::update (const uint8_t *restrict first, const uint8_t *restrict last) noexc
//-----------------------------------------------------------------------------
void
SHA1::update (const uint8_t *restrict data, size_t size) noexcept {
SHA1::update (const uint8_t *restrict data, size_t size) noexcept
{
CHECK_EQ (state, READY);
CHECK_GE (numeric_limits<decltype(total)>::max () - total, size);
CHECK_GE (std::numeric_limits<decltype(total)>::max () - total, size);
while (size > 0) {
// Copy the data into the remaining available buffer slots
@ -139,9 +159,10 @@ SHA1::update (const uint8_t *restrict data, size_t size) noexcept {
}
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
void
SHA1::process (void) {
SHA1::process (void)
{
CHECK_EQ (total % BLOCK_BYTES, 0u);
// Byteswap the raw input we have buffered ready for arithmetic
@ -186,9 +207,10 @@ SHA1::process (void) {
}
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
void
SHA1::finish (void) {
SHA1::finish (void)
{
size_t offset = total % BLOCK_BYTES;
size_t used = total * 8;
@ -226,9 +248,10 @@ SHA1::finish (void) {
}
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
SHA1::digest_t
SHA1::digest (void) const {
SHA1::digest (void) const
{
CHECK_EQ (state, FINISHED);
return { {

View File

@ -23,7 +23,7 @@
#include <array>
//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
namespace util { namespace hash {
class SHA1 {
public:

View File

@ -171,6 +171,7 @@ SHA256::SHA256 ():
}
//-----------------------------------------------------------------------------
void
SHA256::update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept
{
@ -180,8 +181,10 @@ SHA256::update (const uint8_t *restrict first, const uint8_t *restrict last) noe
}
//-----------------------------------------------------------------------------
void
SHA256::update (const uint8_t *restrict data, size_t length) noexcept {
SHA256::update (const uint8_t *restrict data, size_t length) noexcept
{
while (length) {
size_t buffered = m_total % sizeof (M);
size_t chunk = std::min (sizeof (M) - buffered, length);
@ -196,8 +199,10 @@ SHA256::update (const uint8_t *restrict data, size_t length) noexcept {
}
///////////////////////////////////////////////////////////////////////////////
void
SHA256::finish (void) {
SHA256::finish (void)
{
// Append a single 1 bit followed by 0s.
size_t buffered = m_total % sizeof (M);
size_t used = m_total * 8;
@ -235,8 +240,10 @@ SHA256::finish (void) {
}
///////////////////////////////////////////////////////////////////////////////
void
SHA256::process (void) {
SHA256::process (void)
{
CHECK_EQ (m_total % sizeof (M), 0u);
// Initialise the message schedule, W
@ -281,8 +288,10 @@ SHA256::process (void) {
}
///////////////////////////////////////////////////////////////////////////////
SHA256::digest_t
SHA256::digest (void) const {
SHA256::digest (void) const
{
digest_t out;
auto cursor = out.begin ();

View File

@ -21,6 +21,8 @@
#include <array>
#include <cstdint>
///////////////////////////////////////////////////////////////////////////////
namespace util { namespace hash {
class SHA256 {
public: