Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
b4e242ffd4
@ -134,7 +134,6 @@ endif ()
|
|||||||
# Common files
|
# Common files
|
||||||
list (
|
list (
|
||||||
APPEND UTIL_FILES
|
APPEND UTIL_FILES
|
||||||
hash/md2.cpp
|
|
||||||
adapter.hpp
|
adapter.hpp
|
||||||
adapter.cpp
|
adapter.cpp
|
||||||
algo/sort.cpp
|
algo/sort.cpp
|
||||||
@ -186,18 +185,6 @@ list (
|
|||||||
coord/ops.hpp
|
coord/ops.hpp
|
||||||
coord/store.hpp
|
coord/store.hpp
|
||||||
coord/traits.hpp
|
coord/traits.hpp
|
||||||
crypto/arc4.cpp
|
|
||||||
crypto/arc4.hpp
|
|
||||||
crypto/ice.cpp
|
|
||||||
crypto/ice.hpp
|
|
||||||
crypto/salsa.cpp
|
|
||||||
crypto/salsa.hpp
|
|
||||||
crypto/tea.cpp
|
|
||||||
crypto/tea.hpp
|
|
||||||
crypto/xtea.cpp
|
|
||||||
crypto/xtea.hpp
|
|
||||||
crypto/xxtea.cpp
|
|
||||||
crypto/xxtea.hpp
|
|
||||||
debug.cpp
|
debug.cpp
|
||||||
debug.hpp
|
debug.hpp
|
||||||
debug.ipp
|
debug.ipp
|
||||||
@ -241,8 +228,6 @@ list (
|
|||||||
geom/tri.hpp
|
geom/tri.hpp
|
||||||
hash.hpp
|
hash.hpp
|
||||||
hash/fwd.hpp
|
hash/fwd.hpp
|
||||||
hash/simple.hpp
|
|
||||||
hash/simple.cpp
|
|
||||||
hash/adler.cpp
|
hash/adler.cpp
|
||||||
hash/adler.hpp
|
hash/adler.hpp
|
||||||
hash/bsdsum.cpp
|
hash/bsdsum.cpp
|
||||||
@ -255,18 +240,6 @@ list (
|
|||||||
hash/fletcher.hpp
|
hash/fletcher.hpp
|
||||||
hash/fnv1a.cpp
|
hash/fnv1a.cpp
|
||||||
hash/fnv1a.hpp
|
hash/fnv1a.hpp
|
||||||
hash/hmac.cpp
|
|
||||||
hash/hmac.hpp
|
|
||||||
hash/hotp.cpp
|
|
||||||
hash/hotp.hpp
|
|
||||||
hash/keccak.cpp
|
|
||||||
hash/keccak.hpp
|
|
||||||
hash/md2.cpp
|
|
||||||
hash/md2.hpp
|
|
||||||
hash/md4.cpp
|
|
||||||
hash/md4.hpp
|
|
||||||
hash/md5.cpp
|
|
||||||
hash/md5.hpp
|
|
||||||
hash/murmur/common.cpp
|
hash/murmur/common.cpp
|
||||||
hash/murmur/common.hpp
|
hash/murmur/common.hpp
|
||||||
hash/murmur.hpp
|
hash/murmur.hpp
|
||||||
@ -276,18 +249,7 @@ list (
|
|||||||
hash/murmur/murmur2.hpp
|
hash/murmur/murmur2.hpp
|
||||||
hash/murmur/murmur3.cpp
|
hash/murmur/murmur3.cpp
|
||||||
hash/murmur/murmur3.hpp
|
hash/murmur/murmur3.hpp
|
||||||
hash/pbkdf1.cpp
|
|
||||||
hash/pbkdf1.hpp
|
|
||||||
hash/pbkdf2.cpp
|
|
||||||
hash/pbkdf2.hpp
|
|
||||||
hash/ripemd.cpp
|
|
||||||
hash/ripemd.hpp
|
|
||||||
hash/sha1.cpp
|
|
||||||
hash/sha1.hpp
|
|
||||||
hash/sha2.cpp
|
|
||||||
hash/sha2.hpp
|
|
||||||
hash/wang.hpp
|
hash/wang.hpp
|
||||||
hash/wang.ipp
|
|
||||||
hash/xxhash.cpp
|
hash/xxhash.cpp
|
||||||
hash/xxhash.hpp
|
hash/xxhash.hpp
|
||||||
introspection.cpp
|
introspection.cpp
|
||||||
@ -459,7 +421,7 @@ target_link_libraries(cruft-util PUBLIC ${MATH_LIBS})
|
|||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
foreach (tool hash json-clean json-schema json-validate scratch)
|
foreach (tool json-clean json-schema json-validate scratch)
|
||||||
add_executable (util_${tool} tools/${tool}.cpp)
|
add_executable (util_${tool} tools/${tool}.cpp)
|
||||||
set_target_properties (util_${tool} PROPERTIES OUTPUT_NAME ${tool})
|
set_target_properties (util_${tool} PROPERTIES OUTPUT_NAME ${tool})
|
||||||
target_link_libraries (util_${tool} cruft-util)
|
target_link_libraries (util_${tool} cruft-util)
|
||||||
@ -491,12 +453,6 @@ if (TESTS)
|
|||||||
colour
|
colour
|
||||||
comparator
|
comparator
|
||||||
coord
|
coord
|
||||||
crypto/arc4
|
|
||||||
crypto/ice
|
|
||||||
crypto/salsa
|
|
||||||
crypto/tea
|
|
||||||
crypto/xtea
|
|
||||||
crypto/xxtea
|
|
||||||
encode/base
|
encode/base
|
||||||
endian
|
endian
|
||||||
exe
|
exe
|
||||||
@ -509,16 +465,8 @@ if (TESTS)
|
|||||||
hash/checksum
|
hash/checksum
|
||||||
hash/crc
|
hash/crc
|
||||||
hash/fasthash
|
hash/fasthash
|
||||||
hash/hmac
|
hash/fnv1a
|
||||||
hash/hotp
|
|
||||||
hash/keccak
|
|
||||||
hash/md2
|
|
||||||
hash/md4
|
|
||||||
hash/md5
|
|
||||||
hash/murmur
|
hash/murmur
|
||||||
hash/ripemd
|
|
||||||
hash/sha1
|
|
||||||
hash/sha2
|
|
||||||
hash/xxhash
|
hash/xxhash
|
||||||
hton
|
hton
|
||||||
introspection
|
introspection
|
||||||
|
4
README
4
README
@ -1,5 +1,3 @@
|
|||||||
A simple cross-platform C++ utility library.
|
A simple cross-platform C++ utility library.
|
||||||
|
|
||||||
Supported compilers: >=clang-4.x, >=gcc7.x; specifically, we require c++17 features such as structured bindings which aren't present in older compilers. No attempt has been made to compile under MSVC.
|
Supported compilers: >=clang-5.x, >=gcc7.x; specifically, we require c++17 features such as structured bindings which aren't present in older compilers. No attempt has been made to compile under MSVC.
|
||||||
|
|
||||||
For the love of God, do not use the crypto routines. I am not a cryptographer or a security specialist. You have been warned.
|
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "arc4.hpp"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <numeric>
|
|
||||||
|
|
||||||
using util::crypto::ARC4;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
ARC4::ARC4 (const uint8_t *restrict key, size_t len):
|
|
||||||
x (0),
|
|
||||||
y (0)
|
|
||||||
{
|
|
||||||
std::iota (S.begin (), S.end (), 0);
|
|
||||||
|
|
||||||
for (size_t i = 0, j = 0; i < 256; ++i) {
|
|
||||||
j = (j + S[i] + key[i % len]) % 256;
|
|
||||||
std::swap (S[i], S[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
ARC4::discard (size_t len)
|
|
||||||
{
|
|
||||||
while (len--)
|
|
||||||
get ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
ARC4::generate (uint8_t *restrict dst, size_t len)
|
|
||||||
{
|
|
||||||
std::generate_n (dst, len, [this] (void) { return get (); });
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
uint8_t
|
|
||||||
ARC4::get (void)
|
|
||||||
{
|
|
||||||
x = (x + 1) % 256;
|
|
||||||
y = (y + S[x]) % 256;
|
|
||||||
|
|
||||||
std::swap (S[x], S[y]);
|
|
||||||
|
|
||||||
return S[(S[x] + S[y]) % 256];
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTIL_RC4_HPP
|
|
||||||
#define __UTIL_RC4_HPP
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
namespace util::crypto {
|
|
||||||
class ARC4 {
|
|
||||||
public:
|
|
||||||
ARC4 (const uint8_t *restrict key, size_t len);
|
|
||||||
|
|
||||||
void discard (size_t);
|
|
||||||
void generate (uint8_t *restrict dst, size_t len);
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint8_t get (void);
|
|
||||||
|
|
||||||
size_t x, y;
|
|
||||||
std::array<uint8_t,256> S;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
441
crypto/ice.cpp
441
crypto/ice.cpp
@ -1,441 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2016 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Derived from Mathew Kwan's 1996 C++ public domain implementation of ICE:
|
|
||||||
// http://www.darkside.com.au/ice/
|
|
||||||
//
|
|
||||||
// M. Kwan, The Design of the ICE Encryption Algorithm, proceedings of Fast
|
|
||||||
// Software Encryption - Fourth International Workshop, Haifa, Israel,
|
|
||||||
// Springer-Verlag, pp. 69-82, 1997
|
|
||||||
|
|
||||||
#include "ice.hpp"
|
|
||||||
|
|
||||||
#include "../endian.hpp"
|
|
||||||
#include "../debug.hpp"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
/*
|
|
||||||
* C++ implementation of the ICE encryption algorithm.
|
|
||||||
*
|
|
||||||
* Written by Matthew Kwan - July 1996
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* The S-boxes */
|
|
||||||
static uint32_t ice_sbox[4][1024];
|
|
||||||
static bool ice_sboxes_initialised = false;
|
|
||||||
|
|
||||||
|
|
||||||
/* Modulo values for the S-boxes */
|
|
||||||
static
|
|
||||||
constexpr
|
|
||||||
uint_fast16_t
|
|
||||||
ice_smod[4][4] = {
|
|
||||||
{333, 313, 505, 369},
|
|
||||||
{379, 375, 319, 391},
|
|
||||||
{361, 445, 451, 397},
|
|
||||||
{397, 425, 395, 505}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* XOR values for the S-boxes */
|
|
||||||
constexpr
|
|
||||||
uint8_t
|
|
||||||
ice_sxor[4][4] = {
|
|
||||||
{0x83, 0x85, 0x9b, 0xcd},
|
|
||||||
{0xcc, 0xa7, 0xad, 0x41},
|
|
||||||
{0x4b, 0x2e, 0xd4, 0x33},
|
|
||||||
{0xea, 0xcb, 0x2e, 0x04}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Permutation values for the P-box */
|
|
||||||
constexpr
|
|
||||||
uint32_t
|
|
||||||
ice_pbox[32] = {
|
|
||||||
0x00000001, 0x00000080, 0x00000400, 0x00002000,
|
|
||||||
0x00080000, 0x00200000, 0x01000000, 0x40000000,
|
|
||||||
0x00000008, 0x00000020, 0x00000100, 0x00004000,
|
|
||||||
0x00010000, 0x00800000, 0x04000000, 0x20000000,
|
|
||||||
0x00000004, 0x00000010, 0x00000200, 0x00008000,
|
|
||||||
0x00020000, 0x00400000, 0x08000000, 0x10000000,
|
|
||||||
0x00000002, 0x00000040, 0x00000800, 0x00001000,
|
|
||||||
0x00040000, 0x00100000, 0x02000000, 0x80000000
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* The key rotation schedule */
|
|
||||||
constexpr
|
|
||||||
std::array<uint_fast8_t,8>
|
|
||||||
ice_keyrot[2] = {
|
|
||||||
{ 0, 1, 2, 3, 2, 1, 3, 0, },
|
|
||||||
{ 1, 3, 2, 0, 3, 1, 0, 2, },
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 8-bit Galois Field multiplication of a by b, modulo m.
|
|
||||||
* Just like arithmetic multiplication, except that additions and
|
|
||||||
* subtractions are replaced by XOR.
|
|
||||||
*/
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static
|
|
||||||
T
|
|
||||||
gf_mult (T a, T b, const T m)
|
|
||||||
{
|
|
||||||
T res = 0;
|
|
||||||
|
|
||||||
while (b) {
|
|
||||||
if (b & 1u)
|
|
||||||
res ^= a;
|
|
||||||
|
|
||||||
a <<= 1u;
|
|
||||||
b >>= 1u;
|
|
||||||
|
|
||||||
if (a >= 256)
|
|
||||||
a ^= m;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Galois Field exponentiation.
|
|
||||||
* Raise the base to the power of 7, modulo m.
|
|
||||||
*/
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static
|
|
||||||
T
|
|
||||||
gf_exp7 (const T b,
|
|
||||||
const T m)
|
|
||||||
{
|
|
||||||
if (b == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
T x;
|
|
||||||
|
|
||||||
x = gf_mult (b, b, m);
|
|
||||||
x = gf_mult (b, x, m);
|
|
||||||
x = gf_mult (x, x, m);
|
|
||||||
|
|
||||||
return gf_mult (b, x, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Carry out the ICE 32-bit P-box permutation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static
|
|
||||||
uint32_t
|
|
||||||
ice_perm32 (uint32_t x)
|
|
||||||
{
|
|
||||||
uint32_t res = 0;
|
|
||||||
const uint32_t *pbox = ice_pbox;
|
|
||||||
|
|
||||||
while (x) {
|
|
||||||
if (x & 1)
|
|
||||||
res |= *pbox;
|
|
||||||
pbox++;
|
|
||||||
x >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialise the ICE S-boxes.
|
|
||||||
* This only has to be done once.
|
|
||||||
*/
|
|
||||||
static
|
|
||||||
void
|
|
||||||
ice_sboxes_init (void)
|
|
||||||
{
|
|
||||||
for (unsigned i = 0; i < 1024; i++) {
|
|
||||||
const uint_fast16_t col = (i >> 1) & 0xff;
|
|
||||||
const uint_fast16_t row = (i & 0x1) | ((i & 0x200) >> 8);
|
|
||||||
|
|
||||||
for (unsigned j = 0; j < 4; ++j) {
|
|
||||||
const auto p = gf_exp7<uint_fast16_t> (
|
|
||||||
col ^ ice_sxor[j][row],
|
|
||||||
ice_smod[j][row]
|
|
||||||
) << (24 - j * 8);
|
|
||||||
|
|
||||||
ice_sbox[j][i] = ice_perm32 (static_cast<uint32_t>(p));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a new ICE key.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ice::ice (unsigned n,
|
|
||||||
const uint64_t *key_first,
|
|
||||||
const uint64_t *key_last)
|
|
||||||
{
|
|
||||||
if (!ice_sboxes_initialised) {
|
|
||||||
ice_sboxes_init ();
|
|
||||||
ice_sboxes_initialised = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n < 1) {
|
|
||||||
m_size = 1;
|
|
||||||
m_rounds = 8;
|
|
||||||
} else {
|
|
||||||
m_size = n;
|
|
||||||
m_rounds = n * 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_schedule.resize (m_rounds);
|
|
||||||
|
|
||||||
set (key_first, key_last);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Destroy an ICE key.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ice::~ice ()
|
|
||||||
{
|
|
||||||
for (auto &s: m_schedule)
|
|
||||||
std::fill (std::begin (s), std::end (s), 0);
|
|
||||||
|
|
||||||
m_rounds = m_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The single round ICE f function.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static
|
|
||||||
uint32_t
|
|
||||||
ice_f (uint32_t p, const ice::subkey_t &sk)
|
|
||||||
{
|
|
||||||
uint_fast64_t tl, tr; /* Expanded 40-bit values */
|
|
||||||
uint_fast64_t al, ar; /* Salted expanded 40-bit values */
|
|
||||||
|
|
||||||
/* Left half expansion */
|
|
||||||
tl = ((p >> 16) & 0x3ff) | (((p >> 14) | (p << 18)) & 0xffc00);
|
|
||||||
|
|
||||||
/* Right half expansion */
|
|
||||||
tr = (p & 0x3ff) | ((p << 2) & 0xffc00);
|
|
||||||
|
|
||||||
/* Perform the salt permutation */
|
|
||||||
// al = (tr & sk->val[2]) | (tl & ~sk->val[2]);
|
|
||||||
// ar = (tl & sk->val[2]) | (tr & ~sk->val[2]);
|
|
||||||
al = sk[2] & (tl ^ tr);
|
|
||||||
ar = al ^ tr;
|
|
||||||
al ^= tl;
|
|
||||||
|
|
||||||
al ^= sk[0]; /* XOR with the subkey */
|
|
||||||
ar ^= sk[1];
|
|
||||||
|
|
||||||
/* S-box lookup and permutation */
|
|
||||||
return (
|
|
||||||
ice_sbox[0][al >> 10] | ice_sbox[1][al & 0x3ff]
|
|
||||||
| ice_sbox[2][ar >> 10] | ice_sbox[3][ar & 0x3ff]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Encrypt a block of 8 bytes of data with the given ICE key.
|
|
||||||
*/
|
|
||||||
uint64_t
|
|
||||||
ice::encrypt (const uint64_t _ptext) const
|
|
||||||
{
|
|
||||||
union {
|
|
||||||
uint64_t pword;
|
|
||||||
uint8_t pbytes[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
pword = util::hton (_ptext);
|
|
||||||
|
|
||||||
uint32_t l, r;
|
|
||||||
|
|
||||||
l = (((uint32_t) pbytes[0]) << 24u)
|
|
||||||
| (((uint32_t) pbytes[1]) << 16u)
|
|
||||||
| (((uint32_t) pbytes[2]) << 8u)
|
|
||||||
| pbytes[3];
|
|
||||||
r = (((uint32_t) pbytes[4]) << 24u)
|
|
||||||
| (((uint32_t) pbytes[5]) << 16u)
|
|
||||||
| (((uint32_t) pbytes[6]) << 8u)
|
|
||||||
| pbytes[7];
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < m_rounds; i += 2) {
|
|
||||||
l ^= ice_f (r, m_schedule[i]);
|
|
||||||
r ^= ice_f (l, m_schedule[i + 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
union {
|
|
||||||
uint64_t cword;
|
|
||||||
uint8_t cbytes[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < 4; i++) {
|
|
||||||
cbytes[3 - i] = r & 0xff;
|
|
||||||
cbytes[7 - i] = l & 0xff;
|
|
||||||
|
|
||||||
r >>= 8u;
|
|
||||||
l >>= 8u;
|
|
||||||
}
|
|
||||||
|
|
||||||
return util::hton (cword);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Decrypt a block of 8 bytes of data with the given ICE key.
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint64_t
|
|
||||||
ice::decrypt (const uint64_t _ctext) const
|
|
||||||
{
|
|
||||||
union {
|
|
||||||
uint64_t cword;
|
|
||||||
uint8_t cbytes[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
cword = util::hton (_ctext);
|
|
||||||
|
|
||||||
uint32_t l, r;
|
|
||||||
|
|
||||||
l = (((uint32_t) cbytes[0]) << 24u)
|
|
||||||
| (((uint32_t) cbytes[1]) << 16u)
|
|
||||||
| (((uint32_t) cbytes[2]) << 8u)
|
|
||||||
| cbytes[3];
|
|
||||||
r = (((uint32_t) cbytes[4]) << 24u)
|
|
||||||
| (((uint32_t) cbytes[5]) << 16u)
|
|
||||||
| (((uint32_t) cbytes[6]) << 8u)
|
|
||||||
| cbytes[7];
|
|
||||||
|
|
||||||
for (int i = m_rounds - 1; i > 0; i -= 2) {
|
|
||||||
l ^= ice_f (r, m_schedule[i]);
|
|
||||||
r ^= ice_f (l, m_schedule[i - 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
union {
|
|
||||||
uint64_t pword;
|
|
||||||
uint8_t pbytes[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < 4; i++) {
|
|
||||||
pbytes[3 - i] = r & 0xff;
|
|
||||||
pbytes[7 - i] = l & 0xff;
|
|
||||||
|
|
||||||
r >>= 8;
|
|
||||||
l >>= 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
return util::hton (pword);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set 8 rounds [n, n+7] of the key schedule of an ICE key.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
ice::scheduleBuild (std::array<uint16_t,4> &kb,
|
|
||||||
int n,
|
|
||||||
const std::array<uint_fast8_t,8> &keyrot)
|
|
||||||
{
|
|
||||||
for (unsigned i = 0; i < 8; i++) {
|
|
||||||
int kr = keyrot[i];
|
|
||||||
subkey_t &isk = m_schedule[n + i];
|
|
||||||
|
|
||||||
std::fill (std::begin (isk), std::end (isk), 0);
|
|
||||||
|
|
||||||
for (unsigned j = 0; j < 15; j++) {
|
|
||||||
uint32_t &curr_sk = isk[j % 3];
|
|
||||||
|
|
||||||
for (unsigned k = 0; k < 4; k++) {
|
|
||||||
auto &curr_kb = kb[(kr + k) & 3];
|
|
||||||
unsigned bit = curr_kb & 1;
|
|
||||||
|
|
||||||
curr_sk = (curr_sk << 1) | bit;
|
|
||||||
curr_kb = (curr_kb >> 1) | ((bit ^ 1) << 15);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the key schedule of an ICE key.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
ice::set (const uint64_t *_key_first, const uint64_t *_key_last)
|
|
||||||
{
|
|
||||||
(void)_key_last;
|
|
||||||
CHECK_EQ ((unsigned)(_key_last - _key_first), m_size);
|
|
||||||
|
|
||||||
auto key = reinterpret_cast<const uint8_t*> (_key_first);
|
|
||||||
|
|
||||||
if (m_rounds == 8) {
|
|
||||||
std::array<uint16_t,4> kb;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < 4; i++)
|
|
||||||
kb[3 - i] = (key[i * 2] << 8) | key[i * 2 + 1];
|
|
||||||
|
|
||||||
scheduleBuild (kb, 0, ice_keyrot[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < m_size; i++) {
|
|
||||||
std::array<uint16_t,4> kb;
|
|
||||||
|
|
||||||
for (unsigned j = 0; j < 4; j++)
|
|
||||||
kb[3 - j] = (key[i * 8 + j * 2] << 8) | key[i * 8 + j * 2 + 1];
|
|
||||||
|
|
||||||
scheduleBuild (kb, i * 8, ice_keyrot[0]);
|
|
||||||
scheduleBuild (kb, m_rounds - 8 - i * 8, ice_keyrot[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the key size, in bytes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
unsigned
|
|
||||||
ice::key_size () const
|
|
||||||
{
|
|
||||||
return (m_size * 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the block size, in bytes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
unsigned
|
|
||||||
ice::block_size () const
|
|
||||||
{
|
|
||||||
return (8);
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2016 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __CRYPTO_ICE_HPP
|
|
||||||
#define __CRYPTO_ICE_HPP
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <array>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// An implementation of the ICE symmetric-key block cipher
|
|
||||||
//
|
|
||||||
// we make a token attempt to zero our buffers, but we can't guarantee this
|
|
||||||
// will take place (given compiler optimisations). further security is
|
|
||||||
// outside the scope of this class.
|
|
||||||
class ice {
|
|
||||||
public:
|
|
||||||
ice (unsigned n, uint64_t key);
|
|
||||||
|
|
||||||
ice (unsigned n,
|
|
||||||
const uint64_t *key_first,
|
|
||||||
const uint64_t *key_last);
|
|
||||||
~ice ();
|
|
||||||
|
|
||||||
void
|
|
||||||
set (const uint64_t *key_first, const uint64_t *key_last);
|
|
||||||
|
|
||||||
uint64_t encrypt (uint64_t plaintext) const;
|
|
||||||
uint64_t decrypt (uint64_t ciphertext) const;
|
|
||||||
|
|
||||||
unsigned key_size () const;
|
|
||||||
unsigned block_size () const;
|
|
||||||
|
|
||||||
using subkey_t = std::array<uint32_t,3>;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void
|
|
||||||
scheduleBuild (std::array<uint16_t,4> &k,
|
|
||||||
int n,
|
|
||||||
const std::array<uint_fast8_t,8> &keyrot);
|
|
||||||
|
|
||||||
unsigned m_size;
|
|
||||||
unsigned m_rounds;
|
|
||||||
|
|
||||||
std::vector<subkey_t> m_schedule;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ice_error : public std::runtime_error { using runtime_error::runtime_error; };
|
|
||||||
struct level_error : public ice_error { using ice_error::ice_error; };
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,24 +0,0 @@
|
|||||||
#include "./salsa.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
std::array<uint8_t,64>
|
|
||||||
util::crypto::salsa20 (const std::array<uint8_t,64> bytes) noexcept
|
|
||||||
{
|
|
||||||
auto x = *reinterpret_cast<const std::array<uint32_t,16>*> (&bytes);
|
|
||||||
auto y = x;
|
|
||||||
|
|
||||||
for (auto &t: x)
|
|
||||||
t = util::ltoh (t);
|
|
||||||
|
|
||||||
for (int i = 0; i < 10; ++i)
|
|
||||||
x = salsa::doubleround (x);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < std::size (y); ++i)
|
|
||||||
x[i] += y[i];
|
|
||||||
|
|
||||||
for (auto &t: x)
|
|
||||||
t = util::htol (t);
|
|
||||||
|
|
||||||
return *reinterpret_cast<std::array<uint8_t,64>*> (&x);
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
#include <cstdint>
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
#include "../bitwise.hpp"
|
|
||||||
#include "../endian.hpp"
|
|
||||||
|
|
||||||
namespace util::crypto::salsa {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
constexpr
|
|
||||||
uint32_t
|
|
||||||
R (uint32_t a, uint32_t b, uint32_t c, uint32_t k)
|
|
||||||
{
|
|
||||||
return b ^ util::rotatel (a + c, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
constexpr
|
|
||||||
std::array<uint32_t,4>
|
|
||||||
quarter (std::array<uint32_t,4> y) noexcept
|
|
||||||
{
|
|
||||||
std::array<uint32_t,4> z {};
|
|
||||||
|
|
||||||
z[1] = R (y[0], y[1], y[3], 7);
|
|
||||||
z[2] = R (z[1], y[2], y[0], 9);
|
|
||||||
z[3] = R (z[2], y[3], z[1], 13);
|
|
||||||
z[0] = R (z[3], y[0], z[2], 18);
|
|
||||||
|
|
||||||
return z;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
constexpr
|
|
||||||
std::array<uint32_t,16>
|
|
||||||
row (const std::array<uint32_t,16> y) noexcept
|
|
||||||
{
|
|
||||||
const auto [z00, z01, z02, z03] = quarter ({y[ 0], y[ 1], y[ 2], y[ 3]});
|
|
||||||
const auto [z05, z06, z07, z04] = quarter ({y[ 5], y[ 6], y[ 7], y[ 4]});
|
|
||||||
const auto [z10, z11, z08, z09] = quarter ({y[10], y[11], y[ 8], y[ 9]});
|
|
||||||
const auto [z15, z12, z13, z14] = quarter ({y[15], y[12], y[13], y[14]});
|
|
||||||
|
|
||||||
return {
|
|
||||||
z00, z01, z02, z03,
|
|
||||||
z04, z05, z06, z07,
|
|
||||||
z08, z09, z10, z11,
|
|
||||||
z12, z13, z14, z15
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
constexpr
|
|
||||||
std::array<uint32_t,16>
|
|
||||||
col (const std::array<uint32_t,16> x) noexcept
|
|
||||||
{
|
|
||||||
const auto [y00, y04, y08, y12] = quarter ({x[ 0], x[ 4], x[ 8], x[12]});
|
|
||||||
const auto [y05, y09, y13, y01] = quarter ({x[ 5], x[ 9], x[13], x[ 1]});
|
|
||||||
const auto [y10, y14, y02, y06] = quarter ({x[10], x[14], x[ 2], x[ 6]});
|
|
||||||
const auto [y15, y03, y07, y11] = quarter ({x[15], x[ 3], x[ 7], x[11]});
|
|
||||||
|
|
||||||
return {
|
|
||||||
y00, y01, y02, y03,
|
|
||||||
y04, y05, y06, y07,
|
|
||||||
y08, y09, y10, y11,
|
|
||||||
y12, y13, y14, y15,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
constexpr
|
|
||||||
std::array<uint32_t,16>
|
|
||||||
doubleround (const std::array<uint32_t,16> x) noexcept
|
|
||||||
{
|
|
||||||
return row (col (x));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
namespace util::crypto {
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
std::array<uint8_t,64>
|
|
||||||
salsa20 (const std::array<uint8_t,64>) noexcept;
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "tea.hpp"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
using util::crypto::TEA;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
static const std::uint32_t MAGIC = 0x9E3779B9;
|
|
||||||
|
|
||||||
// each iteration performs two feistel rounds, for a total of 64
|
|
||||||
static const unsigned ITERATIONS = 32;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
TEA::TEA (key_t _key):
|
|
||||||
m_key (_key)
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
TEA::encrypt (uint32_t *restrict data, size_t count)
|
|
||||||
{
|
|
||||||
if (count % 2)
|
|
||||||
throw std::invalid_argument ("TEA requires even data count");
|
|
||||||
|
|
||||||
auto last = data + count;
|
|
||||||
while (data < last) {
|
|
||||||
uint32_t sum = 0;
|
|
||||||
uint32_t v0 = data[0];
|
|
||||||
uint32_t v1 = data[1];
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < ITERATIONS; ++i) {
|
|
||||||
sum += MAGIC;
|
|
||||||
v0 += ((v1 << 4) + m_key[0]) ^ (v1 + sum) ^ ((v1 >> 5) + m_key[1]);
|
|
||||||
v1 += ((v0 << 4) + m_key[2]) ^ (v0 + sum) ^ ((v0 >> 5) + m_key[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
*data++ = v0;
|
|
||||||
*data++ = v1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
TEA::decrypt (uint32_t *restrict data, size_t count)
|
|
||||||
{
|
|
||||||
if (count % 2)
|
|
||||||
throw std::invalid_argument ("TEA requires even data count");
|
|
||||||
|
|
||||||
auto last = data + count;
|
|
||||||
|
|
||||||
while (data < last) {
|
|
||||||
uint32_t sum = MAGIC << 5;
|
|
||||||
uint32_t v0 = data[0];
|
|
||||||
uint32_t v1 = data[1];
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < ITERATIONS; ++i) {
|
|
||||||
v1 -= ((v0 << 4) + m_key[2]) ^ (v0 + sum) ^ ((v0 >> 5) + m_key[3]);
|
|
||||||
v0 -= ((v1 << 4) + m_key[0]) ^ (v1 + sum) ^ ((v1 >> 5) + m_key[1]);
|
|
||||||
sum -= MAGIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
*data++ = v0;
|
|
||||||
*data++ = v1;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTIL_TEA_HPP
|
|
||||||
#define __UTIL_TEA_HPP
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
namespace util::crypto {
|
|
||||||
// http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
|
|
||||||
class TEA {
|
|
||||||
public:
|
|
||||||
using key_t = std::array<uint32_t,4>;
|
|
||||||
|
|
||||||
explicit TEA (key_t);
|
|
||||||
|
|
||||||
void encrypt (uint32_t *restrict data, size_t count);
|
|
||||||
void decrypt (uint32_t *restrict data, size_t count);
|
|
||||||
|
|
||||||
private:
|
|
||||||
key_t m_key;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "xtea.hpp"
|
|
||||||
|
|
||||||
using util::crypto::XTEA;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
static const uint32_t MAGIC = 0x9E3779B9;
|
|
||||||
|
|
||||||
// each iteration performs two feistel rounds, for a total of 64
|
|
||||||
static const unsigned ITERATIONS = 32;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
XTEA::XTEA (key_t _key):
|
|
||||||
m_key (_key)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
XTEA::encrypt (uint32_t *restrict data, size_t count)
|
|
||||||
{
|
|
||||||
if (count % 2)
|
|
||||||
throw std::invalid_argument ("XTEA requires even data count");
|
|
||||||
|
|
||||||
auto last = data + count;
|
|
||||||
|
|
||||||
while (data < last) {
|
|
||||||
uint32_t sum = 0;
|
|
||||||
uint32_t v0 = data[0];
|
|
||||||
uint32_t v1 = data[1];
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < ITERATIONS; ++i) {
|
|
||||||
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + m_key[sum & 3]);
|
|
||||||
sum += MAGIC;
|
|
||||||
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + m_key[(sum >> 11) & 3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
*data++ = v0;
|
|
||||||
*data++ = v1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
XTEA::decrypt (uint32_t *restrict data, size_t count)
|
|
||||||
{
|
|
||||||
if (count % 2)
|
|
||||||
throw std::invalid_argument ("XTEA requires even data count");
|
|
||||||
|
|
||||||
auto last = data + count;
|
|
||||||
|
|
||||||
while (data < last) {
|
|
||||||
uint32_t sum = ITERATIONS * MAGIC;
|
|
||||||
uint32_t v0 = data[0];
|
|
||||||
uint32_t v1 = data[1];
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < ITERATIONS; ++i) {
|
|
||||||
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + m_key[(sum >> 11) & 3]);
|
|
||||||
sum -= MAGIC;
|
|
||||||
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + m_key[sum & 3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
*data++ = v0;
|
|
||||||
*data++ = v1;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTIL_TEA_HPP
|
|
||||||
#define __UTIL_TEA_HPP
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
namespace util::crypto {
|
|
||||||
// http://en.wikipedia.org/wiki/XTEA
|
|
||||||
class XTEA {
|
|
||||||
public:
|
|
||||||
using key_t = std::array<uint32_t,4>;
|
|
||||||
|
|
||||||
explicit XTEA (key_t);
|
|
||||||
|
|
||||||
void encrypt (uint32_t *restrict data, size_t count);
|
|
||||||
void decrypt (uint32_t *restrict data, size_t count);
|
|
||||||
|
|
||||||
private:
|
|
||||||
key_t m_key;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
106
crypto/xxtea.cpp
106
crypto/xxtea.cpp
@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "xxtea.hpp"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
// test vectors: http://www.cix.co.uk/~klockstone/teavect.htm
|
|
||||||
|
|
||||||
using util::crypto::XXTEA;
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
static const uint32_t MAGIC = 0x9E3779B9;
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
static constexpr
|
|
||||||
uint32_t
|
|
||||||
mix (uint32_t Z,
|
|
||||||
uint32_t Y,
|
|
||||||
uint32_t S,
|
|
||||||
size_t E,
|
|
||||||
size_t P,
|
|
||||||
const uint32_t *restrict K)
|
|
||||||
{
|
|
||||||
return ((Z >> 5 ^ Y << 2) + (Y >> 3 ^ Z << 4)) ^ ((S ^ Y) + (K[(P & 3) ^ E] ^ Z));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
XXTEA::XXTEA (key_t _key):
|
|
||||||
m_key (_key)
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
XXTEA::encrypt (uint32_t *restrict data, size_t count)
|
|
||||||
{
|
|
||||||
if (count < 2)
|
|
||||||
throw std::invalid_argument ("minimum blocksize is 64 bits");
|
|
||||||
|
|
||||||
uint32_t sum = 0;
|
|
||||||
uint32_t z = data[count - 1];
|
|
||||||
uint32_t y, p;
|
|
||||||
|
|
||||||
unsigned rounds = 6 + 52 / count;
|
|
||||||
|
|
||||||
do {
|
|
||||||
sum += MAGIC;
|
|
||||||
uint32_t e = (sum >> 2) & 3;
|
|
||||||
|
|
||||||
for (p = 0; p < count - 1; p++) {
|
|
||||||
y = data[p + 1];
|
|
||||||
z = data[p] += mix (z, y, sum, e, p, m_key.data ());
|
|
||||||
}
|
|
||||||
|
|
||||||
y = data[0];
|
|
||||||
z = data[count - 1] += mix (z, y, sum, e, p, m_key.data ());
|
|
||||||
} while (--rounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
XXTEA::decrypt (uint32_t *restrict data, size_t count)
|
|
||||||
{
|
|
||||||
if (count < 2)
|
|
||||||
throw std::invalid_argument ("minimum blocksize is 64 bits");
|
|
||||||
|
|
||||||
uint32_t y, z, sum;
|
|
||||||
uint32_t rounds;
|
|
||||||
size_t p;
|
|
||||||
|
|
||||||
rounds = 6 + 52 / count;
|
|
||||||
sum = rounds * MAGIC;
|
|
||||||
y = data[0];
|
|
||||||
|
|
||||||
do {
|
|
||||||
uint32_t e = (sum >> 2) & 3;
|
|
||||||
|
|
||||||
for (p = count - 1; p > 0; p--) {
|
|
||||||
z = data[p - 1];
|
|
||||||
y = data[p ] -= mix (z, y, sum, e, p, m_key.data ());
|
|
||||||
}
|
|
||||||
|
|
||||||
z = data[count - 1];
|
|
||||||
y = data[ 0] -= mix (z, y, sum, e, p, m_key.data ());
|
|
||||||
|
|
||||||
sum -= MAGIC;
|
|
||||||
} while (--rounds);
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTIL_TEA_HPP
|
|
||||||
#define __UTIL_TEA_HPP
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
namespace util::crypto {
|
|
||||||
// http://en.wikipedia.org/wiki/XXTEA
|
|
||||||
// 'corrected' block TEA
|
|
||||||
class XXTEA {
|
|
||||||
public:
|
|
||||||
using key_t = std::array<uint32_t,4>;
|
|
||||||
|
|
||||||
explicit XXTEA (key_t);
|
|
||||||
|
|
||||||
void encrypt (uint32_t *restrict data, size_t count);
|
|
||||||
void decrypt (uint32_t *restrict data, size_t count);
|
|
||||||
|
|
||||||
private:
|
|
||||||
key_t m_key;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
14
hash.hpp
14
hash.hpp
@ -23,8 +23,18 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
namespace util::hash {
|
namespace util::hash {
|
||||||
constexpr std::uint32_t mix (std::uint32_t a, std::uint32_t b) { return murmur2::mix (a, b); }
|
constexpr std::uint32_t
|
||||||
constexpr std::uint64_t mix (std::uint64_t a, std::uint64_t b) { return murmur2::mix (a, b); }
|
mix (std::uint32_t a, std::uint32_t b)
|
||||||
|
{
|
||||||
|
return murmur2<std::uint32_t>::mix (a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
constexpr std::uint64_t
|
||||||
|
mix (std::uint64_t a, std::uint64_t b)
|
||||||
|
{
|
||||||
|
return murmur2<std::uint64_t>::mix (a, b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,9 +16,6 @@
|
|||||||
|
|
||||||
#include "adler.hpp"
|
#include "adler.hpp"
|
||||||
|
|
||||||
#include "fletcher.hpp"
|
|
||||||
#include "../debug.hpp"
|
|
||||||
|
|
||||||
static constexpr unsigned MODULUS = 65521;
|
static constexpr unsigned MODULUS = 65521;
|
||||||
|
|
||||||
using util::hash::adler32;
|
using util::hash::adler32;
|
||||||
@ -29,21 +26,3 @@ adler32::adler32 ():
|
|||||||
fletcher (MODULUS, 1, 0)
|
fletcher (MODULUS, 1, 0)
|
||||||
{ ; }
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//uint32_t
|
|
||||||
//util::hash::adler32 (const void* restrict _data, size_t _size) noexcept
|
|
||||||
//{
|
|
||||||
// return adler32 (
|
|
||||||
// static_cast<const uint8_t*> (_data),
|
|
||||||
// static_cast<const uint8_t*> (_data) + _size
|
|
||||||
// );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//
|
|
||||||
////-----------------------------------------------------------------------------
|
|
||||||
//uint32_t
|
|
||||||
//util::hash::adler32 (const uint8_t *restrict first, const uint8_t *restrict last) noexcept
|
|
||||||
//{
|
|
||||||
// return fletcher<32, MODULUS, 1, 0> (first, last - first);
|
|
||||||
//}
|
|
||||||
|
@ -11,67 +11,24 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright 2010 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2010-2018 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "bsdsum.hpp"
|
#include "bsdsum.hpp"
|
||||||
|
|
||||||
#include "../debug.hpp"
|
#include "../bitwise.hpp"
|
||||||
|
|
||||||
using util::hash::bsdsum;
|
using util::hash::bsdsum;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
bsdsum::bsdsum ()
|
|
||||||
{
|
|
||||||
reset ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
bsdsum::reset (void)
|
|
||||||
{
|
|
||||||
m_accum = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
bsdsum::update (const void *restrict data, size_t size) noexcept
|
|
||||||
{
|
|
||||||
auto first = static_cast<const uint8_t *restrict> (data);
|
|
||||||
|
|
||||||
update (first, first + size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
bsdsum::update (const uint8_t *const restrict first,
|
|
||||||
const uint8_t *const restrict last) noexcept
|
|
||||||
{
|
|
||||||
CHECK (first);
|
|
||||||
CHECK (last);
|
|
||||||
CHECK_LE (first, last);
|
|
||||||
|
|
||||||
for (auto cursor = first; cursor != last; ++cursor) {
|
|
||||||
m_accum = (m_accum >> 1u) | ((m_accum & 0x01u) << 15u);
|
|
||||||
m_accum += *cursor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
bsdsum::finish (void)
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
typename bsdsum::digest_t
|
typename bsdsum::digest_t
|
||||||
bsdsum::digest (void) const
|
bsdsum::operator() (util::view<const uint8_t*> data) const noexcept
|
||||||
{
|
{
|
||||||
return m_accum;
|
digest_t accum = 0;
|
||||||
|
|
||||||
|
for (const auto i: data)
|
||||||
|
accum = util::rotater (accum, 1) + i;
|
||||||
|
|
||||||
|
return accum;
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,13 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2011-2018 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __UTIL_HASH_BSDSUM_HPP
|
#ifndef CRUFT_UTIL_HASH_BSDSUM_HPP
|
||||||
#define __UTIL_HASH_BSDSUM_HPP
|
#define CRUFT_UTIL_HASH_BSDSUM_HPP
|
||||||
|
|
||||||
|
#include "../view.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@ -27,18 +29,7 @@ namespace util::hash {
|
|||||||
public:
|
public:
|
||||||
using digest_t = uint16_t;
|
using digest_t = uint16_t;
|
||||||
|
|
||||||
bsdsum (void);
|
digest_t operator() (util::view<const uint8_t*>) const noexcept;
|
||||||
void reset (void);
|
|
||||||
|
|
||||||
void update (const void *restrict data, size_t bytes) noexcept;
|
|
||||||
void update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept;
|
|
||||||
|
|
||||||
void finish (void);
|
|
||||||
|
|
||||||
digest_t digest (void) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
digest_t m_accum;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
103
hash/crc.cpp
103
hash/crc.cpp
@ -48,112 +48,23 @@ template <
|
|||||||
bool ReflectIn,
|
bool ReflectIn,
|
||||||
bool ReflectOut
|
bool ReflectOut
|
||||||
>
|
>
|
||||||
|
typename crc<DigestT,Generator,Initial,Final,ReflectIn,ReflectOut>::digest_t
|
||||||
crc<
|
crc<
|
||||||
DigestT,Generator,Initial,Final,ReflectIn,ReflectOut
|
DigestT,Generator,Initial,Final,ReflectIn,ReflectOut
|
||||||
>::crc () noexcept
|
>::operator() (const util::view<const uint8_t*> data) const noexcept
|
||||||
{
|
{
|
||||||
reset ();
|
auto accum = Initial;
|
||||||
}
|
|
||||||
|
|
||||||
|
for (auto i: data) {
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <
|
|
||||||
typename DigestT,
|
|
||||||
DigestT Generator,
|
|
||||||
DigestT Initial,
|
|
||||||
DigestT Final,
|
|
||||||
bool ReflectIn,
|
|
||||||
bool ReflectOut
|
|
||||||
>
|
|
||||||
void
|
|
||||||
crc<
|
|
||||||
DigestT,Generator,Initial,Final,ReflectIn,ReflectOut
|
|
||||||
>::reset (void) noexcept
|
|
||||||
{
|
|
||||||
m_digest = Initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <
|
|
||||||
typename DigestT,
|
|
||||||
DigestT Generator,
|
|
||||||
DigestT Initial,
|
|
||||||
DigestT Final,
|
|
||||||
bool ReflectIn,
|
|
||||||
bool ReflectOut
|
|
||||||
>
|
|
||||||
void
|
|
||||||
crc<
|
|
||||||
DigestT,Generator,Initial,Final,ReflectIn,ReflectOut
|
|
||||||
>::update (const uint8_t *restrict first,
|
|
||||||
const uint8_t *restrict last) noexcept
|
|
||||||
{
|
|
||||||
CHECK_LE (first, last);
|
|
||||||
|
|
||||||
for (auto cursor = first; cursor != last; ++cursor) {
|
|
||||||
if (ReflectIn)
|
if (ReflectIn)
|
||||||
m_digest = s_table[*cursor ^ (m_digest & 0xFFu)] ^ (m_digest >> 8u);
|
accum = s_table[i ^ (accum & 0xFFu)] ^ (accum >> 8u);
|
||||||
else {
|
else {
|
||||||
constexpr auto shift = sizeof (DigestT) * 8u - 8u;
|
constexpr auto shift = sizeof (DigestT) * 8u - 8u;
|
||||||
m_digest = (m_digest << 8u) ^ s_table[(m_digest >> shift) ^ *cursor];
|
accum = (accum << 8u) ^ s_table[(accum >> shift) ^ i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
return (ReflectIn != ReflectOut ? util::reverse (accum) : accum) ^ Final;
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <
|
|
||||||
typename DigestT,
|
|
||||||
DigestT Generator,
|
|
||||||
DigestT Initial,
|
|
||||||
DigestT Final,
|
|
||||||
bool ReflectIn,
|
|
||||||
bool ReflectOut
|
|
||||||
>
|
|
||||||
void
|
|
||||||
crc<
|
|
||||||
DigestT,Generator,Initial,Final,ReflectIn,ReflectOut
|
|
||||||
>::update (const void *restrict _data, size_t len) noexcept
|
|
||||||
{
|
|
||||||
auto data = reinterpret_cast<const uint8_t *restrict> (_data);
|
|
||||||
return update(data, data + len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <
|
|
||||||
typename DigestT,
|
|
||||||
DigestT Generator,
|
|
||||||
DigestT Initial,
|
|
||||||
DigestT Final,
|
|
||||||
bool ReflectIn,
|
|
||||||
bool ReflectOut
|
|
||||||
>
|
|
||||||
void
|
|
||||||
crc<
|
|
||||||
DigestT,Generator,Initial,Final,ReflectIn,ReflectOut
|
|
||||||
>::finish (void)
|
|
||||||
{
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <
|
|
||||||
typename DigestT,
|
|
||||||
DigestT Generator,
|
|
||||||
DigestT Initial,
|
|
||||||
DigestT Final,
|
|
||||||
bool ReflectIn,
|
|
||||||
bool ReflectOut
|
|
||||||
>
|
|
||||||
DigestT
|
|
||||||
crc<
|
|
||||||
DigestT,Generator,Initial,Final,ReflectIn,ReflectOut
|
|
||||||
>::digest (void) const
|
|
||||||
{
|
|
||||||
return (ReflectIn != ReflectOut ? util::reverse (m_digest) : m_digest) ^ Final;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
30
hash/crc.hpp
30
hash/crc.hpp
@ -11,11 +11,13 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2011-2018 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __UTIL_HASH_CRC_HPP
|
#ifndef CRUFT_UTIL_HASH_CRC_HPP
|
||||||
#define __UTIL_HASH_CRC_HPP
|
#define CRUFT_UTIL_HASH_CRC_HPP
|
||||||
|
|
||||||
|
#include "../view.hpp"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -24,7 +26,7 @@
|
|||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
namespace util { namespace hash {
|
namespace util::hash {
|
||||||
// Implements the crc checksum (from ethernet, png, etc).
|
// Implements the crc checksum (from ethernet, png, etc).
|
||||||
//
|
//
|
||||||
// Adapted from the PNG specification (ISO/IEC 15948:2003), appendix D and
|
// Adapted from the PNG specification (ISO/IEC 15948:2003), appendix D and
|
||||||
@ -37,8 +39,8 @@ namespace util { namespace hash {
|
|||||||
// ReflectOut: whether to reverse the bits of the digest at finish time
|
// ReflectOut: whether to reverse the bits of the digest at finish time
|
||||||
//
|
//
|
||||||
// Note that reflection isn't necessarily explicitly performed at update
|
// Note that reflection isn't necessarily explicitly performed at update
|
||||||
// time. Instead we construct the lookup table appropriately to directly
|
// time. Instead we construct the lookup table appropriately to use the
|
||||||
// use the data values directly.
|
// data values directly.
|
||||||
template <
|
template <
|
||||||
typename DigestT,
|
typename DigestT,
|
||||||
DigestT Generator,
|
DigestT Generator,
|
||||||
@ -53,33 +55,23 @@ namespace util { namespace hash {
|
|||||||
|
|
||||||
static constexpr auto generator = Generator;
|
static constexpr auto generator = Generator;
|
||||||
|
|
||||||
crc () noexcept;
|
digest_t operator() (util::view<const uint8_t*>) const noexcept;
|
||||||
|
|
||||||
void reset (void) noexcept;
|
|
||||||
|
|
||||||
void update (const void *restrict data, size_t bytes) noexcept;
|
|
||||||
void update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept;
|
|
||||||
|
|
||||||
void finish (void);
|
|
||||||
|
|
||||||
digest_t digest (void) const;
|
|
||||||
|
|
||||||
static constexpr
|
static constexpr
|
||||||
std::array<DigestT,256>
|
std::array<DigestT,256>
|
||||||
table (void);
|
table (void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
digest_t m_digest;
|
|
||||||
|
|
||||||
static const std::array<DigestT,256> s_table;
|
static const std::array<DigestT,256> s_table;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
using crc32 = crc<uint32_t, 0x04c11db7, 0xffffffff, 0xffffffff, true, true>;
|
using crc32 = crc<uint32_t, 0x04c11db7, 0xffffffff, 0xffffffff, true, true>;
|
||||||
using crc32b = crc<uint32_t, 0x04c11db7, 0xffffffff, 0xffffffff, false, false>;
|
using crc32b = crc<uint32_t, 0x04c11db7, 0xffffffff, 0xffffffff, false, false>;
|
||||||
using crc32c = crc<uint32_t, 0x1edc6f41, 0xffffffff, 0xffffffff, true, true>;
|
using crc32c = crc<uint32_t, 0x1edc6f41, 0xffffffff, 0xffffffff, true, true>;
|
||||||
using crc32d = crc<uint32_t, 0xa833982b, 0xffffffff, 0xffffffff, true, true>;
|
using crc32d = crc<uint32_t, 0xa833982b, 0xffffffff, 0xffffffff, true, true>;
|
||||||
|
|
||||||
using crc64 = crc<uint64_t, 0x42f0e1eba9ea3693, 0, 0, false, false>;
|
using crc64 = crc<uint64_t, 0x42f0e1eba9ea3693, 0, 0, false, false>;
|
||||||
} }
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,35 +16,26 @@
|
|||||||
|
|
||||||
#include "fasthash.hpp"
|
#include "fasthash.hpp"
|
||||||
|
|
||||||
|
using util::hash::fasthash;
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
uint64_t
|
|
||||||
util::hash::fasthash::mix (uint64_t v)
|
|
||||||
{
|
|
||||||
v ^= v >> 23;
|
|
||||||
v *= 0x2127599bf4325c37;
|
|
||||||
v ^= v >> 47;
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <>
|
||||||
uint64_t
|
uint64_t
|
||||||
util::hash::fasthash::hash64 (const void *restrict data, size_t len, uint64_t seed)
|
fasthash<uint64_t>::operator() (uint64_t seed, const util::view<const uint8_t*> data) const
|
||||||
{
|
{
|
||||||
static const uint64_t m = 0x880355f21e6d1965;
|
static const uint64_t m = 0x880355f21e6d1965;
|
||||||
|
|
||||||
uint64_t result = seed ^ (len * m);
|
uint64_t result = seed ^ (data.size () * m);
|
||||||
|
|
||||||
auto cursor = reinterpret_cast<const uint64_t*> (data);
|
auto cursor = reinterpret_cast<const uint64_t*> (data.begin ());
|
||||||
auto last = cursor + len / sizeof (*cursor);
|
auto last = cursor + data.size () / sizeof (*cursor);
|
||||||
for (; cursor < last; ++cursor) {
|
for (; cursor < last; ++cursor) {
|
||||||
result ^= mix (*cursor);
|
result ^= mix (*cursor);
|
||||||
result *= m;
|
result *= m;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t remain = len % sizeof (*cursor);
|
size_t remain = data.size () % sizeof (*cursor);
|
||||||
if (remain) {
|
if (remain) {
|
||||||
auto tail = reinterpret_cast<const uint8_t*> (cursor);
|
auto tail = reinterpret_cast<const uint8_t*> (cursor);
|
||||||
|
|
||||||
@ -61,10 +52,11 @@ util::hash::fasthash::hash64 (const void *restrict data, size_t len, uint64_t se
|
|||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
template <>
|
||||||
uint32_t
|
uint32_t
|
||||||
util::hash::fasthash::hash32 (const void *restrict data, size_t len, uint32_t seed)
|
fasthash<uint32_t>::operator() (uint64_t seed, const util::view<const uint8_t*> data) const
|
||||||
{
|
{
|
||||||
uint64_t h = hash64 (data, len, seed);
|
auto h = fasthash<uint64_t> {} (seed, data);
|
||||||
return (h & 0xffffffff) - (h >> 32);
|
return (h & 0xffffffff) - (h >> 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,17 +17,31 @@
|
|||||||
#ifndef __UTIL_HASH_FASTHASH_HPP
|
#ifndef __UTIL_HASH_FASTHASH_HPP
|
||||||
#define __UTIL_HASH_FASTHASH_HPP
|
#define __UTIL_HASH_FASTHASH_HPP
|
||||||
|
|
||||||
|
#include "../view.hpp"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
// Zilong Tan's FastHash, via George Marsaglia's "Xorshift RNGs"
|
|
||||||
namespace util::hash::fasthash {
|
|
||||||
uint64_t mix (uint64_t);
|
|
||||||
|
|
||||||
uint32_t hash32 (const void *restrict data, size_t len, uint32_t seed);
|
// Zilong Tan's FastHash, via George Marsaglia's "Xorshift RNGs"
|
||||||
uint64_t hash64 (const void *restrict data, size_t len, uint64_t seed);
|
namespace util::hash {
|
||||||
|
template <typename ValueT>
|
||||||
|
struct fasthash {
|
||||||
|
using digest_t = ValueT;
|
||||||
|
|
||||||
|
static constexpr
|
||||||
|
uint64_t mix (uint64_t v)
|
||||||
|
{
|
||||||
|
v ^= v >> 23;
|
||||||
|
v *= 0x2127599bf4325c37;
|
||||||
|
v ^= v >> 47;
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
digest_t operator() (uint64_t seed, util::view<const uint8_t*>) const;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,61 +27,24 @@ using util::hash::fletcher;
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
fletcher<T>::fletcher (part_t _modulus, part_t _a, part_t _b):
|
fletcher<T>::fletcher (part_t _modulus, part_t _a, part_t _b):
|
||||||
m_modulus { _modulus },
|
m_modulus { _modulus },
|
||||||
m_initial { _a, _b },
|
m_initial { _a, _b }
|
||||||
m_state { m_initial }
|
|
||||||
{ ; }
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T>
|
|
||||||
void
|
|
||||||
fletcher<T>::reset (void)
|
|
||||||
{
|
|
||||||
m_state = m_initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
template <typename T>
|
template <typename DigestT>
|
||||||
void
|
typename fletcher<DigestT>::digest_t
|
||||||
fletcher<T>::update (const void *restrict data, size_t size) noexcept
|
fletcher<DigestT>::operator() (util::view<const std::uint8_t*> data) const noexcept
|
||||||
{
|
{
|
||||||
CHECK (data);
|
state_t accum = m_initial;
|
||||||
|
|
||||||
auto first = static_cast<const uint8_t *restrict> (data);
|
for (const auto i: data) {
|
||||||
update (first, first + size);
|
accum.a = (accum.a + i) % m_modulus;
|
||||||
}
|
accum.b = (accum.a + accum.b) % m_modulus;
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T>
|
|
||||||
void
|
|
||||||
fletcher<T>::update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept
|
|
||||||
{
|
|
||||||
CHECK (first);
|
|
||||||
CHECK (last);
|
|
||||||
CHECK_LE (first, last);
|
|
||||||
|
|
||||||
for (auto cursor = first; cursor < last; ++cursor) {
|
|
||||||
m_state.a = (m_state.a + *cursor ) % m_modulus;
|
|
||||||
m_state.b = (m_state.a + m_state.b) % m_modulus;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
return accum.b << (sizeof(part_t) * 8u) | accum.a;
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T>
|
|
||||||
void
|
|
||||||
fletcher<T>::finish (void)
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
typename fletcher<T>::digest_t
|
|
||||||
fletcher<T>::digest (void) const
|
|
||||||
{
|
|
||||||
return (m_state.b << (sizeof (part_t) * 8)) + m_state.a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#define __UTIL_HASH_FLETCHER_HPP
|
#define __UTIL_HASH_FLETCHER_HPP
|
||||||
|
|
||||||
#include "../types/bits.hpp"
|
#include "../types/bits.hpp"
|
||||||
|
#include "../view.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@ -25,31 +26,24 @@
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
namespace util::hash {
|
namespace util::hash {
|
||||||
template <typename DIGEST>
|
template <typename DigestT>
|
||||||
class fletcher {
|
class fletcher {
|
||||||
public:
|
public:
|
||||||
using digest_t = DIGEST;
|
using digest_t = DigestT;
|
||||||
using part_t = typename bytes_type<sizeof (digest_t) / 2>::uint;
|
using part_t = typename bytes_type<sizeof (digest_t) / 2>::uint;
|
||||||
|
|
||||||
fletcher (part_t modulus, part_t a, part_t b);
|
fletcher (part_t modulus, part_t a, part_t b);
|
||||||
|
|
||||||
void update (const void *restrict, size_t) noexcept;
|
digest_t
|
||||||
void update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept;
|
operator() (util::view<const std::uint8_t*>) const noexcept;
|
||||||
|
|
||||||
void finish (void);
|
|
||||||
digest_t digest (void) const;
|
|
||||||
|
|
||||||
void reset (void);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const digest_t m_modulus;
|
|
||||||
|
|
||||||
struct state_t {
|
struct state_t {
|
||||||
part_t a, b;
|
part_t a, b;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const digest_t m_modulus;
|
||||||
const state_t m_initial;
|
const state_t m_initial;
|
||||||
state_t m_state;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
#include "fnv1a.hpp"
|
#include "fnv1a.hpp"
|
||||||
|
|
||||||
|
using util::hash::fnv1a;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Prime is,
|
// Prime is,
|
||||||
@ -28,48 +30,41 @@
|
|||||||
//
|
//
|
||||||
// Bias is the FNV-0 hash of "chongo <Landon Curt Noll> /\\../\\"
|
// Bias is the FNV-0 hash of "chongo <Landon Curt Noll> /\\../\\"
|
||||||
|
|
||||||
template <size_t B>
|
template <typename DigestT>
|
||||||
struct constants { };
|
struct constants { };
|
||||||
|
|
||||||
template <> struct constants<32> {
|
|
||||||
static constexpr uint32_t PRIME = 16777619u;
|
|
||||||
static constexpr uint32_t BIAS = 2166136261u;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct constants<64> {
|
//-----------------------------------------------------------------------------
|
||||||
static constexpr uint64_t PRIME = 1099511628211u;
|
template <>
|
||||||
static constexpr uint64_t BIAS = 14695981039346656037u;
|
struct constants<uint32_t> {
|
||||||
|
static constexpr uint32_t prime = 16777619u;
|
||||||
|
static constexpr uint32_t bias = 2166136261u;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template <typename T>
|
template <>
|
||||||
T
|
struct constants<uint64_t> {
|
||||||
fnv1a (const void *restrict _data, size_t len)
|
static constexpr uint64_t prime = 1099511628211u;
|
||||||
{
|
static constexpr uint64_t bias = 14695981039346656037u;
|
||||||
auto *data = static_cast<const uint8_t *restrict> (_data);
|
};
|
||||||
T result = constants<sizeof(T)*8>::BIAS;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < len; ++i) {
|
|
||||||
result ^= data[i];
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
result *= constants<sizeof(T)*8>::PRIME;
|
template <typename DigestT>
|
||||||
|
typename fnv1a<DigestT>::digest_t
|
||||||
|
fnv1a<DigestT>::operator() (const util::view<const uint8_t*> data) const noexcept
|
||||||
|
{
|
||||||
|
auto result = constants<DigestT>::bias;
|
||||||
|
|
||||||
|
for (auto i: data) {
|
||||||
|
result ^= i;
|
||||||
|
result *= constants<DigestT>::prime;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
template struct util::hash::fnv1a<uint32_t>;
|
||||||
uint32_t
|
template struct util::hash::fnv1a<uint64_t>;
|
||||||
util::hash::fnv1a32 (const void *data, size_t len)
|
|
||||||
{
|
|
||||||
return fnv1a<uint32_t> (data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
uint64_t
|
|
||||||
util::hash::fnv1a64 (const void *data, size_t len)
|
|
||||||
{
|
|
||||||
return fnv1a<uint64_t> (data, len);
|
|
||||||
}
|
|
||||||
|
@ -17,13 +17,19 @@
|
|||||||
#ifndef __UTIL_HASH_FNV1A_HPP
|
#ifndef __UTIL_HASH_FNV1A_HPP
|
||||||
#define __UTIL_HASH_FNV1A_HPP
|
#define __UTIL_HASH_FNV1A_HPP
|
||||||
|
|
||||||
|
#include "view.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
namespace util::hash {
|
namespace util::hash {
|
||||||
// Fast and general hashing using FNV-1a
|
// Fast and general hashing using FNV-1a
|
||||||
uint32_t fnv1a32 (const void *restrict, size_t);
|
template <typename DigestT>
|
||||||
uint64_t fnv1a64 (const void *restrict, size_t);
|
struct fnv1a {
|
||||||
|
using digest_t = DigestT;
|
||||||
|
|
||||||
|
digest_t operator() (util::view<const uint8_t*>) const noexcept;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
12
hash/fwd.hpp
12
hash/fwd.hpp
@ -37,18 +37,6 @@ namespace util::hash {
|
|||||||
class crc;
|
class crc;
|
||||||
|
|
||||||
class xxhash;
|
class xxhash;
|
||||||
|
|
||||||
// hash adapters
|
|
||||||
class PBKDF1;
|
|
||||||
class PBKDF2;
|
|
||||||
|
|
||||||
// cryptographic hashes
|
|
||||||
class MD2;
|
|
||||||
class MD4;
|
|
||||||
class MD5;
|
|
||||||
class RIPEMD;
|
|
||||||
class SHA1;
|
|
||||||
class SHA256;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
124
hash/hmac.cpp
124
hash/hmac.cpp
@ -1,124 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "hmac.hpp"
|
|
||||||
|
|
||||||
#include "../debug.hpp"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
using util::hash::HMAC;
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
static const uint8_t IFILL = 0x36;
|
|
||||||
static const uint8_t OFILL = 0x5C;
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <class T>
|
|
||||||
HMAC<T>::HMAC (const uint8_t *restrict key, size_t len)
|
|
||||||
{
|
|
||||||
CHECK (key);
|
|
||||||
|
|
||||||
static_assert (sizeof (m_ikey) == sizeof (m_okey), "key padding must match");
|
|
||||||
|
|
||||||
// If the key is larger than the blocklength, use the hash of the key
|
|
||||||
if (len > T::BLOCK_SIZE) {
|
|
||||||
m_hash.update (key, len);
|
|
||||||
m_hash.finish ();
|
|
||||||
|
|
||||||
auto d = m_hash.digest ();
|
|
||||||
m_hash.reset ();
|
|
||||||
|
|
||||||
std::copy (d.begin (), d.end (), m_ikey.begin ());
|
|
||||||
len = d.size ();
|
|
||||||
// Use the key directly
|
|
||||||
} else {
|
|
||||||
std::copy (key, key + len, m_ikey.begin ());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::fill (m_ikey.begin () + len,
|
|
||||||
m_ikey.end (),
|
|
||||||
0);
|
|
||||||
|
|
||||||
m_okey = m_ikey;
|
|
||||||
|
|
||||||
std::transform (m_ikey.begin (),
|
|
||||||
m_ikey.end (),
|
|
||||||
m_ikey.begin (),
|
|
||||||
[] (auto v) { return v ^ IFILL; });
|
|
||||||
|
|
||||||
std::transform (m_okey.begin (),
|
|
||||||
m_okey.end (),
|
|
||||||
m_okey.begin (),
|
|
||||||
[] (auto v) { return v ^ OFILL; });
|
|
||||||
|
|
||||||
m_hash.update (m_ikey.data (), m_ikey.size ());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <class T>
|
|
||||||
void
|
|
||||||
HMAC<T>::update (const void *restrict data, size_t len)
|
|
||||||
{
|
|
||||||
m_hash.update ((const uint8_t*)data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <class T>
|
|
||||||
void
|
|
||||||
HMAC<T>::finish (void)
|
|
||||||
{
|
|
||||||
m_hash.finish ();
|
|
||||||
auto d = m_hash.digest ();
|
|
||||||
|
|
||||||
m_hash.reset ();
|
|
||||||
m_hash.update (m_okey.data (), m_okey.size ());
|
|
||||||
m_hash.update (d.data (), d.size ());
|
|
||||||
m_hash.finish ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <class T>
|
|
||||||
void
|
|
||||||
HMAC<T>::reset (void)
|
|
||||||
{
|
|
||||||
m_hash.reset ();
|
|
||||||
m_hash.update (m_ikey.data (), m_ikey.size ());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <class T>
|
|
||||||
typename HMAC<T>::digest_t
|
|
||||||
HMAC<T>::digest (void)
|
|
||||||
{
|
|
||||||
return m_hash.digest ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
#include "md5.hpp"
|
|
||||||
#include "sha1.hpp"
|
|
||||||
|
|
||||||
namespace util::hash {
|
|
||||||
template class HMAC<MD5>;
|
|
||||||
template class HMAC<SHA1>;
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTIL_HASH_HMAC_HPP
|
|
||||||
#define __UTIL_HASH_HMAC_HPP
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
namespace util::hash {
|
|
||||||
template <class T>
|
|
||||||
/// RFC 2104 key-hashing for message authentication
|
|
||||||
class HMAC {
|
|
||||||
public:
|
|
||||||
using digest_t = typename T::digest_t;
|
|
||||||
|
|
||||||
HMAC (const uint8_t *key, size_t);
|
|
||||||
|
|
||||||
void update (const void *restrict, size_t);
|
|
||||||
void finish (void);
|
|
||||||
void reset (void);
|
|
||||||
|
|
||||||
digest_t digest (void);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::array<uint8_t,T::BLOCK_SIZE> m_ikey;
|
|
||||||
std::array<uint8_t,T::BLOCK_SIZE> m_okey;
|
|
||||||
|
|
||||||
T m_hash;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "hotp.hpp"
|
|
||||||
|
|
||||||
#include "../endian.hpp"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
using util::hash::HOTP;
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
HOTP::HOTP (const char *_key, uint64_t _counter):
|
|
||||||
HOTP (_key, strlen (_key), _counter)
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
HOTP::HOTP (const void *_key, size_t _len, uint64_t _counter):
|
|
||||||
m_counter (_counter),
|
|
||||||
m_hash ((const uint8_t*)_key, _len)
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
unsigned
|
|
||||||
HOTP::value (void)
|
|
||||||
{
|
|
||||||
auto c = htob (m_counter);
|
|
||||||
|
|
||||||
m_hash.update (&c, sizeof (c));
|
|
||||||
m_hash.finish ();
|
|
||||||
|
|
||||||
auto h = m_hash.digest ();
|
|
||||||
auto t = truncate (h);
|
|
||||||
|
|
||||||
m_hash.reset ();
|
|
||||||
++m_counter;
|
|
||||||
|
|
||||||
return t % 1000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
uint32_t
|
|
||||||
HOTP::truncate (SHA1::digest_t d)
|
|
||||||
{
|
|
||||||
// offset into the digest by the last 4 bits
|
|
||||||
size_t o= d[d.size () - 1] & 0x0F;
|
|
||||||
|
|
||||||
// mask the highest bit per the specification
|
|
||||||
uint32_t v = (d[o + 0] & 0x7f) << 24 |
|
|
||||||
(d[o + 1] & 0xff) << 16 |
|
|
||||||
(d[o + 2] & 0xff) << 8 |
|
|
||||||
(d[o + 3] & 0xff) << 0;
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTIL_HASH_HOTP_HPP
|
|
||||||
#define __UTIL_HASH_HOTP_HPP
|
|
||||||
|
|
||||||
#include "hmac.hpp"
|
|
||||||
#include "sha1.hpp"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace util::hash {
|
|
||||||
/// HMAC one-time password (RFC 4226)
|
|
||||||
class HOTP {
|
|
||||||
public:
|
|
||||||
HOTP (const char *key, uint64_t counter);
|
|
||||||
HOTP (const void *key, size_t len, uint64_t counter);
|
|
||||||
|
|
||||||
unsigned value (void);
|
|
||||||
uint64_t counter (void) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint32_t truncate (SHA1::digest_t);
|
|
||||||
|
|
||||||
uint64_t m_counter;
|
|
||||||
HMAC<SHA1> m_hash;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
484
hash/keccak.cpp
484
hash/keccak.cpp
@ -1,484 +0,0 @@
|
|||||||
#include "keccak.hpp"
|
|
||||||
|
|
||||||
#include "../endian.hpp"
|
|
||||||
#include "../maths.hpp"
|
|
||||||
#include "../bitwise.hpp"
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <array>
|
|
||||||
#include <iostream>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define FOR(i,n) for(i=0; i<n; ++i)
|
|
||||||
|
|
||||||
int LFSR86540(u8 *R) { (*R)=((*R)<<1)^(((*R)&0x80)?0x71:0); return ((*R)&2)>>1; }
|
|
||||||
#define ROL(a,o) ((((u64)a)<<o)^(((u64)a)>>(64-o)))
|
|
||||||
static u64 load64(const u8 *x) { ui i; u64 u=0; FOR(i,8) { u<<=8; u|=x[7-i]; } return u; }
|
|
||||||
static void store64(u8 *x, u64 u) { ui i; FOR(i,8) { x[i]=u; u>>=8; } }
|
|
||||||
static void xor64(u8 *x, u64 u) { ui i; FOR(i,8) { x[i]^=u; u>>=8; } }
|
|
||||||
#define rL(x,y) load64((u8*)s+8*(x+5*y))
|
|
||||||
#define wL(x,y,l) store64((u8*)s+8*(x+5*y),l)
|
|
||||||
#define XL(x,y,l) xor64((u8*)s+8*(x+5*y),l)
|
|
||||||
void KeccakF1600(void *s)
|
|
||||||
{
|
|
||||||
ui r,x,y,i,j,Y; u8 R=0x01; u64 C[5],D;
|
|
||||||
for(i=0; i<24; i++) {
|
|
||||||
/*θ*/ FOR(x,5) C[x]=rL(x,0)^rL(x,1)^rL(x,2)^rL(x,3)^rL(x,4); FOR(x,5) { D=C[(x+4)%5]^ROL(C[(x+1)%5],1); FOR(y,5) XL(x,y,D); }
|
|
||||||
/*ρπ*/ x=1; y=r=0; D=rL(x,y); FOR(j,24) { r+=j+1; Y=(2*x+3*y)%5; x=y; y=Y; C[0]=rL(x,y); wL(x,y,ROL(D,r%64)); D=C[0]; }
|
|
||||||
/*χ*/ FOR(y,5) { FOR(x,5) C[x]=rL(x,y); FOR(x,5) wL(x,y,C[x]^((~C[(x+1)%5])&C[(x+2)%5])); }
|
|
||||||
/*ι*/ FOR(j,7) if (LFSR86540(&R)) XL(0,0,(u64)1<<((1<<j)-1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void Keccak(ui r, ui c, const u8 *in, u64 inLen, u8 sfx, u8 *out, u64 outLen)
|
|
||||||
{
|
|
||||||
/*initialize*/ u8 s[200]; ui R=r/8; ui i,b=0; FOR(i,200) s[i]=0;
|
|
||||||
/*absorb*/ while(inLen>0) { b=(inLen<R)?inLen:R; FOR(i,b) s[i]^=in[i]; in+=b; inLen-=b; if (b==R) { KeccakF1600(s); b=0; } }
|
|
||||||
/*pad*/ s[b]^=sfx; if((sfx&0x80)&&(b==(R-1))) KeccakF1600(s); s[R-1]^=0x80; KeccakF1600(s);
|
|
||||||
/*squeeze*/ while(outLen>0) { b=(outLen<R)?outLen:R; FOR(i,b) out[i]=s[i]; out+=b; outLen-=b; if(outLen>0) KeccakF1600(s); }
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// derived from Keccak (KCP) readable-and-compact C implementation
|
|
||||||
|
|
||||||
/*
|
|
||||||
Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni,
|
|
||||||
Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby
|
|
||||||
denoted as "the implementer".
|
|
||||||
|
|
||||||
For more information, feedback or questions, please refer to our websites:
|
|
||||||
http://keccak.noekeon.org/
|
|
||||||
http://keyak.noekeon.org/
|
|
||||||
http://ketje.noekeon.org/
|
|
||||||
|
|
||||||
To the extent possible under law, the implementer has waived all copyright
|
|
||||||
and related or neighboring rights to the source code in this file.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
================================================================
|
|
||||||
The purpose of this source file is to demonstrate a readable and compact
|
|
||||||
implementation of all the Keccak instances approved in the FIPS 202 standard,
|
|
||||||
including the hash functions and the extendable-output functions (XOFs).
|
|
||||||
|
|
||||||
We focused on clarity and on source-code compactness,
|
|
||||||
rather than on the performance.
|
|
||||||
|
|
||||||
The advantages of this implementation are:
|
|
||||||
+ The source code is compact, after removing the comments, that is. :-)
|
|
||||||
+ There are no tables with arbitrary constants.
|
|
||||||
+ For clarity, the comments link the operations to the specifications using
|
|
||||||
the same notation as much as possible.
|
|
||||||
+ There is no restriction in cryptographic features. In particular,
|
|
||||||
the SHAKE128 and SHAKE256 XOFs can produce any output length.
|
|
||||||
+ The code does not use much RAM, as all operations are done in place.
|
|
||||||
|
|
||||||
The drawbacks of this implementation are:
|
|
||||||
- There is no message queue. The whole message must be ready in a buffer.
|
|
||||||
- It is not optimized for peformance.
|
|
||||||
|
|
||||||
The implementation is even simpler on a little endian platform. Just define the
|
|
||||||
LITTLE_ENDIAN symbol in that case.
|
|
||||||
|
|
||||||
For a more complete set of implementations, please refer to
|
|
||||||
the Keccak Code Package at https://github.com/gvanas/KeccakCodePackage
|
|
||||||
|
|
||||||
For more information, please refer to:
|
|
||||||
* [Keccak Reference] http://keccak.noekeon.org/Keccak-reference-3.0.pdf
|
|
||||||
* [Keccak Specifications Summary] http://keccak.noekeon.org/specs_summary.html
|
|
||||||
|
|
||||||
This file uses UTF-8 encoding, as some comments use Greek letters.
|
|
||||||
================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to compute the Keccak[r, c] sponge function over a given input.
|
|
||||||
* @param rate The value of the rate r.
|
|
||||||
* @param capacity The value of the capacity c.
|
|
||||||
* @param input Pointer to the input message.
|
|
||||||
* @param inputByteLen The number of input bytes provided in the input message.
|
|
||||||
* @param delimitedSuffix Bits that will be automatically appended to the end
|
|
||||||
* of the input message, as in domain separation.
|
|
||||||
* This is a byte containing from 0 to 7 bits
|
|
||||||
* These <i>n</i> bits must be in the least significant bit positions
|
|
||||||
* and must be delimited with a bit 1 at position <i>n</i>
|
|
||||||
* (counting from 0=LSB to 7=MSB) and followed by bits 0
|
|
||||||
* from position <i>n</i>+1 to position 7.
|
|
||||||
* Some examples:
|
|
||||||
* - If no bits are to be appended, then @a delimitedSuffix must be 0x01.
|
|
||||||
* - If the 2-bit sequence 0,1 is to be appended (as for SHA3-*), @a delimitedSuffix must be 0x06.
|
|
||||||
* - If the 4-bit sequence 1,1,1,1 is to be appended (as for SHAKE*), @a delimitedSuffix must be 0x1F.
|
|
||||||
* - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a delimitedSuffix must be 0x8B.
|
|
||||||
* @param output Pointer to the buffer where to store the output.
|
|
||||||
* @param outputByteLen The number of output bytes desired.
|
|
||||||
* @pre One must have r+c=1600 and the rate a multiple of 8 bits in this implementation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to compute SHAKE128 on the input message with any output length.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
FIPS202_SHAKE128(const uint8_t *input, size_t inputByteLen, uint8_t *output, size_t outputByteLen)
|
|
||||||
{
|
|
||||||
keccak k (1344, 256, 0x1f);
|
|
||||||
k.update (input, inputByteLen);
|
|
||||||
k.digest (output, outputByteLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to compute SHAKE256 on the input message with any output length.
|
|
||||||
*/
|
|
||||||
void FIPS202_SHAKE256(const uint8_t *input, size_t inputByteLen, uint8_t *output, size_t outputByteLen)
|
|
||||||
{
|
|
||||||
keccak k (1088, 512, 0x1f);
|
|
||||||
k.update (input, inputByteLen);
|
|
||||||
k.digest (output, outputByteLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to compute SHA3-224 on the input message. The output length is fixed to 28 bytes.
|
|
||||||
*/
|
|
||||||
void FIPS202_SHA3_224(const uint8_t *input, size_t inputByteLen, uint8_t *output)
|
|
||||||
{
|
|
||||||
keccak k (1152, 448, 0x06);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < inputByteLen; ++i)
|
|
||||||
k.update (&input[i], 1);
|
|
||||||
//k.update (input, inputByteLen);
|
|
||||||
k.digest (output, 28);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to compute SHA3-256 on the input message. The output length is fixed to 32 bytes.
|
|
||||||
*/
|
|
||||||
void FIPS202_SHA3_256(const uint8_t *input, size_t inputByteLen, uint8_t *output)
|
|
||||||
{
|
|
||||||
keccak k (1088, 512, 0x06);
|
|
||||||
k.update (input, inputByteLen);
|
|
||||||
k.digest (output, 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to compute SHA3-384 on the input message. The output length is fixed to 48 bytes.
|
|
||||||
*/
|
|
||||||
void FIPS202_SHA3_384(const uint8_t *input, size_t inputByteLen, uint8_t *output)
|
|
||||||
{
|
|
||||||
keccak k (832, 768, 0x06);
|
|
||||||
k.update (input, inputByteLen);
|
|
||||||
k.digest (output, 48);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to compute SHA3-512 on the input message. The output length is fixed to 64 bytes.
|
|
||||||
*/
|
|
||||||
void FIPS202_SHA3_512(const uint8_t *input, size_t inputByteLen, uint8_t *output)
|
|
||||||
{
|
|
||||||
keccak k (576, 1024, 0x06);
|
|
||||||
k.update (input, inputByteLen);
|
|
||||||
k.digest (output, 64);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
================================================================
|
|
||||||
A readable and compact implementation of the Keccak-f[1600] permutation.
|
|
||||||
================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
//static constexpr
|
|
||||||
//size_t
|
|
||||||
//i (size_t x, size_t y)
|
|
||||||
//{
|
|
||||||
// return x + 5 * y;
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function that computes the linear feedback shift register (LFSR) used to
|
|
||||||
* define the round constants (see [Keccak Reference, Section 1.2]).
|
|
||||||
*/
|
|
||||||
class lfsr86540 {
|
|
||||||
public:
|
|
||||||
lfsr86540 ():
|
|
||||||
value (0x1)
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
update (void)
|
|
||||||
{
|
|
||||||
bool result = value & 0x01;
|
|
||||||
if (value & 0x80)
|
|
||||||
// Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1
|
|
||||||
value = (value << 1) ^ 0x71;
|
|
||||||
else
|
|
||||||
value <<= 1;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint8_t value;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// θ step, see [Keccak Reference, Section 2.3.2]
|
|
||||||
static void
|
|
||||||
permute_theta (uint64_t m_words[5][5])
|
|
||||||
{
|
|
||||||
uint64_t C[5], D;
|
|
||||||
|
|
||||||
// Compute the parity of the columns
|
|
||||||
for (unsigned x = 0; x < 5; ++x)
|
|
||||||
C[x] = m_words[0][x] ^ m_words[1][x] ^ m_words[2][x] ^ m_words[3][x] ^ m_words[4][x];
|
|
||||||
|
|
||||||
for (unsigned x = 0; x < 5; ++x) {
|
|
||||||
// Compute the θ effect for a given column
|
|
||||||
D = C[(x+4)%5] ^ util::rotatel (C[(x+1)%5], 1);
|
|
||||||
|
|
||||||
// Add the θ effect to the whole column
|
|
||||||
for (unsigned y = 0; y < 5; ++y)
|
|
||||||
m_words[y][x] ^= D;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
permute_rho (uint64_t m_words[5][5])
|
|
||||||
{
|
|
||||||
m_words[0][1] = util::rotatel (m_words[0][1], 1);
|
|
||||||
m_words[0][2] = util::rotatel (m_words[0][2], 62);
|
|
||||||
m_words[0][3] = util::rotatel (m_words[0][3], 28);
|
|
||||||
m_words[0][4] = util::rotatel (m_words[0][4], 27);
|
|
||||||
m_words[1][0] = util::rotatel (m_words[1][0], 36);
|
|
||||||
m_words[1][1] = util::rotatel (m_words[1][1], 44);
|
|
||||||
m_words[1][2] = util::rotatel (m_words[1][2], 6);
|
|
||||||
m_words[1][3] = util::rotatel (m_words[1][3], 55);
|
|
||||||
m_words[1][4] = util::rotatel (m_words[1][4], 20);
|
|
||||||
m_words[2][0] = util::rotatel (m_words[2][0], 3);
|
|
||||||
m_words[2][1] = util::rotatel (m_words[2][1], 10);
|
|
||||||
m_words[2][2] = util::rotatel (m_words[2][2], 43);
|
|
||||||
m_words[2][3] = util::rotatel (m_words[2][3], 25);
|
|
||||||
m_words[2][4] = util::rotatel (m_words[2][4], 39);
|
|
||||||
m_words[3][0] = util::rotatel (m_words[3][0], 41);
|
|
||||||
m_words[3][1] = util::rotatel (m_words[3][1], 45);
|
|
||||||
m_words[3][2] = util::rotatel (m_words[3][2], 15);
|
|
||||||
m_words[3][3] = util::rotatel (m_words[3][3], 21);
|
|
||||||
m_words[3][4] = util::rotatel (m_words[3][4], 8);
|
|
||||||
m_words[4][0] = util::rotatel (m_words[4][0], 18);
|
|
||||||
m_words[4][1] = util::rotatel (m_words[4][1], 2);
|
|
||||||
m_words[4][2] = util::rotatel (m_words[4][2], 61);
|
|
||||||
m_words[4][3] = util::rotatel (m_words[4][3], 56);
|
|
||||||
m_words[4][4] = util::rotatel (m_words[4][4], 14);
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
for (size_t i = 1; i < 25; ++i) {
|
|
||||||
//unsigned r = ((t+1)*(t+2)/2)%64;
|
|
||||||
unsigned r = ((i + 1) * (i + 2) / 2) % 64;
|
|
||||||
|
|
||||||
m_words[i/5][i%5] = util::rotatel (m_words[i/5][i%5], r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
permute_pi (uint64_t m_words[5][5])
|
|
||||||
{
|
|
||||||
//auto A = reinterpret_cast<uint64_t*> (m_words);
|
|
||||||
|
|
||||||
//uint64_t A1;
|
|
||||||
//A1 = A[1];
|
|
||||||
//A[ 1] = A[ 6];
|
|
||||||
//A[ 6] = A[ 9];
|
|
||||||
//A[ 9] = A[22];
|
|
||||||
//A[22] = A[14];
|
|
||||||
//A[14] = A[20];
|
|
||||||
//A[20] = A[ 2];
|
|
||||||
//A[ 2] = A[12];
|
|
||||||
//A[12] = A[13];
|
|
||||||
//A[13] = A[19];
|
|
||||||
//A[19] = A[23];
|
|
||||||
//A[23] = A[15];
|
|
||||||
//A[15] = A[ 4];
|
|
||||||
//A[ 4] = A[24];
|
|
||||||
//A[24] = A[21];
|
|
||||||
//A[21] = A[ 8];
|
|
||||||
//A[ 8] = A[16];
|
|
||||||
//A[16] = A[ 5];
|
|
||||||
//A[ 5] = A[ 3];
|
|
||||||
//A[ 3] = A[18];
|
|
||||||
//A[18] = A[17];
|
|
||||||
//A[17] = A[11];
|
|
||||||
//A[11] = A[ 7];
|
|
||||||
//A[ 7] = A[10];
|
|
||||||
//A[10] = A1;
|
|
||||||
//return;
|
|
||||||
|
|
||||||
unsigned x = 1, y = 0;
|
|
||||||
uint64_t current = m_words[y][x];
|
|
||||||
uint64_t temp;
|
|
||||||
// Iterate over ((0 1)(2 3))^t * (1 0) for 0 ≤ t ≤ 23
|
|
||||||
for (unsigned t = 0; t < 24; ++t) {
|
|
||||||
unsigned int Y = (2*x+3*y)%5;
|
|
||||||
x = y;
|
|
||||||
y = Y;
|
|
||||||
|
|
||||||
temp = m_words[y][x];
|
|
||||||
m_words[y][x] = current;
|
|
||||||
current = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
//for (unsigned int i = 0; i < 5; ++i)
|
|
||||||
// for (unsigned int j = 0; j < 5; ++j)
|
|
||||||
// m_words[j][(2*i+3*j)%5] = m_words[i][j];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function that computes the Keccak-f[1600] permutation on the given state.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
keccak::permute (void)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < m_bitrate/64; ++i)
|
|
||||||
m_words[i/5][i%5] = util::ltoh (m_words[i/5][i%5]);
|
|
||||||
|
|
||||||
lfsr86540 shift;
|
|
||||||
|
|
||||||
for (unsigned round = 0; round < 24; ++round) {
|
|
||||||
permute_theta (m_words);
|
|
||||||
permute_rho (m_words);
|
|
||||||
permute_pi (m_words);
|
|
||||||
|
|
||||||
|
|
||||||
if (0) { // === ρ and π steps (see [Keccak Reference, Sections 2.3.3 and 2.3.4]) ===
|
|
||||||
uint64_t current, temp;
|
|
||||||
// Start at coordinates (1 0)
|
|
||||||
unsigned x = 1, y = 0;
|
|
||||||
current = m_words[y][x];
|
|
||||||
// Iterate over ((0 1)(2 3))^t * (1 0) for 0 ≤ t ≤ 23
|
|
||||||
for (unsigned t = 0; t < 24; ++t) {
|
|
||||||
// Compute the rotation constant r = (t+1)(t+2)/2
|
|
||||||
unsigned int r = ((t+1)*(t+2)/2)%64;
|
|
||||||
|
|
||||||
// Compute ((0 1)(2 3)) * (x y)
|
|
||||||
unsigned int Y = (2*x+3*y)%5; x = y; y = Y;
|
|
||||||
|
|
||||||
// Swap current and state(x,y), and rotate
|
|
||||||
temp = m_words[y][x];
|
|
||||||
m_words[y][x] = util::rotatel (current, r);
|
|
||||||
current = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{ // === χ step (see [Keccak Reference, Section 2.3.1]) ===
|
|
||||||
uint64_t temp[5];
|
|
||||||
for (unsigned y = 0; y < 5; ++y) {
|
|
||||||
// Take a copy of the plane
|
|
||||||
for (unsigned x = 0; x < 5; ++x)
|
|
||||||
temp[x] = m_words[y][x];
|
|
||||||
|
|
||||||
// Compute χ on the plane
|
|
||||||
for(unsigned x = 0; x < 5; ++x)
|
|
||||||
m_words[y][x] = temp[x] ^((~temp[(x+1)%5]) & temp[(x+2)%5]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{ // === ι step (see [Keccak Reference, Section 2.3.5]) ===
|
|
||||||
for (unsigned j = 0; j < 7; ++j) {
|
|
||||||
unsigned int bitPosition = (1 << j) - 1; //2^j-1
|
|
||||||
if (shift.update ())
|
|
||||||
m_words[0][0] ^= uint64_t{1} << bitPosition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
================================================================
|
|
||||||
A readable and compact implementation of the Keccak sponge functions
|
|
||||||
that use the Keccak-f[1600] permutation.
|
|
||||||
================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
keccak::update (
|
|
||||||
const uint8_t *input,
|
|
||||||
size_t len
|
|
||||||
) {
|
|
||||||
unsigned int byterate = m_bitrate / 8;
|
|
||||||
|
|
||||||
while (len) {
|
|
||||||
auto chunk = util::min (len, byterate - m_cursor);
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < chunk; ++i)
|
|
||||||
m_bytes[m_cursor++] ^= *input++;
|
|
||||||
|
|
||||||
len -= chunk;
|
|
||||||
|
|
||||||
if (m_cursor == byterate) {
|
|
||||||
permute ();
|
|
||||||
m_cursor = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
keccak::digest (
|
|
||||||
uint8_t *output,
|
|
||||||
size_t len
|
|
||||||
) {
|
|
||||||
unsigned byterate = m_bitrate / 8u;
|
|
||||||
|
|
||||||
// === Do the padding and switch to the squeezing phase ===
|
|
||||||
// Absorb the last few bits and add the first bit of padding (which
|
|
||||||
// coincides with the delimiter in delimitedSuffix)
|
|
||||||
m_bytes[m_cursor] ^= m_suffix;
|
|
||||||
|
|
||||||
// If the first bit of padding is at position rate-1, we need a whole new
|
|
||||||
// block for the second bit of padding
|
|
||||||
if (m_suffix & 0x80 && m_cursor == byterate - 1)
|
|
||||||
permute ();
|
|
||||||
|
|
||||||
// Add the second bit of padding
|
|
||||||
m_bytes[byterate - 1] ^= 0x80;
|
|
||||||
|
|
||||||
// === Squeeze out all the output blocks ===
|
|
||||||
while (len) {
|
|
||||||
permute ();
|
|
||||||
|
|
||||||
auto chunk = util::min (len, byterate);
|
|
||||||
std::copy_n (m_bytes.begin (), chunk, output);
|
|
||||||
|
|
||||||
output += chunk;
|
|
||||||
len -= chunk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
keccak::keccak (unsigned _bitrate,
|
|
||||||
unsigned _capacity,
|
|
||||||
uint8_t _suffix):
|
|
||||||
m_bitrate (_bitrate),
|
|
||||||
m_capacity (_capacity),
|
|
||||||
m_suffix (_suffix),
|
|
||||||
m_cursor (0)
|
|
||||||
{
|
|
||||||
// we could support bitrates that are multiples of 8, but 64 simplifies
|
|
||||||
// some state handling, and the SHA-3 constants are all multiples of 64
|
|
||||||
// bits anyway.
|
|
||||||
if ((m_bitrate + m_capacity) / 8 != sizeof (m_bytes) || m_bitrate % 64 != 0)
|
|
||||||
throw "error";
|
|
||||||
|
|
||||||
std::fill (std::begin (m_bytes), std::end (m_bytes), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2016 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __HASH_KECCAK_HPP
|
|
||||||
#define __HASH_KECCAK_HPP
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
class keccak {
|
|
||||||
public:
|
|
||||||
keccak (unsigned bitrate, unsigned capacity, uint8_t suffix);
|
|
||||||
|
|
||||||
void update (const uint8_t *input, size_t len);
|
|
||||||
void digest (uint8_t *output, size_t len);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void permute (void);
|
|
||||||
|
|
||||||
const unsigned m_bitrate;
|
|
||||||
const unsigned m_capacity;
|
|
||||||
const uint8_t m_suffix;
|
|
||||||
|
|
||||||
size_t m_cursor;
|
|
||||||
|
|
||||||
union {
|
|
||||||
std::array<uint8_t, 200> m_bytes;
|
|
||||||
uint64_t m_words[5][5];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void FIPS202_SHAKE128(const uint8_t *input, size_t inputByteLen, uint8_t *output, size_t outputByteLen);
|
|
||||||
void FIPS202_SHAKE256(const uint8_t *input, size_t inputByteLen, uint8_t *output, size_t outputByteLen);
|
|
||||||
void FIPS202_SHA3_224(const uint8_t *input, size_t inputByteLen, uint8_t *output);
|
|
||||||
void FIPS202_SHA3_256(const uint8_t *input, size_t inputByteLen, uint8_t *output);
|
|
||||||
void FIPS202_SHA3_384(const uint8_t *input, size_t inputByteLen, uint8_t *output);
|
|
||||||
void FIPS202_SHA3_512(const uint8_t *input, size_t inputByteLen, uint8_t *output);
|
|
||||||
|
|
||||||
#endif
|
|
182
hash/md2.cpp
182
hash/md2.cpp
@ -1,182 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2013 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "md2.hpp"
|
|
||||||
|
|
||||||
#include "../debug.hpp"
|
|
||||||
#include "../types.hpp"
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
using util::hash::MD2;
|
|
||||||
|
|
||||||
using std::array;
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
using std::fill;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
static array<uint8_t,256> S = { {
|
|
||||||
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, 19,
|
|
||||||
98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 76, 130, 202,
|
|
||||||
30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 138, 23, 229, 18,
|
|
||||||
190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 245, 142, 187, 47, 238, 122,
|
|
||||||
169, 104, 121, 145, 21, 178, 7, 63, 148, 194, 16, 137, 11, 34, 95, 33,
|
|
||||||
128, 127, 93, 154, 90, 144, 50, 39, 53, 62, 204, 231, 191, 247, 151, 3,
|
|
||||||
255, 25, 48, 179, 72, 165, 181, 209, 215, 94, 146, 42, 172, 86, 170, 198,
|
|
||||||
79, 184, 56, 210, 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241,
|
|
||||||
69, 157, 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2,
|
|
||||||
27, 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
|
|
||||||
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, 234, 38,
|
|
||||||
44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, 129, 77, 82,
|
|
||||||
106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, 8, 12, 189, 177, 74,
|
|
||||||
120, 136, 149, 139, 227, 99, 232, 109, 233, 203, 213, 254, 59, 0, 29, 57,
|
|
||||||
242, 239, 183, 14, 102, 88, 208, 228, 166, 119, 114, 248, 235, 117, 75, 10,
|
|
||||||
49, 68, 80, 180, 143, 237, 31, 26, 219, 153, 141, 51, 159, 17, 131, 20,
|
|
||||||
} };
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
MD2::MD2 ()
|
|
||||||
{
|
|
||||||
reset ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
MD2::reset (void)
|
|
||||||
{
|
|
||||||
m_total = 0;
|
|
||||||
fill (begin (C), end (C), 0);
|
|
||||||
fill (begin (X), end (X), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
MD2::update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept
|
|
||||||
{
|
|
||||||
CHECK_LE (first, last);
|
|
||||||
|
|
||||||
update (first, last - first);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
static const size_t M_OFFSET = 16;
|
|
||||||
static const size_t M_LENGTH = 16;
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
MD2::update (const void *restrict _data, size_t size) noexcept
|
|
||||||
{
|
|
||||||
auto data = static_cast<const uint8_t *restrict> (_data);
|
|
||||||
|
|
||||||
uint8_t *M = X + M_OFFSET;
|
|
||||||
size_t offset = m_total % M_LENGTH;
|
|
||||||
size_t remain = M_LENGTH - offset;
|
|
||||||
|
|
||||||
if (size > remain) {
|
|
||||||
memcpy (M + offset, data, remain);
|
|
||||||
transform ();
|
|
||||||
|
|
||||||
m_total += remain;
|
|
||||||
size -= remain;
|
|
||||||
data += remain;
|
|
||||||
|
|
||||||
while (size >= M_LENGTH) {
|
|
||||||
memcpy (M, data, M_LENGTH);
|
|
||||||
transform ();
|
|
||||||
|
|
||||||
m_total += M_LENGTH;
|
|
||||||
size -= M_LENGTH;
|
|
||||||
data += M_LENGTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (M + offset, data, size);
|
|
||||||
m_total += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
MD2::digest_t
|
|
||||||
MD2::digest (void) const
|
|
||||||
{
|
|
||||||
digest_t d;
|
|
||||||
memcpy (d.data (), X, sizeof (d));
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
MD2::transform (void)
|
|
||||||
{
|
|
||||||
uint8_t *M = X + M_OFFSET;
|
|
||||||
|
|
||||||
// Update the checksum.
|
|
||||||
// XXX: I can't see why we need the xor-assign from the spec, but it's the
|
|
||||||
// only change keeping us from conforming to the test-cases. Pulled from a
|
|
||||||
// review of the reference implementation.
|
|
||||||
uint8_t L = C[15];
|
|
||||||
for (size_t i = 0; i < std::size (C); ++i)
|
|
||||||
L = C[i] ^= S[M[i] ^ L];
|
|
||||||
|
|
||||||
uint8_t t = 0;
|
|
||||||
|
|
||||||
// Setup the blocks
|
|
||||||
for (size_t i = 0; i < 16; ++i)
|
|
||||||
X[32 + i] = X[16 + i] ^ X[i];
|
|
||||||
|
|
||||||
// Perform the processing rounds
|
|
||||||
for (size_t i = 0; i < 18; ++i) {
|
|
||||||
for (size_t j = 0; j < 48; ++j)
|
|
||||||
t = X[j] = X[j] ^ S[t];
|
|
||||||
|
|
||||||
t = (t + i) % 256;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
MD2::finish (void)
|
|
||||||
{
|
|
||||||
uint8_t *M = X + M_OFFSET;
|
|
||||||
|
|
||||||
// Append the padding bytes
|
|
||||||
size_t offset = m_total % M_LENGTH;
|
|
||||||
size_t remain = M_LENGTH - offset;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < remain; ++i)
|
|
||||||
M[offset + i] = remain;
|
|
||||||
transform ();
|
|
||||||
|
|
||||||
// Append the checksum
|
|
||||||
memcpy (M, C, sizeof (C));
|
|
||||||
transform ();
|
|
||||||
}
|
|
||||||
|
|
50
hash/md2.hpp
50
hash/md2.hpp
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2013 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTIL_HASH_MD2_HPP
|
|
||||||
#define __UTIL_HASH_MD2_HPP
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace util::hash {
|
|
||||||
class MD2 {
|
|
||||||
public:
|
|
||||||
typedef std::array<uint8_t,16> digest_t;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MD2 ();
|
|
||||||
|
|
||||||
void update (const void *restrict data, size_t len) noexcept;
|
|
||||||
void update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept;
|
|
||||||
|
|
||||||
void finish (void);
|
|
||||||
digest_t digest (void) const;
|
|
||||||
void reset (void);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void transform (void);
|
|
||||||
|
|
||||||
uint64_t m_total;
|
|
||||||
|
|
||||||
uint8_t C[16];
|
|
||||||
uint8_t X[48];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
269
hash/md4.cpp
269
hash/md4.cpp
@ -1,269 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2013 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "md4.hpp"
|
|
||||||
|
|
||||||
#include "../bitwise.hpp"
|
|
||||||
#include "../debug.hpp"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
|
|
||||||
using util::hash::MD4;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Auxiliary functions for each set of rounds
|
|
||||||
static constexpr
|
|
||||||
uint32_t
|
|
||||||
F (uint32_t X, uint32_t Y, uint32_t Z)
|
|
||||||
{
|
|
||||||
return (X & Y) | (~X & Z);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
static constexpr
|
|
||||||
uint32_t
|
|
||||||
G (uint32_t X, uint32_t Y, uint32_t Z)
|
|
||||||
{
|
|
||||||
return (X & Y) | (X & Z) | (Y & Z);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
static constexpr
|
|
||||||
uint32_t
|
|
||||||
H (uint32_t X, uint32_t Y, uint32_t Z)
|
|
||||||
{
|
|
||||||
return X ^ Y ^ Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
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 ();
|
|
||||||
static_assert (sizeof (MD4::X) == sizeof (MD4::Xb),
|
|
||||||
"Byte and word buffer size must match exactly");
|
|
||||||
static_assert (sizeof (MD4::ABCD) == sizeof (MD4::digest_t),
|
|
||||||
"Internal state must match the size of the digest");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
MD4::reset (void)
|
|
||||||
{
|
|
||||||
m_total = 0;
|
|
||||||
|
|
||||||
ABCD[0] = DEFAULT_A;
|
|
||||||
ABCD[1] = DEFAULT_B;
|
|
||||||
ABCD[2] = DEFAULT_C;
|
|
||||||
ABCD[3] = DEFAULT_D;
|
|
||||||
|
|
||||||
memset (Xb, 0, sizeof (Xb));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
MD4::update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept
|
|
||||||
{
|
|
||||||
CHECK_LE (first, last);
|
|
||||||
|
|
||||||
update (first, last - first);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
MD4::update (const void *restrict _data, size_t size) noexcept
|
|
||||||
{
|
|
||||||
CHECK (_data);
|
|
||||||
auto data = static_cast<const uint8_t *restrict> (_data);
|
|
||||||
|
|
||||||
size_t offset = m_total % sizeof (Xb);
|
|
||||||
size_t remain = sizeof (Xb) - offset;
|
|
||||||
|
|
||||||
if (size > remain) {
|
|
||||||
memcpy (Xb + offset, data, remain);
|
|
||||||
transform ();
|
|
||||||
|
|
||||||
m_total += remain;
|
|
||||||
size -= remain;
|
|
||||||
data += remain;
|
|
||||||
|
|
||||||
while (size >= sizeof (Xb)) {
|
|
||||||
memcpy (Xb, data, sizeof (Xb));
|
|
||||||
transform ();
|
|
||||||
|
|
||||||
m_total += sizeof (Xb);
|
|
||||||
size -= sizeof (Xb);
|
|
||||||
data += sizeof (Xb);
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (Xb + offset, data, size);
|
|
||||||
m_total += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
MD4::digest_t
|
|
||||||
MD4::digest (void) const
|
|
||||||
{
|
|
||||||
digest_t d;
|
|
||||||
memcpy (d.data (), ABCD.data(), sizeof (ABCD));
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
MD4::transform (void)
|
|
||||||
{
|
|
||||||
uint32_t A = ABCD[0],
|
|
||||||
B = ABCD[1],
|
|
||||||
C = ABCD[2],
|
|
||||||
D = ABCD[3];
|
|
||||||
|
|
||||||
#define ROUND1(a,b,c,d,k,s) do { \
|
|
||||||
(a) += F((b), (c), (d)) + X[k]; \
|
|
||||||
(a) = rotatel ((a), (s)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
ROUND1(A,B,C,D, 0, 3);
|
|
||||||
ROUND1(D,A,B,C, 1, 7);
|
|
||||||
ROUND1(C,D,A,B, 2, 11);
|
|
||||||
ROUND1(B,C,D,A, 3, 19);
|
|
||||||
|
|
||||||
ROUND1(A,B,C,D, 4, 3);
|
|
||||||
ROUND1(D,A,B,C, 5, 7);
|
|
||||||
ROUND1(C,D,A,B, 6, 11);
|
|
||||||
ROUND1(B,C,D,A, 7, 19);
|
|
||||||
|
|
||||||
ROUND1(A,B,C,D, 8, 3);
|
|
||||||
ROUND1(D,A,B,C, 9, 7);
|
|
||||||
ROUND1(C,D,A,B, 10, 11);
|
|
||||||
ROUND1(B,C,D,A, 11, 19);
|
|
||||||
|
|
||||||
ROUND1(A,B,C,D, 12, 3);
|
|
||||||
ROUND1(D,A,B,C, 13, 7);
|
|
||||||
ROUND1(C,D,A,B, 14, 11);
|
|
||||||
ROUND1(B,C,D,A, 15, 19);
|
|
||||||
|
|
||||||
#define ROUND2(a,b,c,d,k,s) do { \
|
|
||||||
(a) += G((b),(c),(d)) + X[k] + 0x5A827999u; \
|
|
||||||
(a) = rotatel ((a), (s)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
ROUND2(A,B,C,D, 0, 3);
|
|
||||||
ROUND2(D,A,B,C, 4, 5);
|
|
||||||
ROUND2(C,D,A,B, 8, 9);
|
|
||||||
ROUND2(B,C,D,A, 12, 13);
|
|
||||||
|
|
||||||
ROUND2(A,B,C,D, 1, 3);
|
|
||||||
ROUND2(D,A,B,C, 5, 5);
|
|
||||||
ROUND2(C,D,A,B, 9, 9);
|
|
||||||
ROUND2(B,C,D,A, 13, 13);
|
|
||||||
|
|
||||||
ROUND2(A,B,C,D, 2, 3);
|
|
||||||
ROUND2(D,A,B,C, 6, 5);
|
|
||||||
ROUND2(C,D,A,B, 10, 9);
|
|
||||||
ROUND2(B,C,D,A, 14, 13);
|
|
||||||
|
|
||||||
ROUND2(A,B,C,D, 3, 3);
|
|
||||||
ROUND2(D,A,B,C, 7, 5);
|
|
||||||
ROUND2(C,D,A,B, 11, 9);
|
|
||||||
ROUND2(B,C,D,A, 15, 13);
|
|
||||||
|
|
||||||
#define ROUND3(a,b,c,d,k,s) do { \
|
|
||||||
(a) += H((b),(c),(d)) + X[k] + 0x6ED9EBA1u; \
|
|
||||||
(a) = rotatel ((a), (s)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
ROUND3(A,B,C,D, 0, 3);
|
|
||||||
ROUND3(D,A,B,C, 8, 9);
|
|
||||||
ROUND3(C,D,A,B, 4, 11);
|
|
||||||
ROUND3(B,C,D,A, 12, 15);
|
|
||||||
|
|
||||||
ROUND3(A,B,C,D, 2, 3);
|
|
||||||
ROUND3(D,A,B,C, 10, 9);
|
|
||||||
ROUND3(C,D,A,B, 6, 11);
|
|
||||||
ROUND3(B,C,D,A, 14, 15);
|
|
||||||
|
|
||||||
ROUND3(A,B,C,D, 1, 3);
|
|
||||||
ROUND3(D,A,B,C, 9, 9);
|
|
||||||
ROUND3(C,D,A,B, 5, 11);
|
|
||||||
ROUND3(B,C,D,A, 13, 15);
|
|
||||||
|
|
||||||
ROUND3(A,B,C,D, 3, 3);
|
|
||||||
ROUND3(D,A,B,C, 11, 9);
|
|
||||||
ROUND3(C,D,A,B, 7, 11);
|
|
||||||
ROUND3(B,C,D,A, 15, 15);
|
|
||||||
|
|
||||||
ABCD[0] += A;
|
|
||||||
ABCD[1] += B;
|
|
||||||
ABCD[2] += C;
|
|
||||||
ABCD[3] += D;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
MD4::finish (void)
|
|
||||||
{
|
|
||||||
uint64_t bits = m_total * 8;
|
|
||||||
|
|
||||||
{
|
|
||||||
// Pad with the mandatory 1 bit
|
|
||||||
size_t offset = m_total % sizeof (Xb);
|
|
||||||
Xb[offset] = 0x80;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// Pad the remainder with 0's, until 56 bytes
|
|
||||||
size_t offset = (m_total + 1) % sizeof (Xb);
|
|
||||||
size_t remain = (56 - offset % sizeof (Xb)) % sizeof (Xb);
|
|
||||||
|
|
||||||
if (offset > 56) {
|
|
||||||
memset (Xb + offset, 0, sizeof (Xb) - offset);
|
|
||||||
transform ();
|
|
||||||
remain -= sizeof (Xb) - offset;
|
|
||||||
offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset (Xb + offset, 0, remain);
|
|
||||||
|
|
||||||
// Put in the length (in bits) least significant first
|
|
||||||
for (size_t i = 0; i < sizeof (bits); ++i) {
|
|
||||||
Xb[56 + i] = bits & 0xFF;
|
|
||||||
bits >>= 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
transform ();
|
|
||||||
}
|
|
||||||
}
|
|
53
hash/md4.hpp
53
hash/md4.hpp
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2013 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTIL_HASH_MD4_HPP
|
|
||||||
#define __UTIL_HASH_MD4_HPP
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace util::hash {
|
|
||||||
class MD4 {
|
|
||||||
public:
|
|
||||||
typedef std::array<uint8_t,16> digest_t;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MD4();
|
|
||||||
|
|
||||||
void update (const void *restrict data, size_t len) noexcept;
|
|
||||||
void update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept;
|
|
||||||
|
|
||||||
void finish (void);
|
|
||||||
digest_t digest (void) const;
|
|
||||||
void reset (void);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void transform (void);
|
|
||||||
|
|
||||||
uint64_t m_total;
|
|
||||||
|
|
||||||
std::array<uint32_t,4> ABCD;
|
|
||||||
union {
|
|
||||||
uint32_t X [16];
|
|
||||||
uint8_t Xb[64];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
322
hash/md5.cpp
322
hash/md5.cpp
@ -1,322 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2013 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "md5.hpp"
|
|
||||||
|
|
||||||
#include "../bitwise.hpp"
|
|
||||||
#include "../debug.hpp"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
|
|
||||||
using util::hash::MD5;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Per-round mixing functions
|
|
||||||
static constexpr
|
|
||||||
uint32_t
|
|
||||||
F (uint32_t x, uint32_t y, uint32_t z)
|
|
||||||
{
|
|
||||||
return z ^ (x & (y ^ z));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
static constexpr
|
|
||||||
uint32_t
|
|
||||||
G (uint32_t x, uint32_t y, uint32_t z)
|
|
||||||
{
|
|
||||||
return F (z, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
static constexpr
|
|
||||||
uint32_t
|
|
||||||
H (uint32_t x, uint32_t y, uint32_t z)
|
|
||||||
{
|
|
||||||
return x ^ y ^ z;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
static constexpr
|
|
||||||
uint32_t
|
|
||||||
I (uint32_t x, uint32_t y, uint32_t 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 = { {
|
|
||||||
0x00000000,
|
|
||||||
|
|
||||||
// Round 1
|
|
||||||
0xd76aa478u, 0xe8c7b756u, 0x242070dbu, 0xc1bdceeeu,
|
|
||||||
0xf57c0fafu, 0x4787c62au, 0xa8304613u, 0xfd469501u,
|
|
||||||
0x698098d8u, 0x8b44f7afu, 0xffff5bb1u, 0x895cd7beu,
|
|
||||||
0x6b901122u, 0xfd987193u, 0xa679438eu, 0x49b40821u,
|
|
||||||
|
|
||||||
// Round 2
|
|
||||||
0xf61e2562u, 0xc040b340u, 0x265e5a51u, 0xe9b6c7aau,
|
|
||||||
0xd62f105du, 0x02441453u, 0xd8a1e681u, 0xe7d3fbc8u,
|
|
||||||
0x21e1cde6u, 0xc33707d6u, 0xf4d50d87u, 0x455a14edu,
|
|
||||||
0xa9e3e905u, 0xfcefa3f8u, 0x676f02d9u, 0x8d2a4c8au,
|
|
||||||
|
|
||||||
// Round 3
|
|
||||||
0xfffa3942u, 0x8771f681u, 0x6d9d6122u, 0xfde5380cu,
|
|
||||||
0xa4beea44u, 0x4bdecfa9u, 0xf6bb4b60u, 0xbebfbc70u,
|
|
||||||
0x289b7ec6u, 0xeaa127fau, 0xd4ef3085u, 0x04881d05u,
|
|
||||||
0xd9d4d039u, 0xe6db99e5u, 0x1fa27cf8u, 0xc4ac5665u,
|
|
||||||
|
|
||||||
// Round 4
|
|
||||||
0xf4292244u, 0x432aff97u, 0xab9423a7u, 0xfc93a039u,
|
|
||||||
0x655b59c3u, 0x8f0ccc92u, 0xffeff47du, 0x85845dd1u,
|
|
||||||
0x6fa87e4fu, 0xfe2ce6e0u, 0xa3014314u, 0x4e0811a1u,
|
|
||||||
0xf7537e82u, 0xbd3af235u, 0x2ad7d2bbu, 0xeb86d391u
|
|
||||||
} };
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
m_total = 0;
|
|
||||||
|
|
||||||
ABCD[0] = DEFAULT_A;
|
|
||||||
ABCD[1] = DEFAULT_B;
|
|
||||||
ABCD[2] = DEFAULT_C;
|
|
||||||
ABCD[3] = DEFAULT_D;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
MD5::update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept
|
|
||||||
{
|
|
||||||
CHECK_LE (first, last);
|
|
||||||
|
|
||||||
update (first, last - first);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
MD5::update (const void *restrict _data, size_t size) noexcept
|
|
||||||
{
|
|
||||||
CHECK (_data);
|
|
||||||
auto data = static_cast<const uint8_t *restrict> (_data);
|
|
||||||
|
|
||||||
size_t offset = m_total % sizeof (Xb);
|
|
||||||
size_t remain = sizeof (Xb) - offset;
|
|
||||||
|
|
||||||
if (size >= remain) {
|
|
||||||
memcpy (Xb + offset, data, remain);
|
|
||||||
transform ();
|
|
||||||
|
|
||||||
m_total += remain;
|
|
||||||
size -= remain;
|
|
||||||
data += remain;
|
|
||||||
|
|
||||||
while (size >= sizeof (Xb)) {
|
|
||||||
memcpy (Xb, data, sizeof (Xb));
|
|
||||||
transform ();
|
|
||||||
|
|
||||||
m_total += sizeof (Xb);
|
|
||||||
size -= sizeof (Xb);
|
|
||||||
data += sizeof (Xb);
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (Xb + offset, data, size);
|
|
||||||
m_total += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
MD5::digest_t
|
|
||||||
MD5::digest (void) const
|
|
||||||
{
|
|
||||||
static_assert (sizeof (ABCD) == sizeof (digest_t),
|
|
||||||
"Hash state must be the same size as the final digest");
|
|
||||||
|
|
||||||
digest_t d;
|
|
||||||
memcpy (d.data (), ABCD.data (), sizeof (ABCD));
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
MD5::finish (void)
|
|
||||||
{
|
|
||||||
uint64_t bits = m_total * 8;
|
|
||||||
|
|
||||||
{
|
|
||||||
// Pad with the mandatory 1 bit
|
|
||||||
size_t offset = m_total % sizeof (Xb);
|
|
||||||
Xb[offset] = 0x80;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// Pad the remainder with 0's, until 56 bytes
|
|
||||||
size_t offset = (m_total + 1) % sizeof (Xb);
|
|
||||||
size_t remain = (56 - offset % sizeof (Xb)) % sizeof (Xb);
|
|
||||||
|
|
||||||
if (offset > 56) {
|
|
||||||
memset (Xb + offset, 0, sizeof (Xb) - offset);
|
|
||||||
transform ();
|
|
||||||
remain -= sizeof (Xb) - offset;
|
|
||||||
offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset (Xb + offset, 0, remain);
|
|
||||||
|
|
||||||
// Put in the length (in bits) least significant first
|
|
||||||
for (size_t i = 0; i < sizeof (bits); ++i) {
|
|
||||||
Xb[56 + i] = bits & 0xFF;
|
|
||||||
bits >>= 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
transform ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
MD5::transform (void)
|
|
||||||
{
|
|
||||||
uint32_t A = ABCD[0],
|
|
||||||
B = ABCD[1],
|
|
||||||
C = ABCD[2],
|
|
||||||
D = ABCD[3];
|
|
||||||
|
|
||||||
#define ROUNDx(a,b,c,d,k,s,i,f) do { \
|
|
||||||
(a) += (f)((b), (c), (d)) + X[k] + T[i]; \
|
|
||||||
(a) = rotatel ((a), (s)); \
|
|
||||||
(a) += (b); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
// Round 1
|
|
||||||
ROUNDx(A,B,C,D, 0, 7, 1, F);
|
|
||||||
ROUNDx(D,A,B,C, 1, 12, 2, F);
|
|
||||||
ROUNDx(C,D,A,B, 2, 17, 3, F);
|
|
||||||
ROUNDx(B,C,D,A, 3, 22, 4, F);
|
|
||||||
|
|
||||||
ROUNDx(A,B,C,D, 4, 7, 5, F);
|
|
||||||
ROUNDx(D,A,B,C, 5, 12, 6, F);
|
|
||||||
ROUNDx(C,D,A,B, 6, 17, 7, F);
|
|
||||||
ROUNDx(B,C,D,A, 7, 22, 8, F);
|
|
||||||
|
|
||||||
ROUNDx(A,B,C,D, 8, 7, 9, F);
|
|
||||||
ROUNDx(D,A,B,C, 9, 12, 10, F);
|
|
||||||
ROUNDx(C,D,A,B, 10, 17, 11, F);
|
|
||||||
ROUNDx(B,C,D,A, 11, 22, 12, F);
|
|
||||||
|
|
||||||
ROUNDx(A,B,C,D, 12, 7, 13, F);
|
|
||||||
ROUNDx(D,A,B,C, 13, 12, 14, F);
|
|
||||||
ROUNDx(C,D,A,B, 14, 17, 15, F);
|
|
||||||
ROUNDx(B,C,D,A, 15, 22, 16, F);
|
|
||||||
|
|
||||||
// Round 2
|
|
||||||
ROUNDx(A,B,C,D, 1, 5, 17, G);
|
|
||||||
ROUNDx(D,A,B,C, 6, 9, 18, G);
|
|
||||||
ROUNDx(C,D,A,B, 11, 14, 19, G);
|
|
||||||
ROUNDx(B,C,D,A, 0, 20, 20, G);
|
|
||||||
|
|
||||||
ROUNDx(A,B,C,D, 5, 5, 21, G);
|
|
||||||
ROUNDx(D,A,B,C, 10, 9, 22, G);
|
|
||||||
ROUNDx(C,D,A,B, 15, 14, 23, G);
|
|
||||||
ROUNDx(B,C,D,A, 4, 20, 24, G);
|
|
||||||
|
|
||||||
ROUNDx(A,B,C,D, 9, 5, 25, G);
|
|
||||||
ROUNDx(D,A,B,C, 14, 9, 26, G);
|
|
||||||
ROUNDx(C,D,A,B, 3, 14, 27, G);
|
|
||||||
ROUNDx(B,C,D,A, 8, 20, 28, G);
|
|
||||||
|
|
||||||
ROUNDx(A,B,C,D, 13, 5, 29, G);
|
|
||||||
ROUNDx(D,A,B,C, 2, 9, 30, G);
|
|
||||||
ROUNDx(C,D,A,B, 7, 14, 31, G);
|
|
||||||
ROUNDx(B,C,D,A, 12, 20, 32, G);
|
|
||||||
|
|
||||||
// Round 3
|
|
||||||
ROUNDx(A,B,C,D, 5, 4, 33, H);
|
|
||||||
ROUNDx(D,A,B,C, 8, 11, 34, H);
|
|
||||||
ROUNDx(C,D,A,B, 11, 16, 35, H);
|
|
||||||
ROUNDx(B,C,D,A, 14, 23, 36, H);
|
|
||||||
|
|
||||||
ROUNDx(A,B,C,D, 1, 4, 37, H);
|
|
||||||
ROUNDx(D,A,B,C, 4, 11, 38, H);
|
|
||||||
ROUNDx(C,D,A,B, 7, 16, 39, H);
|
|
||||||
ROUNDx(B,C,D,A, 10, 23, 40, H);
|
|
||||||
|
|
||||||
ROUNDx(A,B,C,D, 13, 4, 41, H);
|
|
||||||
ROUNDx(D,A,B,C, 0, 11, 42, H);
|
|
||||||
ROUNDx(C,D,A,B, 3, 16, 43, H);
|
|
||||||
ROUNDx(B,C,D,A, 6, 23, 44, H);
|
|
||||||
|
|
||||||
ROUNDx(A,B,C,D, 9, 4, 45, H);
|
|
||||||
ROUNDx(D,A,B,C, 12, 11, 46, H);
|
|
||||||
ROUNDx(C,D,A,B, 15, 16, 47, H);
|
|
||||||
ROUNDx(B,C,D,A, 2, 23, 48, H);
|
|
||||||
|
|
||||||
// Round 4
|
|
||||||
ROUNDx(A,B,C,D, 0, 6, 49, I);
|
|
||||||
ROUNDx(D,A,B,C, 7, 10, 50, I);
|
|
||||||
ROUNDx(C,D,A,B, 14, 15, 51, I);
|
|
||||||
ROUNDx(B,C,D,A, 5, 21, 52, I);
|
|
||||||
|
|
||||||
ROUNDx(A,B,C,D, 12, 6, 53, I);
|
|
||||||
ROUNDx(D,A,B,C, 3, 10, 54, I);
|
|
||||||
ROUNDx(C,D,A,B, 10, 15, 55, I);
|
|
||||||
ROUNDx(B,C,D,A, 1, 21, 56, I);
|
|
||||||
|
|
||||||
ROUNDx(A,B,C,D, 8, 6, 57, I);
|
|
||||||
ROUNDx(D,A,B,C, 15, 10, 58, I);
|
|
||||||
ROUNDx(C,D,A,B, 6, 15, 59, I);
|
|
||||||
ROUNDx(B,C,D,A, 13, 21, 60, I);
|
|
||||||
|
|
||||||
ROUNDx(A,B,C,D, 4, 6, 61, I);
|
|
||||||
ROUNDx(D,A,B,C, 11, 10, 62, I);
|
|
||||||
ROUNDx(C,D,A,B, 2, 15, 63, I);
|
|
||||||
ROUNDx(B,C,D,A, 9, 21, 64, I);
|
|
||||||
|
|
||||||
ABCD[0] += A;
|
|
||||||
ABCD[1] += B;
|
|
||||||
ABCD[2] += C;
|
|
||||||
ABCD[3] += D;
|
|
||||||
}
|
|
56
hash/md5.hpp
56
hash/md5.hpp
@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2013 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTIL_HASH_MD5_HPP
|
|
||||||
#define __UTIL_HASH_MD5_HPP
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace util::hash {
|
|
||||||
class MD5 {
|
|
||||||
public:
|
|
||||||
typedef std::array<uint8_t,16> digest_t;
|
|
||||||
static const size_t BLOCK_SIZE = 64;
|
|
||||||
static const size_t DIGEST_SIZE = 16;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MD5();
|
|
||||||
|
|
||||||
void update (const void *restrict data, size_t len) noexcept;
|
|
||||||
void update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept;
|
|
||||||
|
|
||||||
void finish (void);
|
|
||||||
digest_t digest (void) const;
|
|
||||||
void reset (void);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void transform (void);
|
|
||||||
|
|
||||||
uint64_t m_total;
|
|
||||||
std::array<uint32_t, 4> ABCD;
|
|
||||||
|
|
||||||
union {
|
|
||||||
uint32_t X [16];
|
|
||||||
uint8_t Xb[64];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -19,40 +19,25 @@
|
|||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include "../../debug.hpp"
|
#include "../../debug.hpp"
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
using util::hash::murmur1;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
uint32_t
|
uint32_t
|
||||||
util::hash::murmur1::mix (uint32_t h, uint32_t k)
|
murmur1::operator() (util::view<const uint8_t*> data) const noexcept
|
||||||
{
|
{
|
||||||
static const uint32_t m = 0xc6a4a793;
|
static const uint32_t m = 0xc6a4a793;
|
||||||
|
uint32_t h = m_seed ^ ((data.size () & 0xffffffff) * m);
|
||||||
h += k;
|
|
||||||
h *= m;
|
|
||||||
h ^= h >> 16;
|
|
||||||
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
uint32_t
|
|
||||||
util::hash::murmur1::hash_32 (const void *restrict data,
|
|
||||||
size_t len,
|
|
||||||
uint32_t seed)
|
|
||||||
{
|
|
||||||
CHECK (data);
|
|
||||||
|
|
||||||
static const uint32_t m = 0xc6a4a793;
|
|
||||||
uint32_t h = seed ^ ((len & 0xffffffff) * m);
|
|
||||||
|
|
||||||
// mix the body
|
// mix the body
|
||||||
auto cursor = reinterpret_cast<const uint32_t*> (data);
|
auto cursor = reinterpret_cast<const uint32_t*> (data.data ());
|
||||||
auto last = cursor + len / sizeof (uint32_t);
|
auto last = cursor + data.size () / sizeof (uint32_t);
|
||||||
for (; cursor < last; ++cursor)
|
for (; cursor < last; ++cursor)
|
||||||
h = mix (h, *cursor);
|
h = mix (h, *cursor);
|
||||||
|
|
||||||
// mix the tail
|
// mix the tail
|
||||||
if (len % sizeof (uint32_t))
|
if (data.size () % sizeof (uint32_t))
|
||||||
h = mix (h, murmur::tail<uint32_t> (reinterpret_cast<const uint8_t*> (cursor), len));
|
h = mix (h, murmur::tail<uint32_t> (reinterpret_cast<const uint8_t*> (cursor), data.size ()));
|
||||||
|
|
||||||
// finalise
|
// finalise
|
||||||
h *= m; h ^= h >> 10;
|
h *= m; h ^= h >> 10;
|
||||||
|
@ -17,13 +17,38 @@
|
|||||||
#ifndef __UTIL_HASH_MURMUR_MURMUR1_HPP
|
#ifndef __UTIL_HASH_MURMUR_MURMUR1_HPP
|
||||||
#define __UTIL_HASH_MURMUR_MURMUR1_HPP
|
#define __UTIL_HASH_MURMUR_MURMUR1_HPP
|
||||||
|
|
||||||
|
#include "../../view.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
// Austin Appleby's MumurHash1
|
// Austin Appleby's MumurHash1
|
||||||
namespace util::hash::murmur1 {
|
namespace util::hash {
|
||||||
uint32_t mix (uint32_t, uint32_t);
|
class murmur1 {
|
||||||
uint32_t hash_32 (const void *restrict data, size_t len, uint32_t seed);
|
public:
|
||||||
|
using digest_t = uint32_t;
|
||||||
|
using seed_t = uint32_t;
|
||||||
|
|
||||||
|
murmur1 (seed_t _seed):
|
||||||
|
m_seed (_seed)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
static constexpr uint32_t mix (uint32_t h, uint32_t k)
|
||||||
|
{
|
||||||
|
constexpr uint32_t m = 0xc6a4a793;
|
||||||
|
|
||||||
|
h += k;
|
||||||
|
h *= m;
|
||||||
|
h ^= h >> 16;
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
digest_t operator() (util::view<const uint8_t*> data) const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
seed_t m_seed;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,28 +20,28 @@
|
|||||||
#include "../../debug.hpp"
|
#include "../../debug.hpp"
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
|
using util::hash::murmur2;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
uint32_t
|
static uint32_t
|
||||||
util::hash::murmur2::hash_32 (const void *restrict key,
|
hash_32 (const void *restrict key,
|
||||||
size_t len,
|
size_t len,
|
||||||
uint32_t seed)
|
uint32_t seed)
|
||||||
{
|
{
|
||||||
CHECK (key);
|
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
constexpr auto m = detail::constants<uint32_t>::m;
|
constexpr auto m = util::hash::detail::murmur2::constants<uint32_t>::m;
|
||||||
uint32_t h = seed ^ (len & 0xffffffff);
|
uint32_t h = seed ^ (len & 0xffffffff);
|
||||||
|
|
||||||
// body
|
// body
|
||||||
auto cursor = reinterpret_cast<const uint32_t*> (key);
|
auto cursor = reinterpret_cast<const uint32_t*> (key);
|
||||||
auto last = cursor + len / sizeof (uint32_t);
|
auto last = cursor + len / sizeof (uint32_t);
|
||||||
for (; cursor < last; ++cursor)
|
for (; cursor < last; ++cursor)
|
||||||
h = mix (h, *cursor);
|
h = util::hash::murmur2<uint32_t>::mix (h, *cursor);
|
||||||
|
|
||||||
// tail
|
// tail
|
||||||
if (len % sizeof (uint32_t)) {
|
if (len % sizeof (uint32_t)) {
|
||||||
h ^= murmur::tail<uint32_t> (reinterpret_cast<const uint8_t*> (cursor), len);
|
h ^= util::hash::murmur::tail<uint32_t> (reinterpret_cast<const uint8_t*> (cursor), len);
|
||||||
h *= m;
|
h *= m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,14 +55,14 @@ util::hash::murmur2::hash_32 (const void *restrict key,
|
|||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
uint64_t
|
static uint64_t
|
||||||
util::hash::murmur2::hash_64 (const void *restrict key,
|
hash_64 (const void *restrict key,
|
||||||
size_t len,
|
size_t len,
|
||||||
uint64_t seed)
|
uint64_t seed)
|
||||||
{
|
{
|
||||||
// setup
|
// setup
|
||||||
constexpr auto m = detail::constants<uint64_t>::m;
|
constexpr auto m = util::hash::detail::murmur2::constants<uint64_t>::m;
|
||||||
constexpr auto r = detail::constants<uint64_t>::r;
|
constexpr auto r = util::hash::detail::murmur2::constants<uint64_t>::r;
|
||||||
|
|
||||||
uint64_t h = seed ^ (len * m);
|
uint64_t h = seed ^ (len * m);
|
||||||
|
|
||||||
@ -70,11 +70,11 @@ util::hash::murmur2::hash_64 (const void *restrict key,
|
|||||||
auto cursor = reinterpret_cast<const uint64_t*> (key);
|
auto cursor = reinterpret_cast<const uint64_t*> (key);
|
||||||
auto last = cursor + len / sizeof (uint64_t);
|
auto last = cursor + len / sizeof (uint64_t);
|
||||||
for (; cursor < last; ++cursor)
|
for (; cursor < last; ++cursor)
|
||||||
h = mix (h, *cursor);
|
h = util::hash::murmur2<uint64_t>::mix (h, *cursor);
|
||||||
|
|
||||||
// tail
|
// tail
|
||||||
if (len % sizeof (uint64_t)) {
|
if (len % sizeof (uint64_t)) {
|
||||||
h ^= murmur::tail<uint64_t> (reinterpret_cast<const uint8_t*> (cursor), len);
|
h ^= util::hash::murmur::tail<uint64_t> (reinterpret_cast<const uint8_t*> (cursor), len);
|
||||||
h *= m;
|
h *= m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,3 +87,23 @@ util::hash::murmur2::hash_64 (const void *restrict key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename DigestT>
|
||||||
|
typename murmur2<DigestT>::digest_t
|
||||||
|
murmur2<DigestT>::operator() (util::view<const uint8_t*> data) const noexcept
|
||||||
|
{
|
||||||
|
static_assert (std::is_same_v<DigestT,uint32_t> || std::is_same_v<DigestT,uint64_t>);
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<DigestT,uint32_t>)
|
||||||
|
return hash_32 (data.data (), data.size (), m_seed);
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<DigestT,uint64_t>)
|
||||||
|
return hash_64 (data.data (), data.size (), m_seed);
|
||||||
|
|
||||||
|
unreachable ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template class util::hash::murmur2<uint32_t>;
|
||||||
|
template class util::hash::murmur2<uint64_t>;
|
||||||
|
@ -17,21 +17,77 @@
|
|||||||
#ifndef __UTIL_HASH_MURMUR_MURMUR2_HPP
|
#ifndef __UTIL_HASH_MURMUR_MURMUR2_HPP
|
||||||
#define __UTIL_HASH_MURMUR_MURMUR2_HPP
|
#define __UTIL_HASH_MURMUR_MURMUR2_HPP
|
||||||
|
|
||||||
|
#include "../../view.hpp"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
// Austin Appleby's MumurHash2, and MurmurHash64A. The exhaustive list of
|
// Austin Appleby's MumurHash2, and MurmurHash64A. The exhaustive list of
|
||||||
// variants is deliberately not provided. You can damn well align your data or
|
// variants is deliberately not provided. You can damn well align your data or
|
||||||
// fix the algorithm.
|
// fix the algorithm.
|
||||||
namespace util::hash::murmur2 {
|
namespace util::hash {
|
||||||
constexpr uint32_t mix (uint32_t, uint32_t);
|
namespace detail::murmur2 {
|
||||||
constexpr uint64_t mix (uint64_t, uint64_t);
|
template <typename T> struct constants;
|
||||||
|
|
||||||
uint32_t hash_32 (const void *restrict data, size_t len, uint32_t seed);
|
template <>
|
||||||
uint64_t hash_64 (const void *restrict data, size_t len, uint64_t seed);
|
struct constants<uint32_t> {
|
||||||
|
static const uint32_t m = 0x5bd1e995;
|
||||||
|
static const int32_t r = 24;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct constants<uint64_t> {
|
||||||
|
static const uint64_t m = 0xc6a4a7935bd1e995;
|
||||||
|
static const int64_t r = 47;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename DigestT>
|
||||||
|
class murmur2 {
|
||||||
|
public:
|
||||||
|
using digest_t = DigestT;
|
||||||
|
using seed_t = DigestT;
|
||||||
|
|
||||||
|
murmur2 (seed_t _seed):
|
||||||
|
m_seed (_seed)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
static constexpr uint32_t mix (uint32_t h, uint32_t k)
|
||||||
|
{
|
||||||
|
constexpr uint32_t m = detail::murmur2::constants<uint32_t>::m;
|
||||||
|
constexpr uint32_t r = detail::murmur2::constants<uint32_t>::r;
|
||||||
|
|
||||||
|
k *= m;
|
||||||
|
k ^= k >> r;
|
||||||
|
k *= m;
|
||||||
|
|
||||||
|
h *= m;
|
||||||
|
h ^= k;
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint64_t mix (uint64_t h, uint64_t k)
|
||||||
|
{
|
||||||
|
constexpr uint64_t m = detail::murmur2::constants<uint64_t>::m;
|
||||||
|
constexpr uint64_t r = detail::murmur2::constants<uint64_t>::r;
|
||||||
|
|
||||||
|
k *= m;
|
||||||
|
k ^= k >> r;
|
||||||
|
k *= m;
|
||||||
|
|
||||||
|
h ^= k;
|
||||||
|
h *= m;
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
digest_t operator() (util::view<const uint8_t*> data) const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
seed_t m_seed;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "murmur2.ipp"
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2016 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__UTIL_HASH_MURMUR_MURMUR2_IPP)
|
|
||||||
#error
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define __UTIL_HASH_MURMUR_MURMUR2_IPP
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace util::hash::murmur2::detail {
|
|
||||||
template <typename T> struct constants;
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct constants<uint32_t> {
|
|
||||||
static const uint32_t m = 0x5bd1e995;
|
|
||||||
static const int32_t r = 24;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct constants<uint64_t> {
|
|
||||||
static const uint64_t m = 0xc6a4a7935bd1e995;
|
|
||||||
static const int64_t r = 47;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
|
||||||
constexpr uint32_t
|
|
||||||
util::hash::murmur2::mix (uint32_t h, uint32_t k)
|
|
||||||
{
|
|
||||||
constexpr uint32_t m = detail::constants<uint32_t>::m;
|
|
||||||
constexpr uint32_t r = detail::constants<uint32_t>::r;
|
|
||||||
|
|
||||||
k *= m;
|
|
||||||
k ^= k >> r;
|
|
||||||
k *= m;
|
|
||||||
|
|
||||||
h *= m;
|
|
||||||
h ^= k;
|
|
||||||
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// 64 bit murmur2 mixing function. Note the last two lines are swapped
|
|
||||||
// compared with 32 bit murmur2_mix. It's not clear if this is deliberate
|
|
||||||
// in the canonical implementation, so we just leave it to help compatibility.
|
|
||||||
constexpr uint64_t
|
|
||||||
util::hash::murmur2::mix (uint64_t h, uint64_t k)
|
|
||||||
{
|
|
||||||
constexpr uint64_t m = detail::constants<uint64_t>::m;
|
|
||||||
constexpr uint64_t r = detail::constants<uint64_t>::r;
|
|
||||||
|
|
||||||
k *= m;
|
|
||||||
k ^= k >> r;
|
|
||||||
k *= m;
|
|
||||||
|
|
||||||
h ^= k;
|
|
||||||
h *= m;
|
|
||||||
|
|
||||||
return h;
|
|
||||||
}
|
|
@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
using util::hash::murmur3;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
static
|
static
|
||||||
@ -36,8 +38,9 @@ read_u32 (const uint8_t *bytes)
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Finalization mix - force all bits of a hash block to avalanche
|
// Finalization mix - force all bits of a hash block to avalanche
|
||||||
|
template <size_t DigestBits, size_t ArchBits>
|
||||||
uint32_t
|
uint32_t
|
||||||
util::hash::murmur3::mix (uint32_t h)
|
murmur3<DigestBits,ArchBits>::mix (uint32_t h)
|
||||||
{
|
{
|
||||||
h ^= h >> 16;
|
h ^= h >> 16;
|
||||||
h *= 0x85ebca6b;
|
h *= 0x85ebca6b;
|
||||||
@ -50,8 +53,9 @@ util::hash::murmur3::mix (uint32_t h)
|
|||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
template <size_t DigestBits, size_t ArchBits>
|
||||||
uint64_t
|
uint64_t
|
||||||
util::hash::murmur3::mix (uint64_t k)
|
murmur3<DigestBits,ArchBits>::mix (uint64_t k)
|
||||||
{
|
{
|
||||||
k ^= k >> 33;
|
k ^= k >> 33;
|
||||||
k *= 0xff51afd7ed558ccd;
|
k *= 0xff51afd7ed558ccd;
|
||||||
@ -63,14 +67,17 @@ util::hash::murmur3::mix (uint64_t k)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <size_t DigestBits, size_t ArchBits>
|
||||||
|
struct hash { };
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
uint32_t
|
template <size_t ArchBits>
|
||||||
util::hash::murmur3::hash_32(const void *restrict key,
|
struct hash<32,ArchBits> {
|
||||||
size_t len,
|
static auto eval (util::view<const uint8_t*> data, uint32_t seed)
|
||||||
uint32_t seed)
|
{
|
||||||
{
|
auto nblocks = data.size () / sizeof (uint32_t);
|
||||||
auto data = reinterpret_cast<const uint8_t*> (key);
|
|
||||||
auto nblocks = len / sizeof (uint32_t);
|
|
||||||
|
|
||||||
uint32_t h1 = seed;
|
uint32_t h1 = seed;
|
||||||
|
|
||||||
@ -79,7 +86,7 @@ util::hash::murmur3::hash_32(const void *restrict key,
|
|||||||
|
|
||||||
//----------
|
//----------
|
||||||
// body
|
// body
|
||||||
auto cursor = data;
|
auto cursor = data.begin ();
|
||||||
auto last = cursor + nblocks * sizeof (uint32_t);
|
auto last = cursor + nblocks * sizeof (uint32_t);
|
||||||
for (; cursor < last; cursor += sizeof (uint32_t)) {
|
for (; cursor < last; cursor += sizeof (uint32_t)) {
|
||||||
uint32_t k1 = read_u32 (cursor);
|
uint32_t k1 = read_u32 (cursor);
|
||||||
@ -96,8 +103,8 @@ util::hash::murmur3::hash_32(const void *restrict key,
|
|||||||
|
|
||||||
//----------
|
//----------
|
||||||
// tail
|
// tail
|
||||||
if (len % sizeof (uint32_t)) {
|
if (data.size () % sizeof (uint32_t)) {
|
||||||
uint32_t k1 = 0 ^ murmur::tail<uint32_t> (cursor, len);
|
uint32_t k1 = 0 ^ util::hash::murmur::tail<uint32_t> (cursor, data.size ());
|
||||||
|
|
||||||
k1 *= c1;
|
k1 *= c1;
|
||||||
k1 = util::rotatel (k1, 15);
|
k1 = util::rotatel (k1, 15);
|
||||||
@ -108,11 +115,12 @@ util::hash::murmur3::hash_32(const void *restrict key,
|
|||||||
//----------
|
//----------
|
||||||
// finalization
|
// finalization
|
||||||
|
|
||||||
h1 ^= len;
|
h1 ^= data.size ();
|
||||||
h1 = mix (h1);
|
h1 = util::hash::murmur3<32,ArchBits>::mix (h1);
|
||||||
|
|
||||||
return h1;
|
return h1;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -237,7 +245,7 @@ hash_128 (const void *restrict key,
|
|||||||
for (size_t i = 1; i < traits<T>::COMPONENTS; ++i) h[i] += h[0];
|
for (size_t i = 1; i < traits<T>::COMPONENTS; ++i) h[i] += h[0];
|
||||||
|
|
||||||
for (auto &v: h)
|
for (auto &v: h)
|
||||||
v = util::hash::murmur3::mix (v);
|
v = util::hash::murmur3<128,sizeof(T)*8>::mix (v);
|
||||||
|
|
||||||
for (size_t i = 1; i < traits<T>::COMPONENTS; ++i) h[0] += h[i];
|
for (size_t i = 1; i < traits<T>::COMPONENTS; ++i) h[0] += h[i];
|
||||||
for (size_t i = 1; i < traits<T>::COMPONENTS; ++i) h[i] += h[0];
|
for (size_t i = 1; i < traits<T>::COMPONENTS; ++i) h[i] += h[0];
|
||||||
@ -246,21 +254,33 @@ hash_128 (const void *restrict key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
template <>
|
||||||
std::array<uint32_t,4>
|
struct hash<128,32> {
|
||||||
util::hash::murmur3::hash_128_x86 (const void *restrict key,
|
static auto eval (util::view<const uint8_t*> data, uint32_t seed)
|
||||||
const size_t len,
|
{
|
||||||
const uint32_t seed)
|
return ::hash_128<uint32_t> (data.data (), data.size (), seed);
|
||||||
{
|
}
|
||||||
return ::hash_128<uint32_t> (key, len, seed);
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct hash<128,64> {
|
||||||
|
static auto eval (util::view<const uint8_t*> data, uint32_t seed)
|
||||||
|
{
|
||||||
|
return ::hash_128<uint64_t> (data.data (), data.size (), seed);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
std::array<uint64_t,2>
|
template <size_t DigestBits, size_t ArchBits>
|
||||||
util::hash::murmur3::hash_128_x64 (const void *restrict key,
|
typename murmur3<DigestBits,ArchBits>::digest_t
|
||||||
size_t len,
|
murmur3<DigestBits,ArchBits>::operator() (util::view<const uint8_t*> data) const noexcept
|
||||||
const uint32_t seed)
|
|
||||||
{
|
{
|
||||||
return ::hash_128<uint64_t> (key, len, seed);
|
return ::hash<DigestBits,ArchBits>::eval (data, m_seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template class util::hash::murmur3<32, 32>;
|
||||||
|
template class util::hash::murmur3<128,32>;
|
||||||
|
template class util::hash::murmur3<128,64>;
|
||||||
|
@ -17,18 +17,47 @@
|
|||||||
#ifndef __UTIL_HASH_MURMUR_MURMUR3_HPP
|
#ifndef __UTIL_HASH_MURMUR_MURMUR3_HPP
|
||||||
#define __UTIL_HASH_MURMUR_MURMUR3_HPP
|
#define __UTIL_HASH_MURMUR_MURMUR3_HPP
|
||||||
|
|
||||||
|
#include "../../view.hpp"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
// Austin Appleby's MurmurHash3
|
// Austin Appleby's MurmurHash3
|
||||||
namespace util::hash::murmur3 {
|
namespace util::hash {
|
||||||
uint32_t mix (uint32_t);
|
namespace detail::murmur3 {
|
||||||
uint64_t mix (uint64_t);
|
template <size_t DigestBits, size_t ArchBits>
|
||||||
|
struct digest_type { };
|
||||||
|
|
||||||
uint32_t hash_32 (const void *restrict data, size_t len, uint32_t seed);
|
template <> struct digest_type< 32,32> { using type = uint32_t; };
|
||||||
std::array<uint32_t,4> hash_128_x86 (const void *restrict data, size_t len, uint32_t seed);
|
template <> struct digest_type<128,32> { using type = std::array<uint32_t,4>; };
|
||||||
std::array<uint64_t,2> hash_128_x64 (const void *restrict data, size_t len, uint32_t seed);
|
template <> struct digest_type<128,64> { using type = std::array<uint64_t,2>; };
|
||||||
|
};
|
||||||
|
|
||||||
|
template <size_t DigestBits, size_t ArchBits>
|
||||||
|
class murmur3 {
|
||||||
|
public:
|
||||||
|
murmur3 (uint32_t _seed):
|
||||||
|
m_seed (_seed)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
static_assert (DigestBits % 8 == 0);
|
||||||
|
|
||||||
|
using digest_t = typename detail::murmur3::digest_type<DigestBits,ArchBits>::type;
|
||||||
|
|
||||||
|
static uint32_t mix (uint32_t);
|
||||||
|
static uint64_t mix (uint64_t);
|
||||||
|
|
||||||
|
digest_t
|
||||||
|
operator() (util::view<const uint8_t*> data) const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_seed;
|
||||||
|
};
|
||||||
|
|
||||||
|
using murmur3_32 = murmur3< 32,32>;
|
||||||
|
using murmur3_128_x86 = murmur3<128,32>;
|
||||||
|
using murmur3_128_x64 = murmur3<128,64>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2013 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pbkdf1.hpp"
|
|
@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2013 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTIL_HASH_PBKDF1_HPP
|
|
||||||
#define __UTIL_HASH_PBKDF1_HPP
|
|
||||||
|
|
||||||
namespace util {
|
|
||||||
namespace hash {
|
|
||||||
class PBKDF1 {
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2013 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pbkdf2.hpp"
|
|
@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2013 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTIL_HASH_PBKDF2_HPP
|
|
||||||
#define __UTIL_HASH_PBKDF2_HPP
|
|
||||||
|
|
||||||
namespace util {
|
|
||||||
namespace hash {
|
|
||||||
class PBKDF2 {
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
417
hash/ripemd.cpp
417
hash/ripemd.cpp
@ -1,417 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright:
|
|
||||||
* 2014, Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ripemd.hpp"
|
|
||||||
|
|
||||||
#include "../debug.hpp"
|
|
||||||
#include "../bitwise.hpp"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
using util::hash::RIPEMD;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
RIPEMD::RIPEMD()
|
|
||||||
{
|
|
||||||
reset ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
RIPEMD::reset (void)
|
|
||||||
{
|
|
||||||
m_state[0] = 0x67452301u;
|
|
||||||
m_state[1] = 0xEFCDAB89u;
|
|
||||||
m_state[2] = 0x98BADCFEu;
|
|
||||||
m_state[3] = 0x10325476u;
|
|
||||||
m_state[4] = 0xC3D2E1F0u;
|
|
||||||
|
|
||||||
m_length = 0;
|
|
||||||
|
|
||||||
m_buffer.size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
RIPEMD::update (
|
|
||||||
const uint8_t *restrict first,
|
|
||||||
const uint8_t *restrict last) noexcept
|
|
||||||
{
|
|
||||||
CHECK_LE (first, last);
|
|
||||||
|
|
||||||
update (first, last - first);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
RIPEMD::update (const void *restrict _data, size_t len) noexcept
|
|
||||||
{
|
|
||||||
CHECK (_data);
|
|
||||||
|
|
||||||
auto data = static_cast<const uint8_t *restrict> (_data);
|
|
||||||
|
|
||||||
size_t cursor = 0;
|
|
||||||
|
|
||||||
while (cursor < len) {
|
|
||||||
size_t width = sizeof (m_buffer.d08) - m_buffer.size;
|
|
||||||
size_t chunk = min (width, len - cursor);
|
|
||||||
|
|
||||||
memcpy (m_buffer.d08 + m_buffer.size, data + cursor, chunk);
|
|
||||||
m_length += chunk;
|
|
||||||
m_buffer.size += chunk;
|
|
||||||
|
|
||||||
if (m_buffer.size == sizeof (m_buffer.d08))
|
|
||||||
transform ();
|
|
||||||
|
|
||||||
cursor += chunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_length >> sizeof (m_length) * 8 - 3 != 0)
|
|
||||||
panic ("exceeded maximum message length");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
static constexpr
|
|
||||||
uint32_t
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
static constexpr
|
|
||||||
uint32_t
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
static constexpr
|
|
||||||
uint32_t
|
|
||||||
f5 (uint32_t x, uint32_t y, uint32_t z)
|
|
||||||
{
|
|
||||||
return x ^ (y | ~z);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
RIPEMD::transform (void)
|
|
||||||
{
|
|
||||||
CHECK_EQ (m_buffer.size, sizeof (m_buffer.d32));
|
|
||||||
|
|
||||||
// Use: boolean function f
|
|
||||||
// state parameters a, b, c, d, e
|
|
||||||
// offset value o
|
|
||||||
// input data value x
|
|
||||||
// shift length s
|
|
||||||
|
|
||||||
#define ROUND(f,a,b,c,d,e,o,x,s) { \
|
|
||||||
a += f(b, c, d); \
|
|
||||||
a += m_buffer.d32[x] + o; \
|
|
||||||
a = rotatel (a, s); \
|
|
||||||
a += e; \
|
|
||||||
c = rotatel (c, 10); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define R1a(a,b,c,d,e,x,s) ROUND(f1,a,b,c,d,e,0x00000000u,x,s)
|
|
||||||
#define R2a(a,b,c,d,e,x,s) ROUND(f2,a,b,c,d,e,0x5A827999u,x,s)
|
|
||||||
#define R3a(a,b,c,d,e,x,s) ROUND(f3,a,b,c,d,e,0x6ED9EBA1u,x,s)
|
|
||||||
#define R4a(a,b,c,d,e,x,s) ROUND(f4,a,b,c,d,e,0x8F1BBCDCu,x,s)
|
|
||||||
#define R5a(a,b,c,d,e,x,s) ROUND(f5,a,b,c,d,e,0xA953FD4Eu,x,s)
|
|
||||||
|
|
||||||
#define R1b(a,b,c,d,e,x,s) ROUND(f5,a,b,c,d,e,0x50A28BE6u,x,s)
|
|
||||||
#define R2b(a,b,c,d,e,x,s) ROUND(f4,a,b,c,d,e,0x5C4DD124u,x,s)
|
|
||||||
#define R3b(a,b,c,d,e,x,s) ROUND(f3,a,b,c,d,e,0x6D703EF3u,x,s)
|
|
||||||
#define R4b(a,b,c,d,e,x,s) ROUND(f2,a,b,c,d,e,0x7A6D76E9u,x,s)
|
|
||||||
#define R5b(a,b,c,d,e,x,s) ROUND(f1,a,b,c,d,e,0x00000000u,x,s)
|
|
||||||
|
|
||||||
uint32_t a1, b1, c1, d1, e1;
|
|
||||||
uint32_t a2, b2, c2, d2, e2;
|
|
||||||
|
|
||||||
a1 = a2 = m_state[0];
|
|
||||||
b1 = b2 = m_state[1];
|
|
||||||
c1 = c2 = m_state[2];
|
|
||||||
d1 = d2 = m_state[3];
|
|
||||||
e1 = e2 = m_state[4];
|
|
||||||
|
|
||||||
// Left round 1
|
|
||||||
R1a(a1, b1, c1, d1, e1, 0, 11);
|
|
||||||
R1a(e1, a1, b1, c1, d1, 1, 14);
|
|
||||||
R1a(d1, e1, a1, b1, c1, 2, 15);
|
|
||||||
R1a(c1, d1, e1, a1, b1, 3, 12);
|
|
||||||
R1a(b1, c1, d1, e1, a1, 4, 5);
|
|
||||||
R1a(a1, b1, c1, d1, e1, 5, 8);
|
|
||||||
R1a(e1, a1, b1, c1, d1, 6, 7);
|
|
||||||
R1a(d1, e1, a1, b1, c1, 7, 9);
|
|
||||||
R1a(c1, d1, e1, a1, b1, 8, 11);
|
|
||||||
R1a(b1, c1, d1, e1, a1, 9, 13);
|
|
||||||
R1a(a1, b1, c1, d1, e1, 10, 14);
|
|
||||||
R1a(e1, a1, b1, c1, d1, 11, 15);
|
|
||||||
R1a(d1, e1, a1, b1, c1, 12, 6);
|
|
||||||
R1a(c1, d1, e1, a1, b1, 13, 7);
|
|
||||||
R1a(b1, c1, d1, e1, a1, 14, 9);
|
|
||||||
R1a(a1, b1, c1, d1, e1, 15, 8);
|
|
||||||
|
|
||||||
// Left round 2
|
|
||||||
R2a(e1, a1, b1, c1, d1, 7, 7);
|
|
||||||
R2a(d1, e1, a1, b1, c1, 4, 6);
|
|
||||||
R2a(c1, d1, e1, a1, b1, 13, 8);
|
|
||||||
R2a(b1, c1, d1, e1, a1, 1, 13);
|
|
||||||
R2a(a1, b1, c1, d1, e1, 10, 11);
|
|
||||||
R2a(e1, a1, b1, c1, d1, 6, 9);
|
|
||||||
R2a(d1, e1, a1, b1, c1, 15, 7);
|
|
||||||
R2a(c1, d1, e1, a1, b1, 3, 15);
|
|
||||||
R2a(b1, c1, d1, e1, a1, 12, 7);
|
|
||||||
R2a(a1, b1, c1, d1, e1, 0, 12);
|
|
||||||
R2a(e1, a1, b1, c1, d1, 9, 15);
|
|
||||||
R2a(d1, e1, a1, b1, c1, 5, 9);
|
|
||||||
R2a(c1, d1, e1, a1, b1, 2, 11);
|
|
||||||
R2a(b1, c1, d1, e1, a1, 14, 7);
|
|
||||||
R2a(a1, b1, c1, d1, e1, 11, 13);
|
|
||||||
R2a(e1, a1, b1, c1, d1, 8, 12);
|
|
||||||
|
|
||||||
// Left round 3
|
|
||||||
R3a(d1, e1, a1, b1, c1, 3, 11);
|
|
||||||
R3a(c1, d1, e1, a1, b1, 10, 13);
|
|
||||||
R3a(b1, c1, d1, e1, a1, 14, 6);
|
|
||||||
R3a(a1, b1, c1, d1, e1, 4, 7);
|
|
||||||
R3a(e1, a1, b1, c1, d1, 9, 14);
|
|
||||||
R3a(d1, e1, a1, b1, c1, 15, 9);
|
|
||||||
R3a(c1, d1, e1, a1, b1, 8, 13);
|
|
||||||
R3a(b1, c1, d1, e1, a1, 1, 15);
|
|
||||||
R3a(a1, b1, c1, d1, e1, 2, 14);
|
|
||||||
R3a(e1, a1, b1, c1, d1, 7, 8);
|
|
||||||
R3a(d1, e1, a1, b1, c1, 0, 13);
|
|
||||||
R3a(c1, d1, e1, a1, b1, 6, 6);
|
|
||||||
R3a(b1, c1, d1, e1, a1, 13, 5);
|
|
||||||
R3a(a1, b1, c1, d1, e1, 11, 12);
|
|
||||||
R3a(e1, a1, b1, c1, d1, 5, 7);
|
|
||||||
R3a(d1, e1, a1, b1, c1, 12, 5);
|
|
||||||
|
|
||||||
// Left round 4
|
|
||||||
R4a(c1, d1, e1, a1, b1, 1, 11);
|
|
||||||
R4a(b1, c1, d1, e1, a1, 9, 12);
|
|
||||||
R4a(a1, b1, c1, d1, e1, 11, 14);
|
|
||||||
R4a(e1, a1, b1, c1, d1, 10, 15);
|
|
||||||
R4a(d1, e1, a1, b1, c1, 0, 14);
|
|
||||||
R4a(c1, d1, e1, a1, b1, 8, 15);
|
|
||||||
R4a(b1, c1, d1, e1, a1, 12, 9);
|
|
||||||
R4a(a1, b1, c1, d1, e1, 4, 8);
|
|
||||||
R4a(e1, a1, b1, c1, d1, 13, 9);
|
|
||||||
R4a(d1, e1, a1, b1, c1, 3, 14);
|
|
||||||
R4a(c1, d1, e1, a1, b1, 7, 5);
|
|
||||||
R4a(b1, c1, d1, e1, a1, 15, 6);
|
|
||||||
R4a(a1, b1, c1, d1, e1, 14, 8);
|
|
||||||
R4a(e1, a1, b1, c1, d1, 5, 6);
|
|
||||||
R4a(d1, e1, a1, b1, c1, 6, 5);
|
|
||||||
R4a(c1, d1, e1, a1, b1, 2, 12);
|
|
||||||
|
|
||||||
// Left round 5
|
|
||||||
R5a(b1, c1, d1, e1, a1, 4, 9);
|
|
||||||
R5a(a1, b1, c1, d1, e1, 0, 15);
|
|
||||||
R5a(e1, a1, b1, c1, d1, 5, 5);
|
|
||||||
R5a(d1, e1, a1, b1, c1, 9, 11);
|
|
||||||
R5a(c1, d1, e1, a1, b1, 7, 6);
|
|
||||||
R5a(b1, c1, d1, e1, a1, 12, 8);
|
|
||||||
R5a(a1, b1, c1, d1, e1, 2, 13);
|
|
||||||
R5a(e1, a1, b1, c1, d1, 10, 12);
|
|
||||||
R5a(d1, e1, a1, b1, c1, 14, 5);
|
|
||||||
R5a(c1, d1, e1, a1, b1, 1, 12);
|
|
||||||
R5a(b1, c1, d1, e1, a1, 3, 13);
|
|
||||||
R5a(a1, b1, c1, d1, e1, 8, 14);
|
|
||||||
R5a(e1, a1, b1, c1, d1, 11, 11);
|
|
||||||
R5a(d1, e1, a1, b1, c1, 6, 8);
|
|
||||||
R5a(c1, d1, e1, a1, b1, 15, 5);
|
|
||||||
R5a(b1, c1, d1, e1, a1, 13, 6);
|
|
||||||
|
|
||||||
// Right round 1
|
|
||||||
R1b(a2, b2, c2, d2, e2, 5, 8);
|
|
||||||
R1b(e2, a2, b2, c2, d2, 14, 9);
|
|
||||||
R1b(d2, e2, a2, b2, c2, 7, 9);
|
|
||||||
R1b(c2, d2, e2, a2, b2, 0, 11);
|
|
||||||
R1b(b2, c2, d2, e2, a2, 9, 13);
|
|
||||||
R1b(a2, b2, c2, d2, e2, 2, 15);
|
|
||||||
R1b(e2, a2, b2, c2, d2, 11, 15);
|
|
||||||
R1b(d2, e2, a2, b2, c2, 4, 5);
|
|
||||||
R1b(c2, d2, e2, a2, b2, 13, 7);
|
|
||||||
R1b(b2, c2, d2, e2, a2, 6, 7);
|
|
||||||
R1b(a2, b2, c2, d2, e2, 15, 8);
|
|
||||||
R1b(e2, a2, b2, c2, d2, 8, 11);
|
|
||||||
R1b(d2, e2, a2, b2, c2, 1, 14);
|
|
||||||
R1b(c2, d2, e2, a2, b2, 10, 14);
|
|
||||||
R1b(b2, c2, d2, e2, a2, 3, 12);
|
|
||||||
R1b(a2, b2, c2, d2, e2, 12, 6);
|
|
||||||
|
|
||||||
// Right round 2
|
|
||||||
R2b(e2, a2, b2, c2, d2, 6, 9);
|
|
||||||
R2b(d2, e2, a2, b2, c2, 11, 13);
|
|
||||||
R2b(c2, d2, e2, a2, b2, 3, 15);
|
|
||||||
R2b(b2, c2, d2, e2, a2, 7, 7);
|
|
||||||
R2b(a2, b2, c2, d2, e2, 0, 12);
|
|
||||||
R2b(e2, a2, b2, c2, d2, 13, 8);
|
|
||||||
R2b(d2, e2, a2, b2, c2, 5, 9);
|
|
||||||
R2b(c2, d2, e2, a2, b2, 10, 11);
|
|
||||||
R2b(b2, c2, d2, e2, a2, 14, 7);
|
|
||||||
R2b(a2, b2, c2, d2, e2, 15, 7);
|
|
||||||
R2b(e2, a2, b2, c2, d2, 8, 12);
|
|
||||||
R2b(d2, e2, a2, b2, c2, 12, 7);
|
|
||||||
R2b(c2, d2, e2, a2, b2, 4, 6);
|
|
||||||
R2b(b2, c2, d2, e2, a2, 9, 15);
|
|
||||||
R2b(a2, b2, c2, d2, e2, 1, 13);
|
|
||||||
R2b(e2, a2, b2, c2, d2, 2, 11);
|
|
||||||
|
|
||||||
// Right round 3
|
|
||||||
R3b(d2, e2, a2, b2, c2, 15, 9);
|
|
||||||
R3b(c2, d2, e2, a2, b2, 5, 7);
|
|
||||||
R3b(b2, c2, d2, e2, a2, 1, 15);
|
|
||||||
R3b(a2, b2, c2, d2, e2, 3, 11);
|
|
||||||
R3b(e2, a2, b2, c2, d2, 7, 8);
|
|
||||||
R3b(d2, e2, a2, b2, c2, 14, 6);
|
|
||||||
R3b(c2, d2, e2, a2, b2, 6, 6);
|
|
||||||
R3b(b2, c2, d2, e2, a2, 9, 14);
|
|
||||||
R3b(a2, b2, c2, d2, e2, 11, 12);
|
|
||||||
R3b(e2, a2, b2, c2, d2, 8, 13);
|
|
||||||
R3b(d2, e2, a2, b2, c2, 12, 5);
|
|
||||||
R3b(c2, d2, e2, a2, b2, 2, 14);
|
|
||||||
R3b(b2, c2, d2, e2, a2, 10, 13);
|
|
||||||
R3b(a2, b2, c2, d2, e2, 0, 13);
|
|
||||||
R3b(e2, a2, b2, c2, d2, 4, 7);
|
|
||||||
R3b(d2, e2, a2, b2, c2, 13, 5);
|
|
||||||
|
|
||||||
// Right round 4
|
|
||||||
R4b(c2, d2, e2, a2, b2, 8, 15);
|
|
||||||
R4b(b2, c2, d2, e2, a2, 6, 5);
|
|
||||||
R4b(a2, b2, c2, d2, e2, 4, 8);
|
|
||||||
R4b(e2, a2, b2, c2, d2, 1, 11);
|
|
||||||
R4b(d2, e2, a2, b2, c2, 3, 14);
|
|
||||||
R4b(c2, d2, e2, a2, b2, 11, 14);
|
|
||||||
R4b(b2, c2, d2, e2, a2, 15, 6);
|
|
||||||
R4b(a2, b2, c2, d2, e2, 0, 14);
|
|
||||||
R4b(e2, a2, b2, c2, d2, 5, 6);
|
|
||||||
R4b(d2, e2, a2, b2, c2, 12, 9);
|
|
||||||
R4b(c2, d2, e2, a2, b2, 2, 12);
|
|
||||||
R4b(b2, c2, d2, e2, a2, 13, 9);
|
|
||||||
R4b(a2, b2, c2, d2, e2, 9, 12);
|
|
||||||
R4b(e2, a2, b2, c2, d2, 7, 5);
|
|
||||||
R4b(d2, e2, a2, b2, c2, 10, 15);
|
|
||||||
R4b(c2, d2, e2, a2, b2, 14, 8);
|
|
||||||
|
|
||||||
// Right round 5
|
|
||||||
R5b(b2, c2, d2, e2, a2, 12 , 8);
|
|
||||||
R5b(a2, b2, c2, d2, e2, 15 , 5);
|
|
||||||
R5b(e2, a2, b2, c2, d2, 10 , 12);
|
|
||||||
R5b(d2, e2, a2, b2, c2, 4 , 9);
|
|
||||||
R5b(c2, d2, e2, a2, b2, 1 , 12);
|
|
||||||
R5b(b2, c2, d2, e2, a2, 5 , 5);
|
|
||||||
R5b(a2, b2, c2, d2, e2, 8 , 14);
|
|
||||||
R5b(e2, a2, b2, c2, d2, 7 , 6);
|
|
||||||
R5b(d2, e2, a2, b2, c2, 6 , 8);
|
|
||||||
R5b(c2, d2, e2, a2, b2, 2 , 13);
|
|
||||||
R5b(b2, c2, d2, e2, a2, 13 , 6);
|
|
||||||
R5b(a2, b2, c2, d2, e2, 14 , 5);
|
|
||||||
R5b(e2, a2, b2, c2, d2, 0 , 15);
|
|
||||||
R5b(d2, e2, a2, b2, c2, 3 , 13);
|
|
||||||
R5b(c2, d2, e2, a2, b2, 9 , 11);
|
|
||||||
R5b(b2, c2, d2, e2, a2, 11 , 11);
|
|
||||||
|
|
||||||
// Finalise state
|
|
||||||
d2 = m_state[1] + c1 + d2;
|
|
||||||
m_state[1] = m_state[2] + d1 + e2;
|
|
||||||
m_state[2] = m_state[3] + e1 + a2;
|
|
||||||
m_state[3] = m_state[4] + a1 + b2;
|
|
||||||
m_state[4] = m_state[0] + b1 + c2;
|
|
||||||
m_state[0] = d2;
|
|
||||||
|
|
||||||
m_buffer.size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
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);
|
|
||||||
uint64_t length = m_length * 8;
|
|
||||||
|
|
||||||
// Push a padding byte into the buffer
|
|
||||||
uint8_t padding = 0x80;
|
|
||||||
update (&padding, 1);
|
|
||||||
|
|
||||||
// Pad out the line if we couldn't fit a length at the end
|
|
||||||
size_t remaining = sizeof (m_buffer.d32) - m_buffer.size;
|
|
||||||
if (remaining < 8) {
|
|
||||||
static const uint8_t ZEROES[8] = { 0 };
|
|
||||||
|
|
||||||
update (ZEROES, remaining);
|
|
||||||
|
|
||||||
CHECK_EQ (m_buffer.size, 0u);
|
|
||||||
remaining = sizeof (m_buffer.d08);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the length to the end of the buffer
|
|
||||||
union {
|
|
||||||
uint32_t d32[16];
|
|
||||||
uint8_t d08[64];
|
|
||||||
};
|
|
||||||
|
|
||||||
memset (d32, 0, sizeof (d32));
|
|
||||||
d32[14] = length & 0xFFFFFFFF;
|
|
||||||
d32[15] = length >> 32u;
|
|
||||||
|
|
||||||
// Do the final update
|
|
||||||
size_t offset = sizeof(d08) - remaining;
|
|
||||||
update (d08 + offset, remaining);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
RIPEMD::digest_t
|
|
||||||
RIPEMD::digest (void) const
|
|
||||||
{
|
|
||||||
digest_t d;
|
|
||||||
memcpy (d.data (), m_state, sizeof (m_state));
|
|
||||||
return d;
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright:
|
|
||||||
* 2014, Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTIL_HASH_RIPEMD_HPP
|
|
||||||
#define __UTIL_HASH_RIPEMD_HPP
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace util::hash {
|
|
||||||
class RIPEMD {
|
|
||||||
public:
|
|
||||||
typedef std::array<uint8_t,20> digest_t;
|
|
||||||
|
|
||||||
public:
|
|
||||||
RIPEMD();
|
|
||||||
|
|
||||||
void update (const void *restrict, size_t) noexcept;
|
|
||||||
void update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept;
|
|
||||||
|
|
||||||
digest_t digest (void) const;
|
|
||||||
void finish (void);
|
|
||||||
void reset (void);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void transform ();
|
|
||||||
|
|
||||||
bool m_finished;
|
|
||||||
|
|
||||||
uint32_t m_state[5];
|
|
||||||
uint64_t m_length;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
union {
|
|
||||||
uint32_t d32[16];
|
|
||||||
uint8_t d08[64];
|
|
||||||
};
|
|
||||||
size_t size;
|
|
||||||
} m_buffer;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
281
hash/sha1.cpp
281
hash/sha1.cpp
@ -1,281 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2013 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sha1.hpp"
|
|
||||||
|
|
||||||
#include "../bitwise.hpp"
|
|
||||||
#include "../debug.hpp"
|
|
||||||
#include "../endian.hpp"
|
|
||||||
#include "../cast.hpp"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <limits>
|
|
||||||
#include <ostream>
|
|
||||||
|
|
||||||
|
|
||||||
using util::hash::SHA1;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
std::ostream&
|
|
||||||
operator<< (std::ostream &os, SHA1::state_t t)
|
|
||||||
{
|
|
||||||
switch (t) {
|
|
||||||
case SHA1::READY: return os << "READY";
|
|
||||||
case SHA1::FINISHED: return os << "FINISHED";
|
|
||||||
}
|
|
||||||
|
|
||||||
unreachable ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Logical function for sequence of rounds
|
|
||||||
static constexpr
|
|
||||||
uint32_t
|
|
||||||
f_00 (uint32_t B, uint32_t C, uint32_t 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 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
|
|
||||||
constexpr uint32_t DEFAULT_H[] = {
|
|
||||||
0x67452301,
|
|
||||||
0xEFCDAB89,
|
|
||||||
0x98BADCFE,
|
|
||||||
0x10325476,
|
|
||||||
0xC3D2E1F0
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
total = 0;
|
|
||||||
state = READY;
|
|
||||||
|
|
||||||
std::copy (std::begin (DEFAULT_H), std::end (DEFAULT_H), H);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
SHA1::update (
|
|
||||||
const uint8_t *restrict first,
|
|
||||||
const uint8_t *restrict last) noexcept
|
|
||||||
{
|
|
||||||
CHECK_LE (first, last);
|
|
||||||
|
|
||||||
update (first, last - first);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
SHA1::update (const void *restrict _data, size_t size) noexcept
|
|
||||||
{
|
|
||||||
CHECK (_data);
|
|
||||||
CHECK_EQ (+state, +READY);
|
|
||||||
CHECK_GE (std::numeric_limits<decltype(total)>::max () - total, size);
|
|
||||||
|
|
||||||
auto data = static_cast<const uint8_t *restrict> (_data);
|
|
||||||
|
|
||||||
while (size > 0) {
|
|
||||||
// Copy the data into the remaining available buffer slots
|
|
||||||
const size_t offset = total % BLOCK_BYTES;
|
|
||||||
const size_t chunk = std::min (BLOCK_BYTES - offset, size);
|
|
||||||
|
|
||||||
std::copy (data, data + chunk, c + offset);
|
|
||||||
|
|
||||||
total += chunk;
|
|
||||||
|
|
||||||
// Attempt to process if full
|
|
||||||
if (total % BLOCK_BYTES == 0)
|
|
||||||
process ();
|
|
||||||
|
|
||||||
size -= chunk;
|
|
||||||
data += chunk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
SHA1::process (void)
|
|
||||||
{
|
|
||||||
CHECK_EQ (total % BLOCK_BYTES, 0u);
|
|
||||||
|
|
||||||
// Byteswap the raw input we have buffered ready for arithmetic
|
|
||||||
std::transform (std::begin (W),
|
|
||||||
std::end (W),
|
|
||||||
std::begin (W),
|
|
||||||
[] (uint32_t x) {
|
|
||||||
return ntoh (x);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Initialise the work buffer and the state variables
|
|
||||||
for (size_t t = 16; t < 80; ++t)
|
|
||||||
W[t] = rotatel (W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
|
|
||||||
|
|
||||||
uint32_t A = H[0],
|
|
||||||
B = H[1],
|
|
||||||
C = H[2],
|
|
||||||
D = H[3],
|
|
||||||
E = H[4];
|
|
||||||
|
|
||||||
// Perform each of the four rounds
|
|
||||||
#define ROTATE_STATE(i) do { \
|
|
||||||
uint32_t temp = rotatel (A, 5) + f_##i (B, C, D) + E + W[t] + K_##i; \
|
|
||||||
E = D; \
|
|
||||||
D = C; \
|
|
||||||
C = rotatel (B, 30); \
|
|
||||||
B = A; \
|
|
||||||
A = temp; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
for (size_t t = 0; t < 20; ++t) ROTATE_STATE(00);
|
|
||||||
for (size_t t = 20; t < 40; ++t) ROTATE_STATE(20);
|
|
||||||
for (size_t t = 40; t < 60; ++t) ROTATE_STATE(40);
|
|
||||||
for (size_t t = 60; t < 80; ++t) ROTATE_STATE(60);
|
|
||||||
|
|
||||||
// Update the resulting hash state
|
|
||||||
H[0] += A;
|
|
||||||
H[1] += B;
|
|
||||||
H[2] += C;
|
|
||||||
H[3] += D;
|
|
||||||
H[4] += E;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
SHA1::finish (void)
|
|
||||||
{
|
|
||||||
size_t offset = total % BLOCK_BYTES;
|
|
||||||
size_t used = total * 8;
|
|
||||||
|
|
||||||
// Append a single one bit
|
|
||||||
c[offset++] = 0x80;
|
|
||||||
total += 1;
|
|
||||||
|
|
||||||
// Zero fill if we can't append length
|
|
||||||
size_t chunk = BLOCK_BYTES - offset;
|
|
||||||
if (chunk < sizeof (total)) {
|
|
||||||
std::fill_n (c + offset, chunk, 0);
|
|
||||||
total += chunk;
|
|
||||||
|
|
||||||
process ();
|
|
||||||
|
|
||||||
chunk = BLOCK_BYTES;
|
|
||||||
offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zero fill and append total length
|
|
||||||
std::fill_n (c + offset, chunk - sizeof (total), 0);
|
|
||||||
c[BLOCK_BYTES - 1] = used & 0xFF; used >>= 8;
|
|
||||||
c[BLOCK_BYTES - 2] = used & 0xFF; used >>= 8;
|
|
||||||
c[BLOCK_BYTES - 3] = used & 0xFF; used >>= 8;
|
|
||||||
c[BLOCK_BYTES - 4] = used & 0xFF; used >>= 8;
|
|
||||||
c[BLOCK_BYTES - 5] = used & 0xFF; used >>= 8;
|
|
||||||
c[BLOCK_BYTES - 6] = used & 0xFF; used >>= 8;
|
|
||||||
c[BLOCK_BYTES - 7] = used & 0xFF; used >>= 8;
|
|
||||||
c[BLOCK_BYTES - 8] = used & 0xFF;
|
|
||||||
|
|
||||||
total += chunk;
|
|
||||||
process ();
|
|
||||||
|
|
||||||
state = FINISHED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
SHA1::digest_t
|
|
||||||
SHA1::digest (void) const
|
|
||||||
{
|
|
||||||
CHECK_EQ (+state, +FINISHED);
|
|
||||||
|
|
||||||
return { {
|
|
||||||
util::cast::lossless<uint8_t> ((H[0] >> 24u) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[0] >> 16u) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[0] >> 8u) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[0] ) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[1] >> 24u) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[1] >> 16u) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[1] >> 8u) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[1] ) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[2] >> 24u) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[2] >> 16u) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[2] >> 8u) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[2] ) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[3] >> 24u) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[3] >> 16u) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[3] >> 8u) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[3] ) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[4] >> 24u) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[4] >> 16u) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[4] >> 8u) & 0xFF),
|
|
||||||
util::cast::lossless<uint8_t> ((H[4] ) & 0xFF)
|
|
||||||
} };
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2013 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTIL_HASH_SHA1_HPP
|
|
||||||
#define __UTIL_HASH_SHA1_HPP
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace util::hash {
|
|
||||||
class SHA1 {
|
|
||||||
public:
|
|
||||||
typedef std::array<uint8_t,20> digest_t;
|
|
||||||
static const size_t BLOCK_SIZE = 64;
|
|
||||||
static const size_t DIGEST_SIZE = 20;
|
|
||||||
|
|
||||||
public:
|
|
||||||
SHA1();
|
|
||||||
|
|
||||||
void update (const void *restrict, size_t) noexcept;
|
|
||||||
void update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept;
|
|
||||||
|
|
||||||
void finish (void);
|
|
||||||
digest_t digest (void) const;
|
|
||||||
void reset (void);
|
|
||||||
|
|
||||||
enum state_t {
|
|
||||||
READY,
|
|
||||||
FINISHED
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void process (void);
|
|
||||||
|
|
||||||
state_t state;
|
|
||||||
|
|
||||||
uint64_t total;
|
|
||||||
uint32_t H[5];
|
|
||||||
|
|
||||||
union {
|
|
||||||
uint8_t c[16*4+64*4];
|
|
||||||
uint32_t W[16 +64 ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
332
hash/sha2.cpp
332
hash/sha2.cpp
@ -1,332 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright:
|
|
||||||
* 2014, Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sha2.hpp"
|
|
||||||
|
|
||||||
#include "../bitwise.hpp"
|
|
||||||
#include "../debug.hpp"
|
|
||||||
#include "../endian.hpp"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
using namespace util::hash;
|
|
||||||
|
|
||||||
// First 32 bits of the fractional parts
|
|
||||||
// of the cube roots
|
|
||||||
// of the first 64 prime numbers
|
|
||||||
static constexpr
|
|
||||||
uint32_t K_64[] = {
|
|
||||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
|
||||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
|
||||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
||||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
|
||||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
|
||||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
||||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
|
||||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// First 64 bits of the fractional parts
|
|
||||||
// of the cube roots
|
|
||||||
// of the first 80 prime numbers
|
|
||||||
static constexpr
|
|
||||||
uint64_t K_80[] = {
|
|
||||||
0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
|
|
||||||
0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
|
|
||||||
0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
|
|
||||||
0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
|
|
||||||
0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
|
|
||||||
0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
|
|
||||||
0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
|
|
||||||
0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
|
|
||||||
0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
|
|
||||||
0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
|
|
||||||
0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
|
|
||||||
0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
|
|
||||||
0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
|
|
||||||
0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
|
|
||||||
0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
|
|
||||||
0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
|
|
||||||
0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
|
|
||||||
0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
|
|
||||||
0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
|
|
||||||
0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
static constexpr
|
|
||||||
uint32_t
|
|
||||||
Ch (uint32_t x, uint32_t y, uint32_t z)
|
|
||||||
{
|
|
||||||
return (x & y) ^ (~x & z);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
static constexpr
|
|
||||||
uint32_t
|
|
||||||
Maj (uint32_t x, uint32_t y, uint32_t z)
|
|
||||||
{
|
|
||||||
return (x & y) ^ (x & z) ^ (y & z);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#define FUNC(NAME,r0,r1,r2) \
|
|
||||||
static constexpr \
|
|
||||||
uint32_t \
|
|
||||||
NAME (uint32_t x) \
|
|
||||||
{ \
|
|
||||||
return util::rotater (x, (r0)) ^ \
|
|
||||||
util::rotater (x, (r1)) ^ \
|
|
||||||
util::rotater (x, (r2)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
FUNC(S0, 2, 13, 22)
|
|
||||||
FUNC(S1, 6, 11, 25)
|
|
||||||
|
|
||||||
#undef FUNC
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#define FUNC(NAME,r0,r1,s) \
|
|
||||||
static constexpr \
|
|
||||||
uint32_t \
|
|
||||||
NAME (uint32_t x) \
|
|
||||||
{ \
|
|
||||||
return util::rotater (x, (r0)) ^ \
|
|
||||||
util::rotater (x, (r1)) ^ \
|
|
||||||
(x >> (s)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
FUNC(s0, 7, 18, 3)
|
|
||||||
FUNC(s1, 17, 19, 10)
|
|
||||||
|
|
||||||
#undef FUNC
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
static constexpr
|
|
||||||
uint32_t
|
|
||||||
H_224[] = {
|
|
||||||
0xc1059ed8,
|
|
||||||
0x367cd507,
|
|
||||||
0x3070dd17,
|
|
||||||
0xf70e5939,
|
|
||||||
0xffc00b31,
|
|
||||||
0x68581511,
|
|
||||||
0x64f98fa7,
|
|
||||||
0xbefa4fa4,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
static constexpr
|
|
||||||
uint32_t
|
|
||||||
H_256[] = {
|
|
||||||
0x6a09e667,
|
|
||||||
0xbb67ae85,
|
|
||||||
0x3c6ef372,
|
|
||||||
0xa54ff53a,
|
|
||||||
0x510e527f,
|
|
||||||
0x9b05688c,
|
|
||||||
0x1f83d9ab,
|
|
||||||
0x5be0cd19,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
static constexpr
|
|
||||||
uint64_t
|
|
||||||
H_384[] = {
|
|
||||||
0xcbbb9d5dc1059ed8,
|
|
||||||
0x629a292a367cd507,
|
|
||||||
0x9159015a3070dd17,
|
|
||||||
0x152fecd8f70e5939,
|
|
||||||
0x67332667ffc00b31,
|
|
||||||
0x8eb44a8768581511,
|
|
||||||
0xdb0c2e0d64f98fa7,
|
|
||||||
0x47b5481dbefa4fa4,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
static constexpr
|
|
||||||
uint64_t
|
|
||||||
H_512[] = {
|
|
||||||
0x6a09e667f3bcc908,
|
|
||||||
0xbb67ae8584caa73b,
|
|
||||||
0x3c6ef372fe94f82b,
|
|
||||||
0xa54ff53a5f1d36f1,
|
|
||||||
0x510e527fade682d1,
|
|
||||||
0x9b05688c2b3e6c1f,
|
|
||||||
0x1f83d9abfb41bd6b,
|
|
||||||
0x5be0cd19137e2179,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
SHA256::SHA256 ():
|
|
||||||
m_total (0)
|
|
||||||
{
|
|
||||||
(void)K_80;
|
|
||||||
(void)H_224;
|
|
||||||
(void)H_384;
|
|
||||||
(void)H_512;
|
|
||||||
|
|
||||||
std::copy (std::begin (H_256), std::end (H_256), std::begin (H));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
SHA256::update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept
|
|
||||||
{
|
|
||||||
CHECK_LE (first, last);
|
|
||||||
|
|
||||||
update (first, last - first);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
SHA256::update (const void *restrict _data, size_t length) noexcept
|
|
||||||
{
|
|
||||||
CHECK (_data);
|
|
||||||
auto data = static_cast<const uint8_t *restrict> (_data);
|
|
||||||
|
|
||||||
while (length) {
|
|
||||||
size_t buffered = m_total % sizeof (M);
|
|
||||||
size_t chunk = std::min (sizeof (M) - buffered, length);
|
|
||||||
std::copy (data, data + chunk, C.begin () + buffered);
|
|
||||||
|
|
||||||
length -= chunk;
|
|
||||||
m_total += chunk;
|
|
||||||
|
|
||||||
if (m_total % sizeof (M) == 0)
|
|
||||||
process ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
SHA256::finish (void)
|
|
||||||
{
|
|
||||||
// Append a single 1 bit followed by 0s.
|
|
||||||
auto buffered = m_total % sizeof (M);
|
|
||||||
auto used = m_total * 8u;
|
|
||||||
|
|
||||||
C[buffered++] = 0x80;
|
|
||||||
++m_total;
|
|
||||||
|
|
||||||
// Pad out to 56 byte length
|
|
||||||
if (buffered > 56) {
|
|
||||||
size_t chunk = sizeof (M) - buffered;
|
|
||||||
std::fill_n (C.begin () + buffered, chunk, 0);
|
|
||||||
m_total += chunk;
|
|
||||||
process ();
|
|
||||||
|
|
||||||
buffered = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t chunk = sizeof (M) - sizeof (uint64_t) - buffered;
|
|
||||||
std::fill_n (C.begin () + buffered, chunk, 0);
|
|
||||||
m_total += chunk;
|
|
||||||
|
|
||||||
// Finish with the m_total size
|
|
||||||
C[56] = (used >> 56) & 0xFF;
|
|
||||||
C[57] = (used >> 48) & 0xFF;
|
|
||||||
C[58] = (used >> 40) & 0xFF;
|
|
||||||
C[59] = (used >> 32) & 0xFF;
|
|
||||||
C[60] = (used >> 24) & 0xFF;
|
|
||||||
C[61] = (used >> 16) & 0xFF;
|
|
||||||
C[62] = (used >> 8) & 0xFF;
|
|
||||||
C[63] = (used >> 0) & 0xFF;
|
|
||||||
m_total += 8;
|
|
||||||
|
|
||||||
// Reprocess
|
|
||||||
process ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
SHA256::process (void)
|
|
||||||
{
|
|
||||||
CHECK_EQ (m_total % sizeof (M), 0u);
|
|
||||||
|
|
||||||
// Initialise the message schedule, W
|
|
||||||
uint32_t W[64];
|
|
||||||
std::transform (M.begin (), M.end (), std::begin (W), [] (uint32_t x) { return ntoh (x); });
|
|
||||||
|
|
||||||
for (size_t i = 16; i < 64; ++i)
|
|
||||||
W[i] = s1(W[i - 2]) + W[i - 7] + s0 (W[i - 15]) + W[i - 16];
|
|
||||||
|
|
||||||
// Working variables
|
|
||||||
uint32_t a = H[0],
|
|
||||||
b = H[1],
|
|
||||||
c = H[2],
|
|
||||||
d = H[3],
|
|
||||||
e = H[4],
|
|
||||||
f = H[5],
|
|
||||||
g = H[6],
|
|
||||||
h = H[7];
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < 64; ++i) {
|
|
||||||
uint32_t t1 = h + S1 (e) + Ch (e, f, g) + K_64[i] + W[i];
|
|
||||||
uint32_t t2 = S0 (a) + Maj (a, b, c);
|
|
||||||
|
|
||||||
h = g;
|
|
||||||
g = f;
|
|
||||||
f = e;
|
|
||||||
e = d + t1;
|
|
||||||
d = c;
|
|
||||||
c = b;
|
|
||||||
b = a;
|
|
||||||
a = t1 + t2;
|
|
||||||
}
|
|
||||||
|
|
||||||
H[0] += a;
|
|
||||||
H[1] += b;
|
|
||||||
H[2] += c;
|
|
||||||
H[3] += d;
|
|
||||||
H[4] += e;
|
|
||||||
H[5] += f;
|
|
||||||
H[6] += g;
|
|
||||||
H[7] += h;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
SHA256::digest_t
|
|
||||||
SHA256::digest (void) const
|
|
||||||
{
|
|
||||||
digest_t out;
|
|
||||||
|
|
||||||
auto cursor = out.begin ();
|
|
||||||
for (auto i: H) {
|
|
||||||
*cursor++ = (i >> 24) & 0xFF;
|
|
||||||
*cursor++ = (i >> 16) & 0xFF;
|
|
||||||
*cursor++ = (i >> 8) & 0xFF;
|
|
||||||
*cursor++ = (i >> 0) & 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright:
|
|
||||||
* 2014, Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTIL_HASH_SHA2_HPP
|
|
||||||
#define __UTIL_HASH_SHA2_HPP
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace util::hash {
|
|
||||||
class SHA256 {
|
|
||||||
public:
|
|
||||||
typedef std::array<uint8_t,32> digest_t;
|
|
||||||
|
|
||||||
public:
|
|
||||||
SHA256();
|
|
||||||
|
|
||||||
void update (const void *restrict, size_t) noexcept;
|
|
||||||
void update (const uint8_t *restrict first, const uint8_t *restrict last) noexcept;
|
|
||||||
|
|
||||||
void finish (void);
|
|
||||||
digest_t digest (void) const;
|
|
||||||
|
|
||||||
void reset (void);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void process (void);
|
|
||||||
|
|
||||||
uint64_t m_total;
|
|
||||||
std::array<uint32_t, 8> H;
|
|
||||||
|
|
||||||
union {
|
|
||||||
std::array<uint32_t, 16> M;
|
|
||||||
std::array<uint8_t, 64> C;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2016, Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "simple.hpp"
|
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2016, Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTIL_HASH_SIMPLE_HPP
|
|
||||||
#define __UTIL_HASH_SIMPLE_HPP
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace util { namespace hash {
|
|
||||||
//template <class H, class InputT>
|
|
||||||
template <class H, typename ...Args>
|
|
||||||
typename H::digest_t
|
|
||||||
simple (const void *restrict first, const void *restrict last, Args&&...args) noexcept
|
|
||||||
{
|
|
||||||
H h (std::forward<Args> (args)...);
|
|
||||||
|
|
||||||
h.update (
|
|
||||||
static_cast<const uint8_t*restrict> (first),
|
|
||||||
static_cast<const uint8_t*restrict> (last)
|
|
||||||
);
|
|
||||||
h.finish ();
|
|
||||||
|
|
||||||
return h.digest ();
|
|
||||||
}
|
|
||||||
} }
|
|
||||||
|
|
||||||
#endif
|
|
@ -21,10 +21,37 @@
|
|||||||
|
|
||||||
namespace util::hash {
|
namespace util::hash {
|
||||||
// Thomas Wang's integer mixing functions, ca 2007
|
// Thomas Wang's integer mixing functions, ca 2007
|
||||||
constexpr uint32_t wang (uint32_t);
|
//-------------------------------------------------------------------------
|
||||||
constexpr uint64_t wang (uint64_t);
|
constexpr uint32_t
|
||||||
|
wang (uint32_t key)
|
||||||
|
{
|
||||||
|
// a prime or an odd constant
|
||||||
|
constexpr uint32_t c2 = 0x27d4eb2d;
|
||||||
|
|
||||||
|
key = (key ^ 61) ^ (key >> 16);
|
||||||
|
key = key + (key << 3);
|
||||||
|
key = key ^ (key >> 4);
|
||||||
|
key = key * c2;
|
||||||
|
key = key ^ (key >> 15);
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
constexpr uint64_t
|
||||||
|
wang (uint64_t key)
|
||||||
|
{
|
||||||
|
key = ~key + (key << 21); // key = (key << 21) - key - 1;
|
||||||
|
key = key ^ (key >> 24);
|
||||||
|
key = (key + (key << 3)) + (key << 8); // key * 265
|
||||||
|
key = key ^ (key >> 14);
|
||||||
|
key = (key + (key << 2)) + (key << 4); // key * 21
|
||||||
|
key = key ^ (key >> 28);
|
||||||
|
key = key + (key << 31);
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "wang.ipp"
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright 2010-2015 Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __UTIL_HASH_WANG_IPP
|
|
||||||
#error
|
|
||||||
#endif
|
|
||||||
#define __UTIL_HASH_WANG_IPP
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
constexpr uint32_t
|
|
||||||
util::hash::wang (uint32_t key) {
|
|
||||||
// a prime or an odd constant
|
|
||||||
constexpr uint32_t c2 = 0x27d4eb2d;
|
|
||||||
|
|
||||||
key = (key ^ 61) ^ (key >> 16);
|
|
||||||
key = key + (key << 3);
|
|
||||||
key = key ^ (key >> 4);
|
|
||||||
key = key * c2;
|
|
||||||
key = key ^ (key >> 15);
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
constexpr uint64_t
|
|
||||||
util::hash::wang (uint64_t key) {
|
|
||||||
key = ~key + (key << 21); // key = (key << 21) - key - 1;
|
|
||||||
key = key ^ (key >> 24);
|
|
||||||
key = (key + (key << 3)) + (key << 8); // key * 265
|
|
||||||
key = key ^ (key >> 14);
|
|
||||||
key = (key + (key << 2)) + (key << 4); // key * 21
|
|
||||||
key = key ^ (key >> 28);
|
|
||||||
key = key + (key << 31);
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
|
@ -78,40 +78,6 @@ const uint64_t
|
|||||||
constants<uint64_t>::round_rotl = 31;
|
constants<uint64_t>::round_rotl = 31;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
constexpr uint32_t DEFAULT_SEED = 0;
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T>
|
|
||||||
xxhash<T>::xxhash (void):
|
|
||||||
xxhash (DEFAULT_SEED)
|
|
||||||
{ ; }
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T>
|
|
||||||
xxhash<T>::xxhash (uint32_t _seed):
|
|
||||||
m_seed (_seed)
|
|
||||||
{
|
|
||||||
reset ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T>
|
|
||||||
void
|
|
||||||
xxhash<T>::reset (void)
|
|
||||||
{
|
|
||||||
memset (&m_state, 0, sizeof (m_state));
|
|
||||||
|
|
||||||
m_state.v1 = m_seed + constants<T>::prime[0] + constants<T>::prime[1];
|
|
||||||
m_state.v2 = m_seed + constants<T>::prime[1];
|
|
||||||
m_state.v3 = m_seed;
|
|
||||||
m_state.v4 = m_seed - constants<T>::prime[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static
|
static
|
||||||
@ -128,9 +94,46 @@ round (T seed, T input)
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void
|
xxhash<T>::xxhash (uint32_t _seed):
|
||||||
xxhash<T>::update (const uint8_t *restrict first, const uint8_t *restrict last)
|
m_seed (_seed)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
typename xxhash<T>::digest_t
|
||||||
|
xxhash<T>::operator() (const util::view<const uint8_t*> data)
|
||||||
{
|
{
|
||||||
|
struct {
|
||||||
|
uint32_t total_len_32;
|
||||||
|
uint32_t large_len;
|
||||||
|
|
||||||
|
T v1, v2, v3, v4;
|
||||||
|
uint32_t mem32[4];
|
||||||
|
uint32_t memsize;
|
||||||
|
uint32_t reserved;
|
||||||
|
|
||||||
|
//uint64_t length;
|
||||||
|
//T v[4];
|
||||||
|
//T mem[4];
|
||||||
|
//unsigned memsize;
|
||||||
|
} m_state;
|
||||||
|
|
||||||
|
/* RESET */
|
||||||
|
memset (&m_state, 0, sizeof (m_state));
|
||||||
|
|
||||||
|
m_state.v1 = m_seed + constants<T>::prime[0] + constants<T>::prime[1];
|
||||||
|
m_state.v2 = m_seed + constants<T>::prime[1];
|
||||||
|
m_state.v3 = m_seed;
|
||||||
|
m_state.v4 = m_seed - constants<T>::prime[0];
|
||||||
|
|
||||||
|
/* UPDATE */
|
||||||
|
do {
|
||||||
|
auto first = data.begin ();
|
||||||
|
auto last = data.end ();
|
||||||
|
if (first == last)
|
||||||
|
break;
|
||||||
|
|
||||||
CHECK (first);
|
CHECK (first);
|
||||||
CHECK (last);
|
CHECK (last);
|
||||||
CHECK_LE (first, last);
|
CHECK_LE (first, last);
|
||||||
@ -150,7 +153,7 @@ xxhash<T>::update (const uint8_t *restrict first, const uint8_t *restrict last)
|
|||||||
if (m_state.memsize + len < CHUNK) { /* fill in tmp buffer */
|
if (m_state.memsize + len < CHUNK) { /* fill in tmp buffer */
|
||||||
memcpy ((uint8_t*)(m_state.mem32) + m_state.memsize, input, len);
|
memcpy ((uint8_t*)(m_state.mem32) + m_state.memsize, input, len);
|
||||||
m_state.memsize += (unsigned)len;
|
m_state.memsize += (unsigned)len;
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_state.memsize) { /* some data left from previous update */
|
if (m_state.memsize) { /* some data left from previous update */
|
||||||
@ -189,23 +192,10 @@ xxhash<T>::update (const uint8_t *restrict first, const uint8_t *restrict last)
|
|||||||
memcpy (m_state.mem32, p, (size_t)(bEnd-p));
|
memcpy (m_state.mem32, p, (size_t)(bEnd-p));
|
||||||
m_state.memsize = (unsigned)(bEnd-p);
|
m_state.memsize = (unsigned)(bEnd-p);
|
||||||
}
|
}
|
||||||
}
|
} while (0);
|
||||||
|
|
||||||
|
/* DIGEST */
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
{
|
||||||
template <typename T>
|
|
||||||
void
|
|
||||||
xxhash<T>::finish (void)
|
|
||||||
{
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
typename xxhash<T>::digest_t
|
|
||||||
xxhash<T>::digest (void) const
|
|
||||||
{
|
|
||||||
auto p = reinterpret_cast<const uint8_t*> (m_state.mem32);
|
auto p = reinterpret_cast<const uint8_t*> (m_state.mem32);
|
||||||
auto last = p + m_state.memsize;
|
auto last = p + m_state.memsize;
|
||||||
|
|
||||||
@ -239,6 +229,7 @@ xxhash<T>::digest (void) const
|
|||||||
h ^= h >> 16;
|
h ^= h >> 16;
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
#ifndef CRUFT_UTIL_HASH_XXHASH_HPP
|
#ifndef CRUFT_UTIL_HASH_XXHASH_HPP
|
||||||
#define CRUFT_UTIL_HASH_XXHASH_HPP
|
#define CRUFT_UTIL_HASH_XXHASH_HPP
|
||||||
|
|
||||||
|
#include "../view.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
@ -27,33 +29,14 @@ namespace util::hash {
|
|||||||
static_assert (std::is_same<T,uint32_t>::value || std::is_same<T,uint64_t>::value);
|
static_assert (std::is_same<T,uint32_t>::value || std::is_same<T,uint64_t>::value);
|
||||||
using digest_t = T;
|
using digest_t = T;
|
||||||
|
|
||||||
xxhash (void);
|
static constexpr uint32_t DEFAULT_SEED = 0;
|
||||||
xxhash (uint32_t seed);
|
|
||||||
|
|
||||||
void update (const uint8_t *restrict first, const uint8_t *restrict last);
|
xxhash (uint32_t seed = DEFAULT_SEED);
|
||||||
void finish (void);
|
|
||||||
|
|
||||||
digest_t digest (void) const;
|
digest_t operator() (const util::view<const uint8_t*> data);
|
||||||
|
|
||||||
void reset (void);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t m_seed;
|
uint32_t m_seed;
|
||||||
|
|
||||||
struct {
|
|
||||||
uint32_t total_len_32;
|
|
||||||
uint32_t large_len;
|
|
||||||
|
|
||||||
T v1, v2, v3, v4;
|
|
||||||
uint32_t mem32[4];
|
|
||||||
uint32_t memsize;
|
|
||||||
uint32_t reserved;
|
|
||||||
|
|
||||||
//uint64_t length;
|
|
||||||
//T v[4];
|
|
||||||
//T mem[4];
|
|
||||||
//unsigned memsize;
|
|
||||||
} m_state;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using xxhash32 = xxhash<uint32_t>;
|
using xxhash32 = xxhash<uint32_t>;
|
||||||
|
2
io.hpp
2
io.hpp
@ -90,7 +90,7 @@ namespace util {
|
|||||||
{
|
{
|
||||||
auto remain = src;
|
auto remain = src;
|
||||||
while (!remain.empty ())
|
while (!remain.empty ())
|
||||||
remain = src - dst.write (remain);
|
remain = remain.consume (dst.write (remain));
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
io_posix.hpp
34
io_posix.hpp
@ -31,6 +31,14 @@ namespace util {
|
|||||||
namespace detail::posix {
|
namespace detail::posix {
|
||||||
class mapped_file {
|
class mapped_file {
|
||||||
public:
|
public:
|
||||||
|
using value_type = uint8_t;
|
||||||
|
using reference = value_type&;
|
||||||
|
using const_reference = const value_type&;
|
||||||
|
using iterator = value_type*;
|
||||||
|
using const_iterator = const value_type*;
|
||||||
|
using difference_type = std::iterator_traits<iterator>::difference_type;
|
||||||
|
using size_type = size_t;
|
||||||
|
|
||||||
mapped_file (const std::experimental::filesystem::path&,
|
mapped_file (const std::experimental::filesystem::path&,
|
||||||
int fflags = O_RDONLY | O_BINARY,
|
int fflags = O_RDONLY | O_BINARY,
|
||||||
int mflags = PROT_READ);
|
int mflags = PROT_READ);
|
||||||
@ -50,27 +58,19 @@ namespace util {
|
|||||||
/// often use this in conjunction with sizeof and packed structure.
|
/// often use this in conjunction with sizeof and packed structure.
|
||||||
/// it is greatly simpler to cast to signed where it's actually
|
/// it is greatly simpler to cast to signed where it's actually
|
||||||
/// required rather than the other way around.
|
/// required rather than the other way around.
|
||||||
size_t size (void) const;
|
size_type size (void) const;
|
||||||
|
|
||||||
const uint8_t* data (void) const &;
|
const_iterator data (void) const &;
|
||||||
uint8_t* data (void) &;
|
iterator data (void) &;
|
||||||
|
|
||||||
uint8_t* begin (void) &;
|
iterator begin (void) &;
|
||||||
uint8_t* end (void) &;
|
iterator end (void) &;
|
||||||
|
|
||||||
const uint8_t* begin (void) const &;
|
const_iterator begin (void) const &;
|
||||||
const uint8_t* end (void) const &;
|
const_iterator end (void) const &;
|
||||||
|
|
||||||
const uint8_t* cbegin (void) const &;
|
const_iterator cbegin (void) const &;
|
||||||
const uint8_t* cend (void) const &;
|
const_iterator cend (void) const &;
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
util::view<std::add_const_t<T>*>
|
|
||||||
as_view () const &;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
util::view<T*>
|
|
||||||
as_view () &;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t *m_data;
|
uint8_t *m_data;
|
||||||
|
24
io_posix.ipp
24
io_posix.ipp
@ -21,27 +21,3 @@
|
|||||||
#define __UTIL_IO_POSIX_IPP
|
#define __UTIL_IO_POSIX_IPP
|
||||||
|
|
||||||
#include "pointer.hpp"
|
#include "pointer.hpp"
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
util::view<std::add_const_t<T>*>
|
|
||||||
util::detail::posix::mapped_file::as_view (void) const&
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
reinterpret_cast<const T*> (cbegin ()),
|
|
||||||
reinterpret_cast<const T*> (align (cend (), alignof (T)))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <typename T>
|
|
||||||
util::view<T*>
|
|
||||||
util::detail::posix::mapped_file::as_view (void) &
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
reinterpret_cast<T *> (begin ()),
|
|
||||||
reinterpret_cast<T *> (align (end (), alignof(T)))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
69
iterator.hpp
69
iterator.hpp
@ -516,6 +516,75 @@ namespace util {
|
|||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename OutputIt, typename FunctionT>
|
||||||
|
OutputIt
|
||||||
|
_transform_by_block (
|
||||||
|
const util::view<OutputIt> &,
|
||||||
|
OutputIt cursor,
|
||||||
|
FunctionT &&
|
||||||
|
) {
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
template <typename OutputIt, typename FunctionT, typename InputT, typename ...TailT>
|
||||||
|
OutputIt
|
||||||
|
_transform_by_block (
|
||||||
|
const util::view<OutputIt> &dst,
|
||||||
|
OutputIt cursor,
|
||||||
|
FunctionT &&func,
|
||||||
|
const InputT &_src,
|
||||||
|
TailT &&...tail
|
||||||
|
) {
|
||||||
|
auto remain = _src;
|
||||||
|
if (cursor != dst.begin ()) {
|
||||||
|
auto infill = std::distance (cursor, dst.end ());
|
||||||
|
if (remain.size () < static_cast<size_t> (infill)) {
|
||||||
|
return _transform_by_block (
|
||||||
|
dst,
|
||||||
|
std::copy_n (remain.begin (), remain.size (), cursor),
|
||||||
|
std::forward<FunctionT> (func),
|
||||||
|
std::forward<TailT> (tail)...
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::copy_n (remain.begin (), infill, cursor);
|
||||||
|
func (dst);
|
||||||
|
cursor = dst.begin ();
|
||||||
|
remain = { remain.begin () + infill, remain.end () };
|
||||||
|
}
|
||||||
|
|
||||||
|
while (remain.size () >= dst.size ()) {
|
||||||
|
std::copy_n (remain.begin (), dst.size (), dst.begin ());
|
||||||
|
func (dst);
|
||||||
|
remain = { remain.begin () + dst.size (), remain.end () };
|
||||||
|
}
|
||||||
|
|
||||||
|
return _transform_by_block (
|
||||||
|
dst,
|
||||||
|
std::copy (remain.begin (), remain.end (), cursor),
|
||||||
|
std::forward<FunctionT> (func),
|
||||||
|
std::forward<TailT> (tail)...
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
template <typename OutputIt, typename FunctionT, typename ...Args>
|
||||||
|
OutputIt
|
||||||
|
transform_by_block (const util::view<OutputIt> &dst, FunctionT &&func, Args &&...src)
|
||||||
|
{
|
||||||
|
return _transform_by_block (
|
||||||
|
dst,
|
||||||
|
dst.begin (),
|
||||||
|
std::forward<FunctionT> (func),
|
||||||
|
std::forward<Args> (src)...
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -52,7 +52,8 @@ namespace json::flat {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector<item<T>> parse (util::view<T> data);
|
std::vector<item<T>>
|
||||||
|
parse (util::view<T> data);
|
||||||
|
|
||||||
std::ostream& operator<< (std::ostream&, type);
|
std::ostream& operator<< (std::ostream&, type);
|
||||||
}
|
}
|
||||||
|
@ -535,6 +535,6 @@ json::schema::validate (json::tree::node &data,
|
|||||||
const std::experimental::filesystem::path &schema_path)
|
const std::experimental::filesystem::path &schema_path)
|
||||||
{
|
{
|
||||||
const util::mapped_file schema_data (schema_path);
|
const util::mapped_file schema_data (schema_path);
|
||||||
auto schema_object = json::tree::parse (schema_data.as_view<char> ());
|
auto schema_object = json::tree::parse (util::view{schema_data}.cast<const char> ());
|
||||||
validate (data, schema_object->as_object ());
|
validate (data, schema_object->as_object ());
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ parse (typename std::vector<json::flat::item<T>>::const_iterator first,
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::unique_ptr<json::tree::node>
|
std::unique_ptr<json::tree::node>
|
||||||
json::tree::parse (const util::view<T> src)
|
json::tree::parse (const util::view<T> &src)
|
||||||
{
|
{
|
||||||
std::unique_ptr<json::tree::node> output;
|
std::unique_ptr<json::tree::node> output;
|
||||||
auto data = json::flat::parse (src);
|
auto data = json::flat::parse (src);
|
||||||
@ -225,7 +225,7 @@ json::tree::parse (const util::view<T> src)
|
|||||||
#define INSTANTIATE(KLASS) \
|
#define INSTANTIATE(KLASS) \
|
||||||
template \
|
template \
|
||||||
std::unique_ptr<json::tree::node> \
|
std::unique_ptr<json::tree::node> \
|
||||||
json::tree::parse (util::view<KLASS>);
|
json::tree::parse (const util::view<KLASS>&);
|
||||||
|
|
||||||
MAP0(INSTANTIATE,
|
MAP0(INSTANTIATE,
|
||||||
std::string::iterator,
|
std::string::iterator,
|
||||||
@ -244,7 +244,7 @@ std::unique_ptr<json::tree::node>
|
|||||||
json::tree::parse (const std::experimental::filesystem::path &src)
|
json::tree::parse (const std::experimental::filesystem::path &src)
|
||||||
{
|
{
|
||||||
const util::mapped_file data (src);
|
const util::mapped_file data (src);
|
||||||
return parse (data.as_view<char> ());
|
return parse (util::view{data}.cast<const char> ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -443,6 +443,15 @@ namespace json::tree {
|
|||||||
{
|
{
|
||||||
return static_cast<int64_t> (as_sint ());
|
return static_cast<int64_t> (as_sint ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
template <>
|
||||||
|
const std::string&
|
||||||
|
json::tree::node::as (void) const
|
||||||
|
{
|
||||||
|
return as_string ().native ();
|
||||||
|
}
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
@ -46,7 +46,7 @@ namespace json::tree {
|
|||||||
/// Parse an encoded form of JSON into a tree structure
|
/// Parse an encoded form of JSON into a tree structure
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::unique_ptr<node>
|
std::unique_ptr<node>
|
||||||
parse (util::view<T> data);
|
parse (const util::view<T> &data);
|
||||||
|
|
||||||
std::unique_ptr<node>
|
std::unique_ptr<node>
|
||||||
parse (const std::experimental::filesystem::path &);
|
parse (const std::experimental::filesystem::path &);
|
||||||
|
@ -225,7 +225,7 @@ namespace util {
|
|||||||
typename BaseT,
|
typename BaseT,
|
||||||
typename ExponentT,
|
typename ExponentT,
|
||||||
typename = std::enable_if_t<
|
typename = std::enable_if_t<
|
||||||
std::is_unsigned_v<ExponentT>,
|
std::is_integral_v<ExponentT>,
|
||||||
void
|
void
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
|
42
stringid.hpp
42
stringid.hpp
@ -11,11 +11,13 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright 2014 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2014-2018 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __UTIL_STRINGID_HPP
|
#ifndef CRUFT_UTIL_STRINGID_HPP
|
||||||
#define __UTIL_STRINGID_HPP
|
#define CRUFT_UTIL_STRINGID_HPP
|
||||||
|
|
||||||
|
#include "view.hpp"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -25,11 +27,45 @@ namespace util {
|
|||||||
public:
|
public:
|
||||||
typedef size_t id_t;
|
typedef size_t id_t;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
id_t add (std::string);
|
id_t add (std::string);
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
template <typename T>
|
||||||
|
id_t add (util::view<T> key)
|
||||||
|
{
|
||||||
|
return add (
|
||||||
|
std::string{
|
||||||
|
std::cbegin (key),
|
||||||
|
std::cend (key)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
id_t find (const std::string&) const;
|
id_t find (const std::string&) const;
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
template <typename T>
|
||||||
|
id_t find (util::view<T> key) const
|
||||||
|
{
|
||||||
|
return find (
|
||||||
|
std::string {
|
||||||
|
std::cbegin (key),
|
||||||
|
std::cend (key)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
void clear (void);
|
void clear (void);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<const std::string, id_t> m_map;
|
std::map<const std::string, id_t> m_map;
|
||||||
};
|
};
|
||||||
|
@ -1,395 +0,0 @@
|
|||||||
#include "crypto/arc4.hpp"
|
|
||||||
|
|
||||||
#include "debug.hpp"
|
|
||||||
#include "tap.hpp"
|
|
||||||
#include "types.hpp"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
util::TAP::logger tap;
|
|
||||||
|
|
||||||
// Test vectors from RFC 6229.
|
|
||||||
static const size_t OFFSETS[] = {
|
|
||||||
0, 16, 240, 256, 496, 512, 752, 768, 1008, 1024, 1520, 1536, 2032, 2048, 3056, 3072, 4080, 4096
|
|
||||||
};
|
|
||||||
|
|
||||||
struct {
|
|
||||||
std::vector<uint8_t> key;
|
|
||||||
const uint64_t data[std::size (OFFSETS)][16];
|
|
||||||
} TESTS[] = {
|
|
||||||
{
|
|
||||||
{ 1, 2, 3, 4, 5 },
|
|
||||||
{
|
|
||||||
{ 0xb2, 0x39, 0x63, 0x05, 0xf0, 0x3d, 0xc0, 0x27, 0xcc, 0xc3, 0x52, 0x4a, 0x0a, 0x11, 0x18, 0xa8 },
|
|
||||||
{ 0x69, 0x82, 0x94, 0x4f, 0x18, 0xfc, 0x82, 0xd5, 0x89, 0xc4, 0x03, 0xa4, 0x7a, 0x0d, 0x09, 0x19 },
|
|
||||||
{ 0x28, 0xcb, 0x11, 0x32, 0xc9, 0x6c, 0xe2, 0x86, 0x42, 0x1d, 0xca, 0xad, 0xb8, 0xb6, 0x9e, 0xae },
|
|
||||||
{ 0x1c, 0xfc, 0xf6, 0x2b, 0x03, 0xed, 0xdb, 0x64, 0x1d, 0x77, 0xdf, 0xcf, 0x7f, 0x8d, 0x8c, 0x93 },
|
|
||||||
{ 0x42, 0xb7, 0xd0, 0xcd, 0xd9, 0x18, 0xa8, 0xa3, 0x3d, 0xd5, 0x17, 0x81, 0xc8, 0x1f, 0x40, 0x41 },
|
|
||||||
{ 0x64, 0x59, 0x84, 0x44, 0x32, 0xa7, 0xda, 0x92, 0x3c, 0xfb, 0x3e, 0xb4, 0x98, 0x06, 0x61, 0xf6 },
|
|
||||||
{ 0xec, 0x10, 0x32, 0x7b, 0xde, 0x2b, 0xee, 0xfd, 0x18, 0xf9, 0x27, 0x76, 0x80, 0x45, 0x7e, 0x22 },
|
|
||||||
{ 0xeb, 0x62, 0x63, 0x8d, 0x4f, 0x0b, 0xa1, 0xfe, 0x9f, 0xca, 0x20, 0xe0, 0x5b, 0xf8, 0xff, 0x2b },
|
|
||||||
{ 0x45, 0x12, 0x90, 0x48, 0xe6, 0xa0, 0xed, 0x0b, 0x56, 0xb4, 0x90, 0x33, 0x8f, 0x07, 0x8d, 0xa5 },
|
|
||||||
{ 0x30, 0xab, 0xbc, 0xc7, 0xc2, 0x0b, 0x01, 0x60, 0x9f, 0x23, 0xee, 0x2d, 0x5f, 0x6b, 0xb7, 0xdf },
|
|
||||||
{ 0x32, 0x94, 0xf7, 0x44, 0xd8, 0xf9, 0x79, 0x05, 0x07, 0xe7, 0x0f, 0x62, 0xe5, 0xbb, 0xce, 0xea },
|
|
||||||
{ 0xd8, 0x72, 0x9d, 0xb4, 0x18, 0x82, 0x25, 0x9b, 0xee, 0x4f, 0x82, 0x53, 0x25, 0xf5, 0xa1, 0x30 },
|
|
||||||
{ 0x1e, 0xb1, 0x4a, 0x0c, 0x13, 0xb3, 0xbf, 0x47, 0xfa, 0x2a, 0x0b, 0xa9, 0x3a, 0xd4, 0x5b, 0x8b },
|
|
||||||
{ 0xcc, 0x58, 0x2f, 0x8b, 0xa9, 0xf2, 0x65, 0xe2, 0xb1, 0xbe, 0x91, 0x12, 0xe9, 0x75, 0xd2, 0xd7 },
|
|
||||||
{ 0xf2, 0xe3, 0x0f, 0x9b, 0xd1, 0x02, 0xec, 0xbf, 0x75, 0xaa, 0xad, 0xe9, 0xbc, 0x35, 0xc4, 0x3c },
|
|
||||||
{ 0xec, 0x0e, 0x11, 0xc4, 0x79, 0xdc, 0x32, 0x9d, 0xc8, 0xda, 0x79, 0x68, 0xfe, 0x96, 0x56, 0x81 },
|
|
||||||
{ 0x06, 0x83, 0x26, 0xa2, 0x11, 0x84, 0x16, 0xd2, 0x1f, 0x9d, 0x04, 0xb2, 0xcd, 0x1c, 0xa0, 0x50 },
|
|
||||||
{ 0xff, 0x25, 0xb5, 0x89, 0x95, 0x99, 0x67, 0x07, 0xe5, 0x1f, 0xbd, 0xf0, 0x8b, 0x34, 0xd8, 0x75 },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
|
|
||||||
{
|
|
||||||
{ 0x29, 0x3f, 0x02, 0xd4, 0x7f, 0x37, 0xc9, 0xb6, 0x33, 0xf2, 0xaf, 0x52, 0x85, 0xfe, 0xb4, 0x6b },
|
|
||||||
{ 0xe6, 0x20, 0xf1, 0x39, 0x0d, 0x19, 0xbd, 0x84, 0xe2, 0xe0, 0xfd, 0x75, 0x20, 0x31, 0xaf, 0xc1 },
|
|
||||||
{ 0x91, 0x4f, 0x02, 0x53, 0x1c, 0x92, 0x18, 0x81, 0x0d, 0xf6, 0x0f, 0x67, 0xe3, 0x38, 0x15, 0x4c },
|
|
||||||
{ 0xd0, 0xfd, 0xb5, 0x83, 0x07, 0x3c, 0xe8, 0x5a, 0xb8, 0x39, 0x17, 0x74, 0x0e, 0xc0, 0x11, 0xd5 },
|
|
||||||
{ 0x75, 0xf8, 0x14, 0x11, 0xe8, 0x71, 0xcf, 0xfa, 0x70, 0xb9, 0x0c, 0x74, 0xc5, 0x92, 0xe4, 0x54 },
|
|
||||||
{ 0x0b, 0xb8, 0x72, 0x02, 0x93, 0x8d, 0xad, 0x60, 0x9e, 0x87, 0xa5, 0xa1, 0xb0, 0x79, 0xe5, 0xe4 },
|
|
||||||
{ 0xc2, 0x91, 0x12, 0x46, 0xb6, 0x12, 0xe7, 0xe7, 0xb9, 0x03, 0xdf, 0xed, 0xa1, 0xda, 0xd8, 0x66 },
|
|
||||||
{ 0x32, 0x82, 0x8f, 0x91, 0x50, 0x2b, 0x62, 0x91, 0x36, 0x8d, 0xe8, 0x08, 0x1d, 0xe3, 0x6f, 0xc2 },
|
|
||||||
{ 0xf3, 0xb9, 0xa7, 0xe3, 0xb2, 0x97, 0xbf, 0x9a, 0xd8, 0x04, 0x51, 0x2f, 0x90, 0x63, 0xef, 0xf1 },
|
|
||||||
{ 0x8e, 0xcb, 0x67, 0xa9, 0xba, 0x1f, 0x55, 0xa5, 0xa0, 0x67, 0xe2, 0xb0, 0x26, 0xa3, 0x67, 0x6f },
|
|
||||||
{ 0xd2, 0xaa, 0x90, 0x2b, 0xd4, 0x2d, 0x0d, 0x7c, 0xfd, 0x34, 0x0c, 0xd4, 0x58, 0x10, 0x52, 0x9f },
|
|
||||||
{ 0x78, 0xb2, 0x72, 0xc9, 0x6e, 0x42, 0xea, 0xb4, 0xc6, 0x0b, 0xd9, 0x14, 0xe3, 0x9d, 0x06, 0xe3 },
|
|
||||||
{ 0xf4, 0x33, 0x2f, 0xd3, 0x1a, 0x07, 0x93, 0x96, 0xee, 0x3c, 0xee, 0x3f, 0x2a, 0x4f, 0xf0, 0x49 },
|
|
||||||
{ 0x05, 0x45, 0x97, 0x81, 0xd4, 0x1f, 0xda, 0x7f, 0x30, 0xc1, 0xbe, 0x7e, 0x12, 0x46, 0xc6, 0x23 },
|
|
||||||
{ 0xad, 0xfd, 0x38, 0x68, 0xb8, 0xe5, 0x14, 0x85, 0xd5, 0xe6, 0x10, 0x01, 0x7e, 0x3d, 0xd6, 0x09 },
|
|
||||||
{ 0xad, 0x26, 0x58, 0x1c, 0x0c, 0x5b, 0xe4, 0x5f, 0x4c, 0xea, 0x01, 0xdb, 0x2f, 0x38, 0x05, 0xd5 },
|
|
||||||
{ 0xf3, 0x17, 0x2c, 0xef, 0xfc, 0x3b, 0x3d, 0x99, 0x7c, 0x85, 0xcc, 0xd5, 0xaf, 0x1a, 0x95, 0x0c },
|
|
||||||
{ 0xe7, 0x4b, 0x0b, 0x97, 0x31, 0x22, 0x7f, 0xd3, 0x7c, 0x0e, 0xc0, 0x8a, 0x47, 0xdd, 0xd8, 0xb8 },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
|
|
||||||
{
|
|
||||||
{ 0x97, 0xab, 0x8a, 0x1b, 0xf0, 0xaf, 0xb9, 0x61, 0x32, 0xf2, 0xf6, 0x72, 0x58, 0xda, 0x15, 0xa8 },
|
|
||||||
{ 0x82, 0x63, 0xef, 0xdb, 0x45, 0xc4, 0xa1, 0x86, 0x84, 0xef, 0x87, 0xe6, 0xb1, 0x9e, 0x5b, 0x09 },
|
|
||||||
{ 0x96, 0x36, 0xeb, 0xc9, 0x84, 0x19, 0x26, 0xf4, 0xf7, 0xd1, 0xf3, 0x62, 0xbd, 0xdf, 0x6e, 0x18 },
|
|
||||||
{ 0xd0, 0xa9, 0x90, 0xff, 0x2c, 0x05, 0xfe, 0xf5, 0xb9, 0x03, 0x73, 0xc9, 0xff, 0x4b, 0x87, 0x0a },
|
|
||||||
{ 0x73, 0x23, 0x9f, 0x1d, 0xb7, 0xf4, 0x1d, 0x80, 0xb6, 0x43, 0xc0, 0xc5, 0x25, 0x18, 0xec, 0x63 },
|
|
||||||
{ 0x16, 0x3b, 0x31, 0x99, 0x23, 0xa6, 0xbd, 0xb4, 0x52, 0x7c, 0x62, 0x61, 0x26, 0x70, 0x3c, 0x0f },
|
|
||||||
{ 0x49, 0xd6, 0xc8, 0xaf, 0x0f, 0x97, 0x14, 0x4a, 0x87, 0xdf, 0x21, 0xd9, 0x14, 0x72, 0xf9, 0x66 },
|
|
||||||
{ 0x44, 0x17, 0x3a, 0x10, 0x3b, 0x66, 0x16, 0xc5, 0xd5, 0xad, 0x1c, 0xee, 0x40, 0xc8, 0x63, 0xd0 },
|
|
||||||
{ 0x27, 0x3c, 0x9c, 0x4b, 0x27, 0xf3, 0x22, 0xe4, 0xe7, 0x16, 0xef, 0x53, 0xa4, 0x7d, 0xe7, 0xa4 },
|
|
||||||
{ 0xc6, 0xd0, 0xe7, 0xb2, 0x26, 0x25, 0x9f, 0xa9, 0x02, 0x34, 0x90, 0xb2, 0x61, 0x67, 0xad, 0x1d },
|
|
||||||
{ 0x1f, 0xe8, 0x98, 0x67, 0x13, 0xf0, 0x7c, 0x3d, 0x9a, 0xe1, 0xc1, 0x63, 0xff, 0x8c, 0xf9, 0xd3 },
|
|
||||||
{ 0x83, 0x69, 0xe1, 0xa9, 0x65, 0x61, 0x0b, 0xe8, 0x87, 0xfb, 0xd0, 0xc7, 0x91, 0x62, 0xaa, 0xfb },
|
|
||||||
{ 0x0a, 0x01, 0x27, 0xab, 0xb4, 0x44, 0x84, 0xb9, 0xfb, 0xef, 0x5a, 0xbc, 0xae, 0x1b, 0x57, 0x9f },
|
|
||||||
{ 0xc2, 0xcd, 0xad, 0xc6, 0x40, 0x2e, 0x8e, 0xe8, 0x66, 0xe1, 0xf3, 0x7b, 0xdb, 0x47, 0xe4, 0x2c },
|
|
||||||
{ 0x26, 0xb5, 0x1e, 0xa3, 0x7d, 0xf8, 0xe1, 0xd6, 0xf7, 0x6f, 0xc3, 0xb6, 0x6a, 0x74, 0x29, 0xb3 },
|
|
||||||
{ 0xbc, 0x76, 0x83, 0x20, 0x5d, 0x4f, 0x44, 0x3d, 0xc1, 0xf2, 0x9d, 0xda, 0x33, 0x15, 0xc8, 0x7b },
|
|
||||||
{ 0xd5, 0xfa, 0x5a, 0x34, 0x69, 0xd2, 0x9a, 0xaa, 0xf8, 0x3d, 0x23, 0x58, 0x9d, 0xb8, 0xc8, 0x5b },
|
|
||||||
{ 0x3f, 0xb4, 0x6e, 0x2c, 0x8f, 0x0f, 0x06, 0x8e, 0xdc, 0xe8, 0xcd, 0xcd, 0x7d, 0xfc, 0x58, 0x62 },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a },
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0xed, 0xe3, 0xb0, 0x46, 0x43, 0xe5, 0x86, 0xcc, 0x90, 0x7d, 0xc2, 0x18, 0x51, 0x70, 0x99, 0x02, },
|
|
||||||
{ 0x03, 0x51, 0x6b, 0xa7, 0x8f, 0x41, 0x3b, 0xeb, 0x22, 0x3a, 0xa5, 0xd4, 0xd2, 0xdf, 0x67, 0x11, },
|
|
||||||
{ 0x3c, 0xfd, 0x6c, 0xb5, 0x8e, 0xe0, 0xfd, 0xde, 0x64, 0x01, 0x76, 0xad, 0x00, 0x00, 0x04, 0x4d, },
|
|
||||||
{ 0x48, 0x53, 0x2b, 0x21, 0xfb, 0x60, 0x79, 0xc9, 0x11, 0x4c, 0x0f, 0xfd, 0x9c, 0x04, 0xa1, 0xad, },
|
|
||||||
{ 0x3e, 0x8c, 0xea, 0x98, 0x01, 0x71, 0x09, 0x97, 0x90, 0x84, 0xb1, 0xef, 0x92, 0xf9, 0x9d, 0x86, },
|
|
||||||
{ 0xe2, 0x0f, 0xb4, 0x9b, 0xdb, 0x33, 0x7e, 0xe4, 0x8b, 0x8d, 0x8d, 0xc0, 0xf4, 0xaf, 0xef, 0xfe, },
|
|
||||||
{ 0x5c, 0x25, 0x21, 0xea, 0xcd, 0x79, 0x66, 0xf1, 0x5e, 0x05, 0x65, 0x44, 0xbe, 0xa0, 0xd3, 0x15, },
|
|
||||||
{ 0xe0, 0x67, 0xa7, 0x03, 0x19, 0x31, 0xa2, 0x46, 0xa6, 0xc3, 0x87, 0x5d, 0x2f, 0x67, 0x8a, 0xcb, },
|
|
||||||
{ 0xa6, 0x4f, 0x70, 0xaf, 0x88, 0xae, 0x56, 0xb6, 0xf8, 0x75, 0x81, 0xc0, 0xe2, 0x3e, 0x6b, 0x08, },
|
|
||||||
{ 0xf4, 0x49, 0x03, 0x1d, 0xe3, 0x12, 0x81, 0x4e, 0xc6, 0xf3, 0x19, 0x29, 0x1f, 0x4a, 0x05, 0x16, },
|
|
||||||
{ 0xbd, 0xae, 0x85, 0x92, 0x4b, 0x3c, 0xb1, 0xd0, 0xa2, 0xe3, 0x3a, 0x30, 0xc6, 0xd7, 0x95, 0x99, },
|
|
||||||
{ 0x8a, 0x0f, 0xed, 0xdb, 0xac, 0x86, 0x5a, 0x09, 0xbc, 0xd1, 0x27, 0xfb, 0x56, 0x2e, 0xd6, 0x0a, },
|
|
||||||
{ 0xb5, 0x5a, 0x0a, 0x5b, 0x51, 0xa1, 0x2a, 0x8b, 0xe3, 0x48, 0x99, 0xc3, 0xe0, 0x47, 0x51, 0x1a, },
|
|
||||||
{ 0xd9, 0xa0, 0x9c, 0xea, 0x3c, 0xe7, 0x5f, 0xe3, 0x96, 0x98, 0x07, 0x03, 0x17, 0xa7, 0x13, 0x39, },
|
|
||||||
{ 0x55, 0x22, 0x25, 0xed, 0x11, 0x77, 0xf4, 0x45, 0x84, 0xac, 0x8c, 0xfa, 0x6c, 0x4e, 0xb5, 0xfc, },
|
|
||||||
{ 0x7e, 0x82, 0xcb, 0xab, 0xfc, 0x95, 0x38, 0x1b, 0x08, 0x09, 0x98, 0x44, 0x21, 0x29, 0xc2, 0xf8, },
|
|
||||||
{ 0x1f, 0x13, 0x5e, 0xd1, 0x4c, 0xe6, 0x0a, 0x91, 0x36, 0x9d, 0x23, 0x22, 0xbe, 0xf2, 0x5e, 0x3c, },
|
|
||||||
{ 0x08, 0xb6, 0xbe, 0x45, 0x12, 0x4a, 0x43, 0xe2, 0xeb, 0x77, 0x95, 0x3f, 0x84, 0xdc, 0x85, 0x53, },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x9a, 0xc7, 0xcc, 0x9a, 0x60, 0x9d, 0x1e, 0xf7, 0xb2, 0x93, 0x28, 0x99, 0xcd, 0xe4, 0x1b, 0x97, },
|
|
||||||
{ 0x52, 0x48, 0xc4, 0x95, 0x90, 0x14, 0x12, 0x6a, 0x6e, 0x8a, 0x84, 0xf1, 0x1d, 0x1a, 0x9e, 0x1c, },
|
|
||||||
{ 0x06, 0x59, 0x02, 0xe4, 0xb6, 0x20, 0xf6, 0xcc, 0x36, 0xc8, 0x58, 0x9f, 0x66, 0x43, 0x2f, 0x2b, },
|
|
||||||
{ 0xd3, 0x9d, 0x56, 0x6b, 0xc6, 0xbc, 0xe3, 0x01, 0x07, 0x68, 0x15, 0x15, 0x49, 0xf3, 0x87, 0x3f, },
|
|
||||||
{ 0xb6, 0xd1, 0xe6, 0xc4, 0xa5, 0xe4, 0x77, 0x1c, 0xad, 0x79, 0x53, 0x8d, 0xf2, 0x95, 0xfb, 0x11, },
|
|
||||||
{ 0xc6, 0x8c, 0x1d, 0x5c, 0x55, 0x9a, 0x97, 0x41, 0x23, 0xdf, 0x1d, 0xbc, 0x52, 0xa4, 0x3b, 0x89, },
|
|
||||||
{ 0xc5, 0xec, 0xf8, 0x8d, 0xe8, 0x97, 0xfd, 0x57, 0xfe, 0xd3, 0x01, 0x70, 0x1b, 0x82, 0xa2, 0x59, },
|
|
||||||
{ 0xec, 0xcb, 0xe1, 0x3d, 0xe1, 0xfc, 0xc9, 0x1c, 0x11, 0xa0, 0xb2, 0x6c, 0x0b, 0xc8, 0xfa, 0x4d, },
|
|
||||||
{ 0xe7, 0xa7, 0x25, 0x74, 0xf8, 0x78, 0x2a, 0xe2, 0x6a, 0xab, 0xcf, 0x9e, 0xbc, 0xd6, 0x60, 0x65, },
|
|
||||||
{ 0xbd, 0xf0, 0x32, 0x4e, 0x60, 0x83, 0xdc, 0xc6, 0xd3, 0xce, 0xdd, 0x3c, 0xa8, 0xc5, 0x3c, 0x16, },
|
|
||||||
{ 0xb4, 0x01, 0x10, 0xc4, 0x19, 0x0b, 0x56, 0x22, 0xa9, 0x61, 0x16, 0xb0, 0x01, 0x7e, 0xd2, 0x97, },
|
|
||||||
{ 0xff, 0xa0, 0xb5, 0x14, 0x64, 0x7e, 0xc0, 0x4f, 0x63, 0x06, 0xb8, 0x92, 0xae, 0x66, 0x11, 0x81, },
|
|
||||||
{ 0xd0, 0x3d, 0x1b, 0xc0, 0x3c, 0xd3, 0x3d, 0x70, 0xdf, 0xf9, 0xfa, 0x5d, 0x71, 0x96, 0x3e, 0xbd, },
|
|
||||||
{ 0x8a, 0x44, 0x12, 0x64, 0x11, 0xea, 0xa7, 0x8b, 0xd5, 0x1e, 0x8d, 0x87, 0xa8, 0x87, 0x9b, 0xf5, },
|
|
||||||
{ 0xfa, 0xbe, 0xb7, 0x60, 0x28, 0xad, 0xe2, 0xd0, 0xe4, 0x87, 0x22, 0xe4, 0x6c, 0x46, 0x15, 0xa3, },
|
|
||||||
{ 0xc0, 0x5d, 0x88, 0xab, 0xd5, 0x03, 0x57, 0xf9, 0x35, 0xa6, 0x3c, 0x59, 0xee, 0x53, 0x76, 0x23, },
|
|
||||||
{ 0xff, 0x38, 0x26, 0x5c, 0x16, 0x42, 0xc1, 0xab, 0xe8, 0xd3, 0xc2, 0xfe, 0x5e, 0x57, 0x2b, 0xf8, },
|
|
||||||
{ 0xa3, 0x6a, 0x4c, 0x30, 0x1a, 0xe8, 0xac, 0x13, 0x61, 0x0c, 0xcb, 0xc1, 0x22, 0x56, 0xca, 0xcc, },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18 },
|
|
||||||
{
|
|
||||||
{ 0x05, 0x95, 0xe5, 0x7f, 0xe5, 0xf0, 0xbb, 0x3c, 0x70, 0x6e, 0xda, 0xc8, 0xa4, 0xb2, 0xdb, 0x11, },
|
|
||||||
{ 0xdf, 0xde, 0x31, 0x34, 0x4a, 0x1a, 0xf7, 0x69, 0xc7, 0x4f, 0x07, 0x0a, 0xee, 0x9e, 0x23, 0x26, },
|
|
||||||
{ 0xb0, 0x6b, 0x9b, 0x1e, 0x19, 0x5d, 0x13, 0xd8, 0xf4, 0xa7, 0x99, 0x5c, 0x45, 0x53, 0xac, 0x05, },
|
|
||||||
{ 0x6b, 0xd2, 0x37, 0x8e, 0xc3, 0x41, 0xc9, 0xa4, 0x2f, 0x37, 0xba, 0x79, 0xf8, 0x8a, 0x32, 0xff, },
|
|
||||||
{ 0xe7, 0x0b, 0xce, 0x1d, 0xf7, 0x64, 0x5a, 0xdb, 0x5d, 0x2c, 0x41, 0x30, 0x21, 0x5c, 0x35, 0x22, },
|
|
||||||
{ 0x9a, 0x57, 0x30, 0xc7, 0xfc, 0xb4, 0xc9, 0xaf, 0x51, 0xff, 0xda, 0x89, 0xc7, 0xf1, 0xad, 0x22, },
|
|
||||||
{ 0x04, 0x85, 0x05, 0x5f, 0xd4, 0xf6, 0xf0, 0xd9, 0x63, 0xef, 0x5a, 0xb9, 0xa5, 0x47, 0x69, 0x82, },
|
|
||||||
{ 0x59, 0x1f, 0xc6, 0x6b, 0xcd, 0xa1, 0x0e, 0x45, 0x2b, 0x03, 0xd4, 0x55, 0x1f, 0x6b, 0x62, 0xac, },
|
|
||||||
{ 0x27, 0x53, 0xcc, 0x83, 0x98, 0x8a, 0xfa, 0x3e, 0x16, 0x88, 0xa1, 0xd3, 0xb4, 0x2c, 0x9a, 0x02, },
|
|
||||||
{ 0x93, 0x61, 0x0d, 0x52, 0x3d, 0x1d, 0x3f, 0x00, 0x62, 0xb3, 0xc2, 0xa3, 0xbb, 0xc7, 0xc7, 0xf0, },
|
|
||||||
{ 0x96, 0xc2, 0x48, 0x61, 0x0a, 0xad, 0xed, 0xfe, 0xaf, 0x89, 0x78, 0xc0, 0x3d, 0xe8, 0x20, 0x5a, },
|
|
||||||
{ 0x0e, 0x31, 0x7b, 0x3d, 0x1c, 0x73, 0xb9, 0xe9, 0xa4, 0x68, 0x8f, 0x29, 0x6d, 0x13, 0x3a, 0x19, },
|
|
||||||
{ 0xbd, 0xf0, 0xe6, 0xc3, 0xcc, 0xa5, 0xb5, 0xb9, 0xd5, 0x33, 0xb6, 0x9c, 0x56, 0xad, 0xa1, 0x20, },
|
|
||||||
{ 0x88, 0xa2, 0x18, 0xb6, 0xe2, 0xec, 0xe1, 0xe6, 0x24, 0x6d, 0x44, 0xc7, 0x59, 0xd1, 0x9b, 0x10, },
|
|
||||||
{ 0x68, 0x66, 0x39, 0x7e, 0x95, 0xc1, 0x40, 0x53, 0x4f, 0x94, 0x26, 0x34, 0x21, 0x00, 0x6e, 0x40, },
|
|
||||||
{ 0x32, 0xcb, 0x0a, 0x1e, 0x95, 0x42, 0xc6, 0xb3, 0xb8, 0xb3, 0x98, 0xab, 0xc3, 0xb0, 0xf1, 0xd5, },
|
|
||||||
{ 0x29, 0xa0, 0xb8, 0xae, 0xd5, 0x4a, 0x13, 0x23, 0x24, 0xc6, 0x2e, 0x42, 0x3f, 0x54, 0xb4, 0xc8, },
|
|
||||||
{ 0x3c, 0xb0, 0xf3, 0xb5, 0x02, 0x0a, 0x98, 0xb8, 0x2a, 0xf9, 0xfe, 0x15, 0x44, 0x84, 0xa1, 0x68, },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20 },
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0xea, 0xa6, 0xbd, 0x25, 0x88, 0x0b, 0xf9, 0x3d, 0x3f, 0x5d, 0x1e, 0x4c, 0xa2, 0x61, 0x1d, 0x91, },
|
|
||||||
{ 0xcf, 0xa4, 0x5c, 0x9f, 0x7e, 0x71, 0x4b, 0x54, 0xbd, 0xfa, 0x80, 0x02, 0x7c, 0xb1, 0x43, 0x80, },
|
|
||||||
{ 0x11, 0x4a, 0xe3, 0x44, 0xde, 0xd7, 0x1b, 0x35, 0xf2, 0xe6, 0x0f, 0xeb, 0xad, 0x72, 0x7f, 0xd8, },
|
|
||||||
{ 0x02, 0xe1, 0xe7, 0x05, 0x6b, 0x0f, 0x62, 0x39, 0x00, 0x49, 0x64, 0x22, 0x94, 0x3e, 0x97, 0xb6, },
|
|
||||||
{ 0x91, 0xcb, 0x93, 0xc7, 0x87, 0x96, 0x4e, 0x10, 0xd9, 0x52, 0x7d, 0x99, 0x9c, 0x6f, 0x93, 0x6b, },
|
|
||||||
{ 0x49, 0xb1, 0x8b, 0x42, 0xf8, 0xe8, 0x36, 0x7c, 0xbe, 0xb5, 0xef, 0x10, 0x4b, 0xa1, 0xc7, 0xcd, },
|
|
||||||
{ 0x87, 0x08, 0x4b, 0x3b, 0xa7, 0x00, 0xba, 0xde, 0x95, 0x56, 0x10, 0x67, 0x27, 0x45, 0xb3, 0x74, },
|
|
||||||
{ 0xe7, 0xa7, 0xb9, 0xe9, 0xec, 0x54, 0x0d, 0x5f, 0xf4, 0x3b, 0xdb, 0x12, 0x79, 0x2d, 0x1b, 0x35, },
|
|
||||||
{ 0xc7, 0x99, 0xb5, 0x96, 0x73, 0x8f, 0x6b, 0x01, 0x8c, 0x76, 0xc7, 0x4b, 0x17, 0x59, 0xbd, 0x90, },
|
|
||||||
{ 0x7f, 0xec, 0x5b, 0xfd, 0x9f, 0x9b, 0x89, 0xce, 0x65, 0x48, 0x30, 0x90, 0x92, 0xd7, 0xe9, 0x58, },
|
|
||||||
{ 0x40, 0xf2, 0x50, 0xb2, 0x6d, 0x1f, 0x09, 0x6a, 0x4a, 0xfd, 0x4c, 0x34, 0x0a, 0x58, 0x88, 0x15, },
|
|
||||||
{ 0x3e, 0x34, 0x13, 0x5c, 0x79, 0xdb, 0x01, 0x02, 0x00, 0x76, 0x76, 0x51, 0xcf, 0x26, 0x30, 0x73, },
|
|
||||||
{ 0xf6, 0x56, 0xab, 0xcc, 0xf8, 0x8d, 0xd8, 0x27, 0x02, 0x7b, 0x2c, 0xe9, 0x17, 0xd4, 0x64, 0xec, },
|
|
||||||
{ 0x18, 0xb6, 0x25, 0x03, 0xbf, 0xbc, 0x07, 0x7f, 0xba, 0xbb, 0x98, 0xf2, 0x0d, 0x98, 0xab, 0x34, },
|
|
||||||
{ 0x8a, 0xed, 0x95, 0xee, 0x5b, 0x0d, 0xcb, 0xfb, 0xef, 0x4e, 0xb2, 0x1d, 0x3a, 0x3f, 0x52, 0xf9, },
|
|
||||||
{ 0x62, 0x5a, 0x1a, 0xb0, 0x0e, 0xe3, 0x9a, 0x53, 0x27, 0x34, 0x6b, 0xdd, 0xb0, 0x1a, 0x9c, 0x18, },
|
|
||||||
{ 0xa1, 0x3a, 0x7c, 0x79, 0xc7, 0xe1, 0x19, 0xb5, 0xab, 0x02, 0x96, 0xab, 0x28, 0xc3, 0x00, 0xb9, },
|
|
||||||
{ 0xf3, 0xe4, 0xc0, 0xa2, 0xe0, 0x2d, 0x1d, 0x01, 0xf7, 0xf0, 0xa7, 0x46, 0x18, 0xaf, 0x2b, 0x48, },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x83, 0x32, 0x22, 0x77, 0x2a },
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x80, 0xad, 0x97, 0xbd, 0xc9, 0x73, 0xdf, 0x8a, 0x2e, 0x87, 0x9e, 0x92, 0xa4, 0x97, 0xef, 0xda, },
|
|
||||||
{ 0x20, 0xf0, 0x60, 0xc2, 0xf2, 0xe5, 0x12, 0x65, 0x01, 0xd3, 0xd4, 0xfe, 0xa1, 0x0d, 0x5f, 0xc0, },
|
|
||||||
{ 0xfa, 0xa1, 0x48, 0xe9, 0x90, 0x46, 0x18, 0x1f, 0xec, 0x6b, 0x20, 0x85, 0xf3, 0xb2, 0x0e, 0xd9, },
|
|
||||||
{ 0xf0, 0xda, 0xf5, 0xba, 0xb3, 0xd5, 0x96, 0x83, 0x98, 0x57, 0x84, 0x6f, 0x73, 0xfb, 0xfe, 0x5a, },
|
|
||||||
{ 0x1c, 0x7e, 0x2f, 0xc4, 0x63, 0x92, 0x32, 0xfe, 0x29, 0x75, 0x84, 0xb2, 0x96, 0x99, 0x6b, 0xc8, },
|
|
||||||
{ 0x3d, 0xb9, 0xb2, 0x49, 0x40, 0x6c, 0xc8, 0xed, 0xff, 0xac, 0x55, 0xcc, 0xd3, 0x22, 0xba, 0x12, },
|
|
||||||
{ 0xe4, 0xf9, 0xf7, 0xe0, 0x06, 0x61, 0x54, 0xbb, 0xd1, 0x25, 0xb7, 0x45, 0x56, 0x9b, 0xc8, 0x97, },
|
|
||||||
{ 0x75, 0xd5, 0xef, 0x26, 0x2b, 0x44, 0xc4, 0x1a, 0x9c, 0xf6, 0x3a, 0xe1, 0x45, 0x68, 0xe1, 0xb9, },
|
|
||||||
{ 0x6d, 0xa4, 0x53, 0xdb, 0xf8, 0x1e, 0x82, 0x33, 0x4a, 0x3d, 0x88, 0x66, 0xcb, 0x50, 0xa1, 0xe3, },
|
|
||||||
{ 0x78, 0x28, 0xd0, 0x74, 0x11, 0x9c, 0xab, 0x5c, 0x22, 0xb2, 0x94, 0xd7, 0xa9, 0xbf, 0xa0, 0xbb, },
|
|
||||||
{ 0xad, 0xb8, 0x9c, 0xea, 0x9a, 0x15, 0xfb, 0xe6, 0x17, 0x29, 0x5b, 0xd0, 0x4b, 0x8c, 0xa0, 0x5c, },
|
|
||||||
{ 0x62, 0x51, 0xd8, 0x7f, 0xd4, 0xaa, 0xae, 0x9a, 0x7e, 0x4a, 0xd5, 0xc2, 0x17, 0xd3, 0xf3, 0x00, },
|
|
||||||
{ 0xe7, 0x11, 0x9b, 0xd6, 0xdd, 0x9b, 0x22, 0xaf, 0xe8, 0xf8, 0x95, 0x85, 0x43, 0x28, 0x81, 0xe2, },
|
|
||||||
{ 0x78, 0x5b, 0x60, 0xfd, 0x7e, 0xc4, 0xe9, 0xfc, 0xb6, 0x54, 0x5f, 0x35, 0x0d, 0x66, 0x0f, 0xab, },
|
|
||||||
{ 0xaf, 0xec, 0xc0, 0x37, 0xfd, 0xb7, 0xb0, 0x83, 0x8e, 0xb3, 0xd7, 0x0b, 0xcd, 0x26, 0x83, 0x82, },
|
|
||||||
{ 0xdb, 0xc1, 0xa7, 0xb4, 0x9d, 0x57, 0x35, 0x8c, 0xc9, 0xfa, 0x6d, 0x61, 0xd7, 0x3b, 0x7c, 0xf0, },
|
|
||||||
{ 0x63, 0x49, 0xd1, 0x26, 0xa3, 0x7a, 0xfc, 0xba, 0x89, 0x79, 0x4f, 0x98, 0x04, 0x91, 0x4f, 0xdc, },
|
|
||||||
{ 0xbf, 0x42, 0xc3, 0x01, 0x8c, 0x2f, 0x7c, 0x66, 0xbf, 0xde, 0x52, 0x49, 0x75, 0x76, 0x81, 0x15, },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x19, 0x10, 0x83, 0x32, 0x22, 0x77, 0x2a },
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0xbc, 0x92, 0x22, 0xdb, 0xd3, 0x27, 0x4d, 0x8f, 0xc6, 0x6d, 0x14, 0xcc, 0xbd, 0xa6, 0x69, 0x0b, },
|
|
||||||
{ 0x7a, 0xe6, 0x27, 0x41, 0x0c, 0x9a, 0x2b, 0xe6, 0x93, 0xdf, 0x5b, 0xb7, 0x48, 0x5a, 0x63, 0xe3, },
|
|
||||||
{ 0x3f, 0x09, 0x31, 0xaa, 0x03, 0xde, 0xfb, 0x30, 0x0f, 0x06, 0x01, 0x03, 0x82, 0x6f, 0x2a, 0x64, },
|
|
||||||
{ 0xbe, 0xaa, 0x9e, 0xc8, 0xd5, 0x9b, 0xb6, 0x81, 0x29, 0xf3, 0x02, 0x7c, 0x96, 0x36, 0x11, 0x81, },
|
|
||||||
{ 0x74, 0xe0, 0x4d, 0xb4, 0x6d, 0x28, 0x64, 0x8d, 0x7d, 0xee, 0x8a, 0x00, 0x64, 0xb0, 0x6c, 0xfe, },
|
|
||||||
{ 0x9b, 0x5e, 0x81, 0xc6, 0x2f, 0xe0, 0x23, 0xc5, 0x5b, 0xe4, 0x2f, 0x87, 0xbb, 0xf9, 0x32, 0xb8, },
|
|
||||||
{ 0xce, 0x17, 0x8f, 0xc1, 0x82, 0x6e, 0xfe, 0xcb, 0xc1, 0x82, 0xf5, 0x79, 0x99, 0xa4, 0x61, 0x40, },
|
|
||||||
{ 0x8b, 0xdf, 0x55, 0xcd, 0x55, 0x06, 0x1c, 0x06, 0xdb, 0xa6, 0xbe, 0x11, 0xde, 0x4a, 0x57, 0x8a, },
|
|
||||||
{ 0x62, 0x6f, 0x5f, 0x4d, 0xce, 0x65, 0x25, 0x01, 0xf3, 0x08, 0x7d, 0x39, 0xc9, 0x2c, 0xc3, 0x49, },
|
|
||||||
{ 0x42, 0xda, 0xac, 0x6a, 0x8f, 0x9a, 0xb9, 0xa7, 0xfd, 0x13, 0x7c, 0x60, 0x37, 0x82, 0x56, 0x82, },
|
|
||||||
{ 0xcc, 0x03, 0xfd, 0xb7, 0x91, 0x92, 0xa2, 0x07, 0x31, 0x2f, 0x53, 0xf5, 0xd4, 0xdc, 0x33, 0xd9, },
|
|
||||||
{ 0xf7, 0x0f, 0x14, 0x12, 0x2a, 0x1c, 0x98, 0xa3, 0x15, 0x5d, 0x28, 0xb8, 0xa0, 0xa8, 0xa4, 0x1d, },
|
|
||||||
{ 0x2a, 0x3a, 0x30, 0x7a, 0xb2, 0x70, 0x8a, 0x9c, 0x00, 0xfe, 0x0b, 0x42, 0xf9, 0xc2, 0xd6, 0xa1, },
|
|
||||||
{ 0x86, 0x26, 0x17, 0x62, 0x7d, 0x22, 0x61, 0xea, 0xb0, 0xb1, 0x24, 0x65, 0x97, 0xca, 0x0a, 0xe9, },
|
|
||||||
{ 0x55, 0xf8, 0x77, 0xce, 0x4f, 0x2e, 0x1d, 0xdb, 0xbf, 0x8e, 0x13, 0xe2, 0xcd, 0xe0, 0xfd, 0xc8, },
|
|
||||||
{ 0x1b, 0x15, 0x56, 0xcb, 0x93, 0x5f, 0x17, 0x33, 0x37, 0x70, 0x5f, 0xbb, 0x5d, 0x50, 0x1f, 0xc1, },
|
|
||||||
{ 0xec, 0xd0, 0xe9, 0x66, 0x02, 0xbe, 0x7f, 0x8d, 0x50, 0x92, 0x81, 0x6c, 0xcc, 0xf2, 0xc2, 0xe9, },
|
|
||||||
{ 0x02, 0x78, 0x81, 0xfa, 0xb4, 0x99, 0x3a, 0x1c, 0x26, 0x20, 0x24, 0xa9, 0x4f, 0xff, 0x3f, 0x61, },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x64, 0x19, 0x10, 0x83, 0x32, 0x22, 0x77, 0x2a },
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0xbb, 0xf6, 0x09, 0xde, 0x94, 0x13, 0x17, 0x2d, 0x07, 0x66, 0x0c, 0xb6, 0x80, 0x71, 0x69, 0x26, },
|
|
||||||
{ 0x46, 0x10, 0x1a, 0x6d, 0xab, 0x43, 0x11, 0x5d, 0x6c, 0x52, 0x2b, 0x4f, 0xe9, 0x36, 0x04, 0xa9, },
|
|
||||||
{ 0xcb, 0xe1, 0xff, 0xf2, 0x1c, 0x96, 0xf3, 0xee, 0xf6, 0x1e, 0x8f, 0xe0, 0x54, 0x2c, 0xbd, 0xf0, },
|
|
||||||
{ 0x34, 0x79, 0x38, 0xbf, 0xfa, 0x40, 0x09, 0xc5, 0x12, 0xcf, 0xb4, 0x03, 0x4b, 0x0d, 0xd1, 0xa7, },
|
|
||||||
{ 0x78, 0x67, 0xa7, 0x86, 0xd0, 0x0a, 0x71, 0x47, 0x90, 0x4d, 0x76, 0xdd, 0xf1, 0xe5, 0x20, 0xe3, },
|
|
||||||
{ 0x8d, 0x3e, 0x9e, 0x1c, 0xae, 0xfc, 0xcc, 0xb3, 0xfb, 0xf8, 0xd1, 0x8f, 0x64, 0x12, 0x0b, 0x32, },
|
|
||||||
{ 0x94, 0x23, 0x37, 0xf8, 0xfd, 0x76, 0xf0, 0xfa, 0xe8, 0xc5, 0x2d, 0x79, 0x54, 0x81, 0x06, 0x72, },
|
|
||||||
{ 0xb8, 0x54, 0x8c, 0x10, 0xf5, 0x16, 0x67, 0xf6, 0xe6, 0x0e, 0x18, 0x2f, 0xa1, 0x9b, 0x30, 0xf7, },
|
|
||||||
{ 0x02, 0x11, 0xc7, 0xc6, 0x19, 0x0c, 0x9e, 0xfd, 0x12, 0x37, 0xc3, 0x4c, 0x8f, 0x2e, 0x06, 0xc4, },
|
|
||||||
{ 0xbd, 0xa6, 0x4f, 0x65, 0x27, 0x6d, 0x2a, 0xac, 0xb8, 0xf9, 0x02, 0x12, 0x20, 0x3a, 0x80, 0x8e, },
|
|
||||||
{ 0xbd, 0x38, 0x20, 0xf7, 0x32, 0xff, 0xb5, 0x3e, 0xc1, 0x93, 0xe7, 0x9d, 0x33, 0xe2, 0x7c, 0x73, },
|
|
||||||
{ 0xd0, 0x16, 0x86, 0x16, 0x86, 0x19, 0x07, 0xd4, 0x82, 0xe3, 0x6c, 0xda, 0xc8, 0xcf, 0x57, 0x49, },
|
|
||||||
{ 0x97, 0xb0, 0xf0, 0xf2, 0x24, 0xb2, 0xd2, 0x31, 0x71, 0x14, 0x80, 0x8f, 0xb0, 0x3a, 0xf7, 0xa0, },
|
|
||||||
{ 0xe5, 0x96, 0x16, 0xe4, 0x69, 0x78, 0x79, 0x39, 0xa0, 0x63, 0xce, 0xea, 0x9a, 0xf9, 0x56, 0xd1, },
|
|
||||||
{ 0xc4, 0x7e, 0x0d, 0xc1, 0x66, 0x09, 0x19, 0xc1, 0x11, 0x01, 0x20, 0x8f, 0x9e, 0x69, 0xaa, 0x1f, },
|
|
||||||
{ 0x5a, 0xe4, 0xf1, 0x28, 0x96, 0xb8, 0x37, 0x9a, 0x2a, 0xad, 0x89, 0xb5, 0xb5, 0x53, 0xd6, 0xb0, },
|
|
||||||
{ 0x6b, 0x6b, 0x09, 0x8d, 0x0c, 0x29, 0x3b, 0xc2, 0x99, 0x3d, 0x80, 0xbf, 0x05, 0x18, 0xb6, 0xd9, },
|
|
||||||
{ 0x81, 0x70, 0xcc, 0x3c, 0xcd, 0x92, 0xa6, 0x98, 0x62, 0x1b, 0x93, 0x9d, 0xd3, 0x8f, 0xe7, 0xb9, },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x8b, 0x37, 0x64, 0x19, 0x10, 0x83, 0x32, 0x22, 0x77, 0x2a },
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0xab, 0x65, 0xc2, 0x6e, 0xdd, 0xb2, 0x87, 0x60, 0x0d, 0xb2, 0xfd, 0xa1, 0x0d, 0x1e, 0x60, 0x5c, },
|
|
||||||
{ 0xbb, 0x75, 0x90, 0x10, 0xc2, 0x96, 0x58, 0xf2, 0xc7, 0x2d, 0x93, 0xa2, 0xd1, 0x6d, 0x29, 0x30, },
|
|
||||||
{ 0xb9, 0x01, 0xe8, 0x03, 0x6e, 0xd1, 0xc3, 0x83, 0xcd, 0x3c, 0x4c, 0x4d, 0xd0, 0xa6, 0xab, 0x05, },
|
|
||||||
{ 0x3d, 0x25, 0xce, 0x49, 0x22, 0x92, 0x4c, 0x55, 0xf0, 0x64, 0x94, 0x33, 0x53, 0xd7, 0x8a, 0x6c, },
|
|
||||||
{ 0x12, 0xc1, 0xaa, 0x44, 0xbb, 0xf8, 0x7e, 0x75, 0xe6, 0x11, 0xf6, 0x9b, 0x2c, 0x38, 0xf4, 0x9b, },
|
|
||||||
{ 0x28, 0xf2, 0xb3, 0x43, 0x4b, 0x65, 0xc0, 0x98, 0x77, 0x47, 0x00, 0x44, 0xc6, 0xea, 0x17, 0x0d, },
|
|
||||||
{ 0xbd, 0x9e, 0xf8, 0x22, 0xde, 0x52, 0x88, 0x19, 0x61, 0x34, 0xcf, 0x8a, 0xf7, 0x83, 0x93, 0x04, },
|
|
||||||
{ 0x67, 0x55, 0x9c, 0x23, 0xf0, 0x52, 0x15, 0x84, 0x70, 0xa2, 0x96, 0xf7, 0x25, 0x73, 0x5a, 0x32, },
|
|
||||||
{ 0x8b, 0xab, 0x26, 0xfb, 0xc2, 0xc1, 0x2b, 0x0f, 0x13, 0xe2, 0xab, 0x18, 0x5e, 0xab, 0xf2, 0x41, },
|
|
||||||
{ 0x31, 0x18, 0x5a, 0x6d, 0x69, 0x6f, 0x0c, 0xfa, 0x9b, 0x42, 0x80, 0x8b, 0x38, 0xe1, 0x32, 0xa2, },
|
|
||||||
{ 0x56, 0x4d, 0x3d, 0xae, 0x18, 0x3c, 0x52, 0x34, 0xc8, 0xaf, 0x1e, 0x51, 0x06, 0x1c, 0x44, 0xb5, },
|
|
||||||
{ 0x3c, 0x07, 0x78, 0xa7, 0xb5, 0xf7, 0x2d, 0x3c, 0x23, 0xa3, 0x13, 0x5c, 0x7d, 0x67, 0xb9, 0xf4, },
|
|
||||||
{ 0xf3, 0x43, 0x69, 0x89, 0x0f, 0xcf, 0x16, 0xfb, 0x51, 0x7d, 0xca, 0xae, 0x44, 0x63, 0xb2, 0xdd, },
|
|
||||||
{ 0x02, 0xf3, 0x1c, 0x81, 0xe8, 0x20, 0x07, 0x31, 0xb8, 0x99, 0xb0, 0x28, 0xe7, 0x91, 0xbf, 0xa7, },
|
|
||||||
{ 0x72, 0xda, 0x64, 0x62, 0x83, 0x22, 0x8c, 0x14, 0x30, 0x08, 0x53, 0x70, 0x17, 0x95, 0x61, 0x6f, },
|
|
||||||
{ 0x4e, 0x0a, 0x8c, 0x6f, 0x79, 0x34, 0xa7, 0x88, 0xe2, 0x26, 0x5e, 0x81, 0xd6, 0xd0, 0xc8, 0xf4, },
|
|
||||||
{ 0x43, 0x8d, 0xd5, 0xea, 0xfe, 0xa0, 0x11, 0x1b, 0x6f, 0x36, 0xb4, 0xb9, 0x38, 0xda, 0x2a, 0x68, },
|
|
||||||
{ 0x5f, 0x6b, 0xfc, 0x73, 0x81, 0x58, 0x74, 0xd9, 0x71, 0x00, 0xf0, 0x86, 0x97, 0x93, 0x57, 0xd8, },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0xeb, 0xb4, 0x62, 0x27, 0xc6, 0xcc, 0x8b, 0x37, 0x64, 0x19, 0x10, 0x83, 0x32, 0x22, 0x77, 0x2a },
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x72, 0x0c, 0x94, 0xb6, 0x3e, 0xdf, 0x44, 0xe1, 0x31, 0xd9, 0x50, 0xca, 0x21, 0x1a, 0x5a, 0x30, },
|
|
||||||
{ 0xc3, 0x66, 0xfd, 0xea, 0xcf, 0x9c, 0xa8, 0x04, 0x36, 0xbe, 0x7c, 0x35, 0x84, 0x24, 0xd2, 0x0b, },
|
|
||||||
{ 0xb3, 0x39, 0x4a, 0x40, 0xaa, 0xbf, 0x75, 0xcb, 0xa4, 0x22, 0x82, 0xef, 0x25, 0xa0, 0x05, 0x9f, },
|
|
||||||
{ 0x48, 0x47, 0xd8, 0x1d, 0xa4, 0x94, 0x2d, 0xbc, 0x24, 0x9d, 0xef, 0xc4, 0x8c, 0x92, 0x2b, 0x9f, },
|
|
||||||
{ 0x08, 0x12, 0x8c, 0x46, 0x9f, 0x27, 0x53, 0x42, 0xad, 0xda, 0x20, 0x2b, 0x2b, 0x58, 0xda, 0x95, },
|
|
||||||
{ 0x97, 0x0d, 0xac, 0xef, 0x40, 0xad, 0x98, 0x72, 0x3b, 0xac, 0x5d, 0x69, 0x55, 0xb8, 0x17, 0x61, },
|
|
||||||
{ 0x3c, 0xb8, 0x99, 0x93, 0xb0, 0x7b, 0x0c, 0xed, 0x93, 0xde, 0x13, 0xd2, 0xa1, 0x10, 0x13, 0xac, },
|
|
||||||
{ 0xef, 0x2d, 0x67, 0x6f, 0x15, 0x45, 0xc2, 0xc1, 0x3d, 0xc6, 0x80, 0xa0, 0x2f, 0x4a, 0xdb, 0xfe, },
|
|
||||||
{ 0xb6, 0x05, 0x95, 0x51, 0x4f, 0x24, 0xbc, 0x9f, 0xe5, 0x22, 0xa6, 0xca, 0xd7, 0x39, 0x36, 0x44, },
|
|
||||||
{ 0xb5, 0x15, 0xa8, 0xc5, 0x01, 0x17, 0x54, 0xf5, 0x90, 0x03, 0x05, 0x8b, 0xdb, 0x81, 0x51, 0x4e, },
|
|
||||||
{ 0x3c, 0x70, 0x04, 0x7e, 0x8c, 0xbc, 0x03, 0x8e, 0x3b, 0x98, 0x20, 0xdb, 0x60, 0x1d, 0xa4, 0x95, },
|
|
||||||
{ 0x11, 0x75, 0xda, 0x6e, 0xe7, 0x56, 0xde, 0x46, 0xa5, 0x3e, 0x2b, 0x07, 0x56, 0x60, 0xb7, 0x70, },
|
|
||||||
{ 0x00, 0xa5, 0x42, 0xbb, 0xa0, 0x21, 0x11, 0xcc, 0x2c, 0x65, 0xb3, 0x8e, 0xbd, 0xba, 0x58, 0x7e, },
|
|
||||||
{ 0x58, 0x65, 0xfd, 0xbb, 0x5b, 0x48, 0x06, 0x41, 0x04, 0xe8, 0x30, 0xb3, 0x80, 0xf2, 0xae, 0xde, },
|
|
||||||
{ 0x34, 0xb2, 0x1a, 0xd2, 0xad, 0x44, 0xe9, 0x99, 0xdb, 0x2d, 0x7f, 0x08, 0x63, 0xf0, 0xd9, 0xb6, },
|
|
||||||
{ 0x84, 0xa9, 0x21, 0x8f, 0xc3, 0x6e, 0x8a, 0x5f, 0x2c, 0xcf, 0xbe, 0xae, 0x53, 0xa2, 0x7d, 0x25, },
|
|
||||||
{ 0xa2, 0x22, 0x1a, 0x11, 0xb8, 0x33, 0xcc, 0xb4, 0x98, 0xa5, 0x95, 0x40, 0xf0, 0x54, 0x5f, 0x4a, },
|
|
||||||
{ 0x5b, 0xbe, 0xb4, 0x78, 0x7d, 0x59, 0xe5, 0x37, 0x3f, 0xdb, 0xea, 0x6c, 0x6f, 0x75, 0xc2, 0x9b, },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0xc1, 0x09, 0x16, 0x39, 0x08, 0xeb, 0xe5, 0x1d, 0xeb, 0xb4, 0x62, 0x27, 0xc6, 0xcc, 0x8b, 0x37, 0x64, 0x19, 0x10, 0x83, 0x32, 0x22, 0x77, 0x2a },
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x54, 0xb6, 0x4e, 0x6b, 0x5a, 0x20, 0xb5, 0xe2, 0xec, 0x84, 0x59, 0x3d, 0xc7, 0x98, 0x9d, 0xa7, },
|
|
||||||
{ 0xc1, 0x35, 0xee, 0xe2, 0x37, 0xa8, 0x54, 0x65, 0xff, 0x97, 0xdc, 0x03, 0x92, 0x4f, 0x45, 0xce, },
|
|
||||||
{ 0xcf, 0xcc, 0x92, 0x2f, 0xb4, 0xa1, 0x4a, 0xb4, 0x5d, 0x61, 0x75, 0xaa, 0xbb, 0xf2, 0xd2, 0x01, },
|
|
||||||
{ 0x83, 0x7b, 0x87, 0xe2, 0xa4, 0x46, 0xad, 0x0e, 0xf7, 0x98, 0xac, 0xd0, 0x2b, 0x94, 0x12, 0x4f, },
|
|
||||||
{ 0x17, 0xa6, 0xdb, 0xd6, 0x64, 0x92, 0x6a, 0x06, 0x36, 0xb3, 0xf4, 0xc3, 0x7a, 0x4f, 0x46, 0x94, },
|
|
||||||
{ 0x4a, 0x5f, 0x9f, 0x26, 0xae, 0xee, 0xd4, 0xd4, 0xa2, 0x5f, 0x63, 0x2d, 0x30, 0x52, 0x33, 0xd9, },
|
|
||||||
{ 0x80, 0xa3, 0xd0, 0x1e, 0xf0, 0x0c, 0x8e, 0x9a, 0x42, 0x09, 0xc1, 0x7f, 0x4e, 0xeb, 0x35, 0x8c, },
|
|
||||||
{ 0xd1, 0x5e, 0x7d, 0x5f, 0xfa, 0xaa, 0xbc, 0x02, 0x07, 0xbf, 0x20, 0x0a, 0x11, 0x77, 0x93, 0xa2, },
|
|
||||||
{ 0x34, 0x96, 0x82, 0xbf, 0x58, 0x8e, 0xaa, 0x52, 0xd0, 0xaa, 0x15, 0x60, 0x34, 0x6a, 0xea, 0xfa, },
|
|
||||||
{ 0xf5, 0x85, 0x4c, 0xdb, 0x76, 0xc8, 0x89, 0xe3, 0xad, 0x63, 0x35, 0x4e, 0x5f, 0x72, 0x75, 0xe3, },
|
|
||||||
{ 0x53, 0x2c, 0x7c, 0xec, 0xcb, 0x39, 0xdf, 0x32, 0x36, 0x31, 0x84, 0x05, 0xa4, 0xb1, 0x27, 0x9c, },
|
|
||||||
{ 0xba, 0xef, 0xe6, 0xd9, 0xce, 0xb6, 0x51, 0x84, 0x22, 0x60, 0xe0, 0xd1, 0xe0, 0x5e, 0x3b, 0x90, },
|
|
||||||
{ 0xe8, 0x2d, 0x8c, 0x6d, 0xb5, 0x4e, 0x3c, 0x63, 0x3f, 0x58, 0x1c, 0x95, 0x2b, 0xa0, 0x42, 0x07, },
|
|
||||||
{ 0x4b, 0x16, 0xe5, 0x0a, 0xbd, 0x38, 0x1b, 0xd7, 0x09, 0x00, 0xa9, 0xcd, 0x9a, 0x62, 0xcb, 0x23, },
|
|
||||||
{ 0x36, 0x82, 0xee, 0x33, 0xbd, 0x14, 0x8b, 0xd9, 0xf5, 0x86, 0x56, 0xcd, 0x8f, 0x30, 0xd9, 0xfb, },
|
|
||||||
{ 0x1e, 0x5a, 0x0b, 0x84, 0x75, 0x04, 0x5d, 0x9b, 0x20, 0xb2, 0x62, 0x86, 0x24, 0xed, 0xfd, 0x9e, },
|
|
||||||
{ 0x63, 0xed, 0xd6, 0x84, 0xfb, 0x82, 0x62, 0x82, 0xfe, 0x52, 0x8f, 0x9c, 0x0e, 0x92, 0x37, 0xbc, },
|
|
||||||
{ 0xe4, 0xdd, 0x2e, 0x98, 0xd6, 0x96, 0x0f, 0xae, 0x0b, 0x43, 0x54, 0x54, 0x56, 0x74, 0x33, 0x91, },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x1a, 0xda, 0x31, 0xd5, 0xcf, 0x68, 0x82, 0x21, 0xc1, 0x09, 0x16, 0x39, 0x08, 0xeb, 0xe5, 0x1d, 0xeb, 0xb4, 0x62, 0x27, 0xc6, 0xcc, 0x8b, 0x37, 0x64, 0x19, 0x10, 0x83, 0x32, 0x22, 0x77, 0x2a },
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0xdd, 0x5b, 0xcb, 0x00, 0x18, 0xe9, 0x22, 0xd4, 0x94, 0x75, 0x9d, 0x7c, 0x39, 0x5d, 0x02, 0xd3, },
|
|
||||||
{ 0xc8, 0x44, 0x6f, 0x8f, 0x77, 0xab, 0xf7, 0x37, 0x68, 0x53, 0x53, 0xeb, 0x89, 0xa1, 0xc9, 0xeb, },
|
|
||||||
{ 0xaf, 0x3e, 0x30, 0xf9, 0xc0, 0x95, 0x04, 0x59, 0x38, 0x15, 0x15, 0x75, 0xc3, 0xfb, 0x90, 0x98, },
|
|
||||||
{ 0xf8, 0xcb, 0x62, 0x74, 0xdb, 0x99, 0xb8, 0x0b, 0x1d, 0x20, 0x12, 0xa9, 0x8e, 0xd4, 0x8f, 0x0e, },
|
|
||||||
{ 0x25, 0xc3, 0x00, 0x5a, 0x1c, 0xb8, 0x5d, 0xe0, 0x76, 0x25, 0x98, 0x39, 0xab, 0x71, 0x98, 0xab, },
|
|
||||||
{ 0x9d, 0xcb, 0xc1, 0x83, 0xe8, 0xcb, 0x99, 0x4b, 0x72, 0x7b, 0x75, 0xbe, 0x31, 0x80, 0x76, 0x9c, },
|
|
||||||
{ 0xa1, 0xd3, 0x07, 0x8d, 0xfa, 0x91, 0x69, 0x50, 0x3e, 0xd9, 0xd4, 0x49, 0x1d, 0xee, 0x4e, 0xb2, },
|
|
||||||
{ 0x85, 0x14, 0xa5, 0x49, 0x58, 0x58, 0x09, 0x6f, 0x59, 0x6e, 0x4b, 0xcd, 0x66, 0xb1, 0x06, 0x65, },
|
|
||||||
{ 0x5f, 0x40, 0xd5, 0x9e, 0xc1, 0xb0, 0x3b, 0x33, 0x73, 0x8e, 0xfa, 0x60, 0xb2, 0x25, 0x5d, 0x31, },
|
|
||||||
{ 0x34, 0x77, 0xc7, 0xf7, 0x64, 0xa4, 0x1b, 0xac, 0xef, 0xf9, 0x0b, 0xf1, 0x4f, 0x92, 0xb7, 0xcc, },
|
|
||||||
{ 0xac, 0x4e, 0x95, 0x36, 0x8d, 0x99, 0xb9, 0xeb, 0x78, 0xb8, 0xda, 0x8f, 0x81, 0xff, 0xa7, 0x95, },
|
|
||||||
{ 0x8c, 0x3c, 0x13, 0xf8, 0xc2, 0x38, 0x8b, 0xb7, 0x3f, 0x38, 0x57, 0x6e, 0x65, 0xb7, 0xc4, 0x46, },
|
|
||||||
{ 0x13, 0xc4, 0xb9, 0xc1, 0xdf, 0xb6, 0x65, 0x79, 0xed, 0xdd, 0x8a, 0x28, 0x0b, 0x9f, 0x73, 0x16, },
|
|
||||||
{ 0xdd, 0xd2, 0x78, 0x20, 0x55, 0x01, 0x26, 0x69, 0x8e, 0xfa, 0xad, 0xc6, 0x4b, 0x64, 0xf6, 0x6e, },
|
|
||||||
{ 0xf0, 0x8f, 0x2e, 0x66, 0xd2, 0x8e, 0xd1, 0x43, 0xf3, 0xa2, 0x37, 0xcf, 0x9d, 0xe7, 0x35, 0x59, },
|
|
||||||
{ 0x9e, 0xa3, 0x6c, 0x52, 0x55, 0x31, 0xb8, 0x80, 0xba, 0x12, 0x43, 0x34, 0xf5, 0x7b, 0x0b, 0x70, },
|
|
||||||
{ 0xd5, 0xa3, 0x9e, 0x3d, 0xfc, 0xc5, 0x02, 0x80, 0xba, 0xc4, 0xa6, 0xb5, 0xaa, 0x0d, 0xca, 0x7d, },
|
|
||||||
{ 0x37, 0x0b, 0x1c, 0x1f, 0xe6, 0x55, 0x91, 0x6d, 0x97, 0xfd, 0x0d, 0x47, 0xca, 0x1d, 0x72, 0xb8, },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
for (size_t i = 0; i < std::size (TESTS); ++i) {
|
|
||||||
const auto &t = TESTS[i];
|
|
||||||
|
|
||||||
util::crypto::ARC4 gen (t.key.data (), t.key.size ());
|
|
||||||
uint8_t data[16];
|
|
||||||
size_t consumed = 0;
|
|
||||||
bool success = true;
|
|
||||||
|
|
||||||
for (size_t j = 0; j < std::size (OFFSETS); ++j) {
|
|
||||||
CHECK_GE (OFFSETS[j], consumed);
|
|
||||||
|
|
||||||
size_t diff = OFFSETS[j] - consumed;
|
|
||||||
gen.discard (diff);
|
|
||||||
consumed += diff;
|
|
||||||
|
|
||||||
gen.generate (data, 16);
|
|
||||||
consumed += 16;
|
|
||||||
|
|
||||||
success = success && std::equal (std::begin (data), std::end (data), std::begin (t.data[j]));
|
|
||||||
};
|
|
||||||
|
|
||||||
tap.expect (success, "ARC4 %zu", i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tap.status ();
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
#include "crypto/ice.hpp"
|
|
||||||
#include "tap.hpp"
|
|
||||||
#include "iterator.hpp"
|
|
||||||
#include "stream.hpp"
|
|
||||||
#include "endian.hpp"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <array>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int, char**)
|
|
||||||
{
|
|
||||||
const uint64_t data = 0xfedcba9876543210;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
unsigned level;
|
|
||||||
uint64_t crypt;
|
|
||||||
std::vector<uint64_t> key;
|
|
||||||
} TESTS[] = {
|
|
||||||
{ 0, 0xde240d83a00a9cc0, { 0xdeadbeef01234567 } },
|
|
||||||
{ 1, 0x7d6ef1ef30d47a96, { 0xdeadbeef01234567 } },
|
|
||||||
{ 2, 0xf94840d86972f21c, { 0x0011223344556677, 0x8899aabbccddeeff } },
|
|
||||||
};
|
|
||||||
|
|
||||||
util::TAP::logger tap;
|
|
||||||
|
|
||||||
for (const auto &t: TESTS) {
|
|
||||||
std::vector<uint64_t> k (t.key.cbegin (), t.key.cend ());
|
|
||||||
std::transform (k.cbegin (), k.cend (), k.begin (), util::hton<uint64_t>);
|
|
||||||
|
|
||||||
ice key (t.level, k.data (), k.data () + k.size ());
|
|
||||||
|
|
||||||
auto crypt = key.encrypt (data);
|
|
||||||
auto plain = key.decrypt (t.crypt);
|
|
||||||
|
|
||||||
tap.expect_eq (crypt, t.crypt, "ICE level %u certification, encrypt", t.level);
|
|
||||||
tap.expect_eq (plain, data, "ICE level %u certification, decrypt", t.level);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tap.status ();
|
|
||||||
}
|
|
@ -1,229 +0,0 @@
|
|||||||
#include "crypto/salsa.hpp"
|
|
||||||
|
|
||||||
#include "tap.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
test_quarter (util::TAP::logger &tap)
|
|
||||||
{
|
|
||||||
static const struct {
|
|
||||||
std::array<uint32_t, 4> a, b;
|
|
||||||
} TESTS[] = {
|
|
||||||
{ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
|
|
||||||
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
|
|
||||||
{ { 0x00000001, 0x00000000, 0x00000000, 0x00000000 },
|
|
||||||
{ 0x08008145, 0x00000080, 0x00010200, 0x20500000 } },
|
|
||||||
{ { 0x00000000, 0x00000001, 0x00000000, 0x00000000 },
|
|
||||||
{ 0x88000100, 0x00000001, 0x00000200, 0x00402000 } },
|
|
||||||
{ { 0x00000000, 0x00000000, 0x00000001, 0x00000000 },
|
|
||||||
{ 0x80040000, 0x00000000, 0x00000001, 0x00002000 } },
|
|
||||||
{ { 0x00000000, 0x00000000, 0x00000000, 0x00000001 },
|
|
||||||
{ 0x00048044, 0x00000080, 0x00010000, 0x20100001 } },
|
|
||||||
{ { 0xe7e8c006, 0xc4f9417d, 0x6479b4b2, 0x68c67137 },
|
|
||||||
{ 0xe876d72b, 0x9361dfd5, 0xf1460244, 0x948541a3 } },
|
|
||||||
{ { 0xd3917c5b, 0x55f1c407, 0x52a58a7a, 0x8f887a3b },
|
|
||||||
{ 0x3e2f308c, 0xd90a8f36, 0x6ab2a923, 0x2883524c } },
|
|
||||||
};
|
|
||||||
|
|
||||||
for (size_t i = 0; i < std::size (TESTS); ++i)
|
|
||||||
tap.expect_eq (util::crypto::salsa::quarter (TESTS[i].a), TESTS[i].b, "quarter %zu", i);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
test_row (util::TAP::logger &tap)
|
|
||||||
{
|
|
||||||
static const struct {
|
|
||||||
std::array<uint32_t, 16> a, b;
|
|
||||||
} TESTS[] = {
|
|
||||||
{ { 0x00000001, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0x00000001, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0x00000001, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0x00000001, 0x00000000, 0x00000000, 0x00000000, },
|
|
||||||
{ 0x08008145, 0x00000080, 0x00010200, 0x20500000,
|
|
||||||
0x20100001, 0x00048044, 0x00000080, 0x00010000,
|
|
||||||
0x00000001, 0x00002000, 0x80040000, 0x00000000,
|
|
||||||
0x00000001, 0x00000200, 0x00402000, 0x88000100, }
|
|
||||||
},
|
|
||||||
{ { 0x08521bd6, 0x1fe88837, 0xbb2aa576, 0x3aa26365,
|
|
||||||
0xc54c6a5b, 0x2fc74c2f, 0x6dd39cc3, 0xda0a64f6,
|
|
||||||
0x90a2f23d, 0x067f95a6, 0x06b35f61, 0x41e4732e,
|
|
||||||
0xe859c100, 0xea4d84b7, 0x0f619bff, 0xbc6e965a, },
|
|
||||||
{ 0xa890d39d, 0x65d71596, 0xe9487daa, 0xc8ca6a86,
|
|
||||||
0x949d2192, 0x764b7754, 0xe408d9b9, 0x7a41b4d1,
|
|
||||||
0x3402e183, 0x3c3af432, 0x50669f96, 0xd89ef0a8,
|
|
||||||
0x0040ede5, 0xb545fbce, 0xd257ed4f, 0x1818882d, },
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (size_t i = 0; i < std::size (TESTS); ++i)
|
|
||||||
tap.expect_eq (util::crypto::salsa::row (TESTS[i].a), TESTS[i].b, "row %zu", i);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
test_col (util::TAP::logger &tap)
|
|
||||||
{
|
|
||||||
static const struct {
|
|
||||||
std::array<uint32_t,16> a, b;
|
|
||||||
} TESTS[] = {
|
|
||||||
{ { 0x00000001, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0x00000001, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0x00000001, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0x00000001, 0x00000000, 0x00000000, 0x00000000, },
|
|
||||||
{ 0x10090288, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0x00000101, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0x00020401, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0x40a04001, 0x00000000, 0x00000000, 0x00000000, } },
|
|
||||||
{ { 0x08521bd6, 0x1fe88837, 0xbb2aa576, 0x3aa26365,
|
|
||||||
0xc54c6a5b, 0x2fc74c2f, 0x6dd39cc3, 0xda0a64f6,
|
|
||||||
0x90a2f23d, 0x067f95a6, 0x06b35f61, 0x41e4732e,
|
|
||||||
0xe859c100, 0xea4d84b7, 0x0f619bff, 0xbc6e965a, },
|
|
||||||
{ 0x8c9d190a, 0xce8e4c90, 0x1ef8e9d3, 0x1326a71a,
|
|
||||||
0x90a20123, 0xead3c4f3, 0x63a091a0, 0xf0708d69,
|
|
||||||
0x789b010c, 0xd195a681, 0xeb7d5504, 0xa774135c,
|
|
||||||
0x481c2027, 0x53a8e4b5, 0x4c1f89c5, 0x3f78c9c8, } },
|
|
||||||
};
|
|
||||||
|
|
||||||
for (size_t i = 0; i < std::size (TESTS); ++i)
|
|
||||||
tap.expect_eq (util::crypto::salsa::col (TESTS[i].a), TESTS[i].b, "col %zu", i);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
test_doubleround (util::TAP::logger &tap)
|
|
||||||
{
|
|
||||||
static const struct {
|
|
||||||
std::array<uint32_t,16> a, b;
|
|
||||||
} TESTS[] = {
|
|
||||||
{ { 0x00000001, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, },
|
|
||||||
{ 0x8186a22d, 0x0040a284, 0x82479210, 0x06929051,
|
|
||||||
0x08000090, 0x02402200, 0x00004000, 0x00800000,
|
|
||||||
0x00010200, 0x20400000, 0x08008104, 0x00000000,
|
|
||||||
0x20500000, 0xa0000040, 0x0008180a, 0x612a8020, } },
|
|
||||||
{ { 0xde501066, 0x6f9eb8f7, 0xe4fbbd9b, 0x454e3f57,
|
|
||||||
0xb75540d3, 0x43e93a4c, 0x3a6f2aa0, 0x726d6b36,
|
|
||||||
0x9243f484, 0x9145d1e8, 0x4fa9d247, 0xdc8dee11,
|
|
||||||
0x054bf545, 0x254dd653, 0xd9421b6d, 0x67b276c1, },
|
|
||||||
{ 0xccaaf672, 0x23d960f7, 0x9153e63a, 0xcd9a60d0,
|
|
||||||
0x50440492, 0xf07cad19, 0xae344aa0, 0xdf4cfdfc,
|
|
||||||
0xca531c29, 0x8e7943db, 0xac1680cd, 0xd503ca00,
|
|
||||||
0xa74b2ad6, 0xbc331c5c, 0x1dda24c7, 0xee928277, } }
|
|
||||||
};
|
|
||||||
|
|
||||||
for (size_t i = 0; i < std::size (TESTS); ++i)
|
|
||||||
tap.expect_eq (util::crypto::salsa::doubleround (TESTS[i].a), TESTS[i].b, "doubleround %zu", i);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
void
|
|
||||||
test_salsa20 (util::TAP::logger &tap)
|
|
||||||
{
|
|
||||||
static const struct {
|
|
||||||
std::array<uint8_t,64> a, b;
|
|
||||||
} TESTS[] = {
|
|
||||||
{ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
|
||||||
|
|
||||||
{ { 0xd3, 0x9f, 0x0d, 0x73, 0x4c, 0x37, 0x52, 0xb7,
|
|
||||||
0x03, 0x75, 0xde, 0x25, 0xbf, 0xbb, 0xea, 0x88,
|
|
||||||
0x31, 0xed, 0xb3, 0x30, 0x01, 0x6a, 0xb2, 0xdb,
|
|
||||||
0xaf, 0xc7, 0xa6, 0x30, 0x56, 0x10, 0xb3, 0xcf,
|
|
||||||
0x1f, 0xf0, 0x20, 0x3f, 0x0f, 0x53, 0x5d, 0xa1,
|
|
||||||
0x74, 0x93, 0x30, 0x71, 0xee, 0x37, 0xcc, 0x24,
|
|
||||||
0x4f, 0xc9, 0xeb, 0x4f, 0x03, 0x51, 0x9c, 0x2f,
|
|
||||||
0xcb, 0x1a, 0xf4, 0xf3, 0x58, 0x76, 0x68, 0x36 },
|
|
||||||
{ 0x6d, 0x2a, 0xb2, 0xa8, 0x9c, 0xf0, 0xf8, 0xee,
|
|
||||||
0xa8, 0xc4, 0xbe, 0xcb, 0x1a, 0x6e, 0xaa, 0x9a,
|
|
||||||
0x1d, 0x1d, 0x96, 0x1a, 0x96, 0x1e, 0xeb, 0xf9,
|
|
||||||
0xbe, 0xa3, 0xfb, 0x30, 0x45, 0x90, 0x33, 0x39,
|
|
||||||
0x76, 0x28, 0x98, 0x9d, 0xb4, 0x39, 0x1b, 0x5e,
|
|
||||||
0x6b, 0x2a, 0xec, 0x23, 0x1b, 0x6f, 0x72, 0x72,
|
|
||||||
0xdb, 0xec, 0xe8, 0x87, 0x6f, 0x9b, 0x6e, 0x12,
|
|
||||||
0x18, 0xe8, 0x5f, 0x9e, 0xb3, 0x13, 0x30, 0xca } },
|
|
||||||
|
|
||||||
{ { 0x58, 0x76, 0x68, 0x36, 0x4f, 0xc9, 0xeb, 0x4f,
|
|
||||||
0x03, 0x51, 0x9c, 0x2f, 0xcb, 0x1a, 0xf4, 0xf3,
|
|
||||||
0xbf, 0xbb, 0xea, 0x88, 0xd3, 0x9f, 0x0d, 0x73,
|
|
||||||
0x4c, 0x37, 0x52, 0xb7, 0x03, 0x75, 0xde, 0x25,
|
|
||||||
0x56, 0x10, 0xb3, 0xcf, 0x31, 0xed, 0xb3, 0x30,
|
|
||||||
0x01, 0x6a, 0xb2, 0xdb, 0xaf, 0xc7, 0xa6, 0x30,
|
|
||||||
0xee, 0x37, 0xcc, 0x24, 0x1f, 0xf0, 0x20, 0x3f,
|
|
||||||
0x0f, 0x53, 0x5d, 0xa1, 0x74, 0x93, 0x30, 0x71 },
|
|
||||||
{ 0xb3, 0x13, 0x30, 0xca, 0xdb, 0xec, 0xe8, 0x87,
|
|
||||||
0x6f, 0x9b, 0x6e, 0x12, 0x18, 0xe8, 0x5f, 0x9e,
|
|
||||||
0x1a, 0x6e, 0xaa, 0x9a, 0x6d, 0x2a, 0xb2, 0xa8,
|
|
||||||
0x9c, 0xf0, 0xf8, 0xee, 0xa8, 0xc4, 0xbe, 0xcb,
|
|
||||||
0x45, 0x90, 0x33, 0x39, 0x1d, 0x1d, 0x96, 0x1a,
|
|
||||||
0x96, 0x1e, 0xeb, 0xf9, 0xbe, 0xa3, 0xfb, 0x30,
|
|
||||||
0x1b, 0x6f, 0x72, 0x72, 0x76, 0x28, 0x98, 0x9d,
|
|
||||||
0xb4, 0x39, 0x1b, 0x5e, 0x6b, 0x2a, 0xec, 0x23 } }
|
|
||||||
};
|
|
||||||
|
|
||||||
for (size_t i = 0; i < std::size (TESTS); ++i)
|
|
||||||
tap.expect_eq (util::crypto::salsa20 (TESTS[i].a), TESTS[i].b, "salsa20 %zu", i);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
std::array<uint8_t,64> a, b;
|
|
||||||
} million = {
|
|
||||||
{ 0x06, 0x7c, 0x53, 0x92, 0x26, 0xbf, 0x09, 0x32,
|
|
||||||
0x04, 0xa1, 0x2f, 0xde, 0x7a, 0xb6, 0xdf, 0xb9,
|
|
||||||
0x4b, 0x1b, 0x00, 0xd8, 0x10, 0x7a, 0x07, 0x59,
|
|
||||||
0xa2, 0x68, 0x65, 0x93, 0xd5, 0x15, 0x36, 0x5f,
|
|
||||||
0xe1, 0xfd, 0x8b, 0xb0, 0x69, 0x84, 0x17, 0x74,
|
|
||||||
0x4c, 0x29, 0xb0, 0xcf, 0xdd, 0x22, 0x9d, 0x6c,
|
|
||||||
0x5e, 0x5e, 0x63, 0x34, 0x5a, 0x75, 0x5b, 0xdc,
|
|
||||||
0x92, 0xbe, 0xef, 0x8f, 0xc4, 0xb0, 0x82, 0xba },
|
|
||||||
{ 0x08, 0x12, 0x26, 0xc7, 0x77, 0x4c, 0xd7, 0x43,
|
|
||||||
0xad, 0x7f, 0x90, 0xa2, 0x67, 0xd4, 0xb0, 0xd9,
|
|
||||||
0xc0, 0x13, 0xe9, 0x21, 0x9f, 0xc5, 0x9a, 0xa0,
|
|
||||||
0x80, 0xf3, 0xdb, 0x41, 0xab, 0x88, 0x87, 0xe1,
|
|
||||||
0x7b, 0x0b, 0x44, 0x56, 0xed, 0x52, 0x14, 0x9b,
|
|
||||||
0x85, 0xbd, 0x09, 0x53, 0xa7, 0x74, 0xc2, 0x4e,
|
|
||||||
0x7a, 0x7f, 0xc3, 0xb9, 0xb9, 0xcc, 0xbc, 0x5a,
|
|
||||||
0xf5, 0x09, 0xb7, 0xf8, 0xe2, 0x55, 0xf5, 0x68 }
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; i < 1'000'000; ++i)
|
|
||||||
million.a = util::crypto::salsa20 (million.a);
|
|
||||||
|
|
||||||
tap.expect_eq (million.a, million.b, "salsa20 million");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
int
|
|
||||||
main (void)
|
|
||||||
{
|
|
||||||
util::TAP::logger tap;
|
|
||||||
|
|
||||||
test_quarter (tap);
|
|
||||||
test_row (tap);
|
|
||||||
test_col (tap);
|
|
||||||
test_doubleround (tap);
|
|
||||||
test_salsa20 (tap);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
#include "tap.hpp"
|
|
||||||
#include "types.hpp"
|
|
||||||
#include "crypto/tea.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
// test vectors from 'TeaCrypt', by Logan J. Drews.
|
|
||||||
static const struct {
|
|
||||||
std::array<uint32_t,4> key;
|
|
||||||
std::array<uint32_t,2> dec;
|
|
||||||
std::array<uint32_t,2> enc;
|
|
||||||
} TESTS[] = {
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
|
|
||||||
{ 0x00000000, 0x00000000 },
|
|
||||||
{ 0x41EA3A0A, 0x94BAA940 },
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
|
|
||||||
{ 0x01020304, 0x05060708 },
|
|
||||||
{ 0x6A2F9CF3, 0xFCCF3C55 },
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF },
|
|
||||||
{ 0x01020304, 0x05060708 },
|
|
||||||
{ 0xDEB1C0A2, 0x7E745DB3 },
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF },
|
|
||||||
{ 0x01234567, 0x89ABCDEF },
|
|
||||||
{ 0x126C6B92, 0xC0653A3E },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
util::TAP::logger tap;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < std::size (TESTS); ++i) {
|
|
||||||
const auto &t = TESTS[i];
|
|
||||||
util::crypto::TEA gen (t.key);
|
|
||||||
|
|
||||||
std::array<uint32_t,2> enc (t.dec);
|
|
||||||
gen.encrypt (enc.data (), enc.size ());
|
|
||||||
|
|
||||||
std::array<uint32_t,2> dec (t.enc);
|
|
||||||
gen.decrypt (dec.data (), dec.size ());
|
|
||||||
|
|
||||||
tap.expect (enc == t.enc, "TEA_enc %zu", i);
|
|
||||||
tap.expect (dec == t.dec, "TEA_dec %zu", i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tap.status ();
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
#include "tap.hpp"
|
|
||||||
#include "crypto/xtea.hpp"
|
|
||||||
#include "types.hpp"
|
|
||||||
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
// test vectors from 'TeaCrypt', by Logan J. Drews.
|
|
||||||
static const struct {
|
|
||||||
std::array<uint32_t,4> key;
|
|
||||||
std::array<uint32_t,2> dec;
|
|
||||||
std::array<uint32_t,2> enc;
|
|
||||||
} TESTS[] = {
|
|
||||||
{
|
|
||||||
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
|
||||||
{0x00000000, 0x00000000},
|
|
||||||
{0xDEE9D4D8, 0xF7131ED9},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
|
||||||
{0x01020304, 0x05060708},
|
|
||||||
{0x065C1B89, 0x75C6A816},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF},
|
|
||||||
{0x01020304, 0x05060708},
|
|
||||||
{0xDCDD7ACD, 0xC1584B79},
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF},
|
|
||||||
{0x01234567, 0x89ABCDEF},
|
|
||||||
{0xB8BF2821, 0x622B5B30},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
util::TAP::logger tap;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < std::size (TESTS); ++i) {
|
|
||||||
const auto &t = TESTS[i];
|
|
||||||
util::crypto::XTEA gen (t.key);
|
|
||||||
|
|
||||||
std::array<uint32_t,2> enc (t.dec);
|
|
||||||
gen.encrypt (enc.data (), enc.size ());
|
|
||||||
|
|
||||||
std::array<uint32_t,2> dec (t.enc);
|
|
||||||
gen.decrypt (dec.data (), dec.size ());
|
|
||||||
|
|
||||||
tap.expect (enc == t.enc, "XTEA_enc %zu", i);
|
|
||||||
tap.expect (dec == t.dec, "XTEA_dec %zu", i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tap.status ();
|
|
||||||
}
|
|
@ -1,114 +0,0 @@
|
|||||||
#include "crypto/xxtea.hpp"
|
|
||||||
|
|
||||||
#include "debug.hpp"
|
|
||||||
#include "tap.hpp"
|
|
||||||
#include "types.hpp"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
int
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
// test vectors from 'TeaCrypt', by Logan J. Drews.
|
|
||||||
static const struct {
|
|
||||||
std::array<uint32_t,4> key;
|
|
||||||
std::vector<uint32_t> dec;
|
|
||||||
std::vector<uint32_t> enc;
|
|
||||||
} TESTS[] = {
|
|
||||||
// 64 bit
|
|
||||||
{
|
|
||||||
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
|
|
||||||
{ 0x00000000, 0x00000000 },
|
|
||||||
{ 0x053704AB, 0x575D8C80 }
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
|
||||||
{0x01020304, 0x05060708},
|
|
||||||
{0xE6911910, 0x0C35DCDA},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF},
|
|
||||||
{0x01020304, 0x05060708},
|
|
||||||
{0x961D49FC, 0x61FF12D6},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF},
|
|
||||||
{0x01234567, 0x89ABCDEF},
|
|
||||||
{0x34354989, 0xDD7D1A7A},
|
|
||||||
},
|
|
||||||
|
|
||||||
// 96 bit
|
|
||||||
{
|
|
||||||
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
|
||||||
{0x00000000, 0x00000000, 0x00000000},
|
|
||||||
{0x5E3CD3F0, 0xE109E3CE, 0x79D7C945},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
|
||||||
{0x00010203, 0x04050607, 0x08090A0B},
|
|
||||||
{0x5A545AAC, 0x684EB2CB, 0x3E1B8AA0},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF},
|
|
||||||
{0x00010203, 0x04050607, 0x08090A0B},
|
|
||||||
{0x2E77CCEC, 0x674F5149, 0xA0E56496},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF},
|
|
||||||
{0x01234567, 0x89ABCDEF, 0x01234567},
|
|
||||||
{0xEBC5DD46, 0xBE0FEE71, 0xC6BF7193},
|
|
||||||
},
|
|
||||||
|
|
||||||
// 128 bit
|
|
||||||
{
|
|
||||||
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
|
||||||
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
|
||||||
{0xE6C8D5FF, 0x070FB6E4, 0x98A534F7, 0xAC03E399},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
|
||||||
{0x00010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F},
|
|
||||||
{0xAF5CFB0E, 0xAE73552B, 0x1D968A9F, 0x5CB94509},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF},
|
|
||||||
{0x00010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F},
|
|
||||||
{0x3EA0E16C, 0x9969535A, 0xE4796D50, 0xF217EEEA},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF},
|
|
||||||
{0x01234567, 0x89ABCDEF, 0x01234567, 0x89ABCDEF},
|
|
||||||
{0x2B4AB1A4, 0x0E487B6D, 0x9A3AACC7, 0xE4132216},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
util::TAP::logger tap;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < std::size (TESTS); ++i) {
|
|
||||||
const auto &t = TESTS[i];
|
|
||||||
|
|
||||||
CHECK_EQ (t.dec.size (), t.enc.size ());
|
|
||||||
|
|
||||||
util::crypto::XXTEA gen (t.key);
|
|
||||||
|
|
||||||
std::vector<uint32_t> enc (t.dec);
|
|
||||||
gen.encrypt (enc.data (), enc.size ());
|
|
||||||
|
|
||||||
std::vector<uint32_t> dec (enc);
|
|
||||||
gen.decrypt (dec.data (), dec.size ());
|
|
||||||
|
|
||||||
tap.expect (enc == t.enc, "XXTEA_enc %zu", i);
|
|
||||||
tap.expect (dec == t.dec, "XXTEA_dec %zu", i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tap.status ();
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
|
|
||||||
#include "hash/adler.hpp"
|
#include "hash/adler.hpp"
|
||||||
#include "hash/bsdsum.hpp"
|
#include "hash/bsdsum.hpp"
|
||||||
#include "hash/simple.hpp"
|
|
||||||
|
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
#include "tap.hpp"
|
#include "tap.hpp"
|
||||||
@ -35,19 +34,19 @@ int
|
|||||||
main (int, char**) {
|
main (int, char**) {
|
||||||
util::TAP::logger tap;
|
util::TAP::logger tap;
|
||||||
|
|
||||||
|
util::hash::adler32 a;
|
||||||
|
util::hash::bsdsum b;
|
||||||
|
|
||||||
for (const auto &t: TESTS) {
|
for (const auto &t: TESTS) {
|
||||||
tap.expect_eq (
|
tap.expect_eq (
|
||||||
t.adler,
|
t.adler,
|
||||||
util::hash::simple<util::hash::adler32> (
|
a (util::view {t.data}.template cast<const uint8_t> ()),
|
||||||
(const void*)t.data,
|
|
||||||
(const void*)(t.data + strlen (t.data))
|
|
||||||
),
|
|
||||||
"adler checksum: %s", t.msg
|
"adler checksum: %s", t.msg
|
||||||
);
|
);
|
||||||
|
|
||||||
tap.expect_eq (
|
tap.expect_eq (
|
||||||
t.bsd,
|
t.bsd,
|
||||||
util::hash::simple<util::hash::bsdsum> (t.data, t.data + strlen (t.data)),
|
b (util::view {t.data}.template cast<const uint8_t> ()),
|
||||||
"bsdsum checksum: %s", t.msg);
|
"bsdsum checksum: %s", t.msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "tap.hpp"
|
#include "tap.hpp"
|
||||||
#include "hash/crc.hpp"
|
#include "hash/crc.hpp"
|
||||||
#include "hash/simple.hpp"
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -34,15 +33,8 @@ main (int, char**)
|
|||||||
util::TAP::logger tap;
|
util::TAP::logger tap;
|
||||||
|
|
||||||
for (const auto &t: TESTS) {
|
for (const auto &t: TESTS) {
|
||||||
auto first = t.dat;
|
|
||||||
auto last = first + strlen (t.dat);
|
|
||||||
|
|
||||||
#define TEST(KLASS) do { \
|
#define TEST(KLASS) do { \
|
||||||
auto computed = \
|
auto computed = util::hash::KLASS{}(util::view {t.dat}.template cast<const uint8_t> ()); \
|
||||||
util::hash::simple< \
|
|
||||||
util::hash::KLASS \
|
|
||||||
> (first, last); \
|
|
||||||
\
|
|
||||||
tap.expect_eq (t.result.KLASS, computed, "%s: %s", #KLASS, t.msg); \
|
tap.expect_eq (t.result.KLASS, computed, "%s: %s", #KLASS, t.msg); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -3,6 +3,19 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
std::vector<uint8_t>
|
||||||
|
operator"" _u8s (const char *str, size_t len)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> res;
|
||||||
|
res.resize (len);
|
||||||
|
std::copy_n (str, len, std::begin (res));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
int
|
int
|
||||||
main (void)
|
main (void)
|
||||||
{
|
{
|
||||||
@ -13,23 +26,26 @@ main (void)
|
|||||||
uint32_t hash32;
|
uint32_t hash32;
|
||||||
uint64_t seed64;
|
uint64_t seed64;
|
||||||
uint64_t hash64;
|
uint64_t hash64;
|
||||||
const char *str;
|
std::vector<uint8_t> data;
|
||||||
} TESTS[] = {
|
} TESTS[] = {
|
||||||
{ 0x00000000, 0x00000000, 0x0000000000000000, 0x0000000000000000, "" },
|
{ 0x00000000, 0x00000000, 0x0000000000000000, 0x0000000000000000, ""_u8s },
|
||||||
{ 0x00000001, 0xd30ac4de, 0x0000000000000001, 0x2127599bf4321e79, "" },
|
{ 0x00000001, 0xd30ac4de, 0x0000000000000001, 0x2127599bf4321e79, ""_u8s },
|
||||||
{ 0xffffffff, 0xf5c7b4b0, 0xffffffffffffffff, 0x9b4792000001368f, "" },
|
{ 0xffffffff, 0xf5c7b4b0, 0xffffffffffffffff, 0x9b4792000001368f, ""_u8s },
|
||||||
{ 0xf5c7b4b0, 0x228128b7, 0x9b4792000001368f, 0x67a642098cc81da6, "a" },
|
{ 0xf5c7b4b0, 0x228128b7, 0x9b4792000001368f, 0x67a642098cc81da6, "a"_u8s },
|
||||||
{ 0x228128b7, 0x8400568d, 0x67a642098cc81da6, 0xc906440e03ce99a8, "abc" },
|
{ 0x228128b7, 0x8400568d, 0x67a642098cc81da6, 0xc906440e03ce99a8, "abc"_u8s },
|
||||||
{ 0x8400568d, 0x12b4858b, 0x67a642098cc81da6, 0x1a36fbf3d71b0737, "message digest" },
|
{ 0x8400568d, 0x12b4858b, 0x67a642098cc81da6, 0x1a36fbf3d71b0737, "message digest"_u8s },
|
||||||
{ 0x12b4858b, 0x730b822e, 0x1a36fbf3d71b0737, 0x7b48e31e3ac40a0f, "abcdefghijklmnopqrstuvwxyz" },
|
{ 0x12b4858b, 0x730b822e, 0x1a36fbf3d71b0737, 0x7b48e31e3ac40a0f, "abcdefghijklmnopqrstuvwxyz"_u8s },
|
||||||
};
|
};
|
||||||
|
|
||||||
bool success32 = true;
|
bool success32 = true;
|
||||||
bool success64 = true;
|
bool success64 = true;
|
||||||
|
|
||||||
|
util::hash::fasthash<uint32_t> h32{};
|
||||||
|
util::hash::fasthash<uint64_t> h64{};
|
||||||
|
|
||||||
for (const auto &t: TESTS) {
|
for (const auto &t: TESTS) {
|
||||||
success32 = success32 && t.hash32 == util::hash::fasthash::hash32 (t.str, strlen (t.str), t.seed32);
|
success32 = success32 && t.hash32 == h32 (t.seed32, t.data);
|
||||||
success64 = success64 && t.hash64 == util::hash::fasthash::hash64 (t.str, strlen (t.str), t.seed64);
|
success64 = success64 && t.hash64 == h64 (t.seed64, t.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
tap.expect (success32, "fasthash32");
|
tap.expect (success32, "fasthash32");
|
||||||
|
32
test/hash/fnv1a.cpp
Normal file
32
test/hash/fnv1a.cpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#include "hash/fnv1a.hpp"
|
||||||
|
#include "tap.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
static const struct {
|
||||||
|
uint32_t h32;
|
||||||
|
uint64_t h64;
|
||||||
|
const char *data;
|
||||||
|
} TESTS[] = {
|
||||||
|
{ 0x811c9dc5, 0xcbf29ce484222325, "" },
|
||||||
|
{ 0xe40c292c, 0xaf63dc4c8601ec8c, "a" },
|
||||||
|
{ 0xbf9cf968, 0x85944171f73967e8, "foobar" },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
util::TAP::logger tap;
|
||||||
|
|
||||||
|
const util::hash::fnv1a<uint32_t> h32;
|
||||||
|
const util::hash::fnv1a<uint64_t> h64;
|
||||||
|
|
||||||
|
for (const auto &t: TESTS) {
|
||||||
|
tap.expect_eq (h32 (util::view{t.data}.cast <const uint8_t> ()), t.h32, "fnv1a32: '%s'", t.data);
|
||||||
|
tap.expect_eq (h64 (util::view{t.data}.cast <const uint8_t> ()), t.h64, "fnv1a64: '%s'", t.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tap.status ();
|
||||||
|
}
|
@ -1,280 +0,0 @@
|
|||||||
#include "hash/hmac.hpp"
|
|
||||||
|
|
||||||
#include "debug.hpp"
|
|
||||||
#include "hash/md5.hpp"
|
|
||||||
#include "hash/sha1.hpp"
|
|
||||||
#include "tap.hpp"
|
|
||||||
#include "types.hpp"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
using util::hash::HMAC;
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
std::vector<uint8_t>
|
|
||||||
to_vector (const char *str)
|
|
||||||
{
|
|
||||||
return std::vector<uint8_t> (str, str + strlen (str));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <class T>
|
|
||||||
bool
|
|
||||||
test_hmac (const std::vector<uint8_t> &key,
|
|
||||||
const std::vector<uint8_t> &dat,
|
|
||||||
const std::vector<uint8_t> &res)
|
|
||||||
{
|
|
||||||
util::hash::HMAC<T> h (key.data (), key.size ());
|
|
||||||
h.update (dat.data (), dat.size ());
|
|
||||||
h.finish ();
|
|
||||||
|
|
||||||
auto ours = h.digest ();
|
|
||||||
|
|
||||||
return std::equal (ours.begin (), ours.end (), res.begin ());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
typedef bool (*test_func) (const std::vector<uint8_t>&,
|
|
||||||
const std::vector<uint8_t>&,
|
|
||||||
const std::vector<uint8_t>&);
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
static const struct {
|
|
||||||
std::vector<uint8_t> key;
|
|
||||||
std::vector<uint8_t> dat;
|
|
||||||
std::vector<uint8_t> res;
|
|
||||||
test_func fun;
|
|
||||||
} TESTS[] = {
|
|
||||||
// RFC 2104 test data, MD5
|
|
||||||
{
|
|
||||||
{ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
|
||||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b },
|
|
||||||
{ 'H', 'i', ' ', 'T', 'h', 'e', 'r', 'e' },
|
|
||||||
{ 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
|
|
||||||
0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d },
|
|
||||||
&test_hmac<util::hash::MD5>
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
to_vector ("Jefe"),
|
|
||||||
to_vector ("what do ya want for nothing?"),
|
|
||||||
{ 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
|
|
||||||
0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 },
|
|
||||||
&test_hmac<util::hash::MD5>
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
|
||||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA },
|
|
||||||
{ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
|
|
||||||
0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
|
|
||||||
0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
|
|
||||||
0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
|
|
||||||
0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
|
|
||||||
0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
|
|
||||||
0xDD, 0xDD },
|
|
||||||
{ 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
|
|
||||||
0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 },
|
|
||||||
&test_hmac<util::hash::MD5>
|
|
||||||
},
|
|
||||||
|
|
||||||
// RFC 2202 test data, MD5
|
|
||||||
{
|
|
||||||
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
|
||||||
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
|
||||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
|
||||||
0x19 },
|
|
||||||
{ 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD,
|
|
||||||
0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD,
|
|
||||||
0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD,
|
|
||||||
0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD,
|
|
||||||
0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD,
|
|
||||||
0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD,
|
|
||||||
0xCD, 0xCD },
|
|
||||||
{ 0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea,
|
|
||||||
0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79 },
|
|
||||||
&test_hmac<util::hash::MD5>
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
|
||||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
|
|
||||||
to_vector ("Test With Truncation"),
|
|
||||||
{ 0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00,
|
|
||||||
0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c },
|
|
||||||
&test_hmac<util::hash::MD5>
|
|
||||||
// digest-96: 0x56461ef2342edc00f9bab995
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
|
|
||||||
to_vector ("Test Using Larger Than Block-Size Key - Hash Key First"),
|
|
||||||
{ 0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f,
|
|
||||||
0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd },
|
|
||||||
&test_hmac<util::hash::MD5>
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
|
|
||||||
to_vector ("Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"),
|
|
||||||
{ 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee,
|
|
||||||
0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e },
|
|
||||||
&test_hmac<util::hash::MD5>
|
|
||||||
},
|
|
||||||
|
|
||||||
// RFC 2202 test data, SHA1
|
|
||||||
{
|
|
||||||
{ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
|
||||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
|
||||||
0x0b, 0x0b, 0x0b, 0x0b },
|
|
||||||
to_vector ("Hi There"),
|
|
||||||
{ 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
|
|
||||||
0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
|
|
||||||
0xf1, 0x46, 0xbe, 0x00 },
|
|
||||||
&test_hmac<util::hash::SHA1>
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
to_vector ("Jefe"),
|
|
||||||
to_vector ("what do ya want for nothing?"),
|
|
||||||
{ 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2,
|
|
||||||
0xd2, 0x74, 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c,
|
|
||||||
0x25, 0x9a, 0x7c, 0x79 },
|
|
||||||
&test_hmac<util::hash::SHA1>
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa },
|
|
||||||
{ 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
|
||||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
|
||||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
|
||||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
|
||||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
|
||||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
|
||||||
0xdd, 0xdd },
|
|
||||||
{ 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd,
|
|
||||||
0x91, 0xa3, 0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f,
|
|
||||||
0x63, 0xf1, 0x75, 0xd3 },
|
|
||||||
&test_hmac<util::hash::SHA1>
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
|
||||||
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
|
||||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
|
||||||
0x19 },
|
|
||||||
{ 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
|
||||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
|
||||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
|
||||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
|
||||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
|
||||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
|
||||||
0xcd, 0xcd },
|
|
||||||
{ 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6,
|
|
||||||
0xbc, 0x84, 0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c,
|
|
||||||
0x2d, 0x72, 0x35, 0xda },
|
|
||||||
&test_hmac<util::hash::SHA1>
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
|
||||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
|
||||||
0x0c, 0x0c, 0x0c, 0x0c },
|
|
||||||
to_vector ("Test With Truncation"),
|
|
||||||
{ 0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f,
|
|
||||||
0xe7, 0xf2, 0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32,
|
|
||||||
0x4a, 0x9a, 0x5a, 0x04 },
|
|
||||||
&test_hmac<util::hash::SHA1>
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
|
|
||||||
to_vector ("Test Using Larger Than Block-Size Key - Hash Key First"),
|
|
||||||
{ 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e,
|
|
||||||
0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55,
|
|
||||||
0xed, 0x40, 0x21, 0x12 },
|
|
||||||
&test_hmac<util::hash::SHA1>
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
|
|
||||||
to_vector ("Test Using Larger Than Block-Size Key - Hash Key First"),
|
|
||||||
{ 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e,
|
|
||||||
0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55,
|
|
||||||
0xed, 0x40, 0x21, 0x12 },
|
|
||||||
&test_hmac<util::hash::SHA1>
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
||||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
|
|
||||||
to_vector ("Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data"),
|
|
||||||
{ 0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78,
|
|
||||||
0x6d, 0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08,
|
|
||||||
0xbb, 0xff, 0x1a, 0x91 },
|
|
||||||
&test_hmac<util::hash::SHA1>
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
int
|
|
||||||
main (int, char**)
|
|
||||||
{
|
|
||||||
util::TAP::logger tap;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < std::size (TESTS); ++i)
|
|
||||||
tap.expect (TESTS[i].fun (TESTS[i].key, TESTS[i].dat, TESTS[i].res), "standard test vector %zu", i);
|
|
||||||
|
|
||||||
return tap.status ();
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
#include "hash/hotp.hpp"
|
|
||||||
|
|
||||||
#include "debug.hpp"
|
|
||||||
#include "tap.hpp"
|
|
||||||
#include "types.hpp"
|
|
||||||
|
|
||||||
using util::hash::HOTP;
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int, char**)
|
|
||||||
{
|
|
||||||
HOTP h ("12345678901234567890", 0);
|
|
||||||
|
|
||||||
const unsigned EXPECTED[] = {
|
|
||||||
755224,
|
|
||||||
287082,
|
|
||||||
359152,
|
|
||||||
969429,
|
|
||||||
338314,
|
|
||||||
254676,
|
|
||||||
287922,
|
|
||||||
162583,
|
|
||||||
399871,
|
|
||||||
520489,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
util::TAP::logger tap;
|
|
||||||
|
|
||||||
for (auto &i: EXPECTED)
|
|
||||||
tap.expect_eq (i, h.value (), "sequence");
|
|
||||||
|
|
||||||
return tap.status ();
|
|
||||||
}
|
|
@ -1,180 +0,0 @@
|
|||||||
#include "hash/keccak.hpp"
|
|
||||||
#include "debug.hpp"
|
|
||||||
#include "tap.hpp"
|
|
||||||
|
|
||||||
#include <iomanip>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
static constexpr
|
|
||||||
uint8_t
|
|
||||||
from_hex (char c) {
|
|
||||||
switch (c) {
|
|
||||||
case '0':
|
|
||||||
case '1':
|
|
||||||
case '2':
|
|
||||||
case '3':
|
|
||||||
case '4':
|
|
||||||
case '5':
|
|
||||||
case '6':
|
|
||||||
case '7':
|
|
||||||
case '8':
|
|
||||||
case '9':
|
|
||||||
return c - '0';
|
|
||||||
|
|
||||||
case 'A':
|
|
||||||
case 'B':
|
|
||||||
case 'C':
|
|
||||||
case 'D':
|
|
||||||
case 'E':
|
|
||||||
case 'F':
|
|
||||||
return 10 + c - 'A';
|
|
||||||
|
|
||||||
case 'a':
|
|
||||||
case 'b':
|
|
||||||
case 'c':
|
|
||||||
case 'd':
|
|
||||||
case 'e':
|
|
||||||
case 'f':
|
|
||||||
return 10 + c - 'a';
|
|
||||||
}
|
|
||||||
|
|
||||||
unreachable ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <size_t S>
|
|
||||||
static constexpr
|
|
||||||
std::array<uint8_t,S/2>
|
|
||||||
make_array (const char (&str)[S])
|
|
||||||
{
|
|
||||||
if (S < 1)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
static_assert (S % 2 == 1, "requires full bytes + null");
|
|
||||||
std::array<uint8_t,S/2> out {};
|
|
||||||
|
|
||||||
for (size_t i = 0; i < S - 1; i+=2) {
|
|
||||||
out[i / 2] = +from_hex (str[i]) << 4 | +from_hex (str[i+1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <size_t S>
|
|
||||||
static
|
|
||||||
std::vector<uint8_t>
|
|
||||||
make_vector (const char (&str)[S]) {
|
|
||||||
const auto arr = make_array (str);
|
|
||||||
return std::vector<uint8_t> (arr.cbegin (), arr.cend ());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int, char**)
|
|
||||||
{
|
|
||||||
util::TAP::logger tap;
|
|
||||||
|
|
||||||
static const struct {
|
|
||||||
const char *msg;
|
|
||||||
std::vector<uint8_t> data;
|
|
||||||
|
|
||||||
std::array<uint8_t, 28> sha3_224;
|
|
||||||
std::array<uint8_t, 32> sha3_256;
|
|
||||||
std::array<uint8_t, 48> sha3_384;
|
|
||||||
std::array<uint8_t, 64> sha3_512;
|
|
||||||
} TESTS[] = {
|
|
||||||
{
|
|
||||||
" empty string",
|
|
||||||
{ },
|
|
||||||
make_array ("6B4E03423667DBB73B6E15454F0EB1ABD4597F9A1B078E3F5B5A6BC7"),
|
|
||||||
make_array ("A7FFC6F8BF1ED76651C14756A061D662F580FF4DE43B49FA82D80A4B80F8434A"),
|
|
||||||
make_array ("0C63A75B845E4F7D01107D852E4C2485C51A50AAAA94FC61995E71BBEE983A2AC3713831264ADB47FB6BD1E058D5F004"),
|
|
||||||
make_array ("A69F73CCA23A9AC5C8B567DC185A756E97C982164FE25859E0D1DCC1475C80A615B2123AF1F5F94C11E3E9402C3AC558F500199D95B6D3E301758586281DCD26"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
" 8-bit string",
|
|
||||||
make_vector ("CC"),
|
|
||||||
make_array ("DF70ADC49B2E76EEE3A6931B93FA41841C3AF2CDF5B32A18B5478C39"),
|
|
||||||
make_array ("677035391CD3701293D385F037BA32796252BB7CE180B00B582DD9B20AAAD7F0"),
|
|
||||||
make_array ("5EE7F374973CD4BB3DC41E3081346798497FF6E36CB9352281DFE07D07FC530CA9AD8EF7AAD56EF5D41BE83D5E543807"),
|
|
||||||
make_array ("3939FCC8B57B63612542DA31A834E5DCC36E2EE0F652AC72E02624FA2E5ADEECC7DD6BB3580224B4D6138706FC6E80597B528051230B00621CC2B22999EAA205"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
" 16-bit string",
|
|
||||||
make_vector ("41FB"),
|
|
||||||
make_array ("BFF295861DAEDF33E70519B1E2BCB4C2E9FE3364D789BC3B17301C15"),
|
|
||||||
make_array ("39F31B6E653DFCD9CAED2602FD87F61B6254F581312FB6EEEC4D7148FA2E72AA"),
|
|
||||||
make_array ("1DD81609DCC290EFFD7AC0A95D4A20821580E56BD50DBD843920650BE7A80A1719577DA337CFDF86E51C764CAA2E10BD"),
|
|
||||||
make_array ("AA092865A40694D91754DBC767B5202C546E226877147A95CB8B4C8F8709FE8CD6905256B089DA37896EA5CA19D2CD9AB94C7192FC39F7CD4D598975A3013C69"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"224-bit string",
|
|
||||||
make_vector ("0F8B2D8FCFD9D68CFFC17CCFB117709B53D26462A3F346FB7C79B85E"),
|
|
||||||
make_array ("1E693B0BCE2372550DAEF35B14F13AB43441ED6742DEE3E86FD1D8EF"),
|
|
||||||
make_array ("6DE164A9626D5A4F54D854AC158994F35A8E362ECC753F55182790934A2E0D06"),
|
|
||||||
make_array ("641A7AF13B889D1A0F1AA3E4E4FF8CC5903C47E1A52BDEA257D80E37E596564AB33EEAD06717CDB6B706CB6986293D4F"),
|
|
||||||
make_array ("21132FC11F6040AD493D627027C752CE29816589DE7BE78562914B63D1A9219803DDBD9673AA749F37FF4D6E1B5AE2A12633BA8B0C9994E031EBF6C42E58A793"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"256-bit string",
|
|
||||||
make_vector ("9F2FCC7C90DE090D6B87CD7E9718C1EA6CB21118FC2D5DE9F97E5DB6AC1E9C10"),
|
|
||||||
make_array ("887921848AD98458F3DB3E0ECD5AD5DB1F0BF9F2D0CA08601074D597"),
|
|
||||||
make_array ("2F1A5F7159E34EA19CDDC70EBF9B81F1A66DB40615D7EAD3CC1F1B954D82A3AF"),
|
|
||||||
make_array ("BAAE7AAED4FBF42F9316C7E8F722EEB06A598B509F184B22FBD5A81C93D95FFF711F5DE90847B3248B6DF76CABCE07EE"),
|
|
||||||
make_array ("B087C90421AEBF87911647DE9D465CBDA166B672EC47CCD4054A7135A1EF885E7903B52C3F2C3FE722B1C169297A91B82428956A02C631A2240F12162C7BC726"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"384-bit string",
|
|
||||||
make_vector ("D8FABA1F5194C4DB5F176FABFFF856924EF627A37CD08CF55608BBA8F1E324D7C7F157298EABC4DCE7D89CE5162499F9"),
|
|
||||||
make_array ("B7A51FBB084DEEB55136EFD7260E5B112E3C40D1A2D14B142DF930DF"),
|
|
||||||
make_array ("34F8607EC10C092C1BA0B6565CE6197062C4E1A35A8E8C723E48A2D2416C3790"),
|
|
||||||
make_array ("A127FEFCDD240F762CCE3F5F1551FC7E1CDEBC7950D1CD94C6888F490CB2285A10FD0EE797B168C5CA4761FA232AAF05"),
|
|
||||||
make_array ("7EF3A2894C6ECBC4201B15348F90671515ACCBA3C8166621F864A9184BF08C3F5A895F6B599D3CB41F20A8A1DF25AE84F1A6D7C8DE74FB7CEF48F7E96FDE8D43"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"512-bit string",
|
|
||||||
make_vector ("E926AE8B0AF6E53176DBFFCC2A6B88C6BD765F939D3D178A9BDE9EF3AA131C61E31C1E42CDFAF4B4DCDE579A37E150EFBEF5555B4C1CB40439D835A724E2FAE7"),
|
|
||||||
make_array ("C154607F986F9BF902D831293C8386D36B201EABA6F6FB0B678B4B81"),
|
|
||||||
make_array ("27A6441EE939B46E2C378D7AFEB0E891C47A28120E488EFF0AB71AF08788CEB3"),
|
|
||||||
make_array ("423BA134D3BCB5E440AC83372C7EDDBA3AE3BDDF1222F505C19CDE246AD76A2B0D07239A54E1D0934C9B3D29D49E5FBD"),
|
|
||||||
make_array ("EB5067BF762A291CF258AD69A816A0B089E0BD44F8E5B74CF60BCE64734E59853CCB8D091CD2E33F90AA063FB7942CF5965D459200144C1A0801ABD69A9A094A"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"520-bit string",
|
|
||||||
make_vector ("16E8B3D8F988E9BB04DE9C96F2627811C973CE4A5296B4772CA3EEFEB80A652BDF21F50DF79F32DB23F9F73D393B2D57D9A0297F7A2F2E79CFDA39FA393DF1AC00"),
|
|
||||||
make_array ("95E87AC90F541AB90CBCF7FD7E0E0C152CEF78D5EE1830E9ED8A1ED7"),
|
|
||||||
make_array ("C4BB067383002DB44CA773918BB74104B604A583E12B06BE56C270F8B43512F2"),
|
|
||||||
make_array ("662C4851D311A786DE4CDA7E9EA1EFF0BFA462761FF6CF804E591ED9A15B0DC93A2BB6A6CFFDC8D7D23A233A52C86EAD"),
|
|
||||||
make_array ("B0E23D600BA4215F79D50047BBFED50DF7D6E769514D796AFD166DEECA88BD1CBE0AFC72A41E0317A223225B4F5882F723AFCBA3AF7C457EB525946DA6C53BB0"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"1,000,000 'a' string",
|
|
||||||
std::vector<uint8_t> (1'000'000, 'a'),
|
|
||||||
make_array ("d69335b93325192e516a912e6d19a15cb51c6ed5c15243e7a7fd653c"),
|
|
||||||
make_array ("5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1"),
|
|
||||||
make_array ("eee9e24d78c1855337983451df97c8ad9eedf256c6334f8e948d252d5e0e76847aa0774ddb90a842190d2c558b4b8340"),
|
|
||||||
make_array ("3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87"),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const auto &t: TESTS) {
|
|
||||||
#define TEST(WIDTH) \
|
|
||||||
do { \
|
|
||||||
std::array<uint8_t, WIDTH/8> sha3_##WIDTH; \
|
|
||||||
std::fill (std::begin (sha3_##WIDTH), std::end (sha3_##WIDTH), 0); \
|
|
||||||
\
|
|
||||||
FIPS202_SHA3_##WIDTH (t.data.data (), t.data.size (), &sha3_##WIDTH[0]); \
|
|
||||||
\
|
|
||||||
tap.expect_eq (t.sha3_##WIDTH, sha3_##WIDTH, "sha3-%u %s", unsigned (WIDTH), t.msg); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
TEST(224);
|
|
||||||
TEST(256);
|
|
||||||
TEST(384);
|
|
||||||
TEST(512);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tap.status ();
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
#include "hash/md2.hpp"
|
|
||||||
|
|
||||||
#include "tap.hpp"
|
|
||||||
|
|
||||||
using util::hash::MD2;
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int, char **) {
|
|
||||||
static const struct {
|
|
||||||
const char *input;
|
|
||||||
MD2::digest_t output;
|
|
||||||
} TESTS[] = {
|
|
||||||
{ "",
|
|
||||||
{ { 0x83, 0x50, 0xe5, 0xa3, 0xe2, 0x4c, 0x15, 0x3d,
|
|
||||||
0xf2, 0x27, 0x5c, 0x9f, 0x80, 0x69, 0x27, 0x73 } }
|
|
||||||
},
|
|
||||||
{ "a",
|
|
||||||
{ { 0x32, 0xec, 0x01, 0xec, 0x4a, 0x6d, 0xac, 0x72,
|
|
||||||
0xc0, 0xab, 0x96, 0xfb, 0x34, 0xc0, 0xb5, 0xd1 } }
|
|
||||||
},
|
|
||||||
{ "abc",
|
|
||||||
{ { 0xda, 0x85, 0x3b, 0x0d, 0x3f, 0x88, 0xd9, 0x9b,
|
|
||||||
0x30, 0x28, 0x3a, 0x69, 0xe6, 0xde, 0xd6, 0xbb } }
|
|
||||||
},
|
|
||||||
{ "message digest",
|
|
||||||
{ { 0xab, 0x4f, 0x49, 0x6b, 0xfb, 0x2a, 0x53, 0x0b,
|
|
||||||
0x21, 0x9f, 0xf3, 0x30, 0x31, 0xfe, 0x06, 0xb0 } }
|
|
||||||
},
|
|
||||||
{ "abcdefghijklmnopqrstuvwxyz",
|
|
||||||
{ { 0x4e, 0x8d, 0xdf, 0xf3, 0x65, 0x02, 0x92, 0xab,
|
|
||||||
0x5a, 0x41, 0x08, 0xc3, 0xaa, 0x47, 0x94, 0x0b } }
|
|
||||||
},
|
|
||||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
|
||||||
{ { 0xda, 0x33, 0xde, 0xf2, 0xa4, 0x2d, 0xf1, 0x39,
|
|
||||||
0x75, 0x35, 0x28, 0x46, 0xc3, 0x03, 0x38, 0xcd } }
|
|
||||||
},
|
|
||||||
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
|
||||||
{ { 0xd5, 0x97, 0x6f, 0x79, 0xd8, 0x3d, 0x3a, 0x0d,
|
|
||||||
0xc9, 0x80, 0x6c, 0x3c, 0x66, 0xf3, 0xef, 0xd8 } }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool success = true;
|
|
||||||
|
|
||||||
for (const auto &i: TESTS) {
|
|
||||||
MD2 h;
|
|
||||||
h.update (i.input, strlen (i.input));
|
|
||||||
h.finish ();
|
|
||||||
auto out = h.digest ();
|
|
||||||
|
|
||||||
if (out != i.output) {
|
|
||||||
std::cerr << "Failed on " << i.input << "\n";
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
util::TAP::logger tap;
|
|
||||||
tap.expect (success, "test vectors");
|
|
||||||
return tap.status ();
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
#include "hash/md4.hpp"
|
|
||||||
|
|
||||||
#include "tap.hpp"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
|
|
||||||
using util::hash::MD4;
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int, char**) {
|
|
||||||
static const struct {
|
|
||||||
const char *input;
|
|
||||||
MD4::digest_t output;
|
|
||||||
} TESTS[] = {
|
|
||||||
{
|
|
||||||
"",
|
|
||||||
{ { 0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31,
|
|
||||||
0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0 } }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"a",
|
|
||||||
{ { 0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46,
|
|
||||||
0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24 } }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"abc",
|
|
||||||
{ { 0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52,
|
|
||||||
0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d } }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"message digest",
|
|
||||||
{ { 0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8,
|
|
||||||
0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b } }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"abcdefghijklmnopqrstuvwxyz",
|
|
||||||
{ { 0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd,
|
|
||||||
0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9 }, }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
|
||||||
{ { 0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35,
|
|
||||||
0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4 } }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
|
||||||
{ { 0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19,
|
|
||||||
0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36 } }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool success = true;
|
|
||||||
|
|
||||||
for (auto i: TESTS) {
|
|
||||||
MD4 h;
|
|
||||||
h.update (i.input, strlen (i.input));
|
|
||||||
h.finish ();
|
|
||||||
auto out = h.digest ();
|
|
||||||
|
|
||||||
if (out != i.output) {
|
|
||||||
std::cerr << "Failed on '" << i.input << "'\n";
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
util::TAP::logger tap;
|
|
||||||
tap.expect (success, "test vectors");
|
|
||||||
return tap.status ();
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
#include "hash/md5.hpp"
|
|
||||||
|
|
||||||
#include "tap.hpp"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
using util::hash::MD5;
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int, char**) {
|
|
||||||
static const struct {
|
|
||||||
const char *input;
|
|
||||||
MD5::digest_t output;
|
|
||||||
} TESTS[] = {
|
|
||||||
{ "",
|
|
||||||
{ { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
|
|
||||||
0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } }
|
|
||||||
},
|
|
||||||
{ "a",
|
|
||||||
{ { 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
|
|
||||||
0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } }
|
|
||||||
},
|
|
||||||
{ "abc",
|
|
||||||
{ { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
|
|
||||||
0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } }
|
|
||||||
},
|
|
||||||
{ "message digest",
|
|
||||||
{ { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
|
|
||||||
0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } }
|
|
||||||
},
|
|
||||||
{ "abcdefghijklmnopqrstuvwxyz",
|
|
||||||
{ { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
|
|
||||||
0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } }
|
|
||||||
},
|
|
||||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
|
||||||
{ { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
|
|
||||||
0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } }
|
|
||||||
},
|
|
||||||
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
|
||||||
{ { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
|
|
||||||
0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool success = true;
|
|
||||||
|
|
||||||
for (auto i: TESTS) {
|
|
||||||
MD5 h;
|
|
||||||
h.update (i.input, strlen (i.input));
|
|
||||||
h.finish ();
|
|
||||||
auto out = h.digest ();
|
|
||||||
|
|
||||||
if (out != i.output) {
|
|
||||||
std::cerr << "Failed on '" << i.input << "'\n";
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
util::TAP::logger tap;
|
|
||||||
tap.expect (success, "test vectors");
|
|
||||||
return tap.status ();
|
|
||||||
}
|
|
@ -6,11 +6,35 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
std::vector<uint8_t>
|
||||||
|
operator"" _u8s (const char *str, size_t len)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> res;
|
||||||
|
res.resize (len);
|
||||||
|
std::copy_n (str, len, std::begin (res));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <size_t N>
|
||||||
|
std::ostream&
|
||||||
|
operator<< (std::ostream &os, std::array<uint8_t,N> &val)
|
||||||
|
{
|
||||||
|
for (auto c: val)
|
||||||
|
os << c;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void
|
void
|
||||||
test (util::TAP::logger &tap)
|
test (util::TAP::logger &tap)
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
const char *key;
|
std::vector<uint8_t> data;
|
||||||
|
const char *msg;
|
||||||
|
|
||||||
struct { uint32_t seed; uint32_t hash; } m1_32;
|
struct { uint32_t seed; uint32_t hash; } m1_32;
|
||||||
struct { uint32_t seed; uint32_t hash; } m2_32;
|
struct { uint32_t seed; uint32_t hash; } m2_32;
|
||||||
@ -21,7 +45,8 @@ test (util::TAP::logger &tap)
|
|||||||
struct { uint32_t seed; std::array<uint64_t,2> hash; } m3_128_x64;
|
struct { uint32_t seed; std::array<uint64_t,2> hash; } m3_128_x64;
|
||||||
|
|
||||||
} TESTS[] = {
|
} TESTS[] = {
|
||||||
{ "",
|
{ ""_u8s,
|
||||||
|
"empty, zero seed",
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
@ -30,7 +55,8 @@ test (util::TAP::logger &tap)
|
|||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
},
|
},
|
||||||
|
|
||||||
{ "",
|
{ ""_u8s,
|
||||||
|
"empty, nonzero seed",
|
||||||
{ 0x00000001, 0x8f5a8d63 },
|
{ 0x00000001, 0x8f5a8d63 },
|
||||||
{ 0x00000001, 0x5bd15e36 },
|
{ 0x00000001, 0x5bd15e36 },
|
||||||
{ 1, 0xc6a4a7935bd064dc },
|
{ 1, 0xc6a4a7935bd064dc },
|
||||||
@ -39,7 +65,8 @@ test (util::TAP::logger &tap)
|
|||||||
{ 1, { 0x4610abe56eff5cb5, 0x51622daa78f83583 } },
|
{ 1, { 0x4610abe56eff5cb5, 0x51622daa78f83583 } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{ "",
|
{ ""_u8s,
|
||||||
|
"empty, max seed",
|
||||||
{ 0xffffffff, 0x7a3f4f7e },
|
{ 0xffffffff, 0x7a3f4f7e },
|
||||||
{ 0xffffffff, 0xb35966b0 },
|
{ 0xffffffff, 0xb35966b0 },
|
||||||
{ uint64_t(-1), 0xb0d9485c2cd761b2 },
|
{ uint64_t(-1), 0xb0d9485c2cd761b2 },
|
||||||
@ -48,7 +75,8 @@ test (util::TAP::logger &tap)
|
|||||||
{ 0xffffffff, { 0x6af1df4d9d3bc9ec, 0x857421121ee6446b } },
|
{ 0xffffffff, { 0x6af1df4d9d3bc9ec, 0x857421121ee6446b } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{ "a",
|
{ "a"_u8s,
|
||||||
|
"1 byte",
|
||||||
{ 0x7a3f4f7e, 0x18abad09 },
|
{ 0x7a3f4f7e, 0x18abad09 },
|
||||||
{ 0xb35966b0, 0x1eea8b10 },
|
{ 0xb35966b0, 0x1eea8b10 },
|
||||||
{ 0xb0d9485c2cd761b2, 0x0a9b4c93b35b1b9f },
|
{ 0xb0d9485c2cd761b2, 0x0a9b4c93b35b1b9f },
|
||||||
@ -56,7 +84,8 @@ test (util::TAP::logger &tap)
|
|||||||
{ 0x051e08a9, { 0x08e91d27, 0x12c6d92a, 0x12c6d92a, 0x12c6d92a } },
|
{ 0x051e08a9, { 0x08e91d27, 0x12c6d92a, 0x12c6d92a, 0x12c6d92a } },
|
||||||
{ 0x9d3bc9ec, { 0xf79489c9f1a785de, 0xf6486d31835a9c7f } },
|
{ 0x9d3bc9ec, { 0xf79489c9f1a785de, 0xf6486d31835a9c7f } },
|
||||||
},
|
},
|
||||||
{ "abc",
|
{ "abc"_u8s,
|
||||||
|
"3 byte",
|
||||||
{ 0x18abad09, 0x1defb5e9 },
|
{ 0x18abad09, 0x1defb5e9 },
|
||||||
{ 0x1eea8b10, 0x72cac527 },
|
{ 0x1eea8b10, 0x72cac527 },
|
||||||
{ 0x0a9b4c93b35b1b9f, 0x2ffdf3214d9a4fa4 },
|
{ 0x0a9b4c93b35b1b9f, 0x2ffdf3214d9a4fa4 },
|
||||||
@ -64,7 +93,8 @@ test (util::TAP::logger &tap)
|
|||||||
{ 0x08e91d27, { 0xc11cc883, 0xb5d7f69a, 0xb5d7f69a, 0xb5d7f69a } },
|
{ 0x08e91d27, { 0xc11cc883, 0xb5d7f69a, 0xb5d7f69a, 0xb5d7f69a } },
|
||||||
{ 0xf1a785de, { 0x946e5ee63ce3b80e, 0xadb7d6d0e2558c3c } },
|
{ 0xf1a785de, { 0x946e5ee63ce3b80e, 0xadb7d6d0e2558c3c } },
|
||||||
},
|
},
|
||||||
{ "message digest",
|
{ "message digest"_u8s,
|
||||||
|
"14 byte",
|
||||||
{ 0x1defb5e9, 0x7b3ea4bd },
|
{ 0x1defb5e9, 0x7b3ea4bd },
|
||||||
{ 0x72cac527, 0x68563c37 },
|
{ 0x72cac527, 0x68563c37 },
|
||||||
{ 0x2ffdf3214d9a4fa4, 0x9a83e79336350cee },
|
{ 0x2ffdf3214d9a4fa4, 0x9a83e79336350cee },
|
||||||
@ -73,7 +103,8 @@ test (util::TAP::logger &tap)
|
|||||||
{ 0x3ce3b80e, { 0x2c91b16326bf5f7f, 0xa21acf13c39485bc } },
|
{ 0x3ce3b80e, { 0x2c91b16326bf5f7f, 0xa21acf13c39485bc } },
|
||||||
},
|
},
|
||||||
|
|
||||||
{ "abcdefghijklmnopqrstuvwxyz",
|
{ "abcdefghijklmnopqrstuvwxyz"_u8s,
|
||||||
|
"26 byte",
|
||||||
{ 0x7b3ea4bd, 0xd94ee9ea },
|
{ 0x7b3ea4bd, 0xd94ee9ea },
|
||||||
{ 0x68563c37, 0x0473b699 },
|
{ 0x68563c37, 0x0473b699 },
|
||||||
{ 0x9a83e79336350cee, 0x1f256c898952ae12 },
|
{ 0x9a83e79336350cee, 0x1f256c898952ae12 },
|
||||||
@ -83,42 +114,29 @@ test (util::TAP::logger &tap)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool m1_32 = true;
|
|
||||||
bool m2_32 = true;
|
|
||||||
bool m2_64 = true;
|
|
||||||
bool m3_32 = true;
|
|
||||||
|
|
||||||
bool m3_128_x86 = true;
|
|
||||||
bool m3_128_x64 = true;
|
|
||||||
|
|
||||||
for (const auto &t: TESTS) {
|
for (const auto &t: TESTS) {
|
||||||
m1_32 = m1_32 && (t.m1_32.hash == util::hash::murmur1::hash_32 (t.key, strlen (t.key), t.m1_32.seed));
|
const util::hash::murmur1 h1 (t.m1_32.seed);
|
||||||
m2_32 = m2_32 && (t.m2_32.hash == util::hash::murmur2::hash_32 (t.key, strlen (t.key), t.m2_32.seed));
|
|
||||||
m2_64 = m2_64 && (t.m2_64.hash == util::hash::murmur2::hash_64 (t.key, strlen (t.key), t.m2_64.seed));
|
|
||||||
m3_32 = m3_32 && (t.m3_32.hash == util::hash::murmur3::hash_32 (t.key, strlen (t.key), t.m3_32.seed));
|
|
||||||
|
|
||||||
{
|
const util::hash::murmur2<uint32_t> h2_32 (t.m2_32.seed);
|
||||||
auto result = util::hash::murmur3::hash_128_x86 (t.key, strlen (t.key), t.m3_128_x86.seed);
|
const util::hash::murmur2<uint64_t> h2_64 (t.m2_64.seed);
|
||||||
bool success = t.m3_128_x86.hash == result;
|
|
||||||
m3_128_x86 = m3_128_x86 && success;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
const util::hash::murmur3_32 h3 (t.m3_32.seed);
|
||||||
auto result = util::hash::murmur3::hash_128_x64 (t.key, strlen (t.key), t.m3_128_x64.seed);
|
const util::hash::murmur3_128_x86 h3_x86 (t.m3_128_x86.seed);
|
||||||
bool success = t.m3_128_x64.hash == result;
|
const util::hash::murmur3_128_x64 h3_x64 (t.m3_128_x64.seed);
|
||||||
m3_128_x64 = m3_128_x64 && success;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tap.expect (m1_32, "murmur1_32");
|
tap.expect_eq (h1 (t.data), t.m1_32.hash, "murmur1_32, '%s'", t.msg);
|
||||||
tap.expect (m2_32, "murmur2_32");
|
tap.expect_eq (h2_32 (t.data), t.m2_32.hash, "murmur2_32, '%s'", t.msg);
|
||||||
tap.expect (m2_64, "murmur2_64");
|
tap.expect_eq (h2_64 (t.data), t.m2_64.hash, "murmur2_64, '%s'", t.msg);
|
||||||
tap.expect (m3_32, "murmur3_32");
|
|
||||||
tap.expect (m3_128_x86, "murmur3_128_x86");
|
tap.expect_eq (h3 (t.data), t.m3_32.hash, "murmur3_32, '%s'", t.msg);
|
||||||
tap.expect (m3_128_x64, "murmur3_128_x64");
|
tap.expect_eq (h3_x86 (t.data), t.m3_128_x86.hash, "murmur3_128_x86, '%s'", t.msg);
|
||||||
|
tap.expect_eq (h3_x64 (t.data), t.m3_128_x64.hash, "murmur3_128_x64, '%s'", t.msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
int
|
int
|
||||||
main (void)
|
main (void)
|
||||||
{
|
{
|
||||||
|
@ -1,142 +0,0 @@
|
|||||||
#include "hash/ripemd.hpp"
|
|
||||||
|
|
||||||
#include "tap.hpp"
|
|
||||||
#include "types.hpp"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
static const
|
|
||||||
struct {
|
|
||||||
const char *msg;
|
|
||||||
const char *data;
|
|
||||||
util::hash::RIPEMD::digest_t output;
|
|
||||||
} TESTS[] = {
|
|
||||||
{
|
|
||||||
"empty",
|
|
||||||
"",
|
|
||||||
{ 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
|
|
||||||
0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
|
|
||||||
// 128: cdf26213a150dc3ecb610f18f6b38b46
|
|
||||||
// 160: 9c1185a5c5e9fc54612808977ee8f548b2258d31
|
|
||||||
// 256: 02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d
|
|
||||||
// 320: 22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"a",
|
|
||||||
"a",
|
|
||||||
{ 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
|
|
||||||
0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
|
|
||||||
// 128: 86be7afa339d0fc7cfc785e72f578d33
|
|
||||||
// 160: 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe
|
|
||||||
// 256: f9333e45d857f5d90a91bab70a1eba0cfb1be4b0783c9acfcd883a9134692925
|
|
||||||
// 320: ce78850638f92658a5a585097579926dda667a5716562cfcf6fbe77f63542f99b04705d6970dff5d
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"abc",
|
|
||||||
"abc",
|
|
||||||
{ 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
|
|
||||||
0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
|
|
||||||
// 128: c14a12199c66e4ba84636b0f69144c77
|
|
||||||
// 160: 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
|
|
||||||
// 256: afbd6e228b9d8cbbcef5ca2d03e6dba10ac0bc7dcbe4680e1e42d2e975459b65
|
|
||||||
// 320: de4c01b3054f8930a79d09ae738e92301e5a17085beffdc1b8d116713e74f82fa942d64cdbc4682d
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"message digest",
|
|
||||||
"message digest",
|
|
||||||
{ 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
|
|
||||||
0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
|
|
||||||
// 128: 9e327b3d6e523062afc1132d7df9d1b8
|
|
||||||
// 160: 5d0689ef49d2fae572b881b123a85ffa21595f36
|
|
||||||
// 256: 87e971759a1ce47a514d5c914c392c9018c7c46bc14465554afcdf54a5070c0e
|
|
||||||
// 320: 3a8e28502ed45d422f68844f9dd316e7b98533fa3f2a91d29f84d425c88d6b4eff727df66a7c0197
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"26 characters",
|
|
||||||
"abcdefghijklmnopqrstuvwxyz",
|
|
||||||
{ 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
|
|
||||||
0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
|
|
||||||
// 128: fd2aa607f71dc8f510714922b371834e
|
|
||||||
// 160: f71c27109c692c1b56bbdceb5b9d2865b3708dbc
|
|
||||||
// 256: 649d3034751ea216776bf9a18acc81bc7896118a5197968782dd1fd97d8d5133
|
|
||||||
// 320: cabdb1810b92470a2093aa6bce05952c28348cf43ff60841975166bb40ed234004b8824463e6b009
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"57 characters",
|
|
||||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
|
||||||
{ 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
|
|
||||||
0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
|
|
||||||
// 128: a1aa0689d0fafa2ddc22e88b49133a06
|
|
||||||
// 160: 12a053384a9c0c88e405a06c27dcf49ada62eb2b
|
|
||||||
// 256: 3843045583aac6c8c8d9128573e7a9809afb2a0f34ccc36ea9e72f16f6368e3f
|
|
||||||
// 320: d034a7950cf722021ba4b84df769a5de2060e259df4c9bb4a4268c0e935bbc7470a969c9d072a1ac
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"63 characters",
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
|
||||||
{ 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
|
|
||||||
0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
|
|
||||||
// 128: d1e959eb179c911faea4624c60c5c702
|
|
||||||
// 160: b0e20b6e3116640286ed3a87a5713079b21f5189
|
|
||||||
// 256: 5740a408ac16b720b84424ae931cbb1fe363d1d0bf4017f1a89f7ea6de77a0b8
|
|
||||||
// 320: ed544940c86d67f250d232c30b7b3e5770e0c60c8cb9a4cafe3b11388af9920e1b99230b843c86a4
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"81 digits",
|
|
||||||
"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
|
||||||
{ 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
|
|
||||||
0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb }
|
|
||||||
// 128: 3f45ef194732c2dbb2c4a2c769795fa3
|
|
||||||
// 160: 9b752e45573d4b39f4dbd3323cab82bf63326bfb
|
|
||||||
// 256: 06fdcc7a409548aaf91368c06a6275b553e3f099bf0ea4edfd6778df89a890dd
|
|
||||||
// 320: 557888af5f6d8ed62ab66945c6d2a0a47ecd5341e915eb8fea1d0524955f825dc717e4a008ab2d42
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 1 million times "a"
|
|
||||||
// 128: 4a7f5723f954eba1216c9d8f6320431f
|
|
||||||
// 160: 52783243c1697bdbe16d37f97f68f08325dc1528
|
|
||||||
// 256: ac953744e10e31514c150d4d8d7b677342e33399788296e43ae4850ce4f97978
|
|
||||||
// 320: bdee37f4371e20646b8b0d862dda16292ae36f40965e8c8509e63d1dbddecc503e2b63eb9245bb66
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int, char**) {
|
|
||||||
util::TAP::logger tap;
|
|
||||||
|
|
||||||
// Check against simple test vectors
|
|
||||||
for (const auto &i: TESTS) {
|
|
||||||
util::hash::RIPEMD obj;
|
|
||||||
obj.update (reinterpret_cast<const uint8_t*> (i.data), strlen (i.data));
|
|
||||||
obj.finish ();
|
|
||||||
|
|
||||||
tap.expect_eq (obj.digest (), i.output, "%s", i.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform 'million-a' check
|
|
||||||
static const size_t CHUNK_WIDTH = 1'000;
|
|
||||||
util::hash::RIPEMD obj;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < 1'000'000; i += CHUNK_WIDTH) {
|
|
||||||
uint8_t data[CHUNK_WIDTH];
|
|
||||||
memset (data, 'a', sizeof (data));
|
|
||||||
|
|
||||||
obj.update (data, sizeof (data));
|
|
||||||
}
|
|
||||||
|
|
||||||
obj.finish ();
|
|
||||||
static const util::hash::RIPEMD::digest_t MILLION {
|
|
||||||
0x52, 0x78, 0x32, 0x43, 0xc1, 0x69, 0x7b, 0xdb, 0xe1, 0x6d,
|
|
||||||
0x37, 0xf9, 0x7f, 0x68, 0xf0, 0x83, 0x25, 0xdc, 0x15, 0x28
|
|
||||||
};
|
|
||||||
|
|
||||||
tap.expect_eq (obj.digest (), MILLION, "million 'a'");
|
|
||||||
|
|
||||||
return tap.status ();
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
#include "hash/sha1.hpp"
|
|
||||||
|
|
||||||
#include "debug.hpp"
|
|
||||||
#include "tap.hpp"
|
|
||||||
#include "types.hpp"
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int, char**)
|
|
||||||
{
|
|
||||||
util::TAP::logger tap;
|
|
||||||
|
|
||||||
static const struct {
|
|
||||||
const char *msg;
|
|
||||||
const char *input;
|
|
||||||
util::hash::SHA1::digest_t output;
|
|
||||||
} TESTS[] = {
|
|
||||||
{
|
|
||||||
"empty string",
|
|
||||||
"",
|
|
||||||
{ { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55,
|
|
||||||
0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09 } }
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"single a",
|
|
||||||
"a",
|
|
||||||
{ { 0x86, 0xf7, 0xe4, 0x37, 0xfa, 0xa5, 0xa7, 0xfc, 0xe1, 0x5d,
|
|
||||||
0x1d, 0xdc, 0xb9, 0xea, 0xea, 0xea, 0x37, 0x76, 0x67, 0xb8 } }
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"abc",
|
|
||||||
"abc",
|
|
||||||
{ { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
|
|
||||||
0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D } }
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"abc...opq",
|
|
||||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
|
||||||
{ { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
|
|
||||||
0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 } }
|
|
||||||
},
|
|
||||||
|
|
||||||
// 1'000'000 * 'a'
|
|
||||||
//{ "a",
|
|
||||||
// { { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
|
|
||||||
// 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } }
|
|
||||||
//},
|
|
||||||
|
|
||||||
// 80 repetitions of 01234567
|
|
||||||
//{ "0123456701234567012345670123456701234567012345670123456701234567",
|
|
||||||
// { { 0xDE, 0xA3, 0x56, 0xA2, 0xCD, 0xDD, 0x90, 0xC7, 0xA7, 0xEC,
|
|
||||||
// 0xED, 0xC5, 0xEB, 0xB5, 0x63, 0x93, 0x4F, 0x46, 0x04, 0x52 } }
|
|
||||||
//}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const auto &i: TESTS) {
|
|
||||||
util::hash::SHA1 obj;
|
|
||||||
obj.update (reinterpret_cast<const uint8_t*> (i.input), strlen (i.input));
|
|
||||||
obj.finish ();
|
|
||||||
|
|
||||||
tap.expect_eq (obj.digest (), i.output, "%s", i.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tap.status ();
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
#include "hash/sha2.hpp"
|
|
||||||
|
|
||||||
#include "tap.hpp"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
static const struct {
|
|
||||||
const char *msg;
|
|
||||||
const char *input;
|
|
||||||
util::hash::SHA256::digest_t output;
|
|
||||||
} TESTS[] = {
|
|
||||||
{
|
|
||||||
"empty",
|
|
||||||
"",
|
|
||||||
{ 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24,
|
|
||||||
0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55 }
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"single a",
|
|
||||||
"a",
|
|
||||||
{ 0xCA, 0x97, 0x81, 0x12, 0xCA, 0x1B, 0xBD, 0xCA, 0xFA, 0xC2, 0x31, 0xB3, 0x9A, 0x23, 0xDC, 0x4D,
|
|
||||||
0xA7, 0x86, 0xEF, 0xF8, 0x14, 0x7C, 0x4E, 0x72, 0xB9, 0x80, 0x77, 0x85, 0xAF, 0xEE, 0x48, 0xBB }
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"abc",
|
|
||||||
"abc",
|
|
||||||
{ 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
|
|
||||||
0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"abc...opq",
|
|
||||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
|
||||||
{ 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
|
|
||||||
0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"77 digits",
|
|
||||||
"0123456701234567012345670123456701234567012345670123456701234567",
|
|
||||||
{ 0x81, 0x82, 0xCA, 0xDB, 0x21, 0xAF, 0x0E, 0x37, 0xC0, 0x64, 0x14, 0xEC, 0xE0, 0x8E, 0x19, 0xC6,
|
|
||||||
0x5B, 0xDB, 0x22, 0xC3, 0x96, 0xD4, 0x8B, 0xA7, 0x34, 0x10, 0x12, 0xEE, 0xA9, 0xFF, 0xDF, 0xDD }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int, char **) {
|
|
||||||
util::TAP::logger tap;
|
|
||||||
|
|
||||||
for (const auto &i: TESTS) {
|
|
||||||
util::hash::SHA256 obj;
|
|
||||||
obj.update (reinterpret_cast<const uint8_t*> (i.input), strlen (i.input));
|
|
||||||
obj.finish ();
|
|
||||||
|
|
||||||
tap.expect_eq (obj.digest (), i.output, "%s", i.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tap.status ();
|
|
||||||
}
|
|
@ -17,9 +17,21 @@
|
|||||||
|
|
||||||
#include "tap.hpp"
|
#include "tap.hpp"
|
||||||
|
|
||||||
#include "hash/simple.hpp"
|
|
||||||
#include "hash/xxhash.hpp"
|
#include "hash/xxhash.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
std::vector<uint8_t>
|
||||||
|
operator"" _u8s (const char *str, size_t len)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> res;
|
||||||
|
res.resize (len);
|
||||||
|
std::copy_n (str, len, std::begin (res));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
int
|
int
|
||||||
main (int, char **)
|
main (int, char **)
|
||||||
{
|
{
|
||||||
@ -29,29 +41,27 @@ main (int, char **)
|
|||||||
uint32_t hash32;
|
uint32_t hash32;
|
||||||
uint64_t hash64;
|
uint64_t hash64;
|
||||||
unsigned seed;
|
unsigned seed;
|
||||||
std::string data;
|
std::vector<uint8_t> data;
|
||||||
std::string msg;
|
const char *msg;
|
||||||
} TESTS[] = {
|
} TESTS[] = {
|
||||||
{ 0x02CC5D05, 0xef46db3751d8e999, 0, "", "empty string, 0 seed" },
|
{ 0x02CC5D05, 0xef46db3751d8e999, 0, ""_u8s, "empty string, 0 seed" },
|
||||||
{ 0x0b2cb792, 0xd5afba1336a3be4b, 1, "", "empty string, 1 seed" },
|
{ 0x0b2cb792, 0xd5afba1336a3be4b, 1, ""_u8s, "empty string, 1 seed" },
|
||||||
{ 0x550d7456, 0xd24ec4f1a98c6e5b, 0, "a", "single a, 0 seed" },
|
{ 0x550d7456, 0xd24ec4f1a98c6e5b, 0, "a"_u8s, "single a, 0 seed" },
|
||||||
{ 0xf514706f, 0xdec2bc81c3cd46c6, 1, "a", "single a, 1 seed" },
|
{ 0xf514706f, 0xdec2bc81c3cd46c6, 1, "a"_u8s, "single a, 1 seed" },
|
||||||
{ 0x32d153ff, 0x44bc2cf5ad770999, 0, "abc", "abc, 0 seed" },
|
{ 0x32d153ff, 0x44bc2cf5ad770999, 0, "abc"_u8s, "abc, 0 seed" },
|
||||||
{ 0xaa3da8ff, 0xbea9ca8199328908, 1, "abc", "abc, 1 seed" },
|
{ 0xaa3da8ff, 0xbea9ca8199328908, 1, "abc"_u8s, "abc, 1 seed" },
|
||||||
{ 0x54ca7e46, 0x892a0760a6343391, 0x1234,
|
{ 0x54ca7e46, 0x892a0760a6343391, 0x1234,
|
||||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+",
|
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+"_u8s,
|
||||||
"long alphabet" }
|
"long alphabet" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
for (const auto &t: TESTS) {
|
for (const auto &t: TESTS) {
|
||||||
auto first = t.data.data ();
|
util::hash::xxhash32 h32 (t.seed);
|
||||||
auto last = first + t.data.size ();
|
//util::hash::xxhash32 h64 (t.seed);
|
||||||
|
|
||||||
auto digest32 = util::hash::simple<util::hash::xxhash32> (first, last, t.seed);
|
tap.expect_eq (h32 (t.data), t.hash32, "xxhash32 %s", t.msg);
|
||||||
//auto digest64 = util::hash::simple<util::hash::xxhash64> (first, last, t.seed);
|
//tap.expect_eq (h64 (t.data), t.hash64, "xxhash64 %s", t.msg);
|
||||||
|
|
||||||
tap.expect_eq (digest32, t.hash32, "xxhash32 %s", t.msg);
|
|
||||||
//tap.expect_eq (digest64, t.hash64, "xxhash64 %s", t.msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tap.status ();
|
return tap.status ();
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
using namespace util;
|
using namespace util;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
int
|
int
|
||||||
main (void)
|
main (void)
|
||||||
{
|
{
|
||||||
|
@ -97,7 +97,6 @@ to_epoch (const tm &t)
|
|||||||
// similar. in the future we can account for this
|
// similar. in the future we can account for this
|
||||||
CHECK_SANITY (t);
|
CHECK_SANITY (t);
|
||||||
|
|
||||||
|
|
||||||
constexpr int
|
constexpr int
|
||||||
cumulative_days [12] = {
|
cumulative_days [12] = {
|
||||||
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
|
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
|
||||||
|
151
tools/hash.cpp
151
tools/hash.cpp
@ -1,151 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright:
|
|
||||||
* 2014-2016, Danny Robson <danny@nerdcruft.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include "io.hpp"
|
|
||||||
#include "stream.hpp"
|
|
||||||
|
|
||||||
#include "hash/simple.hpp"
|
|
||||||
|
|
||||||
#include "hash/adler.hpp"
|
|
||||||
#include "hash/bsdsum.cpp"
|
|
||||||
#include "hash/crc.hpp"
|
|
||||||
#include "hash/md2.hpp"
|
|
||||||
#include "hash/md4.hpp"
|
|
||||||
#include "hash/md5.hpp"
|
|
||||||
#include "hash/ripemd.hpp"
|
|
||||||
#include "hash/sha1.hpp"
|
|
||||||
#include "hash/sha2.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
static
|
|
||||||
const char* NAMES[] = {
|
|
||||||
"adler32",
|
|
||||||
"bsdsum",
|
|
||||||
"crc",
|
|
||||||
"MD2",
|
|
||||||
"MD4",
|
|
||||||
"MD5",
|
|
||||||
"RIPEMD",
|
|
||||||
"SHA1",
|
|
||||||
"SHA256",
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
std::ostream&
|
|
||||||
print_digest (std::ostream &os, uint32_t t)
|
|
||||||
{
|
|
||||||
return os << std::hex << t << std::dec;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
template <size_t S>
|
|
||||||
std::ostream&
|
|
||||||
print_digest (std::ostream &os, std::array<uint8_t,S> digest)
|
|
||||||
{
|
|
||||||
util::stream::scoped::flags f (os);
|
|
||||||
os << std::hex;
|
|
||||||
|
|
||||||
for (auto c: digest)
|
|
||||||
os << +(c >> 4) << +(c & 0x0F);
|
|
||||||
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
static
|
|
||||||
void
|
|
||||||
compute (const std::string &name,
|
|
||||||
const unsigned char *restrict first,
|
|
||||||
const unsigned char *restrict last)
|
|
||||||
{
|
|
||||||
#define stream(TYPE, ...) do { \
|
|
||||||
if (name != #TYPE) \
|
|
||||||
break; \
|
|
||||||
\
|
|
||||||
auto sum = util::hash::simple<util::hash::TYPE> ( \
|
|
||||||
first, last, ##__VA_ARGS__ \
|
|
||||||
); \
|
|
||||||
\
|
|
||||||
print_digest (std::cout, sum) << '\n'; \
|
|
||||||
return; \
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
stream (adler32);
|
|
||||||
stream (bsdsum);
|
|
||||||
stream (crc32);
|
|
||||||
|
|
||||||
stream (MD2);
|
|
||||||
stream (MD4);
|
|
||||||
stream (MD5);
|
|
||||||
stream (RIPEMD);
|
|
||||||
stream (SHA1);
|
|
||||||
stream (SHA256);
|
|
||||||
|
|
||||||
#undef stream
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
enum {
|
|
||||||
ARG_CMD,
|
|
||||||
ARG_HASH,
|
|
||||||
ARG_INPUT,
|
|
||||||
|
|
||||||
NUM_ARGS
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
print_usage (int argc, char **argv)
|
|
||||||
{
|
|
||||||
(void)argc;
|
|
||||||
|
|
||||||
std::cerr << argv[ARG_CMD] << " [";
|
|
||||||
for (auto name: NAMES)
|
|
||||||
std::cerr << name << "|";
|
|
||||||
std::cerr << "] <input>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
int
|
|
||||||
main (int argc, char **argv)
|
|
||||||
{
|
|
||||||
if (argc != NUM_ARGS) {
|
|
||||||
print_usage (argc, argv);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp (argv[ARG_INPUT], "-")) {
|
|
||||||
util::mapped_file src (argv[ARG_INPUT]);
|
|
||||||
compute (argv[ARG_HASH], src.cbegin (), src.cend ());
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
} else {
|
|
||||||
//compute (argv[ARG_HASH], std::cin);
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
@ -51,7 +51,7 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const util::mapped_file src (argv[ARG_INPUT]);
|
const util::mapped_file src (argv[ARG_INPUT]);
|
||||||
std::cout << *json::tree::parse (src.as_view<const char> ()) << '\n';
|
std::cout << *json::tree::parse (util::view{src}.cast<const char> ()) << '\n';
|
||||||
} catch (const json::error& err) {
|
} catch (const json::error& err) {
|
||||||
std::cerr << err.what () << "\n";
|
std::cerr << err.what () << "\n";
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
@ -50,8 +50,8 @@ main (int argc, char **argv) {
|
|||||||
const util::mapped_file schema_src (argv[ARG_SCHEMA]);
|
const util::mapped_file schema_src (argv[ARG_SCHEMA]);
|
||||||
const util::mapped_file input_src (argv[ARG_INPUT]);
|
const util::mapped_file input_src (argv[ARG_INPUT]);
|
||||||
|
|
||||||
auto schema = json::tree::parse (schema_src.as_view<const char> ());
|
auto schema = json::tree::parse (util::view{schema_src}.cast<const char>());
|
||||||
auto input = json::tree::parse (input_src.as_view<const char> ());
|
auto input = json::tree::parse (util::view{input_src} .cast<const char>());
|
||||||
|
|
||||||
json::schema::validate (*input, schema->as_object ());
|
json::schema::validate (*input, schema->as_object ());
|
||||||
} catch (const json::error &e) {
|
} catch (const json::error &e) {
|
||||||
|
@ -42,7 +42,7 @@ main (int argc, char ** argv) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const util::mapped_file data (argv[ARG_PATH]);
|
const util::mapped_file data (argv[ARG_PATH]);
|
||||||
json::flat::parse (data.as_view<const char> ());
|
json::flat::parse (util::view{data}.cast<const char> ());
|
||||||
} catch (const json::error &x) {
|
} catch (const json::error &x) {
|
||||||
std::cerr << "error: " << x.what () << '\n';
|
std::cerr << "error: " << x.what () << '\n';
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
@ -270,6 +270,29 @@ template <std::size_t N, typename FuncT>
|
|||||||
using nth_argument_t = typename nth_argument<N, FuncT>::type;
|
using nth_argument_t = typename nth_argument<N, FuncT>::type;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T, typename = std::void_t<>>
|
||||||
|
struct is_container : public std::false_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_container<
|
||||||
|
T,
|
||||||
|
std::void_t<
|
||||||
|
typename T::value_type,
|
||||||
|
typename T::reference,
|
||||||
|
typename T::const_reference,
|
||||||
|
typename T::iterator,
|
||||||
|
typename T::const_iterator,
|
||||||
|
typename T::difference_type,
|
||||||
|
typename T::size_type
|
||||||
|
>
|
||||||
|
> : public std::true_type {};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr auto is_container_v = is_container<T>::value;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user