hash/blake2: use aligned storage for u64 salt components

This commit is contained in:
Danny Robson 2019-02-10 13:12:05 +11:00
parent a2474e6b09
commit 2e615b1b19
2 changed files with 11 additions and 12 deletions

View File

@ -135,8 +135,8 @@ blake2::blake2 (cruft::view<const u08 *> key)
if (key.size () > ::traits::max_key_bytes)
throw std::invalid_argument ("key is too large");
std::fill (m_salt.begin (), m_salt.end (), 0);
memcpy (m_salt.data (), key.data (), key.size ());
std::fill (m_salt.val08.begin (), m_salt.val08.end (), 0);
memcpy (m_salt.val08.data (), key.data (), key.size ());
m_keylen = key.size ();
}
@ -145,13 +145,11 @@ blake2::blake2 (cruft::view<const u08 *> key)
blake2::digest_t
blake2::operator() (cruft::view<const u08 *> data) const noexcept
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
auto h = ::traits::iv;
h[0] ^= 0x01010000 ^ (m_keylen << 8) ^ sizeof (digest_t);
if (m_keylen)
F (h, reinterpret_cast<const word_t*> (m_salt.data ()), ::traits::block_bytes, data.empty ());
F (h, m_salt.val64.data (), ::traits::block_bytes, data.empty ());
// special case for the empty key and empty data
if (!m_keylen && data.empty ()) {
@ -164,7 +162,7 @@ blake2::operator() (cruft::view<const u08 *> data) const noexcept
auto cursor = data.begin ();
while (cursor + ::traits::block_bytes < data.end ()) {
counter += ::traits::block_bytes;
F (h, reinterpret_cast<const word_t*> (cursor), counter, false);
F (h, cruft::cast::alignment<word_t const*> (cursor), counter, false);
cursor += ::traits::block_bytes;
}
@ -178,5 +176,4 @@ blake2::operator() (cruft::view<const u08 *> data) const noexcept
digest_t d;
memcpy (&d, h.data (), sizeof (d));
return d;
#pragma GCC diagnostic pop
}

View File

@ -6,9 +6,9 @@
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
*/
#ifndef CRUFT_CRYPTO_HASH_BLAKE2_HPP
#define CRUFT_CRYPTO_HASH_BLAKE2_HPP
#pragma once
#include <cruft/util/std.hpp>
#include <cruft/util/view.hpp>
#include <array>
@ -34,9 +34,11 @@ namespace cruft::crypto::hash {
// updates, not because it's a functional requirement. either way we
// need to copy at least 64 bytes, so the user shouldn't be copying
// these too much regardless.
std::array<uint8_t,128> m_salt;
union {
std::array<u08,128> val08;
std::array<u64, 16> val64;
} m_salt;
uint64_t m_keylen;
};
};
#endif