Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backport: Adds SipHashUint256Extra and moves CSipHasher to it's own file in crypto/ directory #3496

Draft
wants to merge 11 commits into
base: 1.15.0-dev
Choose a base branch
from
29 changes: 29 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,8 @@ AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,,
#include <byteswap.h>
#endif])

AC_CHECK_DECLS([__builtin_clz, __builtin_clzl, __builtin_clzll])

dnl Check for MSG_NOSIGNAL
AC_MSG_CHECKING(for MSG_NOSIGNAL)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]],
Expand Down Expand Up @@ -636,6 +638,33 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([
]
)

# Check for different ways of gathering OS randomness
AC_MSG_CHECKING(for Linux getrandom syscall)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <unistd.h>
#include <sys/syscall.h>
#include <linux/random.h>]],
[[ syscall(SYS_getrandom, nullptr, 32, 0); ]])],
[ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SYS_GETRANDOM, 1,[Define this symbol if the Linux getrandom system call is available]) ],
[ AC_MSG_RESULT(no)]
)

AC_MSG_CHECKING(for getentropy)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <unistd.h>]],
[[ getentropy(nullptr, 32) ]])],
[ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_GETENTROPY, 1,[Define this symbol if the BSD getentropy system call is available]) ],
[ AC_MSG_RESULT(no)]
)

AC_MSG_CHECKING(for sysctl KERN_ARND)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
#include <sys/sysctl.h>]],
[[ static const int name[2] = {CTL_KERN, KERN_ARND};
sysctl(name, 2, nullptr, nullptr, nullptr, 0); ]])],
[ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SYSCTL_ARND, 1,[Define this symbol if the BSD sysctl(KERN_ARND) is available]) ],
[ AC_MSG_RESULT(no)]
)

# Check for reduced exports
if test x$use_reduce_exports = xyes; then
AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"],
[AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])])
Expand Down
6 changes: 5 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ crypto_libdogecoin_crypto_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
crypto_libdogecoin_crypto_a_SOURCES = \
crypto/aes.cpp \
crypto/aes.h \
crypto/chacha20.h \
crypto/chacha20.cpp \
crypto/common.h \
crypto/hmac_sha256.cpp \
crypto/hmac_sha256.h \
Expand All @@ -269,7 +271,9 @@ crypto_libdogecoin_crypto_a_SOURCES = \
crypto/sha256.cpp \
crypto/sha256.h \
crypto/sha512.cpp \
crypto/sha512.h
crypto/sha512.h \
crypto/siphash.cpp \
crypto/siphash.h

# only include SSE2 scrypt sources if USE_SCRYPT_SSE2 is defined
if USE_SCRYPT_SSE2
Expand Down
1 change: 1 addition & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ BITCOIN_TESTS =\
test/pow_tests.cpp \
test/prevector_tests.cpp \
test/raii_event_tests.cpp \
test/random_tests.cpp \
test/reverselock_tests.cpp \
test/rpc_tests.cpp \
test/sanity_tests.cpp \
Expand Down
8 changes: 4 additions & 4 deletions src/addrman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,8 @@ CAddrInfo CAddrMan::Select_(bool newOnly)
int nKBucket = RandomInt(ADDRMAN_TRIED_BUCKET_COUNT);
int nKBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE);
while (vvTried[nKBucket][nKBucketPos] == -1) {
nKBucket = (nKBucket + insecure_rand.rand32()) % ADDRMAN_TRIED_BUCKET_COUNT;
nKBucketPos = (nKBucketPos + insecure_rand.rand32()) % ADDRMAN_BUCKET_SIZE;
nKBucket = (nKBucket + insecure_rand.randbits(ADDRMAN_TRIED_BUCKET_COUNT_LOG2)) % ADDRMAN_TRIED_BUCKET_COUNT;
nKBucketPos = (nKBucketPos + insecure_rand.randbits(ADDRMAN_BUCKET_SIZE_LOG2)) % ADDRMAN_BUCKET_SIZE;
}
int nId = vvTried[nKBucket][nKBucketPos];
assert(mapInfo.count(nId) == 1);
Expand All @@ -368,8 +368,8 @@ CAddrInfo CAddrMan::Select_(bool newOnly)
int nUBucket = RandomInt(ADDRMAN_NEW_BUCKET_COUNT);
int nUBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE);
while (vvNew[nUBucket][nUBucketPos] == -1) {
nUBucket = (nUBucket + insecure_rand.rand32()) % ADDRMAN_NEW_BUCKET_COUNT;
nUBucketPos = (nUBucketPos + insecure_rand.rand32()) % ADDRMAN_BUCKET_SIZE;
nUBucket = (nUBucket + insecure_rand.randbits(ADDRMAN_NEW_BUCKET_COUNT_LOG2)) % ADDRMAN_NEW_BUCKET_COUNT;
nUBucketPos = (nUBucketPos + insecure_rand.randbits(ADDRMAN_BUCKET_SIZE_LOG2)) % ADDRMAN_BUCKET_SIZE;
}
int nId = vvNew[nUBucket][nUBucketPos];
assert(mapInfo.count(nId) == 1);
Expand Down
11 changes: 8 additions & 3 deletions src/addrman.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,13 @@ class CAddrInfo : public CAddress
*/

