aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRiccardo Spagni <ric@spagni.net>2015-02-03 20:15:02 +0200
committerRiccardo Spagni <ric@spagni.net>2015-02-03 20:15:08 +0200
commit6e5797dc1160f73b073b4d9ecdec455ffb11e309 (patch)
treed609032f536e9abe3e154bd52963d9d899fc49f3
parentchanged MM logo (diff)
parentmake fallback compatible with newer slow-hash (diff)
downloadmonero-6e5797dc1160f73b073b4d9ecdec455ffb11e309.tar.xz
Merge pull request #221
3ece158 make fallback compatible with newer slow-hash (Riccardo Spagni) 709bbc5 replaced 64-bit multiplication in difficulty.cpp with a portable version (Riccardo Spagni) 497a514 replaced 64-bit multiplication in difficulty.cpp with a portable version (Riccardo Spagni)
-rw-r--r--src/crypto/slow-hash.c12
-rw-r--r--src/cryptonote_core/difficulty.cpp38
2 files changed, 46 insertions, 4 deletions
diff --git a/src/crypto/slow-hash.c b/src/crypto/slow-hash.c
index fda854ea5..6b410b01a 100644
--- a/src/crypto/slow-hash.c
+++ b/src/crypto/slow-hash.c
@@ -627,6 +627,18 @@ void cn_slow_hash(const void *data, size_t length, char *hash)
#else
// Portable implementation as a fallback
+void slow_hash_allocate_state(void)
+{
+ // Do nothing, this is just to maintain compatibility with the upgraded slow-hash.c
+ return;
+}
+
+void slow_hash_free_state(void)
+{
+ // As above
+ return;
+}
+
static void (*const extra_hashes[4])(const void *, size_t, char *) = {
hash_extra_blake, hash_extra_groestl, hash_extra_jh, hash_extra_skein
};
diff --git a/src/cryptonote_core/difficulty.cpp b/src/cryptonote_core/difficulty.cpp
index 106520440..6486d8124 100644
--- a/src/cryptonote_core/difficulty.cpp
+++ b/src/cryptonote_core/difficulty.cpp
@@ -56,10 +56,40 @@ namespace cryptonote {
#else
static inline void mul(uint64_t a, uint64_t b, uint64_t &low, uint64_t &high) {
- typedef unsigned __int128 uint128_t;
- uint128_t res = (uint128_t) a * (uint128_t) b;
- low = (uint64_t) res;
- high = (uint64_t) (res >> 64);
+ // __int128 isn't part of the standard, so the previous function wasn't portable. mul128() in Windows is fine,
+ // but this portable function should be used elsewhere. Credit for this function goes to latexi95.
+
+ uint64_t aLow = a & 0xFFFFFFFF;
+ uint64_t aHigh = a >> 32;
+ uint64_t bLow = b & 0xFFFFFFFF;
+ uint64_t bHigh = b >> 32;
+
+ uint64_t res = aLow * bLow;
+ uint64_t lowRes1 = res & 0xFFFFFFFF;
+ uint64_t carry = res >> 32;
+
+ res = aHigh * bLow + carry;
+ uint64_t highResHigh1 = res >> 32;
+ uint64_t highResLow1 = res & 0xFFFFFFFF;
+
+ res = aLow * bHigh;
+ uint64_t lowRes2 = res & 0xFFFFFFFF;
+ carry = res >> 32;
+
+ res = aHigh * bHigh + carry;
+ uint64_t highResHigh2 = res >> 32;
+ uint64_t highResLow2 = res & 0xFFFFFFFF;
+
+ //Addition
+
+ uint64_t r = highResLow1 + lowRes2;
+ carry = r >> 32;
+ low = (r << 32) | lowRes1;
+ r = highResHigh1 + highResLow2 + carry;
+ uint64_t d3 = r & 0xFFFFFFFF;
+ carry = r >> 32;
+ r = highResHigh2 + carry;
+ high = d3 | (r << 32);
}
#endif