From 7ecd9739d9439624399a4882a9f196ccf0c7ba4a Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 3 May 2014 01:04:18 +0200 Subject: [PATCH] Move {Read,Write}{LE,BE}{32,64} to common.h and use builtins if possible --- src/Makefile.am | 1 + src/crypto/common.h | 46 ++++++++++++++++++++++++++++++++++++++++ src/crypto/ripemd160.cpp | 17 ++------------- src/crypto/sha1.cpp | 17 ++------------- src/crypto/sha2.cpp | 32 +--------------------------- 5 files changed, 52 insertions(+), 61 deletions(-) create mode 100644 src/crypto/common.h diff --git a/src/Makefile.am b/src/Makefile.am index d583a79032f..01655b7011d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -75,6 +75,7 @@ BITCOIN_CORE_H = \ rpcserver.h \ script.h \ serialize.h \ + crypto/common.h \ crypto/sha2.h \ crypto/sha1.h \ crypto/ripemd160.h \ diff --git a/src/crypto/common.h b/src/crypto/common.h new file mode 100644 index 00000000000..e1bcd3ae114 --- /dev/null +++ b/src/crypto/common.h @@ -0,0 +1,46 @@ +// Copyright (c) 2014 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_CRYPTO_COMMON_H +#define BITCOIN_CRYPTO_COMMON_H + +#include + +#ifdef WIN32 +uint32_t static inline ReadLE32(const unsigned char *ptr) { return *((uint32_t*)ptr); } +uint64_t static inline ReadLE64(const unsigned char *ptr) { return *((uint64_t*)ptr); } + +void static inline WriteLE32(unsigned char *ptr, uint32_t x) { *((uint32_t*)ptr) = x; } +void static inline WriteLE64(unsigned char *ptr, uint64_t x) { *((uint64_t*)ptr) = x; } + +uint32_t static inline ReadBE32(const unsigned char *ptr) { + return ((uint32_t)ptr[0] << 24 | (uint32_t)ptr[1] << 16 | (uint32_t)ptr[2] << 8 | (uint32_t)ptr[3]); +} + +uint64_t static inline ReadBE64(const unsigned char *ptr) { + return ((uint64_t)ptr[0] << 56 | (uint64_t)ptr[1] << 48 | (uint64_t)ptr[2] << 40 | (uint64_t)ptr[3] << 32 | + (uint64_t)ptr[4] << 24 | (uint64_t)ptr[5] << 16 | (uint64_t)ptr[6] << 8 | (uint64_t)ptr[7]); +} + +void static inline WriteBE32(unsigned char *ptr, uint32_t x) { + ptr[0] = x >> 24; ptr[1] = x >> 16; ptr[2] = x >> 8; ptr[3] = x; +} + +void static inline WriteBE64(unsigned char *ptr, uint64_t x) { + ptr[0] = x >> 56; ptr[1] = x >> 48; ptr[2] = x >> 40; ptr[3] = x >> 32; + ptr[4] = x >> 24; ptr[5] = x >> 16; ptr[6] = x >> 8; ptr[7] = x; +} +#else +# include +uint32_t static inline ReadLE32(const unsigned char *ptr) { return le32toh(*((uint32_t*)ptr)); } +uint64_t static inline ReadLE64(const unsigned char *ptr) { return le64toh(*((uint64_t*)ptr)); } +void static inline WriteLE32(unsigned char *ptr, uint32_t x) { *((uint32_t*)ptr) = htole32(x); } +void static inline WriteLE64(unsigned char *ptr, uint64_t x) { *((uint64_t*)ptr) = htole64(x); } + +uint32_t static inline ReadBE32(const unsigned char *ptr) { return be32toh(*((uint32_t*)ptr)); } +uint64_t static inline ReadBE64(const unsigned char *ptr) { return be64toh(*((uint64_t*)ptr)); } +void static inline WriteBE32(unsigned char *ptr, uint32_t x) { *((uint32_t*)ptr) = htobe32(x); } +void static inline WriteBE64(unsigned char *ptr, uint64_t x) { *((uint64_t*)ptr) = htobe64(x); } +#endif +#endif diff --git a/src/crypto/ripemd160.cpp b/src/crypto/ripemd160.cpp index aa6874fa85f..c5e6e2d6967 100644 --- a/src/crypto/ripemd160.cpp +++ b/src/crypto/ripemd160.cpp @@ -4,24 +4,12 @@ #include "crypto/ripemd160.h" +#include "crypto/common.h" #include // Internal implementation code. namespace { -/** Read 4 bytes, and interpret them as a 32-bit unsigned little-endian integer. */ -uint32_t inline ReadLE32(const unsigned char *data) { - return ((uint32_t)data[0] | (uint32_t)data[1] << 8 | (uint32_t)data[2] << 16 | (uint32_t)data[3] << 24); -} - -/** Write a 32-bit unsigned little-endian integer. */ -void inline WriteLE32(unsigned char *data, uint32_t x) { - data[0] = x; - data[1] = x >> 8; - data[2] = x >> 16; - data[3] = x >> 24; -} - /// Internal RIPEMD-160 implementation. namespace ripemd160 { @@ -199,8 +187,7 @@ CRIPEMD160& CRIPEMD160::Write(const unsigned char *data, size_t len) { void CRIPEMD160::Finalize(unsigned char *hash) { static const unsigned char pad[64] = {0x80}; unsigned char sizedesc[8]; - WriteLE32(sizedesc, bytes << 3); - WriteLE32(sizedesc+4, bytes >> 29); + WriteLE64(sizedesc, bytes << 3); Write(pad, 1 + ((119 - (bytes % 64)) % 64)); Write(sizedesc, 8); WriteLE32(hash, s[0]); diff --git a/src/crypto/sha1.cpp b/src/crypto/sha1.cpp index 4b2e3e19d11..e0f32b7d1d1 100644 --- a/src/crypto/sha1.cpp +++ b/src/crypto/sha1.cpp @@ -4,24 +4,12 @@ #include "crypto/sha1.h" +#include "crypto/common.h" #include // Internal implementation code. namespace { -/** Read 4 bytes, and interpret them as a 32-bit unsigned big-endian integer. */ -uint32_t inline ReadBE32(const unsigned char *data) { - return ((uint32_t)data[0] << 24 | (uint32_t)data[1] << 16 | (uint32_t)data[2] << 8 | (uint32_t)data[3]); -} - -/** Write a 32-bit unsigned big-endian integer. */ -void inline WriteBE32(unsigned char *data, uint32_t x) { - data[0] = x >> 24; - data[1] = x >> 16; - data[2] = x >> 8; - data[3] = x; -} - /// Internal SHA-1 implementation. namespace sha1 { @@ -187,8 +175,7 @@ CSHA1& CSHA1::Write(const unsigned char *data, size_t len) { void CSHA1::Finalize(unsigned char *hash) { static const unsigned char pad[64] = {0x80}; unsigned char sizedesc[8]; - WriteBE32(sizedesc, bytes >> 29); - WriteBE32(sizedesc+4, bytes << 3); + WriteBE64(sizedesc, bytes << 3); Write(pad, 1 + ((119 - (bytes % 64)) % 64)); Write(sizedesc, 8); WriteBE32(hash, s[0]); diff --git a/src/crypto/sha2.cpp b/src/crypto/sha2.cpp index 0d0c32883ff..77f35f38d80 100644 --- a/src/crypto/sha2.cpp +++ b/src/crypto/sha2.cpp @@ -4,42 +4,12 @@ #include "crypto/sha2.h" +#include "crypto/common.h" #include // Internal implementation code. namespace { -/** Read 4 bytes, and interpret them as a 32-bit unsigned big-endian integer. */ -uint32_t inline ReadBE32(const unsigned char *data) { - return ((uint32_t)data[0] << 24 | (uint32_t)data[1] << 16 | (uint32_t)data[2] << 8 | (uint32_t)data[3]); -} - -/** Write a 32-bit unsigned big-endian integer. */ -void inline WriteBE32(unsigned char *data, uint32_t x) { - data[0] = x >> 24; - data[1] = x >> 16; - data[2] = x >> 8; - data[3] = x; -} - -/** Read 8 bytes, and interpret them as a 64-bit unsigned big-endian integer. */ -uint64_t inline ReadBE64(const unsigned char *data) { - return ((uint64_t)data[0] << 56 | (uint64_t)data[1] << 48 | (uint64_t)data[2] << 40 | (uint64_t)data[3] << 32 | - (uint64_t)data[4] << 24 | (uint64_t)data[5] << 16 | (uint64_t)data[6] << 8 | (uint64_t)data[7]); -} - -/** Write a 64-bit unsigned big-endian integer. */ -void inline WriteBE64(unsigned char *data, uint64_t x) { - data[0] = x >> 56; - data[1] = x >> 48; - data[2] = x >> 40; - data[3] = x >> 32; - data[4] = x >> 24; - data[5] = x >> 16; - data[6] = x >> 8; - data[7] = x; -} - /// Internal SHA-256 implementation. namespace sha256 {