//! total number of buckets for tried addresses
#define ADDRMAN_TRIED_BUCKET_COUNT 256
#define ADDRMAN_TRIED_BUCKET_COUNT_LOG2 8

//! total number of buckets for new addresses
#define ADDRMAN_NEW_BUCKET_COUNT 1024
#define ADDRMAN_NEW_BUCKET_COUNT_LOG2 10

//! maximum allowed number of entries in buckets for new and tried addresses
#define ADDRMAN_BUCKET_SIZE 64
#define ADDRMAN_BUCKET_SIZE_LOG2 6

//! over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread
#define ADDRMAN_TRIED_BUCKETS_PER_GROUP 8
Expand Down Expand Up @@ -171,6 +171,11 @@ class CAddrInfo : public CAddress
//! the maximum number of nodes to return in a getaddr call
#define ADDRMAN_GETADDR_MAX 2500

//! Convenience
#define ADDRMAN_TRIED_BUCKET_COUNT (1 << ADDRMAN_TRIED_BUCKET_COUNT_LOG2)
#define ADDRMAN_NEW_BUCKET_COUNT (1 << ADDRMAN_NEW_BUCKET_COUNT_LOG2)
#define ADDRMAN_BUCKET_SIZE (1 << ADDRMAN_BUCKET_SIZE_LOG2)

/**
* Stochastical (IP) address manager
*/
Expand Down
2 changes: 1 addition & 1 deletion src/bench/checkqueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static void CCheckQueueSpeedPrevectorJob(benchmark::State& state)
PrevectorJob(){
}
PrevectorJob(FastRandomContext& insecure_rand){
p.resize(insecure_rand.rand32() % (PREVECTOR_SIZE*2));
p.resize(insecure_rand.randrange(PREVECTOR_SIZE*2));
}
bool operator()()
{
Expand Down
26 changes: 26 additions & 0 deletions src/bench/crypto_hash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
#include "bench.h"
#include "bloom.h"
#include "hash.h"
#include "random.h"
#include "uint256.h"
#include "utiltime.h"
#include "crypto/ripemd160.h"
#include "crypto/sha1.h"
#include "crypto/sha256.h"
#include "crypto/sha512.h"
#include "crypto/siphash.h"

/* Number of bytes to hash per iteration */
static const uint64_t BUFFER_SIZE = 1000*1000;
Expand Down Expand Up @@ -69,10 +71,34 @@ static void SipHash_32b(benchmark::State& state)
}
}

static void FastRandom_32bit(benchmark::State& state)
{
FastRandomContext rng(true);
uint32_t x;
while (state.KeepRunning()) {
for (int i = 0; i < 1000000; i++) {
x += rng.rand32();
}
}
}

static void FastRandom_1bit(benchmark::State& state)
{
FastRandomContext rng(true);
uint32_t x;
while (state.KeepRunning()) {
for (int i = 0; i < 1000000; i++) {
x += rng.randbool();
}
}
}

BENCHMARK(RIPEMD160);
BENCHMARK(SHA1);
BENCHMARK(SHA256);
BENCHMARK(SHA512);

BENCHMARK(SHA256_32b);
BENCHMARK(SipHash_32b);
BENCHMARK(FastRandom_32bit);
BENCHMARK(FastRandom_1bit);
1 change: 1 addition & 0 deletions src/blockencodings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "consensus/consensus.h"
#include "consensus/validation.h"
#include "chainparams.h"
#include "crypto/siphash.h"
#include "hash.h"
#include "random.h"
#include "streams.h"
Expand Down
1 change: 1 addition & 0 deletions src/coins.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "compressor.h"
#include "core_memusage.h"
#include "crypto/siphash.h"
#include "hash.h"
#include "memusage.h"
#include "serialize.h"
Expand Down
180 changes: 180 additions & 0 deletions src/crypto/chacha20.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// Copyright (c) 2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

// Based on the public domain implementation 'merged' by D. J. Bernstein
// See https://cr.yp.to/chacha.html.

