initial import from libcruft-util
This commit is contained in:
commit
9fb5ff3136
96
CMakeLists.txt
Normal file
96
CMakeLists.txt
Normal file
@ -0,0 +1,96 @@
|
||||
###############################################################################
|
||||
cmake_minimum_required(VERSION 3.7.0)
|
||||
project(cruft-crypto CXX)
|
||||
|
||||
|
||||
###############################################################################
|
||||
if (NOT TARGET cruft-util)
|
||||
message (FATAL_ERROR "cruft-util was not found")
|
||||
endif ()
|
||||
|
||||
|
||||
###############################################################################
|
||||
list (APPEND sources
|
||||
fwd.hpp
|
||||
|
||||
hash/md2.cpp
|
||||
hash/md2.hpp
|
||||
hash/md4.cpp
|
||||
hash/md4.hpp
|
||||
hash/md5.cpp
|
||||
hash/md5.hpp
|
||||
hash/ripemd.cpp
|
||||
hash/ripemd.hpp
|
||||
hash/sha1.cpp
|
||||
hash/sha1.hpp
|
||||
hash/sha2.cpp
|
||||
hash/sha2.hpp
|
||||
|
||||
hash/hmac.cpp
|
||||
hash/hmac.hpp
|
||||
|
||||
hash/hotp.cpp
|
||||
hash/hotp.hpp
|
||||
|
||||
stream/rc4.cpp
|
||||
stream/rc4.hpp
|
||||
stream/salsa.cpp
|
||||
stream/salsa.hpp
|
||||
|
||||
block/tea.cpp
|
||||
block/tea.hpp
|
||||
block/xtea.cpp
|
||||
block/xtea.hpp
|
||||
block/xxtea.cpp
|
||||
block/xxtea.hpp
|
||||
)
|
||||
|
||||
|
||||
option (TESTS "enable unit testing" ON)
|
||||
|
||||
if (TESTS)
|
||||
include (CTest)
|
||||
enable_testing ()
|
||||
|
||||
list (APPEND tests
|
||||
hash/md2
|
||||
hash/md4
|
||||
hash/md5
|
||||
hash/ripemd
|
||||
hash/sha1
|
||||
hash/sha2
|
||||
|
||||
hash/hmac
|
||||
hash/hotp
|
||||
|
||||
stream/rc4
|
||||
stream/salsa
|
||||
|
||||
block/tea
|
||||
block/xtea
|
||||
block/xxtea
|
||||
)
|
||||
|
||||
foreach (t ${tests})
|
||||
string(REPLACE "/" "_" name "test/${t}")
|
||||
add_executable(crypto_test_${name} test/${t}.cpp)
|
||||
target_link_libraries(crypto_test_${name} PRIVATE cruft-crypto)
|
||||
target_include_directories(crypto_test_${name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_test(NAME crypto_test_${name} COMMAND crypto_test_${name})
|
||||
endforeach()
|
||||
endif ()
|
||||
|
||||
|
||||
###############################################################################
|
||||
add_library (cruft-crypto STATIC ${sources})
|
||||
target_link_libraries (cruft-crypto INTERFACE cruft-util)
|
||||
|
||||
|
||||
##-----------------------------------------------------------------------------
|
||||
add_executable (crypto_hash tools/hash.cpp)
|
||||
target_link_libraries (crypto_hash cruft-crypto)
|
||||
|
||||
|
||||
###############################################################################
|
||||
configure_file(libcruft-crypto.pc.in libcruft-crypto.pc)
|
||||
configure_file(Doxyfile.in Doxyfile)
|
2384
Doxyfile.in
Normal file
2384
Doxyfile.in
Normal file
File diff suppressed because it is too large
Load Diff
3
README
Normal file
3
README
Normal file
@ -0,0 +1,3 @@
|
||||
A naive C++17 implementation of several cryptography primitives.
|
||||
|
||||
Do not use this code for anything that needs security. They are deliberately not secure against many types of attack (such as cache timing attacks). Many were literally written between/during rounds of Overwatch or while watching Netflix...
|
86
block/tea.cpp
Normal file
86
block/tea.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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 cruft::crypto::block::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;
|
||||
}
|
||||
}
|
40
block/tea.hpp
Normal file
40
block/tea.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 CRUFT_CRYPTO_BLOCK_TEA_HPP
|
||||
#define CRUFT_CRYPTO_BLOCK_TEA_HPP
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
namespace cruft::crypto::block {
|
||||
// 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
|
84
block/xtea.cpp
Normal file
84
block/xtea.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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 cruft::crypto::block::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;
|
||||
}
|
||||
}
|
40
block/xtea.hpp
Normal file
40
block/xtea.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 CRUFT_CRYPTO_BLOCK_XTEA_HPP
|
||||
#define CRUFT_CRYPTO_BLOCK_XTEA_HPP
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
namespace cruft::crypto::block {
|
||||
// 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
block/xxtea.cpp
Normal file
106
block/xxtea.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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 cruft::crypto::block::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);
|
||||
}
|
42
block/xxtea.hpp
Normal file
42
block/xxtea.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 CRUFT_CRYPTO_BLOCKXXTEA_HPP
|
||||
#define CRUFT_CRYPTO_BLOCKXXTEA_HPP
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
namespace cruft::crypto::block {
|
||||
// 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
|
||||
|
20
hash/hmac.cpp
Normal file
20
hash/hmac.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
|
||||
using cruft::crypto::hash::HMAC;
|
89
hash/hmac.hpp
Normal file
89
hash/hmac.hpp
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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 CRUFT_CRYPTO_HASH_HMAC_HPP
|
||||
#define CRUFT_CRYPTO_HASH_HMAC_HPP
|
||||
|
||||
#include <cruft/util/debug.hpp>
|
||||
#include <cruft/util/view.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace cruft::crypto::hash {
|
||||
template <class HashT>
|
||||
/// RFC 2104 key-hashing for message authentication
|
||||
class HMAC {
|
||||
public:
|
||||
using digest_t = typename HashT::digest_t;
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
HMAC (util::view<const std::uint8_t*> key)
|
||||
{
|
||||
CHECK (!key.empty ());
|
||||
|
||||
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 (key.size () > HashT::BLOCK_SIZE) {
|
||||
auto d = HashT{} (key);
|
||||
auto tail = std::copy (d.begin (), d.end (), m_ikey.begin ());
|
||||
std::fill (tail, std::end (m_ikey), 0);
|
||||
// Use the key directly
|
||||
} else {
|
||||
auto tail = std::copy (key.begin (), key.end (), m_ikey.begin ());
|
||||
std::fill (tail, m_ikey.end (), 0);
|
||||
}
|
||||
|
||||
// copy and xor the key data to the okey
|
||||
std::transform (
|
||||
std::begin (m_ikey),
|
||||
std::end (m_ikey),
|
||||
std::begin (m_okey),
|
||||
[] (auto v) { return v ^ OFILL; });
|
||||
|
||||
// just xor the ikey in place
|
||||
std::transform (
|
||||
m_ikey.begin (),
|
||||
m_ikey.end (),
|
||||
m_ikey.begin (),
|
||||
[] (auto v) { return v ^ IFILL; });
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
template <typename ...DataT>
|
||||
digest_t
|
||||
operator() (DataT&&...data) const noexcept
|
||||
{
|
||||
HashT h;
|
||||
return h (m_okey, h (m_ikey, std::forward<DataT> (data)...));
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
//---------------------------------------------------------------------
|
||||
static constexpr uint8_t IFILL = 0x36;
|
||||
static constexpr uint8_t OFILL = 0x5C;
|
||||
|
||||
std::array<uint8_t,HashT::BLOCK_SIZE> m_ikey;
|
||||
std::array<uint8_t,HashT::BLOCK_SIZE> m_okey;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
65
hash/hotp.cpp
Normal file
65
hash/hotp.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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-2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#include "hotp.hpp"
|
||||
|
||||
#include <cruft/util/endian.hpp>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using cruft::crypto::hash::HOTP;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
HOTP::HOTP (util::view<const char*> _key, uint64_t _counter):
|
||||
m_counter (_counter),
|
||||
m_hash (_key.template cast<const uint8_t> ())
|
||||
{ ; }
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned
|
||||
HOTP::value (void)
|
||||
{
|
||||
union {
|
||||
uint64_t number;
|
||||
uint8_t bytes[8];
|
||||
};
|
||||
|
||||
number = util::htob (m_counter);
|
||||
|
||||
auto res = truncate (m_hash (util::make_cview (bytes)));
|
||||
++m_counter;
|
||||
return res % 1'000'000;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
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;
|
||||
}
|
44
hash/hotp.hpp
Normal file
44
hash/hotp.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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-2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef CRUFT_CRYPTO_HASH_HOTP_HPP
|
||||
#define CRUFT_CRYPTO_HASH_HOTP_HPP
|
||||
|
||||
#include <cruft/util/view.hpp>
|
||||
|
||||
#include "hmac.hpp"
|
||||
#include "sha1.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace cruft::crypto::hash {
|
||||
/// HMAC one-time password (RFC 4226)
|
||||
class HOTP {
|
||||
public:
|
||||
HOTP (util::view<const char*> key, 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
|
123
hash/md2.cpp
Normal file
123
hash/md2.cpp
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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 <cruft/util/debug.hpp>
|
||||
#include <cruft/util/types.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
using cruft::crypto::hash::MD2;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static constexpr std::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,
|
||||
} };
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
static const size_t M_OFFSET = 16;
|
||||
static const size_t M_LENGTH = 16;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void
|
||||
transform (std::array<uint8_t,16> &C, std::array<uint8_t,48> &X) noexcept
|
||||
{
|
||||
util::view M { X.data () + M_OFFSET, M_LENGTH };
|
||||
|
||||
// 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];
|
||||
|
||||
|
||||
// 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, t = 0; i < 18; ++i) {
|
||||
for (size_t j = 0; j < 48; ++j)
|
||||
t = X[j] ^= S[t];
|
||||
|
||||
t = (t + i) % 256;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
MD2::digest_t
|
||||
MD2::operator() (const util::view<const uint8_t*> data) const noexcept
|
||||
{
|
||||
// zero initialise the state vectors, and create a simple window `M' into
|
||||
// the middle of the `X' state vector.
|
||||
std::array<uint8_t,16> C {};
|
||||
std::array<uint8_t,48> X {};
|
||||
const util::view M { std::begin (X) + M_OFFSET, M_LENGTH };
|
||||
|
||||
// process each complete block by copying to the window `M' and
|
||||
// transforming X and C.
|
||||
//
|
||||
// leave the remainder of the data in `M' for subsequent padding.
|
||||
auto remain = data;
|
||||
while (remain.size () >= M_LENGTH) {
|
||||
std::copy_n (std::begin (remain), M_LENGTH, std::begin (M));
|
||||
transform (C, X);
|
||||
|
||||
remain = { remain.begin () + M_LENGTH, remain.end () };
|
||||
};
|
||||
|
||||
// Copying the remaining data then append the padding bytes. Padding
|
||||
// _must_ be performed even if we have an evenly divisible input buffer.
|
||||
auto tail = std::copy (remain.begin (), remain.end (), std::begin (M));
|
||||
auto unused = std::distance (tail, std::end (M));
|
||||
std::fill (tail, std::end (M), unused);
|
||||
transform (C, X);
|
||||
|
||||
// Append the checksum and transform once more.
|
||||
std::copy (std::begin (C), std::end (C), std::begin (M));
|
||||
transform (C, X);
|
||||
|
||||
// The final digest is the first `n' bytes of the state vector.
|
||||
digest_t d;
|
||||
std::copy_n (std::begin (X), d.size (), std::begin (d));
|
||||
return d;
|
||||
}
|
37
hash/md2.hpp
Normal file
37
hash/md2.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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 CRUFT_CRYPTO_HASH_MD2_HPP
|
||||
#define CRUFT_CRYPTO_HASH_MD2_HPP
|
||||
|
||||
#include <cruft/util/view.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace cruft::crypto::hash {
|
||||
class MD2 {
|
||||
public:
|
||||
typedef std::array<uint8_t,16> digest_t;
|
||||
|
||||
public:
|
||||
digest_t operator() (util::view<const uint8_t*>) const noexcept;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
227
hash/md4.cpp
Normal file
227
hash/md4.cpp
Normal file
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* 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 <cruft/util/bitwise.hpp>
|
||||
#include <cruft/util/debug.hpp>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
|
||||
using cruft::crypto::hash::MD4;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Auxiliary functions for each set of rounds
|
||||
static inline constexpr
|
||||
uint32_t
|
||||
F (uint32_t X, uint32_t Y, uint32_t Z)
|
||||
{
|
||||
return (X & Y) | (~X & Z);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
static inline constexpr
|
||||
uint32_t
|
||||
G (uint32_t X, uint32_t Y, uint32_t Z)
|
||||
{
|
||||
return (X & Y) | (X & Z) | (Y & Z);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
static inline constexpr
|
||||
uint32_t
|
||||
H (uint32_t X, uint32_t Y, uint32_t Z)
|
||||
{
|
||||
return X ^ Y ^ Z;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
static constexpr uint32_t INITIAL_A = 0x67452301;
|
||||
static constexpr uint32_t INITIAL_B = 0xefcdab89;
|
||||
static constexpr uint32_t INITIAL_C = 0x98badcfe;
|
||||
static constexpr uint32_t INITIAL_D = 0x10325476;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void
|
||||
transform (std::array<uint32_t,4> &ABCD, const std::array<uint32_t,16> &X) noexcept
|
||||
{
|
||||
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) = util::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) = util::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) = util::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;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
MD4::digest_t
|
||||
MD4::operator() (util::view<const uint8_t*> data) noexcept
|
||||
{
|
||||
/* RESET */
|
||||
uint64_t total = 0;
|
||||
|
||||
std::array<uint32_t,4> ABCD {
|
||||
INITIAL_A,
|
||||
INITIAL_B,
|
||||
INITIAL_C,
|
||||
INITIAL_D,
|
||||
};
|
||||
|
||||
union {
|
||||
std::array<uint32_t,16> X;
|
||||
std::array<uint8_t, 64> Xb;
|
||||
};
|
||||
static_assert (sizeof (X) == sizeof (Xb));
|
||||
static_assert (sizeof (ABCD) == sizeof (digest_t));
|
||||
|
||||
std::fill (std::begin (X), std::end (X), 0);
|
||||
|
||||
/* UPDATE */
|
||||
{
|
||||
auto remain = data;
|
||||
while (remain.size () >= sizeof (Xb)) {
|
||||
std::copy_n (std::begin (remain), sizeof (Xb), std::begin (Xb));
|
||||
transform (ABCD, X);
|
||||
remain = { remain.begin () + sizeof (Xb), remain.end () };
|
||||
total += sizeof (Xb);
|
||||
}
|
||||
|
||||
std::copy (std::begin (remain), std::end (remain), std::begin (Xb));
|
||||
total += remain.size ();
|
||||
}
|
||||
|
||||
uint64_t bits = total * 8;
|
||||
|
||||
/* FINISH */
|
||||
{
|
||||
// Pad with the mandatory 1 bit
|
||||
size_t offset = total % sizeof (Xb);
|
||||
Xb[offset] = 0x80;
|
||||
}
|
||||
|
||||
{
|
||||
// Pad the remainder with 0's, until 56 bytes
|
||||
size_t offset = (total + 1) % sizeof (Xb);
|
||||
size_t remain = (56 - offset % sizeof (Xb)) % sizeof (Xb);
|
||||
|
||||
if (offset > 56) {
|
||||
std::fill_n (std::begin (Xb) + offset, sizeof (Xb) - offset, 0);
|
||||
transform (ABCD, X);
|
||||
remain -= sizeof (Xb) - offset;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
std::fill (std::begin (Xb) + offset, std::end (Xb), 0);
|
||||
|
||||
// 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 (ABCD, X);
|
||||
}
|
||||
|
||||
/* DIGEEST */
|
||||
digest_t d;
|
||||
memcpy (d.data (), ABCD.data(), sizeof (ABCD));
|
||||
return d;
|
||||
}
|
36
hash/md4.hpp
Normal file
36
hash/md4.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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 <cruft/util/view.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace cruft::crypto::hash {
|
||||
class MD4 {
|
||||
public:
|
||||
using digest_t = std::array<uint8_t,16>;
|
||||
|
||||
digest_t operator() (util::view<const uint8_t*>) noexcept;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
300
hash/md5.cpp
Normal file
300
hash/md5.cpp
Normal file
@ -0,0 +1,300 @@
|
||||
/*
|
||||
* 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 <cruft/util/iterator.hpp>
|
||||
#include <cruft/util/bitwise.hpp>
|
||||
#include <cruft/util/debug.hpp>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using cruft::crypto::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 constexpr uint32_t INITIAL_A = 0x67452301;
|
||||
static constexpr uint32_t INITIAL_B = 0xefcdab89;
|
||||
static constexpr uint32_t INITIAL_C = 0x98badcfe;
|
||||
static constexpr uint32_t INITIAL_D = 0x10325476;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
typename MD5::digest_t
|
||||
MD5::operator() (util::view<const uint8_t*> a) const noexcept
|
||||
{
|
||||
return (*this)(a, nullptr);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
typename MD5::digest_t
|
||||
MD5::operator() (util::view<const uint8_t*> a, util::view<const uint8_t*> b) const noexcept
|
||||
{
|
||||
return (*this)(a, b, nullptr);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
typename MD5::digest_t
|
||||
MD5::operator() (
|
||||
const util::view<const uint8_t*> data_a,
|
||||
const util::view<const uint8_t*> data_b,
|
||||
const util::view<const uint8_t*> data_c
|
||||
) const noexcept {
|
||||
union {
|
||||
std::array<uint32_t,16> w;
|
||||
std::array<uint8_t, 64> b;
|
||||
} X;
|
||||
|
||||
static_assert (sizeof (X.w) == BLOCK_SIZE);
|
||||
static_assert (X.w.size () == DIGEST_SIZE);
|
||||
|
||||
static_assert (sizeof (X.b) == BLOCK_SIZE);
|
||||
static_assert (X.b.size () == BLOCK_SIZE);
|
||||
|
||||
static_assert ((void*)&X.w == (void*)&X.b);
|
||||
|
||||
uint64_t m_total = 0;
|
||||
std::array<uint32_t,4> ABCD = {
|
||||
INITIAL_A,
|
||||
INITIAL_B,
|
||||
INITIAL_C,
|
||||
INITIAL_D
|
||||
};
|
||||
|
||||
// note we pass in a windowed view of the state block, not the whole
|
||||
// thing.
|
||||
util::transform_by_block (
|
||||
util::view {X.b},
|
||||
[&,this] (auto) { ABCD = transform (ABCD, X.w); },
|
||||
data_a, data_b, data_c
|
||||
);
|
||||
m_total = data_a.size () + data_b.size () + data_c.size ();
|
||||
|
||||
uint64_t bits = m_total * 8;
|
||||
|
||||
// Pad with the mandatory 1 bit
|
||||
X.b[m_total % BLOCK_SIZE] = 0x80;
|
||||
|
||||
{
|
||||
// Pad the remainder with 0's, until 56 bytes
|
||||
size_t offset = (m_total + 1) % BLOCK_SIZE;
|
||||
size_t remain = (56 - offset % BLOCK_SIZE) % BLOCK_SIZE;
|
||||
|
||||
if (offset > 56) {
|
||||
std::fill (&X.b[offset], X.b.end (), 0);
|
||||
ABCD = transform (ABCD, X.w);
|
||||
remain -= sizeof (X.b) - offset;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
memset (&X.b[offset], 0, remain);
|
||||
|
||||
// Put in the length (in bits) least significant first
|
||||
for (size_t i = 0; i < sizeof (bits); ++i) {
|
||||
X.b[56 + i] = bits & 0xFF;
|
||||
bits >>= 8;
|
||||
}
|
||||
|
||||
ABCD = transform (ABCD, X.w);
|
||||
}
|
||||
|
||||
|
||||
digest_t d;
|
||||
memcpy (d.data (), ABCD.data (), sizeof (ABCD));
|
||||
return d;
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
std::array<uint32_t,4>
|
||||
MD5::transform (
|
||||
const std::array<uint32_t,4> &ABCD,
|
||||
const std::array<uint32_t,16> &X) const noexcept
|
||||
{
|
||||
|
||||
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) = util::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);
|
||||
|
||||
return {
|
||||
ABCD[0] + A,
|
||||
ABCD[1] + B,
|
||||
ABCD[2] + C,
|
||||
ABCD[3] + D,
|
||||
};
|
||||
}
|
49
hash/md5.hpp
Normal file
49
hash/md5.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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-2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef CRUFT_CRYPTO_HASH_MD5_HPP
|
||||
#define CRUFT_CRYPTO_HASH_MD5_HPP
|
||||
|
||||
#include <cruft/util/view.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace cruft::crypto::hash {
|
||||
class MD5 {
|
||||
public:
|
||||
using digest_t = std::array<uint8_t,16>;
|
||||
static const size_t BLOCK_SIZE = 64;
|
||||
static const size_t DIGEST_SIZE = 16;
|
||||
|
||||
public:
|
||||
digest_t operator() (util::view<const uint8_t*>) const noexcept;
|
||||
digest_t operator() (util::view<const uint8_t*>,util::view<const uint8_t*>) const noexcept;
|
||||
digest_t operator() (util::view<const uint8_t*>,util::view<const uint8_t*>,util::view<const uint8_t*>) const noexcept;
|
||||
|
||||
private:
|
||||
std::array<uint32_t,4>
|
||||
transform (
|
||||
const std::array<uint32_t,4> &ABCD,
|
||||
const std::array<uint32_t,16> &X
|
||||
) const noexcept;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
409
hash/ripemd.cpp
Normal file
409
hash/ripemd.cpp
Normal file
@ -0,0 +1,409 @@
|
||||
/*
|
||||
* 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-2018, Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#include "ripemd.hpp"
|
||||
|
||||
#include <cruft/util/debug.hpp>
|
||||
#include <cruft/util/bitwise.hpp>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using cruft::crypto::hash::RIPEMD;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void
|
||||
transform (uint32_t state[5], const uint32_t d32[16])
|
||||
{
|
||||
// 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 += d32[x] + o; \
|
||||
a = util::rotatel (a, s); \
|
||||
a += e; \
|
||||
c = util::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 = state[0];
|
||||
b1 = b2 = state[1];
|
||||
c1 = c2 = state[2];
|
||||
d1 = d2 = state[3];
|
||||
e1 = e2 = 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 = state[1] + c1 + d2;
|
||||
state[1] = state[2] + d1 + e2;
|
||||
state[2] = state[3] + e1 + a2;
|
||||
state[3] = state[4] + a1 + b2;
|
||||
state[4] = state[0] + b1 + c2;
|
||||
state[0] = d2;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
RIPEMD::digest_t
|
||||
RIPEMD::operator() (const util::view<const uint8_t*> data)
|
||||
{
|
||||
struct {
|
||||
union {
|
||||
uint32_t d32[16];
|
||||
uint8_t d08[64];
|
||||
};
|
||||
size_t size;
|
||||
} m_buffer;
|
||||
|
||||
/* INIT */
|
||||
uint32_t m_state[5] {
|
||||
0x67452301u,
|
||||
0xEFCDAB89u,
|
||||
0x98BADCFEu,
|
||||
0x10325476u,
|
||||
0xC3D2E1F0u,
|
||||
};
|
||||
|
||||
uint64_t m_length = 0;
|
||||
|
||||
m_buffer.size = 0;
|
||||
|
||||
/* UPDATE */
|
||||
{
|
||||
auto len = data.size ();
|
||||
auto base = data.begin ();
|
||||
size_t cursor = 0;
|
||||
|
||||
while (cursor < len) {
|
||||
size_t width = sizeof (m_buffer.d08) - m_buffer.size;
|
||||
size_t chunk = util::min (width, len - cursor);
|
||||
|
||||
memcpy (m_buffer.d08 + m_buffer.size, base + cursor, chunk);
|
||||
m_length += chunk;
|
||||
m_buffer.size += chunk;
|
||||
|
||||
if (m_buffer.size == sizeof (m_buffer.d08)) {
|
||||
transform (m_state, m_buffer.d32);
|
||||
m_buffer.size = 0;
|
||||
}
|
||||
|
||||
cursor += chunk;
|
||||
}
|
||||
|
||||
if (m_length >> sizeof (m_length) * 8 - 3 != 0)
|
||||
panic ("exceeded maximum message length");
|
||||
}
|
||||
|
||||
|
||||
/* FINISH */
|
||||
{
|
||||
// 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;
|
||||
assert (m_buffer.size != sizeof (m_buffer.d08));
|
||||
m_buffer.d08[m_buffer.size] = padding;
|
||||
m_buffer.size++;
|
||||
m_length++;
|
||||
if (m_buffer.size == sizeof (m_buffer.d08)) {
|
||||
transform (m_state, m_buffer.d32);
|
||||
m_buffer.size = 0;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
std::fill_n (m_buffer.d08 + m_buffer.size, remaining, 0);
|
||||
m_buffer.size += remaining;
|
||||
transform (m_state, m_buffer.d32);
|
||||
m_buffer.size = 0;
|
||||
m_length += 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];
|
||||
};
|
||||
|
||||
std::fill (std::begin (d32), std::end (d32), 0);
|
||||
d32[14] = length & 0xFFFFFFFF;
|
||||
d32[15] = length >> 32u;
|
||||
|
||||
// Do the final update
|
||||
size_t offset = sizeof(d08) - remaining;
|
||||
|
||||
std::copy_n (d08 + offset, remaining, m_buffer.d08 + offset);
|
||||
m_length += remaining;
|
||||
m_buffer.size += remaining;
|
||||
transform (m_state, m_buffer.d32);
|
||||
m_buffer.size = 0;
|
||||
}
|
||||
|
||||
/* DIGEST */
|
||||
digest_t d;
|
||||
memcpy (d.data (), m_state, sizeof (m_state));
|
||||
return d;
|
||||
}
|
36
hash/ripemd.hpp
Normal file
36
hash/ripemd.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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-2018, Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef CRUFT_CRYPTO_HASH_RIPEMD_HPP
|
||||
#define CRUFT_CRYPTO_HASH_RIPEMD_HPP
|
||||
|
||||
#include <cruft/util/view.hpp>
|
||||
|
||||
#include <array>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace cruft::crypto::hash {
|
||||
class RIPEMD {
|
||||
public:
|
||||
typedef std::array<uint8_t,20> digest_t;
|
||||
|
||||
digest_t operator() (util::view<const uint8_t*>);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
217
hash/sha1.cpp
Normal file
217
hash/sha1.cpp
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
* 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 <cruft/util/iterator.hpp>
|
||||
#include <cruft/util/bitwise.hpp>
|
||||
#include <cruft/util/debug.hpp>
|
||||
#include <cruft/util/endian.hpp>
|
||||
#include <cruft/util/cast.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
|
||||
using cruft::crypto::hash::SHA1;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
std::array<uint32_t,5> INITIAL_H = {
|
||||
0x67452301,
|
||||
0xEFCDAB89,
|
||||
0x98BADCFE,
|
||||
0x10325476,
|
||||
0xC3D2E1F0
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
static constexpr size_t BLOCK_WORDS = 16;
|
||||
static constexpr size_t BLOCK_BYTES = BLOCK_WORDS * sizeof (uint32_t);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void
|
||||
process (std::array<uint32_t,5> &H, std::array<uint32_t,16+64> &W)
|
||||
{
|
||||
// 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 util::ntoh (x);
|
||||
});
|
||||
|
||||
// Initialise the work buffer and the state variables
|
||||
for (size_t t = 16; t < 80; ++t)
|
||||
W[t] = util::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 = util::rotatel (A, 5) + f_##i (B, C, D) + E + W[t] + K_##i; \
|
||||
E = D; \
|
||||
D = C; \
|
||||
C = util::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;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
SHA1::digest_t
|
||||
SHA1::operator() (util::view<const uint8_t*> data) noexcept
|
||||
{
|
||||
return (*this) (data, nullptr);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
SHA1::digest_t
|
||||
SHA1::operator() (
|
||||
util::view<const uint8_t*> data_a,
|
||||
util::view<const uint8_t*> data_b
|
||||
) noexcept {
|
||||
/* RESET */
|
||||
uint64_t total = 0;
|
||||
|
||||
union {
|
||||
std::array<uint32_t,5> w;
|
||||
std::array<uint8_t,20> b;
|
||||
} H;
|
||||
|
||||
union {
|
||||
std::array<uint8_t, 16*4+64*4> c;
|
||||
std::array<uint32_t, 16 +64 > W;
|
||||
} state;
|
||||
|
||||
H.w = INITIAL_H;
|
||||
|
||||
/* UPDATE */
|
||||
transform_by_block (
|
||||
util::view {state.c.data (), BLOCK_BYTES },
|
||||
[&] (auto) { process (H.w, state.W); },
|
||||
data_a, data_b
|
||||
);
|
||||
|
||||
total += data_a.size () + data_b.size ();
|
||||
|
||||
/* FINISH */
|
||||
{
|
||||
size_t offset = total % BLOCK_BYTES;
|
||||
size_t used = total * 8;
|
||||
|
||||
// Append a single one bit
|
||||
state.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 (std::begin (state.c) + offset, chunk, 0);
|
||||
total += chunk;
|
||||
|
||||
process (H.w, state.W);
|
||||
|
||||
chunk = BLOCK_BYTES;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
// Zero fill and append total length
|
||||
std::fill_n (std::begin (state.c) + offset, chunk - sizeof (total), 0);
|
||||
state.c[BLOCK_BYTES - 1] = used & 0xFF; used >>= 8;
|
||||
state.c[BLOCK_BYTES - 2] = used & 0xFF; used >>= 8;
|
||||
state.c[BLOCK_BYTES - 3] = used & 0xFF; used >>= 8;
|
||||
state.c[BLOCK_BYTES - 4] = used & 0xFF; used >>= 8;
|
||||
state.c[BLOCK_BYTES - 5] = used & 0xFF; used >>= 8;
|
||||
state.c[BLOCK_BYTES - 6] = used & 0xFF; used >>= 8;
|
||||
state.c[BLOCK_BYTES - 7] = used & 0xFF; used >>= 8;
|
||||
state.c[BLOCK_BYTES - 8] = used & 0xFF;
|
||||
|
||||
total += chunk;
|
||||
process (H.w, state.W);
|
||||
}
|
||||
|
||||
/* DIGEST */
|
||||
std::transform (std::begin (H.w), std::end (H.w), std::begin (H.w), util::hton<uint32_t>);
|
||||
return H.b;
|
||||
}
|
44
hash/sha1.hpp
Normal file
44
hash/sha1.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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-2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef CRUFT_CRYPTO_HASH_SHA1_HPP
|
||||
#define CRUFT_CRYPTO_HASH_SHA1_HPP
|
||||
|
||||
#include <cruft/util/view.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace cruft::crypto::hash {
|
||||
class SHA1 {
|
||||
public:
|
||||
using digest_t = std::array<uint8_t,20>;
|
||||
static const size_t BLOCK_SIZE = 64;
|
||||
static const size_t DIGEST_SIZE = 20;
|
||||
|
||||
|
||||
//template <typename ...DataT>
|
||||
//digest_t
|
||||
//operator() (DataT&&...);
|
||||
|
||||
digest_t operator() (util::view<const uint8_t*>, util::view<const uint8_t*>) noexcept;
|
||||
digest_t operator() (util::view<const uint8_t*>) noexcept;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
314
hash/sha2.cpp
Normal file
314
hash/sha2.cpp
Normal file
@ -0,0 +1,314 @@
|
||||
/*
|
||||
* 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 <cruft/util/bitwise.hpp>
|
||||
#include <cruft/util/debug.hpp>
|
||||
#include <cruft/util/endian.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using cruft::crypto::hash::SHA256;
|
||||
|
||||
|
||||
// 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::digest_t
|
||||
SHA256::operator() (util::view<const uint8_t*> data) noexcept
|
||||
{
|
||||
(void)K_80;
|
||||
(void)H_224;
|
||||
(void)H_384;
|
||||
(void)H_512;
|
||||
|
||||
/* INIT */
|
||||
m_total = 0;
|
||||
std::copy (std::begin (H_256), std::end (H_256), std::begin (H));
|
||||
|
||||
/* UPDATE */
|
||||
{
|
||||
auto cursor = data.begin ();
|
||||
auto length = data.size ();
|
||||
|
||||
while (length) {
|
||||
size_t buffered = m_total % sizeof (M);
|
||||
size_t chunk = std::min (sizeof (M) - buffered, length);
|
||||
std::copy (cursor, cursor + chunk, C.begin () + buffered);
|
||||
|
||||
length -= chunk;
|
||||
m_total += chunk;
|
||||
|
||||
if (m_total % sizeof (M) == 0)
|
||||
process ();
|
||||
}
|
||||
}
|
||||
|
||||
/* FINISH */
|
||||
{
|
||||
// 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 ();
|
||||
}
|
||||
|
||||
/* DIGEST */
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
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), util::ntoh<uint32_t>);
|
||||
|
||||
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;
|
||||
}
|
49
hash/sha2.hpp
Normal file
49
hash/sha2.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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 CRUFT_CRYPTO_HASH_SHA2_HPP
|
||||
#define CRUFT_CRYPTO_HASH_SHA2_HPP
|
||||
|
||||
#include <cruft/util/view.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace cruft::crypto::hash {
|
||||
class SHA256 {
|
||||
public:
|
||||
typedef std::array<uint8_t,32> digest_t;
|
||||
|
||||
public:
|
||||
digest_t operator() (util::view<const uint8_t*>) noexcept;
|
||||
|
||||
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
|
12
libcruft-crypto.pc.in
Normal file
12
libcruft-crypto.pc.in
Normal file
@ -0,0 +1,12 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: libcruft-noise
|
||||
Description: A templated noise generation library
|
||||
URL: http://nerdcruft.net/
|
||||
Version: @VERSION@
|
||||
Requires: libcruft-util libcruft-image
|
||||
Libs: -L${libdir} -lcruft-noise
|
||||
Cflags: -I${includedir}
|
66
stream/rc4.cpp
Normal file
66
stream/rc4.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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 "rc4.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
using cruft::crypto::stream::RC4;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
RC4::RC4 (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
|
||||
RC4::discard (size_t len)
|
||||
{
|
||||
while (len--)
|
||||
get ();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
RC4::generate (uint8_t *restrict dst, size_t len)
|
||||
{
|
||||
std::generate_n (dst, len, [this] (void) { return get (); });
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
uint8_t
|
||||
RC4::get (void)
|
||||
{
|
||||
x = (x + 1) % 256;
|
||||
y = (y + S[x]) % 256;
|
||||
|
||||
std::swap (S[x], S[y]);
|
||||
|
||||
return S[(S[x] + S[y]) % 256];
|
||||
}
|
40
stream/rc4.hpp
Normal file
40
stream/rc4.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 CRUFT_CRYPTO_STREAM_RC4_HPP
|
||||
#define CRUFT_CRYPTO_STREAM_RC4_HPP
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
namespace cruft::crypto::stream {
|
||||
class RC4 {
|
||||
public:
|
||||
RC4 (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
|
41
stream/salsa.cpp
Normal file
41
stream/salsa.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 2017-2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "./salsa.hpp"
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
std::array<uint8_t,64>
|
||||
cruft::crypto::stream::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);
|
||||
}
|
109
stream/salsa.hpp
Normal file
109
stream/salsa.hpp
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
*
|
||||
* #endif
|
||||
* 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 2017-2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef CRUFT_CRYPTO_STREAM_SALSA_HPP
|
||||
#define CRUFT_CRYPTO_STREAM_SALSA_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
|
||||
#include <cruft/util/bitwise.hpp>
|
||||
#include <cruft/util/endian.hpp>
|
||||
|
||||
namespace cruft::crypto::stream::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 cruft::crypto::stream {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
std::array<uint8_t,64>
|
||||
salsa20 (const std::array<uint8_t,64>) noexcept;
|
||||
}
|
||||
|
||||
#endif
|
61
test/block/tea.cpp
Normal file
61
test/block/tea.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include "block/tea.hpp"
|
||||
|
||||
#include <cruft/util/tap.hpp>
|
||||
#include <cruft/util/types.hpp>
|
||||
|
||||
using cruft::crypto::block::TEA;
|
||||
|
||||
|
||||
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];
|
||||
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 ();
|
||||
}
|
59
test/block/xtea.cpp
Normal file
59
test/block/xtea.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include "block/xtea.hpp"
|
||||
|
||||
#include <cruft/util/tap.hpp>
|
||||
#include <cruft/util/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];
|
||||
cruft::crypto::block::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 ();
|
||||
}
|
117
test/block/xxtea.cpp
Normal file
117
test/block/xxtea.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
#include "block/xxtea.hpp"
|
||||
|
||||
#include <cruft/util/debug.hpp>
|
||||
#include <cruft/util/tap.hpp>
|
||||
#include <cruft/util/types.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
using cruft::crypto::block::XXTEA;
|
||||
|
||||
|
||||
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 ());
|
||||
|
||||
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 ();
|
||||
}
|
285
test/hash/hmac.cpp
Normal file
285
test/hash/hmac.cpp
Normal file
@ -0,0 +1,285 @@
|
||||
#include "hash/hmac.hpp"
|
||||
|
||||
#include "hash/md5.hpp"
|
||||
#include "hash/sha1.hpp"
|
||||
|
||||
#include <cruft/util/debug.hpp>
|
||||
#include <cruft/util/tap.hpp>
|
||||
#include <cruft/util/types.hpp>
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using cruft::crypto::hash::MD5;
|
||||
using cruft::crypto::hash::SHA1;
|
||||
using cruft::crypto::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)
|
||||
{
|
||||
HMAC<T> h (key);
|
||||
const auto ours = h (dat);
|
||||
|
||||
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[] = {
|
||||
// 1: 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<MD5>
|
||||
},
|
||||
|
||||
// 2:
|
||||
{
|
||||
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<MD5>
|
||||
},
|
||||
|
||||
// 3:
|
||||
{
|
||||
{ 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<MD5>
|
||||
},
|
||||
|
||||
// 4: 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<MD5>
|
||||
},
|
||||
|
||||
// 5:
|
||||
{
|
||||
{ 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<MD5>
|
||||
// digest-96: 0x56461ef2342edc00f9bab995
|
||||
},
|
||||
|
||||
// 6:
|
||||
{
|
||||
{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
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<MD5>
|
||||
},
|
||||
|
||||
// 7:
|
||||
{
|
||||
{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
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<MD5>
|
||||
},
|
||||
|
||||
// 8: 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<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<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<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<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<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<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<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<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 ();
|
||||
}
|
35
test/hash/hotp.cpp
Normal file
35
test/hash/hotp.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include "hash/hotp.hpp"
|
||||
|
||||
#include <cruft/util/debug.hpp>
|
||||
#include <cruft/util/tap.hpp>
|
||||
#include <cruft/util/types.hpp>
|
||||
|
||||
using cruft::crypto::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 ();
|
||||
}
|
60
test/hash/md2.cpp
Normal file
60
test/hash/md2.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
#include "hash/md2.hpp"
|
||||
|
||||
#include <cruft/util/tap.hpp>
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
using cruft::crypto::hash::MD2;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
const MD2 h;
|
||||
for (const auto &i: TESTS) {
|
||||
if (h (util::view{i.input}.cast<const uint8_t> ()) != i.output) {
|
||||
std::cerr << "Failed on " << i.input << "\n";
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
util::TAP::logger tap;
|
||||
tap.expect (success, "test vectors");
|
||||
return tap.status ();
|
||||
}
|
68
test/hash/md4.cpp
Normal file
68
test/hash/md4.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#include "hash/md4.hpp"
|
||||
|
||||
#include <cruft/util/tap.hpp>
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using cruft::crypto::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;
|
||||
|
||||
MD4 h;
|
||||
for (auto i: TESTS) {
|
||||
if (h (util::view{i.input}.cast <const uint8_t> ()) != i.output) {
|
||||
std::cerr << "Failed on '" << i.input << "'\n";
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
util::TAP::logger tap;
|
||||
tap.expect (success, "test vectors");
|
||||
return tap.status ();
|
||||
}
|
93
test/hash/md5.cpp
Normal file
93
test/hash/md5.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
#include "hash/md5.hpp"
|
||||
|
||||
#include <cruft/util/tap.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
using cruft::crypto::hash::MD5;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
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
|
||||
main (int, char**) {
|
||||
static const struct {
|
||||
std::vector<uint8_t> input;
|
||||
MD5::digest_t output;
|
||||
const char *msg;
|
||||
} TESTS[] = {
|
||||
{ {},
|
||||
{ { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
|
||||
0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } },
|
||||
"empty"
|
||||
},
|
||||
{ "a"_u8s,
|
||||
{ { 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
|
||||
0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } },
|
||||
"1 byte"
|
||||
},
|
||||
{ "abc"_u8s,
|
||||
{ { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
|
||||
0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } },
|
||||
"3 bytes"
|
||||
},
|
||||
{ "message digest"_u8s,
|
||||
{ { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
|
||||
0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } },
|
||||
"14 bytes, text"
|
||||
},
|
||||
{ "abcdefghijklmnopqrstuvwxyz"_u8s,
|
||||
{ { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
|
||||
0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } },
|
||||
"14 bytes, alphabet"
|
||||
},
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"_u8s,
|
||||
{ { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
|
||||
0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } },
|
||||
"62 bytes"
|
||||
|
||||
},
|
||||
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890"_u8s,
|
||||
{ { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
|
||||
0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } },
|
||||
"80 bytes"
|
||||
}
|
||||
};
|
||||
|
||||
util::TAP::logger tap;
|
||||
|
||||
MD5 h;
|
||||
for (const auto &t: TESTS)
|
||||
tap.expect_eq (h (t.input), t.output, "%s", t.msg);
|
||||
|
||||
|
||||
// check that appending or prepending an empty data view doesn't change
|
||||
// the hash for a couple of data lengths
|
||||
for (auto l: { 0, 1, 8, 64, 80}) {
|
||||
std::vector<uint8_t> data (l);
|
||||
std::iota (std::begin (data), std::end (data), 0);
|
||||
tap.expect_eq (h (nullptr, data), h (data), "empty-full vs full hash equality, %! bytes", l);
|
||||
tap.expect_eq (h (data, nullptr), h (data), "full-empty vs full hash equality, %! bytes", l);
|
||||
}
|
||||
|
||||
for (auto l: { 2, 64, 80}) {
|
||||
std::vector<uint8_t> data (l);
|
||||
std::iota (std::begin (data), std::end (data), 0);
|
||||
util::view root {data};
|
||||
auto [a,b] = root.split (root.begin () + l / 2);
|
||||
tap.expect_eq (h (a,b), h(root), "split data hash equality, %! bytes", l);
|
||||
};
|
||||
|
||||
return tap.status ();
|
||||
}
|
147
test/hash/ripemd.cpp
Normal file
147
test/hash/ripemd.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
#include "hash/ripemd.hpp"
|
||||
|
||||
#include <cruft/util/tap.hpp>
|
||||
#include <cruft/util/types.hpp>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using cruft::crypto::hash::RIPEMD;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static const
|
||||
struct {
|
||||
const char *msg;
|
||||
std::vector<uint8_t> data;
|
||||
RIPEMD::digest_t output;
|
||||
} TESTS[] = {
|
||||
{
|
||||
"empty",
|
||||
""_u8s,
|
||||
{ 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"_u8s,
|
||||
{ 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"_u8s,
|
||||
{ 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"_u8s,
|
||||
{ 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"_u8s,
|
||||
{ 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"_u8s,
|
||||
{ 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"_u8s,
|
||||
{ 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"_u8s,
|
||||
{ 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
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
main(int, char**) {
|
||||
util::TAP::logger tap;
|
||||
|
||||
// Check against simple test vectors
|
||||
for (const auto &t: TESTS) {
|
||||
RIPEMD obj;
|
||||
tap.expect_eq (obj (t.data), t.output, "%s", t.msg);
|
||||
}
|
||||
|
||||
// Perform 'million-a' check
|
||||
RIPEMD obj;
|
||||
|
||||
// 1 million times "a"
|
||||
// 128: 4a7f5723f954eba1216c9d8f6320431f
|
||||
// 160: 52783243c1697bdbe16d37f97f68f08325dc1528
|
||||
// 256: ac953744e10e31514c150d4d8d7b677342e33399788296e43ae4850ce4f97978
|
||||
// 320: bdee37f4371e20646b8b0d862dda16292ae36f40965e8c8509e63d1dbddecc503e2b63eb9245bb66
|
||||
|
||||
std::vector<uint8_t> data (1'000'000, 'a');
|
||||
static const 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 (data), MILLION, "million 'a'");
|
||||
|
||||
return tap.status ();
|
||||
}
|
111
test/hash/sha1.cpp
Normal file
111
test/hash/sha1.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#include "hash/sha1.hpp"
|
||||
|
||||
#include <cruft/util/debug.hpp>
|
||||
#include <cruft/util/tap.hpp>
|
||||
#include <cruft/util/types.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using cruft::crypto::hash::SHA1;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
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
|
||||
main (int, char**)
|
||||
{
|
||||
util::TAP::logger tap;
|
||||
|
||||
static const struct {
|
||||
const char *msg;
|
||||
std::vector<uint8_t> input;
|
||||
SHA1::digest_t output;
|
||||
} TESTS[] = {
|
||||
{
|
||||
"empty string",
|
||||
""_u8s,
|
||||
{ { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55,
|
||||
0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09 } }
|
||||
},
|
||||
|
||||
{
|
||||
"single a",
|
||||
"a"_u8s,
|
||||
{ { 0x86, 0xf7, 0xe4, 0x37, 0xfa, 0xa5, 0xa7, 0xfc, 0xe1, 0x5d,
|
||||
0x1d, 0xdc, 0xb9, 0xea, 0xea, 0xea, 0x37, 0x76, 0x67, 0xb8 } }
|
||||
},
|
||||
|
||||
{
|
||||
"abc",
|
||||
"abc"_u8s,
|
||||
{ { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
|
||||
0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D } }
|
||||
},
|
||||
|
||||
{
|
||||
"abc...opq",
|
||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"_u8s,
|
||||
{ { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
|
||||
0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 } }
|
||||
},
|
||||
|
||||
{
|
||||
"896 bit alphabet",
|
||||
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
|
||||
"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"_u8s,
|
||||
{ 0xa4, 0x9b, 0x24, 0x46,
|
||||
0xa0, 0x2c, 0x64, 0x5b,
|
||||
0xf4, 0x19, 0xf9, 0x95,
|
||||
0xb6, 0x70, 0x91, 0x25,
|
||||
0x3a, 0x04, 0xa2, 0x59, }
|
||||
}
|
||||
|
||||
// 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 } }
|
||||
//},
|
||||
|
||||
// 16'777'216 x "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno"
|
||||
// about 1GiB of text
|
||||
// 7789f0c9 ef7bfc40 d9331114 3dfbe69e 2017f592
|
||||
|
||||
// 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 } }
|
||||
//}
|
||||
};
|
||||
|
||||
SHA1 obj;
|
||||
|
||||
for (const auto &t: TESTS)
|
||||
tap.expect_eq (obj (t.input), t.output, "%s", t.msg);
|
||||
|
||||
{
|
||||
std::vector<uint8_t> data (1'000'000, 0x61);
|
||||
SHA1::digest_t result {
|
||||
0x34, 0xaa, 0x97, 0x3c,
|
||||
0xd4, 0xc4, 0xda, 0xa4,
|
||||
0xf6, 0x1e, 0xeb, 0x2b,
|
||||
0xdb, 0xad, 0x27, 0x31,
|
||||
0x65, 0x34, 0x01, 0x6f,
|
||||
};
|
||||
tap.expect_eq (obj (data), result, "1'000'000 a's");
|
||||
}
|
||||
|
||||
return tap.status ();
|
||||
}
|
63
test/hash/sha2.cpp
Normal file
63
test/hash/sha2.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
#include "hash/sha2.hpp"
|
||||
|
||||
#include <cruft/util/tap.hpp>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using cruft::crypto::hash::SHA256;
|
||||
|
||||
|
||||
static const struct {
|
||||
const char *msg;
|
||||
const char *input;
|
||||
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) {
|
||||
SHA256 obj;
|
||||
tap.expect_eq (obj (util::view{i.input}.cast<const uint8_t> ()), i.output, "%s", i.msg);
|
||||
}
|
||||
|
||||
return tap.status ();
|
||||
}
|
398
test/stream/rc4.cpp
Normal file
398
test/stream/rc4.cpp
Normal file
@ -0,0 +1,398 @@
|
||||
#include "stream/rc4.hpp"
|
||||
|
||||
#include <cruft/util/debug.hpp>
|
||||
#include <cruft/util/tap.hpp>
|
||||
#include <cruft/util/types.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
using cruft::crypto::stream::RC4;
|
||||
|
||||
|
||||
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];
|
||||
|
||||
RC4 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 ();
|
||||
}
|
249
test/stream/salsa.cpp
Normal file
249
test/stream/salsa.cpp
Normal file
@ -0,0 +1,249 @@
|
||||
#include "stream/salsa.hpp"
|
||||
|
||||
#include <cruft/util/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 (
|
||||
cruft::crypto::stream::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 (
|
||||
cruft::crypto::stream::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 (
|
||||
cruft::crypto::stream::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 (
|
||||
cruft::crypto::stream::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 (
|
||||
cruft::crypto::stream::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 = cruft::crypto::stream::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;
|
||||
}
|
145
tools/hash.cpp
Normal file
145
tools/hash.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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 "../hash/md2.hpp"
|
||||
#include "../hash/md4.hpp"
|
||||
#include "../hash/md5.hpp"
|
||||
#include "../hash/ripemd.hpp"
|
||||
#include "../hash/sha1.hpp"
|
||||
#include "../hash/sha2.hpp"
|
||||
|
||||
#include <cruft/util/hash/adler.hpp>
|
||||
#include <cruft/util/hash/bsdsum.cpp>
|
||||
#include <cruft/util/hash/crc.hpp>
|
||||
|
||||
#include <cruft/util/io.hpp>
|
||||
#include <cruft/util/stream.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
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 util::view<const uint8_t*> data)
|
||||
{
|
||||
#define stream(TYPE, ...) do { \
|
||||
if (name != #TYPE) \
|
||||
break; \
|
||||
\
|
||||
print_digest ( \
|
||||
std::cout, \
|
||||
util::hash::TYPE{} (data) \
|
||||
) << '\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], "-")) {
|
||||
const util::mapped_file src (argv[ARG_INPUT]);
|
||||
compute (argv[ARG_HASH], util::view{src});
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
} else {
|
||||
//compute (argv[ARG_HASH], std::cin);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user