adding support for a more configurable sha512 hasher (#1028)
adding support for a more configurable sha512 hasher, digest32 template, using hasher512.
This commit is contained in:
parent
73d6ba6ae3
commit
44d9f456f8
|
@ -151,7 +151,6 @@ set(ed25519_sources
|
|||
keypair
|
||||
sc
|
||||
seed
|
||||
sha512
|
||||
sign
|
||||
verify
|
||||
)
|
||||
|
@ -215,7 +214,9 @@ if (encryption)
|
|||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
else()
|
||||
add_definitions(-DTORRENT_DISABLE_ENCRYPTION)
|
||||
list(APPEND sources sha1)
|
||||
if (NOT WIN32 AND NOT APPLE)
|
||||
list(APPEND sources sha1)
|
||||
endif()
|
||||
endif (encryption)
|
||||
|
||||
if (NOT logging)
|
||||
|
@ -233,6 +234,10 @@ if (dht)
|
|||
foreach(s ${ed25519_sources})
|
||||
list(APPEND sources2 ed25519/src/${s})
|
||||
endforeach(s)
|
||||
list(APPEND sources2 src/hasher512)
|
||||
if (NOT encryption AND NOT WIN32 AND NOT APPLE)
|
||||
list(APPEND sources2 src/sha512)
|
||||
endif()
|
||||
else()
|
||||
add_definitions(-DTORRENT_DISABLE_DHT)
|
||||
endif()
|
||||
|
|
15
Jamfile
15
Jamfile
|
@ -341,15 +341,21 @@ rule building ( properties * )
|
|||
result += <source>src/pe_crypto.cpp ;
|
||||
}
|
||||
|
||||
if <crypo>built-in in $(properties)
|
||||
if <crypto>built-in in $(properties)
|
||||
&& ! <target-os>windows in $(properties)
|
||||
&& ! <target-os>darwin in $(properties)
|
||||
{
|
||||
result += <source>src/sha1.cpp ;
|
||||
if <dht>on in $(properties)
|
||||
{
|
||||
result += <source>src/sha512.cpp ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( <toolset>darwin in $(properties)
|
||||
|| <toolset>gcc in $(properties)
|
||||
|| <toolset>clang in $(propertoes)
|
||||
|| <toolset>clang-darwin in $(propertoes) )
|
||||
|| <toolset>clang in $(properties)
|
||||
|| <toolset>clang-darwin in $(properties) )
|
||||
&& <link>shared in $(properties)
|
||||
# on GCC, enabling debugging in libstdc++
|
||||
# breaks the ABI and its ability to appear
|
||||
|
@ -652,7 +658,6 @@ SOURCES =
|
|||
tracker_manager
|
||||
http_tracker_connection
|
||||
udp_tracker_connection
|
||||
sha1
|
||||
timestamp_history
|
||||
udp_socket
|
||||
upnp
|
||||
|
@ -714,7 +719,6 @@ ED25519_SOURCES =
|
|||
keypair
|
||||
sc
|
||||
seed
|
||||
sha512
|
||||
sign
|
||||
verify
|
||||
;
|
||||
|
@ -766,6 +770,7 @@ lib torrent
|
|||
|
||||
<dht>on:<source>src/kademlia/$(KADEMLIA_SOURCES).cpp
|
||||
<dht>on:<source>ed25519/src/$(ED25519_SOURCES).cpp
|
||||
<dht>on:<source>src/hasher512.cpp
|
||||
<variant>debug:<asserts>on
|
||||
<variant>debug:<invariant-checks>on
|
||||
|
||||
|
|
|
@ -111,8 +111,7 @@ ED25519_SOURCE = \
|
|||
ed25519/src/fixedint.h \
|
||||
ed25519/src/ge.h \
|
||||
ed25519/src/precomp_data.h \
|
||||
ed25519/src/sc.h \
|
||||
ed25519/src/sha512.h
|
||||
ed25519/src/sc.h
|
||||
|
||||
EXTRA_DIST = \
|
||||
Jamfile \
|
||||
|
|
|
@ -385,6 +385,7 @@ AS_CASE(["$ARG_ENABLE_ENCRYPTION"],
|
|||
|
||||
AX_CHECK_OPENSSL([
|
||||
AC_DEFINE([TORRENT_USE_OPENSSL],[1],[Define to use OpenSSL support.])
|
||||
AC_DEFINE([TORRENT_USE_LIBCRYPTO],[1],[Define to use libcrypto from OpenSSL.])
|
||||
COMPILETIME_OPTIONS="$COMPILETIME_OPTIONS -DTORRENT_USE_OPENSSL -DTORRENT_USE_LIBCRYPTO "
|
||||
], [
|
||||
AC_MSG_ERROR([OpenSSL library not found. Try using --with-openssl=DIR or disabling encryption at all.])
|
||||
|
|
|
@ -94,6 +94,7 @@ category_mapping = {
|
|||
'bitfield.hpp': 'Utility',
|
||||
'sha1_hash.hpp': 'Utility',
|
||||
'hasher.hpp': 'Utility',
|
||||
'hasher512.hpp': 'Utility',
|
||||
'identify_client.hpp': 'Utility',
|
||||
'ip_filter.hpp': 'Filter',
|
||||
'session_settings.hpp': 'Settings',
|
||||
|
|
|
@ -2,14 +2,16 @@
|
|||
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
||||
|
||||
#include "libtorrent/ed25519.hpp"
|
||||
#include "sha512.h"
|
||||
#include "libtorrent/hasher512.hpp"
|
||||
#include "ge.h"
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed) {
|
||||
ge_p3 A;
|
||||
|
||||
sha512(seed, 32, private_key);
|
||||
hasher512 hash({reinterpret_cast<char const*>(seed), 32});
|
||||
std::memcpy(private_key, hash.final().data(), 64);
|
||||
private_key[0] &= 248;
|
||||
private_key[31] &= 63;
|
||||
private_key[31] |= 64;
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
#ifndef SHA512_H
|
||||
#define SHA512_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "fixedint.h"
|
||||
|
||||
/* state */
|
||||
typedef struct sha512_context_ {
|
||||
u64 length, state[8];
|
||||
size_t curlen;
|
||||
unsigned char buf[128];
|
||||
} sha512_context;
|
||||
|
||||
|
||||
int sha512_init(sha512_context * md);
|
||||
int sha512_final(sha512_context * md, unsigned char *out);
|
||||
int sha512_update(sha512_context * md, const unsigned char *in, size_t inlen);
|
||||
int sha512(const unsigned char *message, size_t message_len, unsigned char *out);
|
||||
|
||||
#endif
|
||||
|
|
@ -2,33 +2,33 @@
|
|||
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
||||
|
||||
#include "libtorrent/ed25519.hpp"
|
||||
#include "sha512.h"
|
||||
#include "libtorrent/hasher512.hpp"
|
||||
#include "ge.h"
|
||||
#include "sc.h"
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key) {
|
||||
sha512_context hash;
|
||||
unsigned char hram[64];
|
||||
unsigned char r[64];
|
||||
ge_p3 R;
|
||||
|
||||
hasher512 hash;
|
||||
hash.update({reinterpret_cast<char const*>(private_key) + 32, 32});
|
||||
hash.update({reinterpret_cast<char const*>(message), message_len});
|
||||
sha512_hash r = hash.final();
|
||||
|
||||
sha512_init(&hash);
|
||||
sha512_update(&hash, private_key + 32, 32);
|
||||
sha512_update(&hash, message, message_len);
|
||||
sha512_final(&hash, r);
|
||||
|
||||
sc_reduce(r);
|
||||
ge_scalarmult_base(&R, r);
|
||||
sc_reduce(reinterpret_cast<unsigned char*>(r.data()));
|
||||
ge_scalarmult_base(&R, reinterpret_cast<unsigned char*>(r.data()));
|
||||
ge_p3_tobytes(signature, &R);
|
||||
|
||||
sha512_init(&hash);
|
||||
sha512_update(&hash, signature, 32);
|
||||
sha512_update(&hash, public_key, 32);
|
||||
sha512_update(&hash, message, message_len);
|
||||
sha512_final(&hash, hram);
|
||||
hash.reset();
|
||||
hash.update({reinterpret_cast<char const*>(signature), 32});
|
||||
hash.update({reinterpret_cast<char const*>(public_key), 32});
|
||||
hash.update({reinterpret_cast<char const*>(message), message_len});
|
||||
sha512_hash hram = hash.final();
|
||||
|
||||
sc_reduce(hram);
|
||||
sc_muladd(signature + 32, hram, private_key, r);
|
||||
sc_reduce(reinterpret_cast<unsigned char*>(hram.data()));
|
||||
sc_muladd(signature + 32
|
||||
, reinterpret_cast<unsigned char*>(hram.data())
|
||||
, private_key
|
||||
, reinterpret_cast<unsigned char*>(r.data()));
|
||||
}
|
||||
|
|
|
@ -2,10 +2,12 @@
|
|||
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
||||
|
||||
#include "libtorrent/ed25519.hpp"
|
||||
#include "sha512.h"
|
||||
#include "libtorrent/hasher512.hpp"
|
||||
#include "ge.h"
|
||||
#include "sc.h"
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
static int consttime_equal(const unsigned char *x, const unsigned char *y) {
|
||||
unsigned char r = 0;
|
||||
|
||||
|
@ -48,9 +50,7 @@ static int consttime_equal(const unsigned char *x, const unsigned char *y) {
|
|||
}
|
||||
|
||||
int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) {
|
||||
unsigned char h[64];
|
||||
unsigned char checker[32];
|
||||
sha512_context hash;
|
||||
ge_p3 A;
|
||||
ge_p2 R;
|
||||
|
||||
|
@ -62,14 +62,15 @@ int ed25519_verify(const unsigned char *signature, const unsigned char *message,
|
|||
return 0;
|
||||
}
|
||||
|
||||
sha512_init(&hash);
|
||||
sha512_update(&hash, signature, 32);
|
||||
sha512_update(&hash, public_key, 32);
|
||||
sha512_update(&hash, message, message_len);
|
||||
sha512_final(&hash, h);
|
||||
hasher512 hash;
|
||||
hash.update({reinterpret_cast<char const*>(signature), 32});
|
||||
hash.update({reinterpret_cast<char const*>(public_key), 32});
|
||||
hash.update({reinterpret_cast<char const*>(message), message_len});
|
||||
sha512_hash h = hash.final();
|
||||
|
||||
sc_reduce(h);
|
||||
ge_double_scalarmult_vartime(&R, h, &A, signature + 32);
|
||||
sc_reduce(reinterpret_cast<unsigned char*>(h.data()));
|
||||
ge_double_scalarmult_vartime(&R, reinterpret_cast<unsigned char*>(h.data())
|
||||
, &A, signature + 32);
|
||||
ge_tobytes(checker, &R);
|
||||
|
||||
if (!consttime_equal(checker, signature)) {
|
||||
|
|
|
@ -54,6 +54,7 @@ nobase_include_HEADERS = \
|
|||
fingerprint.hpp \
|
||||
gzip.hpp \
|
||||
hasher.hpp \
|
||||
hasher512.hpp \
|
||||
hex.hpp \
|
||||
heterogeneous_queue.hpp \
|
||||
http_connection.hpp \
|
||||
|
@ -112,6 +113,7 @@ nobase_include_HEADERS = \
|
|||
session_status.hpp \
|
||||
settings_pack.hpp \
|
||||
sha1.hpp \
|
||||
sha512.hpp \
|
||||
sha1_hash.hpp \
|
||||
sliding_average.hpp \
|
||||
socket.hpp \
|
||||
|
|
|
@ -24,7 +24,7 @@ void TORRENT_EXPORT ed25519_create_seed(unsigned char *seed);
|
|||
// public_key and secret_key)
|
||||
void TORRENT_EXPORT ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed);
|
||||
void TORRENT_EXPORT ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key);
|
||||
int TORRENT_EXPORT ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *private_key);
|
||||
int TORRENT_EXPORT ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key);
|
||||
void TORRENT_EXPORT ed25519_add_scalar(unsigned char *public_key, unsigned char *private_key, const unsigned char *scalar);
|
||||
void TORRENT_EXPORT ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key);
|
||||
|
||||
|
|
|
@ -161,6 +161,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/span.hpp"
|
||||
#include "libtorrent/sha1_hash.hpp"
|
||||
#include "libtorrent/string_view.hpp"
|
||||
#include "libtorrent/socket.hpp"
|
||||
|
||||
|
@ -175,7 +176,6 @@ namespace libtorrent
|
|||
struct torrent_plugin;
|
||||
struct add_torrent_params;
|
||||
struct torrent_handle;
|
||||
class sha1_hash;
|
||||
struct session_handle;
|
||||
struct peer_connection_handle;
|
||||
|
||||
|
|
|
@ -34,9 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define TORRENT_HASHER_HPP_INCLUDED
|
||||
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/peer_id.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
#include "libtorrent/sha1_hash.hpp"
|
||||
#include "libtorrent/span.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
@ -48,7 +46,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <CommonCrypto/CommonDigest.h>
|
||||
|
||||
#elif TORRENT_USE_CRYPTOAPI
|
||||
#include <Wincrypt.h>
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
#elif defined TORRENT_USE_LIBCRYPTO
|
||||
|
||||
|
@ -76,7 +75,8 @@ namespace libtorrent
|
|||
// If you want to reuse the hasher object once you have created a hash, you have to
|
||||
// call ``reset()`` to reinitialize it.
|
||||
//
|
||||
// The sha1-algorithm used was implemented by Steve Reid and released as public domain.
|
||||
// The built-in software version of sha1-algorithm was implemented
|
||||
// by Steve Reid and released as public domain.
|
||||
// For more info, see ``src/sha1.cpp``.
|
||||
class TORRENT_EXPORT hasher
|
||||
{
|
||||
|
@ -116,11 +116,10 @@ namespace libtorrent
|
|||
#elif defined TORRENT_USE_LIBCRYPTO
|
||||
SHA_CTX m_context;
|
||||
#else
|
||||
sha_ctx m_context;
|
||||
sha1_ctx m_context;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TORRENT_HASHER_HPP_INCLUDED
|
||||
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2003-2016, Arvid Norberg, Alden Torres
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TORRENT_HASHER512_HPP_INCLUDED
|
||||
#define TORRENT_HASHER512_HPP_INCLUDED
|
||||
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/sha1_hash.hpp"
|
||||
#include "libtorrent/span.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef TORRENT_USE_LIBGCRYPT
|
||||
#include <gcrypt.h>
|
||||
|
||||
#elif TORRENT_USE_COMMONCRYPTO
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
|
||||
#elif TORRENT_USE_CRYPTOAPI
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
#elif defined TORRENT_USE_LIBCRYPTO
|
||||
|
||||
extern "C" {
|
||||
#include <openssl/sha.h>
|
||||
}
|
||||
|
||||
#else
|
||||
#include "libtorrent/sha512.hpp"
|
||||
#endif
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
using sha512_hash = digest32<512>;
|
||||
|
||||
// this is a SHA-512 hash class.
|
||||
//
|
||||
// You use it by first instantiating it, then call ``update()`` to feed it
|
||||
// with data. i.e. you don't have to keep the entire buffer of which you want to
|
||||
// create the hash in memory. You can feed the hasher parts of it at a time. When
|
||||
// You have fed the hasher with all the data, you call ``final()`` and it
|
||||
// will return the sha1-hash of the data.
|
||||
//
|
||||
// The constructor that takes a ``char const*`` and an integer will construct the
|
||||
// sha1 context and feed it the data passed in.
|
||||
//
|
||||
// If you want to reuse the hasher object once you have created a hash, you have to
|
||||
// call ``reset()`` to reinitialize it.
|
||||
//
|
||||
// The built-in software version of the sha512-algorithm is from LibTomCrypt
|
||||
// For more info, see ``src/sha512.cpp``.
|
||||
class TORRENT_EXPORT hasher512
|
||||
{
|
||||
public:
|
||||
|
||||
hasher512();
|
||||
|
||||
// this is the same as default constructing followed by a call to
|
||||
// ``update(data)``.
|
||||
explicit hasher512(span<char const> data);
|
||||
hasher512(hasher512 const&);
|
||||
hasher512& operator=(hasher512 const&);
|
||||
|
||||
// append the following bytes to what is being hashed
|
||||
hasher512& update(span<char const> data);
|
||||
|
||||
// store the SHA-512 digest of the buffers previously passed to
|
||||
// update() and the hasher constructor.
|
||||
sha512_hash final();
|
||||
|
||||
// restore the hasher state to be as if the hasher has just been
|
||||
// default constructed.
|
||||
void reset();
|
||||
|
||||
~hasher512();
|
||||
|
||||
private:
|
||||
|
||||
#ifdef TORRENT_USE_LIBGCRYPT
|
||||
gcry_md_hd_t m_context;
|
||||
#elif TORRENT_USE_COMMONCRYPTO
|
||||
CC_SHA512_CTX m_context;
|
||||
#elif TORRENT_USE_CRYPTOAPI
|
||||
HCRYPTHASH m_context;
|
||||
#elif defined TORRENT_USE_LIBCRYPTO
|
||||
SHA512_CTX m_context;
|
||||
#else
|
||||
sha512_ctx m_context;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TORRENT_HASHER512_HPP_INCLUDED
|
|
@ -19,7 +19,7 @@ changelog at the end of sha1.cpp
|
|||
namespace libtorrent
|
||||
{
|
||||
|
||||
struct TORRENT_EXTRA_EXPORT sha_ctx
|
||||
struct sha1_ctx
|
||||
{
|
||||
std::uint32_t state[5];
|
||||
std::uint32_t count[2];
|
||||
|
@ -27,12 +27,10 @@ namespace libtorrent
|
|||
};
|
||||
|
||||
// we don't want these to clash with openssl's libcrypto
|
||||
TORRENT_EXTRA_EXPORT void SHA1_init(sha_ctx* context);
|
||||
TORRENT_EXTRA_EXPORT void SHA1_update(sha_ctx* context
|
||||
, std::uint8_t const* data
|
||||
, std::uint32_t len);
|
||||
TORRENT_EXTRA_EXPORT void SHA1_final(std::uint8_t* digest, sha_ctx* context);
|
||||
TORRENT_EXTRA_EXPORT void SHA1_init(sha1_ctx* context);
|
||||
TORRENT_EXTRA_EXPORT void SHA1_update(sha1_ctx* context
|
||||
, std::uint8_t const* data, std::uint32_t len);
|
||||
TORRENT_EXTRA_EXPORT void SHA1_final(std::uint8_t* digest, sha1_ctx* context);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -49,66 +49,79 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace libtorrent
|
||||
{
|
||||
// TODO: find a better place for these functions
|
||||
namespace aux
|
||||
{
|
||||
TORRENT_EXTRA_EXPORT void bits_shift_left(span<std::uint32_t> number, int n);
|
||||
TORRENT_EXTRA_EXPORT void bits_shift_right(span<std::uint32_t> number, int n);
|
||||
}
|
||||
|
||||
// This type holds a SHA-1 digest or any other kind of 20 byte
|
||||
// This type holds an N digest or any other kind of N bits
|
||||
// sequence. It implements a number of convenience functions, such
|
||||
// as bit operations, comparison operators etc.
|
||||
//
|
||||
// In libtorrent it is primarily used to hold info-hashes, piece-hashes,
|
||||
// peer IDs, node IDs etc.
|
||||
class TORRENT_EXPORT sha1_hash
|
||||
// This data structure is 32 bits aligned, like it's the case for
|
||||
// each SHA-N specification.
|
||||
template <int N>
|
||||
class digest32
|
||||
{
|
||||
enum { number_size = 5 };
|
||||
static_assert(N % 32 == 0, "N must be a multiple of 32");
|
||||
enum { number_size = N / 32 };
|
||||
public:
|
||||
|
||||
// the size of the hash in bytes
|
||||
static constexpr size_t size() { return number_size * sizeof(std::uint32_t); }
|
||||
static constexpr size_t size() { return N / 8; }
|
||||
|
||||
// constructs an all-zero sha1-hash
|
||||
sha1_hash() { clear(); }
|
||||
// constructs an all-zero digest
|
||||
digest32() { clear(); }
|
||||
|
||||
// returns an all-F sha1-hash. i.e. the maximum value
|
||||
// representable by a 160 bit number (20 bytes). This is
|
||||
digest32(digest32 const&) = default;
|
||||
digest32(digest32&&) = default;
|
||||
digest32& operator=(digest32 const&) = default;
|
||||
digest32& operator=(digest32&&) = default;
|
||||
|
||||
// returns an all-F digest. i.e. the maximum value
|
||||
// representable by an N bit number (N/8 bytes). This is
|
||||
// a static member function.
|
||||
static sha1_hash max()
|
||||
static digest32 max()
|
||||
{
|
||||
sha1_hash ret;
|
||||
digest32 ret;
|
||||
std::memset(ret.m_number, 0xff, size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
// returns an all-zero sha1-hash. i.e. the minimum value
|
||||
// representable by a 160 bit number (20 bytes). This is
|
||||
// returns an all-zero digest. i.e. the minimum value
|
||||
// representable by an N bit number (N/8 bytes). This is
|
||||
// a static member function.
|
||||
static sha1_hash min()
|
||||
static digest32 min()
|
||||
{
|
||||
sha1_hash ret;
|
||||
digest32 ret;
|
||||
// all bits are already 0
|
||||
return ret;
|
||||
}
|
||||
|
||||
// copies 20 bytes from the pointer provided, into the sha1-hash.
|
||||
// The passed in string MUST be at least 20 bytes. 0-terminators
|
||||
// copies N/8 bytes from the pointer provided, into the digest.
|
||||
// The passed in string MUST be at least N/8 bytes. 0-terminators
|
||||
// are ignored, ``s`` is treated like a raw memory buffer.
|
||||
explicit sha1_hash(char const* s)
|
||||
explicit digest32(char const* s)
|
||||
{
|
||||
if (s == nullptr) clear();
|
||||
else std::memcpy(m_number, s, size());
|
||||
}
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
TORRENT_DEPRECATED
|
||||
explicit sha1_hash(std::string const& s)
|
||||
explicit digest32(std::string const& s)
|
||||
{
|
||||
assign(s.data());
|
||||
}
|
||||
#endif
|
||||
explicit sha1_hash(span<char const> s)
|
||||
explicit digest32(span<char const> s)
|
||||
{
|
||||
assign(s);
|
||||
}
|
||||
void assign(span<char const> s)
|
||||
{
|
||||
TORRENT_ASSERT(s.size() >= 20);
|
||||
TORRENT_ASSERT(s.size() >= N / 8);
|
||||
size_t const sl = s.size() < size() ? s.size() : size();
|
||||
std::memcpy(m_number, s.data(), sl);
|
||||
}
|
||||
|
@ -117,10 +130,10 @@ namespace libtorrent
|
|||
char const* data() const { return reinterpret_cast<char const*>(&m_number[0]); }
|
||||
char* data() { return reinterpret_cast<char*>(&m_number[0]); }
|
||||
|
||||
// set the sha1-hash to all zeroes.
|
||||
// set the digest to all zeroes.
|
||||
void clear() { std::memset(m_number, 0, size()); }
|
||||
|
||||
// return true if the sha1-hash is all zero.
|
||||
// return true if the digest is all zero.
|
||||
bool is_all_zeros() const
|
||||
{
|
||||
for (int i = 0; i < number_size; ++i)
|
||||
|
@ -129,21 +142,29 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
// shift left ``n`` bits.
|
||||
sha1_hash& operator<<=(int n);
|
||||
digest32& operator<<=(int n)
|
||||
{
|
||||
aux::bits_shift_left({m_number, number_size}, n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// shift right ``n`` bits.
|
||||
sha1_hash& operator>>=(int n);
|
||||
digest32& operator>>=(int n)
|
||||
{
|
||||
aux::bits_shift_right({m_number, number_size}, n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// standard comparison operators
|
||||
bool operator==(sha1_hash const& n) const
|
||||
bool operator==(digest32 const& n) const
|
||||
{
|
||||
return std::equal(n.m_number, n.m_number + number_size, m_number);
|
||||
}
|
||||
bool operator!=(sha1_hash const& n) const
|
||||
bool operator!=(digest32 const& n) const
|
||||
{
|
||||
return !std::equal(n.m_number, n.m_number + number_size, m_number);
|
||||
}
|
||||
bool operator<(sha1_hash const& n) const
|
||||
bool operator<(digest32 const& n) const
|
||||
{
|
||||
for (int i = 0; i < number_size; ++i)
|
||||
{
|
||||
|
@ -160,49 +181,49 @@ namespace libtorrent
|
|||
return aux::count_leading_zeros({m_number, number_size});
|
||||
}
|
||||
|
||||
// returns a bit-wise negated copy of the sha1-hash
|
||||
sha1_hash operator~() const
|
||||
// returns a bit-wise negated copy of the digest
|
||||
digest32 operator~() const
|
||||
{
|
||||
sha1_hash ret;
|
||||
digest32 ret;
|
||||
for (int i = 0; i < number_size; ++i)
|
||||
ret.m_number[i] = ~m_number[i];
|
||||
return ret;
|
||||
}
|
||||
|
||||
// returns the bit-wise XOR of the two sha1-hashes.
|
||||
sha1_hash operator^(sha1_hash const& n) const
|
||||
// returns the bit-wise XOR of the two digests.
|
||||
digest32 operator^(digest32 const& n) const
|
||||
{
|
||||
sha1_hash ret = *this;
|
||||
digest32 ret = *this;
|
||||
ret ^= n;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// in-place bit-wise XOR with the passed in sha1_hash.
|
||||
sha1_hash& operator^=(sha1_hash const& n)
|
||||
// in-place bit-wise XOR with the passed in digest.
|
||||
digest32& operator^=(digest32 const& n)
|
||||
{
|
||||
for (int i = 0; i < number_size; ++i)
|
||||
m_number[i] ^= n.m_number[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
// returns the bit-wise AND of the two sha1-hashes.
|
||||
sha1_hash operator&(sha1_hash const& n) const
|
||||
// returns the bit-wise AND of the two digests.
|
||||
digest32 operator&(digest32 const& n) const
|
||||
{
|
||||
sha1_hash ret = *this;
|
||||
digest32 ret = *this;
|
||||
ret &= n;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// in-place bit-wise AND of the passed in sha1_hash
|
||||
sha1_hash& operator&=(sha1_hash const& n)
|
||||
// in-place bit-wise AND of the passed in digest
|
||||
digest32& operator&=(digest32 const& n)
|
||||
{
|
||||
for (int i = 0; i < number_size; ++i)
|
||||
m_number[i] &= n.m_number[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
// in-place bit-wise OR of the two sha1-hash.
|
||||
sha1_hash& operator|=(sha1_hash const& n)
|
||||
// in-place bit-wise OR of the two digests.
|
||||
digest32& operator|=(digest32 const& n)
|
||||
{
|
||||
for (int i = 0; i < number_size; ++i)
|
||||
m_number[i] |= n.m_number[i];
|
||||
|
@ -235,8 +256,8 @@ namespace libtorrent
|
|||
iterator end()
|
||||
{ return reinterpret_cast<std::uint8_t*>(m_number) + size(); }
|
||||
|
||||
// return a copy of the 20 bytes representing the sha1-hash as a std::string.
|
||||
// It's still a binary string with 20 binary characters.
|
||||
// return a copy of the N/8 bytes representing the digest as a std::string.
|
||||
// It's still a binary string with N/8 binary characters.
|
||||
std::string to_string() const
|
||||
{
|
||||
return std::string(reinterpret_cast<char const*>(&m_number[0]), size());
|
||||
|
@ -248,6 +269,14 @@ namespace libtorrent
|
|||
|
||||
};
|
||||
|
||||
// This type holds a SHA-1 digest or any other kind of 20 byte
|
||||
// sequence. It implements a number of convenience functions, such
|
||||
// as bit operations, comparison operators etc.
|
||||
//
|
||||
// In libtorrent it is primarily used to hold info-hashes, piece-hashes,
|
||||
// peer IDs, node IDs etc.
|
||||
using sha1_hash = digest32<160>;
|
||||
|
||||
// this is here to support usage of sha1_hash in boost unordered containers
|
||||
typedef sha1_hash peer_id;
|
||||
inline std::size_t hash_value(sha1_hash const& b)
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef TORRENT_SHA512_HPP_INCLUDED
|
||||
#define TORRENT_SHA512_HPP_INCLUDED
|
||||
|
||||
#include "libtorrent/config.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
||||
struct sha512_ctx
|
||||
{
|
||||
std::uint64_t length, state[8];
|
||||
size_t curlen;
|
||||
std::uint8_t buf[128];
|
||||
};
|
||||
|
||||
TORRENT_EXTRA_EXPORT int SHA512_init(sha512_ctx* context);
|
||||
TORRENT_EXTRA_EXPORT int SHA512_update(sha512_ctx* context
|
||||
, std::uint8_t const* data, std::uint32_t len);
|
||||
TORRENT_EXTRA_EXPORT int SHA512_final(std::uint8_t* digest, sha512_ctx* context);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -52,6 +52,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/address.hpp"
|
||||
#include "libtorrent/socket.hpp" // tcp::endpoint
|
||||
#include "libtorrent/span.hpp"
|
||||
#include "libtorrent/sha1_hash.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -69,7 +70,6 @@ namespace libtorrent
|
|||
struct peer_list_entry;
|
||||
struct torrent_status;
|
||||
struct torrent_handle;
|
||||
class sha1_hash;
|
||||
struct storage_interface;
|
||||
class torrent;
|
||||
|
||||
|
|
|
@ -27,9 +27,15 @@ KADEMLIA_SOURCES = \
|
|||
../ed25519/src/keypair.cpp \
|
||||
../ed25519/src/sc.cpp \
|
||||
../ed25519/src/seed.cpp \
|
||||
../ed25519/src/sha512.cpp \
|
||||
../ed25519/src/sign.cpp \
|
||||
../ed25519/src/verify.cpp
|
||||
../ed25519/src/verify.cpp \
|
||||
hasher512.cpp
|
||||
endif
|
||||
|
||||
if ! WITH_OPENSSL
|
||||
BUILTIN_CRYPTO_SOURCES = \
|
||||
sha1.cpp \
|
||||
sha512.cpp
|
||||
endif
|
||||
|
||||
libtorrent_rasterbar_la_SOURCES = \
|
||||
|
@ -113,7 +119,6 @@ libtorrent_rasterbar_la_SOURCES = \
|
|||
session_settings.cpp \
|
||||
proxy_settings.cpp \
|
||||
settings_pack.cpp \
|
||||
sha1.cpp \
|
||||
sha1_hash.cpp \
|
||||
smart_ban.cpp \
|
||||
socket_io.cpp \
|
||||
|
@ -147,7 +152,9 @@ libtorrent_rasterbar_la_SOURCES = \
|
|||
file_progress.cpp \
|
||||
ffs.cpp \
|
||||
\
|
||||
$(KADEMLIA_SOURCES)
|
||||
$(KADEMLIA_SOURCES) \
|
||||
\
|
||||
$(BUILTIN_CRYPTO_SOURCES)
|
||||
|
||||
libtorrent_rasterbar_la_LDFLAGS = -version-info $(INTERFACE_VERSION_INFO)
|
||||
libtorrent_rasterbar_la_LIBADD = @OPENSSL_LIBS@
|
||||
|
|
|
@ -32,6 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "libtorrent/hasher.hpp"
|
||||
#include "libtorrent/error_code.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
#if TORRENT_USE_CRYPTOAPI
|
||||
namespace
|
||||
|
@ -179,7 +180,7 @@ namespace libtorrent
|
|||
gcry_md_final(m_context);
|
||||
digest.assign((char const*)gcry_md_read(m_context, 0));
|
||||
#elif TORRENT_USE_COMMONCRYPTO
|
||||
CC_SHA1_Final(digest.begin(), &m_context);
|
||||
CC_SHA1_Final(reinterpret_cast<unsigned char*>(digest.data()), &m_context);
|
||||
#elif TORRENT_USE_CRYPTOAPI
|
||||
|
||||
DWORD size = DWORD(digest.size());
|
||||
|
@ -194,9 +195,9 @@ namespace libtorrent
|
|||
}
|
||||
TORRENT_ASSERT(size == digest.size());
|
||||
#elif defined TORRENT_USE_LIBCRYPTO
|
||||
SHA1_Final(digest.begin(), &m_context);
|
||||
SHA1_Final(reinterpret_cast<unsigned char*>(digest.data()), &m_context);
|
||||
#else
|
||||
SHA1_final(digest.begin(), &m_context);
|
||||
SHA1_final(reinterpret_cast<unsigned char*>(digest.data()), &m_context);
|
||||
#endif
|
||||
return digest;
|
||||
}
|
||||
|
@ -233,4 +234,3 @@ namespace libtorrent
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2003-2016, Arvid Norberg, Alden Torres
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "libtorrent/hasher512.hpp"
|
||||
#include "libtorrent/error_code.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
#if TORRENT_USE_CRYPTOAPI
|
||||
namespace
|
||||
{
|
||||
HCRYPTPROV make_crypt_provider()
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
HCRYPTPROV ret;
|
||||
if (CryptAcquireContext(&ret, nullptr, nullptr, PROV_RSA_AES
|
||||
, CRYPT_VERIFYCONTEXT) == false)
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
throw system_error(error_code(GetLastError(), system_category()));
|
||||
#else
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
HCRYPTPROV get_crypt_provider()
|
||||
{
|
||||
static HCRYPTPROV prov = make_crypt_provider();
|
||||
return prov;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
hasher512::hasher512()
|
||||
{
|
||||
#ifdef TORRENT_USE_LIBGCRYPT
|
||||
gcry_md_open(&m_context, GCRY_MD_SHA512, 0);
|
||||
#elif TORRENT_USE_COMMONCRYPTO
|
||||
CC_SHA512_Init(&m_context);
|
||||
#elif TORRENT_USE_CRYPTOAPI
|
||||
if (CryptCreateHash(get_crypt_provider(), CALG_SHA_512, 0, 0, &m_context) == false)
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
throw system_error(error_code(GetLastError(), system_category()));
|
||||
#else
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
#elif defined TORRENT_USE_LIBCRYPTO
|
||||
SHA512_Init(&m_context);
|
||||
#else
|
||||
SHA512_init(&m_context);
|
||||
#endif
|
||||
}
|
||||
|
||||
hasher512::hasher512(span<char const> data)
|
||||
: hasher512()
|
||||
{
|
||||
update(data);
|
||||
}
|
||||
|
||||
#ifdef TORRENT_USE_LIBGCRYPT
|
||||
hasher512::hasher512(hasher512 const& h)
|
||||
{
|
||||
gcry_md_copy(&m_context, h.m_context);
|
||||
}
|
||||
|
||||
hasher512& hasher512::operator=(hasher512 const& h)
|
||||
{
|
||||
if (this == &h) return;
|
||||
gcry_md_close(m_context);
|
||||
gcry_md_copy(&m_context, h.m_context);
|
||||
return *this;
|
||||
}
|
||||
#elif TORRENT_USE_CRYPTOAPI
|
||||
hasher512::hasher512(hasher512 const& h)
|
||||
{
|
||||
if (CryptDuplicateHash(h.m_context, 0, 0, &m_context) == false)
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
throw system_error(error_code(GetLastError(), system_category()));
|
||||
#else
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
hasher512& hasher512::operator=(hasher512 const& h)
|
||||
{
|
||||
if (this == &h) return *this;
|
||||
CryptDestroyHash(m_context);
|
||||
if (CryptDuplicateHash(h.m_context, 0, 0, &m_context) == false)
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
throw system_error(error_code(GetLastError(), system_category()));
|
||||
#else
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
hasher512::hasher512(hasher512 const&) = default;
|
||||
hasher512& hasher512::operator=(hasher512 const&) = default;
|
||||
#endif
|
||||
|
||||
hasher512& hasher512::update(span<char const> data)
|
||||
{
|
||||
TORRENT_ASSERT(!data.empty());
|
||||
#ifdef TORRENT_USE_LIBGCRYPT
|
||||
gcry_md_write(m_context, data.data(), data.size());
|
||||
#elif TORRENT_USE_COMMONCRYPTO
|
||||
CC_SHA512_Update(&m_context, reinterpret_cast<unsigned char const*>(data.data()), data.size());
|
||||
#elif TORRENT_USE_CRYPTOAPI
|
||||
if (CryptHashData(m_context, reinterpret_cast<BYTE const*>(data.data()), int(data.size()), 0) == false)
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
throw system_error(error_code(GetLastError(), system_category()));
|
||||
#else
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
#elif defined TORRENT_USE_LIBCRYPTO
|
||||
SHA512_Update(&m_context, reinterpret_cast<unsigned char const*>(data.data()), data.size());
|
||||
#else
|
||||
SHA512_update(&m_context, reinterpret_cast<unsigned char const*>(data.data()), data.size());
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
sha512_hash hasher512::final()
|
||||
{
|
||||
sha512_hash digest;
|
||||
#ifdef TORRENT_USE_LIBGCRYPT
|
||||
gcry_md_final(m_context);
|
||||
digest.assign((char const*)gcry_md_read(m_context, 0));
|
||||
#elif TORRENT_USE_COMMONCRYPTO
|
||||
CC_SHA512_Final(reinterpret_cast<unsigned char*>(digest.data()), &m_context);
|
||||
#elif TORRENT_USE_CRYPTOAPI
|
||||
|
||||
DWORD size = DWORD(digest.size());
|
||||
if (CryptGetHashParam(m_context, HP_HASHVAL
|
||||
, reinterpret_cast<BYTE*>(digest.data()), &size, 0) == false)
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
throw system_error(error_code(GetLastError(), system_category()));
|
||||
#else
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
TORRENT_ASSERT(size == digest.size());
|
||||
#elif defined TORRENT_USE_LIBCRYPTO
|
||||
SHA512_Final(reinterpret_cast<unsigned char*>(digest.data()), &m_context);
|
||||
#else
|
||||
SHA512_final(reinterpret_cast<unsigned char*>(digest.data()), &m_context);
|
||||
#endif
|
||||
return digest;
|
||||
}
|
||||
|
||||
void hasher512::reset()
|
||||
{
|
||||
#ifdef TORRENT_USE_LIBGCRYPT
|
||||
gcry_md_reset(m_context);
|
||||
#elif TORRENT_USE_COMMONCRYPTO
|
||||
CC_SHA512_Init(&m_context);
|
||||
#elif TORRENT_USE_CRYPTOAPI
|
||||
CryptDestroyHash(m_context);
|
||||
if (CryptCreateHash(get_crypt_provider(), CALG_SHA_512, 0, 0, &m_context) == false)
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
throw system_error(error_code(GetLastError(), system_category()));
|
||||
#else
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
#elif defined TORRENT_USE_LIBCRYPTO
|
||||
SHA512_Init(&m_context);
|
||||
#else
|
||||
SHA512_init(&m_context);
|
||||
#endif
|
||||
}
|
||||
|
||||
hasher512::~hasher512()
|
||||
{
|
||||
#if TORRENT_USE_CRYPTOAPI
|
||||
CryptDestroyHash(m_context);
|
||||
#elif defined TORRENT_USE_LIBGCRYPT
|
||||
gcry_md_close(m_context);
|
||||
#endif
|
||||
}
|
||||
}
|
10
src/sha1.cpp
10
src/sha1.cpp
|
@ -120,7 +120,7 @@ namespace
|
|||
}
|
||||
|
||||
#ifdef VERBOSE
|
||||
void SHAPrintContext(sha_ctx *context, char *msg)
|
||||
void SHAPrintContext(sha1_ctx *context, char *msg)
|
||||
{
|
||||
using namespace std;
|
||||
std::printf("%s (%d,%d) %x %x %x %x %x\n"
|
||||
|
@ -135,7 +135,7 @@ namespace
|
|||
#endif
|
||||
|
||||
template <class BlkFun>
|
||||
void internal_update(sha_ctx* context, u8 const* data, u32 len)
|
||||
void internal_update(sha1_ctx* context, u8 const* data, u32 len)
|
||||
{
|
||||
using namespace std;
|
||||
u32 i, j; // JHB
|
||||
|
@ -177,7 +177,7 @@ namespace
|
|||
|
||||
// SHA1Init - Initialize new context
|
||||
|
||||
void SHA1_init(sha_ctx* context)
|
||||
void SHA1_init(sha1_ctx* context)
|
||||
{
|
||||
// SHA1 initialization constants
|
||||
context->state[0] = 0x67452301;
|
||||
|
@ -191,7 +191,7 @@ void SHA1_init(sha_ctx* context)
|
|||
|
||||
// Run your data through this.
|
||||
|
||||
void SHA1_update(sha_ctx* context, u8 const* data, u32 len)
|
||||
void SHA1_update(sha1_ctx* context, u8 const* data, u32 len)
|
||||
{
|
||||
// GCC standard defines for endianness
|
||||
// test with: cpp -dM /dev/null
|
||||
|
@ -212,7 +212,7 @@ void SHA1_update(sha_ctx* context, u8 const* data, u32 len)
|
|||
|
||||
// Add padding and return the message digest.
|
||||
|
||||
void SHA1_final(u8* digest, sha_ctx* context)
|
||||
void SHA1_final(u8* digest, sha1_ctx* context)
|
||||
{
|
||||
u8 finalcount[8];
|
||||
|
||||
|
|
|
@ -62,21 +62,24 @@ namespace libtorrent
|
|||
|
||||
#endif // TORRENT_USE_IOSTREAM
|
||||
|
||||
sha1_hash& sha1_hash::operator<<=(int n)
|
||||
namespace aux
|
||||
{
|
||||
void bits_shift_left(span<std::uint32_t> number, int n)
|
||||
{
|
||||
TORRENT_ASSERT(n >= 0);
|
||||
const int num_words = n / 32;
|
||||
int const num_words = n / 32;
|
||||
int const number_size = int(number.size());
|
||||
if (num_words >= number_size)
|
||||
{
|
||||
std::memset(m_number, 0, size());
|
||||
return *this;
|
||||
std::memset(number.data(), 0, number_size * 4);
|
||||
return;
|
||||
}
|
||||
|
||||
if (num_words > 0)
|
||||
{
|
||||
std::memmove(m_number, m_number + num_words
|
||||
std::memmove(number.data(), number.data() + num_words
|
||||
, (number_size - num_words) * sizeof(std::uint32_t));
|
||||
std::memset(m_number + (number_size - num_words)
|
||||
std::memset(number.data() + (number_size - num_words)
|
||||
, 0, num_words * sizeof(std::uint32_t));
|
||||
n -= num_words * 32;
|
||||
}
|
||||
|
@ -86,34 +89,34 @@ namespace libtorrent
|
|||
// byte order, so they have to be byteswapped before
|
||||
// applying the shift operations, and then byteswapped
|
||||
// back again.
|
||||
m_number[0] = aux::network_to_host(m_number[0]);
|
||||
number[0] = aux::network_to_host(number[0]);
|
||||
for (int i = 0; i < number_size - 1; ++i)
|
||||
{
|
||||
m_number[i] <<= n;
|
||||
m_number[i + 1] = aux::network_to_host(m_number[i + 1]);
|
||||
m_number[i] |= m_number[i + 1] >> (32 - n);
|
||||
m_number[i] = aux::host_to_network(m_number[i]);
|
||||
number[i] <<= n;
|
||||
number[i + 1] = aux::network_to_host(number[i + 1]);
|
||||
number[i] |= number[i + 1] >> (32 - n);
|
||||
number[i] = aux::host_to_network(number[i]);
|
||||
}
|
||||
m_number[number_size - 1] <<= n;
|
||||
m_number[number_size - 1] = aux::host_to_network(m_number[number_size - 1]);
|
||||
number[number_size - 1] <<= n;
|
||||
number[number_size - 1] = aux::host_to_network(number[number_size - 1]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
sha1_hash& sha1_hash::operator>>=(int n)
|
||||
void bits_shift_right(span<std::uint32_t> number, int n)
|
||||
{
|
||||
TORRENT_ASSERT(n >= 0);
|
||||
const int num_words = n / 32;
|
||||
int const num_words = n / 32;
|
||||
int const number_size = int(number.size());
|
||||
if (num_words >= number_size)
|
||||
{
|
||||
std::memset(m_number, 0, size());
|
||||
return *this;
|
||||
std::memset(number.data(), 0, number_size * 4);
|
||||
return;
|
||||
}
|
||||
if (num_words > 0)
|
||||
{
|
||||
std::memmove(m_number + num_words
|
||||
, m_number, (number_size - num_words) * sizeof(std::uint32_t));
|
||||
std::memset(m_number, 0, num_words * sizeof(std::uint32_t));
|
||||
std::memmove(number.data() + num_words
|
||||
, number.data(), (number_size - num_words) * sizeof(std::uint32_t));
|
||||
std::memset(number.data(), 0, num_words * sizeof(std::uint32_t));
|
||||
n -= num_words * 32;
|
||||
}
|
||||
if (n > 0)
|
||||
|
@ -122,19 +125,18 @@ namespace libtorrent
|
|||
// byte order, so they have to be byteswapped before
|
||||
// applying the shift operations, and then byteswapped
|
||||
// back again.
|
||||
m_number[number_size - 1] = aux::network_to_host(m_number[number_size - 1]);
|
||||
number[number_size - 1] = aux::network_to_host(number[number_size - 1]);
|
||||
|
||||
for (int i = number_size - 1; i > 0; --i)
|
||||
{
|
||||
m_number[i] >>= n;
|
||||
m_number[i - 1] = aux::network_to_host(m_number[i - 1]);
|
||||
m_number[i] |= (m_number[i - 1] << (32 - n)) & 0xffffffff;
|
||||
m_number[i] = aux::host_to_network(m_number[i]);
|
||||
number[i] >>= n;
|
||||
number[i - 1] = aux::network_to_host(number[i - 1]);
|
||||
number[i] |= (number[i - 1] << (32 - n)) & 0xffffffff;
|
||||
number[i] = aux::host_to_network(number[i]);
|
||||
}
|
||||
m_number[0] >>= n;
|
||||
m_number[0] = aux::host_to_network(m_number[0]);
|
||||
number[0] >>= n;
|
||||
number[0] = aux::host_to_network(number[0]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include "libtorrent/sha512.hpp"
|
||||
|
||||
// ignore warnings in this file
|
||||
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
||||
|
||||
|
@ -12,13 +17,17 @@
|
|||
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
|
||||
*/
|
||||
|
||||
#include "fixedint.h"
|
||||
#include "sha512.h"
|
||||
using u64 = std::uint64_t;
|
||||
using i64 = std::int64_t;
|
||||
using i32 = std::int32_t;
|
||||
|
||||
#ifndef UINT64_C
|
||||
#define UINT64_C(x) x ## LL
|
||||
#endif
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
||||
/* the K array */
|
||||
static const u64 K[80] = {
|
||||
UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd),
|
||||
|
@ -95,7 +104,7 @@ static const u64 K[80] = {
|
|||
#endif
|
||||
|
||||
/* compress 1024-bits */
|
||||
static int sha512_compress(sha512_context *md, unsigned char *buf)
|
||||
static int sha512_compress(sha512_ctx *md, unsigned char *buf)
|
||||
{
|
||||
u64 S[8], W[80], t0, t1;
|
||||
int i;
|
||||
|
@ -151,7 +160,7 @@ static int sha512_compress(sha512_context *md, unsigned char *buf)
|
|||
@param md The hash state you wish to initialize
|
||||
@return 0 if successful
|
||||
*/
|
||||
int sha512_init(sha512_context * md) {
|
||||
int SHA512_init(sha512_ctx* md) {
|
||||
if (md == NULL) return 1;
|
||||
|
||||
md->curlen = 0;
|
||||
|
@ -175,7 +184,7 @@ int sha512_init(sha512_context * md) {
|
|||
@param inlen The length of the data (octets)
|
||||
@return 0 if successful
|
||||
*/
|
||||
int sha512_update (sha512_context * md, const unsigned char *in, size_t inlen)
|
||||
int SHA512_update(sha512_ctx* md, std::uint8_t const* in, std::uint32_t inlen)
|
||||
{
|
||||
size_t n;
|
||||
size_t i;
|
||||
|
@ -222,28 +231,28 @@ int sha512_update (sha512_context * md, const unsigned char *in, size_t inlen)
|
|||
@param out [out] The destination of the hash (64 bytes)
|
||||
@return 0 if successful
|
||||
*/
|
||||
int sha512_final(sha512_context * md, unsigned char *out)
|
||||
{
|
||||
int SHA512_final(std::uint8_t* out, sha512_ctx* md)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (md == NULL) return 1;
|
||||
if (out == NULL) return 1;
|
||||
|
||||
if (md->curlen >= sizeof(md->buf)) {
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* increase the length of the message */
|
||||
md->length += md->curlen * UINT64_C(8);
|
||||
md->length += md->curlen * UINT64_C(8);
|
||||
|
||||
/* append the '1' bit */
|
||||
md->buf[md->curlen++] = (unsigned char)0x80;
|
||||
md->buf[md->curlen++] = (unsigned char)0x80;
|
||||
|
||||
/* if the length is currently above 112 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (md->curlen > 112) {
|
||||
if (md->curlen > 112) {
|
||||
while (md->curlen < 128) {
|
||||
md->buf[md->curlen++] = (unsigned char)0;
|
||||
}
|
||||
|
@ -255,31 +264,20 @@ int sha512_update (sha512_context * md, const unsigned char *in, size_t inlen)
|
|||
* note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash
|
||||
* > 2^64 bits of data... :-)
|
||||
*/
|
||||
while (md->curlen < 120) {
|
||||
md->buf[md->curlen++] = (unsigned char)0;
|
||||
}
|
||||
while (md->curlen < 120) {
|
||||
md->buf[md->curlen++] = (unsigned char)0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
STORE64H(md->length, md->buf+120);
|
||||
sha512_compress(md, md->buf);
|
||||
STORE64H(md->length, md->buf+120);
|
||||
sha512_compress(md, md->buf);
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 8; i++) {
|
||||
STORE64H(md->state[i], out+(8*i));
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
STORE64H(md->state[i], out+(8*i));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sha512(const unsigned char *message, size_t message_len, unsigned char *out)
|
||||
{
|
||||
sha512_context ctx;
|
||||
int ret;
|
||||
ret = sha512_init(&ctx);
|
||||
if (ret) return ret;
|
||||
ret = sha512_update(&ctx, message, message_len);
|
||||
if (ret) return ret;
|
||||
ret = sha512_final(&ctx, out);
|
||||
if (ret) return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // libtorrent namespace
|
|
@ -144,6 +144,8 @@ test-suite libtorrent :
|
|||
[ run test_dht.cpp
|
||||
test_dht_storage.cpp
|
||||
test_direct_dht.cpp
|
||||
test_hasher512.cpp
|
||||
test_ed25519.cpp
|
||||
]
|
||||
|
||||
[ run test_string.cpp
|
||||
|
|
|
@ -180,6 +180,8 @@ test_primitives_SOURCES = \
|
|||
test_xml.cpp \
|
||||
test_ip_filter.cpp \
|
||||
test_hasher.cpp \
|
||||
test_hasher512.cpp \
|
||||
test_ed25519.cpp \
|
||||
test_dht_storage.cpp \
|
||||
test_dht.cpp \
|
||||
test_block_cache.cpp \
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2016, Alden Torres
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "libtorrent/ed25519.hpp"
|
||||
#include "libtorrent/hex.hpp"
|
||||
|
||||
#include "test.hpp"
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
namespace
|
||||
{
|
||||
void from_hex(std::string s, unsigned char* out)
|
||||
{
|
||||
aux::from_hex(s, reinterpret_cast<char*>(out));
|
||||
}
|
||||
|
||||
void test_vector(std::string seed, std::string pub, std::string signature, std::string message)
|
||||
{
|
||||
unsigned char s[32];
|
||||
unsigned char sk[64];
|
||||
unsigned char pk[32];
|
||||
unsigned char sig[64];
|
||||
int msg_size = int(message.size()) / 2;
|
||||
std::vector<unsigned char> msg(msg_size);
|
||||
|
||||
from_hex(seed, s);
|
||||
ed25519_create_keypair(pk, sk, s);
|
||||
|
||||
TEST_EQUAL(aux::to_hex({reinterpret_cast<char const*>(pk), 32}), pub);
|
||||
|
||||
from_hex(message, msg.data());
|
||||
ed25519_sign(sig, msg.data(), msg_size, pk, sk);
|
||||
|
||||
TEST_EQUAL(aux::to_hex({reinterpret_cast<char const*>(sig), 64}), signature);
|
||||
|
||||
int r = ed25519_verify(sig, msg.data(), msg_size, pk);
|
||||
|
||||
TEST_CHECK(r);
|
||||
}
|
||||
}
|
||||
|
||||
// https://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=blob;f=tests/t-ed25519.inp;hb=HEAD
|
||||
TORRENT_TEST(ed25519_test_vec1)
|
||||
{
|
||||
// TST: 2
|
||||
test_vector(
|
||||
"4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb"
|
||||
, "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"
|
||||
, "92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da"
|
||||
"085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00"
|
||||
, "72"
|
||||
);
|
||||
|
||||
// TST: 3
|
||||
test_vector(
|
||||
"c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7"
|
||||
, "fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025"
|
||||
, "6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac"
|
||||
"18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a"
|
||||
, "af82"
|
||||
);
|
||||
|
||||
// TST: 4
|
||||
test_vector(
|
||||
"0d4a05b07352a5436e180356da0ae6efa0345ff7fb1572575772e8005ed978e9"
|
||||
, "e61a185bcef2613a6c7cb79763ce945d3b245d76114dd440bcf5f2dc1aa57057"
|
||||
, "d9868d52c2bebce5f3fa5a79891970f309cb6591e3e1702a70276fa97c24b3a8"
|
||||
"e58606c38c9758529da50ee31b8219cba45271c689afa60b0ea26c99db19b00c"
|
||||
, "cbc77b"
|
||||
);
|
||||
|
||||
// TST: 47
|
||||
test_vector(
|
||||
"89f0d68299ba0a5a83f248ae0c169f8e3849a9b47bd4549884305c9912b46603"
|
||||
, "aba3e795aab2012acceadd7b3bd9daeeed6ff5258bdcd7c93699c2a3836e3832"
|
||||
, "2c691fa8d487ce20d5d2fa41559116e0bbf4397cf5240e152556183541d66cf7"
|
||||
"53582401a4388d390339dbef4d384743caa346f55f8daba68ba7b9131a8a6e0b"
|
||||
, "4f1846dd7ad50e545d4cfbffbb1dc2ff145dc123754d08af4e44ecc0bc8c9141"
|
||||
"1388bc7653e2d893d1eac2107d05"
|
||||
);
|
||||
|
||||
// TST: 48
|
||||
test_vector(
|
||||
"0a3c1844e2db070fb24e3c95cb1cc6714ef84e2ccd2b9dd2f1460ebf7ecf13b1"
|
||||
, "72e409937e0610eb5c20b326dc6ea1bbbc0406701c5cd67d1fbde09192b07c01"
|
||||
, "87f7fdf46095201e877a588fe3e5aaf476bd63138d8a878b89d6ac60631b3458"
|
||||
"b9d41a3c61a588e1db8d29a5968981b018776c588780922f5aa732ba6379dd05"
|
||||
, "4c8274d0ed1f74e2c86c08d955bde55b2d54327e82062a1f71f70d536fdc8722"
|
||||
"cdead7d22aaead2bfaa1ad00b82957"
|
||||
);
|
||||
|
||||
// TST: 49
|
||||
test_vector(
|
||||
"c8d7a8818b98dfdb20839c871cb5c48e9e9470ca3ad35ba2613a5d3199c8ab23"
|
||||
, "90d2efbba4d43e6b2b992ca16083dbcfa2b322383907b0ee75f3e95845d3c47f"
|
||||
, "fa2e994421aef1d5856674813d05cbd2cf84ef5eb424af6ecd0dc6fdbdc2fe60"
|
||||
"5fe985883312ecf34f59bfb2f1c9149e5b9cc9ecda05b2731130f3ed28ddae0b"
|
||||
, "783e33c3acbdbb36e819f544a7781d83fc283d3309f5d3d12c8dcd6b0b3d0e89"
|
||||
"e38cfd3b4d0885661ca547fb9764abff"
|
||||
);
|
||||
|
||||
// TST: 50
|
||||
test_vector(
|
||||
"b482703612d0c586f76cfcb21cfd2103c957251504a8c0ac4c86c9c6f3e429ff"
|
||||
, "fd711dc7dd3b1dfb9df9704be3e6b26f587fe7dd7ba456a91ba43fe51aec09ad"
|
||||
, "58832bdeb26feafc31b46277cf3fb5d7a17dfb7ccd9b1f58ecbe6feb97966682"
|
||||
"8f239ba4d75219260ecac0acf40f0e5e2590f4caa16bbbcd8a155d347967a607"
|
||||
, "29d77acfd99c7a0070a88feb6247a2bce9984fe3e6fbf19d4045042a21ab26cb"
|
||||
"d771e184a9a75f316b648c6920db92b87b"
|
||||
);
|
||||
|
||||
// TST: 51
|
||||
test_vector(
|
||||
"84e50dd9a0f197e3893c38dbd91fafc344c1776d3a400e2f0f0ee7aa829eb8a2"
|
||||
, "2c50f870ee48b36b0ac2f8a5f336fb090b113050dbcc25e078200a6e16153eea"
|
||||
, "69e6a4491a63837316e86a5f4ba7cd0d731ecc58f1d0a264c67c89befdd8d382"
|
||||
"9d8de13b33cc0bf513931715c7809657e2bfb960e5c764c971d733746093e500"
|
||||
, "f3992cde6493e671f1e129ddca8038b0abdb77bb9035f9f8be54bd5d68c1aeff"
|
||||
"724ff47d29344391dc536166b8671cbbf123"
|
||||
);
|
||||
|
||||
// TST: 52
|
||||
test_vector(
|
||||
"b322d46577a2a991a4d1698287832a39c487ef776b4bff037a05c7f1812bdeec"
|
||||
, "eb2bcadfd3eec2986baff32b98e7c4dbf03ff95d8ad5ff9aa9506e5472ff845f"
|
||||
, "c7b55137317ca21e33489ff6a9bfab97c855dc6f85684a70a9125a261b56d5e6"
|
||||
"f149c5774d734f2d8debfc77b721896a8267c23768e9badb910eef83ec258802"
|
||||
, "19f1bf5dcf1750c611f1c4a2865200504d82298edd72671f62a7b1471ac3d4a3"
|
||||
"0f7de9e5da4108c52a4ce70a3e114a52a3b3c5"
|
||||
);
|
||||
|
||||
// TST: 53
|
||||
test_vector(
|
||||
"960cab5034b9838d098d2dcbf4364bec16d388f6376d73a6273b70f82bbc98c0"
|
||||
, "5e3c19f2415acf729f829a4ebd5c40e1a6bc9fbca95703a9376087ed0937e51a"
|
||||
, "27d4c3a1811ef9d4360b3bdd133c2ccc30d02c2f248215776cb07ee4177f9b13"
|
||||
"fc42dd70a6c2fed8f225c7663c7f182e7ee8eccff20dc7b0e1d5834ec5b1ea01"
|
||||
, "f8b21962447b0a8f2e4279de411bea128e0be44b6915e6cda88341a68a0d8183"
|
||||
"57db938eac73e0af6d31206b3948f8c48a447308"
|
||||
);
|
||||
}
|
||||
|
||||
#endif // TORRENT_DISABLE_DHT
|
|
@ -31,12 +31,14 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
*/
|
||||
|
||||
#include "libtorrent/hasher.hpp"
|
||||
#include "libtorrent/hex.hpp" // from_hex
|
||||
#include "libtorrent/hex.hpp"
|
||||
|
||||
#include "test.hpp"
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
namespace
|
||||
{
|
||||
// test vectors from RFC 3174
|
||||
// http://www.faqs.org/rfcs/rfc3174.html
|
||||
|
||||
|
@ -58,11 +60,19 @@ char const* result_array[4] =
|
|||
"DEA356A2CDDD90C7A7ECEDC5EBB563934F460452"
|
||||
};
|
||||
|
||||
void test_vector(std::string s, std::string output, int const n = 1)
|
||||
{
|
||||
hasher h;
|
||||
for (int i = 0; i < n; i++)
|
||||
h.update(s);
|
||||
std::string digest = h.final().to_string();
|
||||
TEST_EQUAL(aux::to_hex(digest), output);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TORRENT_TEST(hasher)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
for (int test = 0; test < 4; ++test)
|
||||
{
|
||||
hasher h;
|
||||
|
@ -75,3 +85,34 @@ TORRENT_TEST(hasher)
|
|||
}
|
||||
}
|
||||
|
||||
// http://www.di-mgt.com.au/sha_testvectors.html
|
||||
TORRENT_TEST(hasher_test_vec1)
|
||||
{
|
||||
test_vector(
|
||||
"abc"
|
||||
, "a9993e364706816aba3e25717850c26c9cd0d89d"
|
||||
);
|
||||
|
||||
test_vector(
|
||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
|
||||
, "84983e441c3bd26ebaae4aa1f95129e5e54670f1"
|
||||
);
|
||||
|
||||
test_vector(
|
||||
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi"
|
||||
"jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
|
||||
, "a49b2446a02c645bf419f995b67091253a04a259"
|
||||
);
|
||||
|
||||
test_vector(
|
||||
"a"
|
||||
, "34aa973cd4c4daa4f61eeb2bdbad27316534016f"
|
||||
, 1000000
|
||||
);
|
||||
|
||||
test_vector(
|
||||
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno"
|
||||
, "7789f0c9ef7bfc40d93311143dfbe69e2017f592"
|
||||
, 16777216
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2016, Alden Torres
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
|
||||
#include "libtorrent/hasher512.hpp"
|
||||
#include "libtorrent/hex.hpp"
|
||||
|
||||
#include "test.hpp"
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
namespace
|
||||
{
|
||||
void test_vector(std::string s, std::string output, int const n = 1)
|
||||
{
|
||||
hasher512 h;
|
||||
for (int i = 0; i < n; i++)
|
||||
h.update(s);
|
||||
std::string digest = h.final().to_string();
|
||||
TEST_EQUAL(aux::to_hex(digest), output);
|
||||
}
|
||||
}
|
||||
|
||||
// http://www.di-mgt.com.au/sha_testvectors.html
|
||||
TORRENT_TEST(hasher512_test_vec1)
|
||||
{
|
||||
test_vector(
|
||||
"abc"
|
||||
, "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
|
||||
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"
|
||||
);
|
||||
|
||||
test_vector(
|
||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
|
||||
, "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c335"
|
||||
"96fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445"
|
||||
);
|
||||
|
||||
test_vector(
|
||||
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi"
|
||||
"jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
|
||||
, "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
|
||||
"501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"
|
||||
);
|
||||
|
||||
test_vector(
|
||||
"a"
|
||||
, "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"
|
||||
"de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"
|
||||
, 1000000
|
||||
);
|
||||
|
||||
test_vector(
|
||||
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno"
|
||||
, "b47c933421ea2db149ad6e10fce6c7f93d0752380180ffd7f4629a712134831d"
|
||||
"77be6091b819ed352c2967a2e2d4fa5050723c9630691f1a05a7281dbe6c1086"
|
||||
, 16777216
|
||||
);
|
||||
}
|
||||
|
||||
#endif // TORRENT_DISABLE_DHT
|
Loading…
Reference in New Issue