Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ add_library(siphash_hpp INTERFACE)
target_include_directories(siphash_hpp INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/siphash-hpp>
$<INSTALL_INTERFACE:include/siphash-hpp>)
target_compile_features(siphash_hpp INTERFACE cxx_std_11)

include(CMakePackageConfigHelpers)

Expand Down
62 changes: 58 additions & 4 deletions include/siphash-hpp/siphash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <array>
#include <cassert>
#include <cstdint>
#include <cstddef>
#include <string>
#include <tuple>
#include <type_traits>
Expand Down Expand Up @@ -54,14 +55,28 @@ namespace siphash_hpp {

template<typename T>
struct runtime_size_checker<T, true> {
static void check(const T &key) {
static void check(const T &key, size_t = 0) {
assert(key.size() >= 16 && "SipHash key must be at least 16 bytes");
}
};

template<typename T>
struct runtime_size_checker<T, false> {
static void check(const T &) {}
static void check(const T &, size_t = 0) {}
};

template<>
struct runtime_size_checker<const uint8_t*, false> {
static void check(const uint8_t *, size_t length) {
assert(length >= 16 && "SipHash key must be at least 16 bytes");
}
};

template<>
struct runtime_size_checker<const char*, false> {
static void check(const char *, size_t length) {
assert(length >= 16 && "SipHash key must be at least 16 bytes");
}
};

class SipHash {
Expand Down Expand Up @@ -126,11 +141,19 @@ namespace siphash_hpp {
* \param c Number of rounds per message block
* \param d Number of finalization rounds
*/
template<class T>
template<class T, typename std::enable_if<!std::is_pointer<T>::value, int>::type = 0>
SipHash(const T &key, const size_t c = 2, const size_t d = 4) {
init(key, c, d);
};

SipHash(const char *key, size_t length, const size_t c = 2, const size_t d = 4) {
init(key, length, c, d);
};

SipHash(const uint8_t *key, size_t length, const size_t c = 2, const size_t d = 4) {
init(key, length, c, d);
};

~SipHash() {};

/** \brief Initialize SipHash
Expand All @@ -153,7 +176,30 @@ namespace siphash_hpp {
"SipHash key must be at least 16 bytes");

static_size_checker<T>::check();
runtime_size_checker<T>::check(key);
runtime_size_checker<T>::check(key, 0);

const uint64_t k0 = read8(key);
const uint64_t k1 = read8(key, 8);

v0 = (0x736f6d6570736575 ^ k0);
v1 = (0x646f72616e646f6d ^ k1);
v2 = (0x6c7967656e657261 ^ k0);
v3 = (0x7465646279746573 ^ k1);

index = 0;
input_len = 0;
m = 0;
}

inline void init(
const char *key,
size_t length,
const size_t c = 2,
const size_t d = 4) noexcept {
this->c = c;
this->d = d;

runtime_size_checker<const char*>::check(key, length);

const uint64_t k0 = read8(key);
const uint64_t k1 = read8(key, 8);
Expand All @@ -168,6 +214,14 @@ namespace siphash_hpp {
m = 0;
}

inline void init(
const uint8_t *key,
size_t length,
const size_t c = 2,
const size_t d = 4) noexcept {
init(reinterpret_cast<const char*>(key), length, c, d);
}

SipHash& update(const char byte) noexcept {
++input_len;
m |= (((uint64_t) byte & 0xff) << (index++ * 8));
Expand Down
10 changes: 10 additions & 0 deletions tests/siphash_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ TEST(SipHash, KnownValues) {
EXPECT_EQ(14986662229302055855ULL, siphash_hpp::siphash_4_8(data, key));
}

TEST(SipHash, PointerKey) {
const uint8_t key[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
std::string data = "hello";

siphash_hpp::SipHash h;
h.init(key, sizeof(key));
h.update(data);
EXPECT_EQ(4402678656023170274ULL, h.digest());
}

TEST(SipHash, EmptyMessageArrayKey) {
char key[16];
for (int i = 0; i < 16; ++i) key[i] = static_cast<char>(i);
Expand Down
Loading