#include "crypto/common.h"
#include "crypto/chacha20.h"

#include <string.h>

constexpr static inline uint32_t rotl32(uint32_t v, int c) { return (v << c) | (v >> (32 - c)); }

#define QUARTERROUND(a,b,c,d) \
a += b; d = rotl32(d ^ a, 16); \
c += d; b = rotl32(b ^ c, 12); \
a += b; d = rotl32(d ^ a, 8); \
c += d; b = rotl32(b ^ c, 7);

static const unsigned char sigma[] = "expand 32-byte k";
static const unsigned char tau[] = "expand 16-byte k";

void ChaCha20::SetKey(const unsigned char* k, size_t keylen)
{
const unsigned char *constants;

input[4] = ReadLE32(k + 0);
input[5] = ReadLE32(k + 4);
input[6] = ReadLE32(k + 8);
input[7] = ReadLE32(k + 12);
if (keylen == 32) { /* recommended */
k += 16;
constants = sigma;
} else { /* keylen == 16 */
constants = tau;
}
input[8] = ReadLE32(k + 0);
input[9] = ReadLE32(k + 4);
input[10] = ReadLE32(k + 8);
input[11] = ReadLE32(k + 12);
input[0] = ReadLE32(constants + 0);
input[1] = ReadLE32(constants + 4);
input[2] = ReadLE32(constants + 8);
input[3] = ReadLE32(constants + 12);
input[12] = 0;
input[13] = 0;
input[14] = 0;
input[15] = 0;
}

ChaCha20::ChaCha20()
{
memset(input, 0, sizeof(input));
}

ChaCha20::ChaCha20(const unsigned char* k, size_t keylen)
{
SetKey(k, keylen);
}

void ChaCha20::SetIV(uint64_t iv)
{
input[14] = iv;
input[15] = iv >> 32;
}

void ChaCha20::Seek(uint64_t pos)
{
input[12] = pos;
input[13] = pos >> 32;
}

void ChaCha20::Output(unsigned char* c, size_t bytes)
{
uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
unsigned char *ctarget = NULL;
unsigned char tmp[64];
unsigned int i;

if (!bytes) return;

j0 = input[0];
j1 = input[1];
j2 = input[2];
j3 = input[3];
j4 = input[4];
j5 = input[5];
j6 = input[6];
j7 = input[7];
j8 = input[8];
j9 = input[9];
j10 = input[10];
j11 = input[11];
j12 = input[12];
j13 = input[13];
j14 = input[14];
j15 = input[15];

for (;;) {
if (bytes < 64) {
ctarget = c;
c = tmp;
}
x0 = j0;
x1 = j1;
x2 = j2;
x3 = j3;
x4 = j4;
x5 = j5;
x6 = j6;
x7 = j7;
x8 = j8;
x9 = j9;
x10 = j10;
x11 = j11;
x12 = j12;
x13 = j13;
x14 = j14;
x15 = j15;
for (i = 20;i > 0;i -= 2) {
QUARTERROUND( x0, x4, x8,x12)
QUARTERROUND( x1, x5, x9,x13)
QUARTERROUND( x2, x6,x10,x14)
QUARTERROUND( x3, x7,x11,x15)
QUARTERROUND( x0, x5,x10,x15)
QUARTERROUND( x1, x6,x11,x12)
QUARTERROUND( x2, x7, x8,x13)
QUARTERROUND( x3, x4, x9,x14)
}
x0 += j0;
x1 += j1;
x2 += j2;
x3 += j3;
x4 += j4;
x5 += j5;
x6 += j6;
x7 += j7;
x8 += j8;
x9 += j9;
x10 += j10;
x11 += j11;
x12 += j12;
x13 += j13;
x14 += j14;
x15 += j15;

++j12;
if (!j12) ++j13;

WriteLE32(c + 0, x0);
WriteLE32(c + 4, x1);
WriteLE32(c + 8, x2);
WriteLE32(c + 12, x3);
WriteLE32(c + 16, x4);
WriteLE32(c + 20, x5);
WriteLE32(c + 24, x6);
WriteLE32(c + 28, x7);
WriteLE32(c + 32, x8);
WriteLE32(c + 36, x9);
WriteLE32(c + 40, x10);
WriteLE32(c + 44, x11);
WriteLE32(c + 48, x12);
WriteLE32(c + 52, x13);
WriteLE32(c + 56, x14);
WriteLE32(c + 60, x15);

if (bytes <= 64) {
if (bytes < 64) {
for (i = 0;i < bytes;++i) ctarget[i] = c[i];
}
input[12] = j12;
input[13] = j13;
return;
}
bytes -= 64;
c += 64;
}
}