#include "verus_hash.h"
+#include <boost/thread.hpp>
#include <assert.h>
#include <string.h>
#include <x86intrin.h>
-thread_local threadLocalKey verusclhasher_key;
+boost::thread_specific_ptr<unsigned char> verusclhasher_key;
thread_local void *verusclhasherrefresh;
thread_local int64_t verusclhasher_keySizeInBytes;
thread_local uint256 verusclhasher_seed;
#define INCLUDE_VERUS_CLHASH_H
#include <cpuid.h>
+#include <boost/thread.hpp>
#include <stdlib.h>
#include <stdint.h>
VERUSKEYSIZE=1024 * 8 + (40 * 16)
};
-struct threadLocalKey
-{
- void *pKey;
-
- threadLocalKey() : pKey(NULL) {}
- threadLocalKey(void *keyPtr) : pKey(keyPtr) {}
- ~threadLocalKey()
- {
- if (pKey)
- {
- std::free(pKey);
- }
- }
-};
-
-extern thread_local threadLocalKey verusclhasher_key;
+extern boost::thread_specific_ptr<unsigned char> verusclhasher_key;
extern thread_local void *verusclhasherrefresh;
extern thread_local int64_t verusclhasher_keySizeInBytes;
extern thread_local uint256 verusclhasher_seed;
// align to 128 bits
uint64_t newKeySize = keySizeIn64BitWords << 3;
- if (verusclhasher_key.pKey && newKeySize != verusclhasher_keySizeInBytes)
+ if (verusclhasher_key.get() && newKeySize != verusclhasher_keySizeInBytes)
{
- freehashkey();
+ verusclhasher_key.reset();
}
// get buffer space for 2 keys
- if (verusclhasher_key.pKey || (verusclhasher_key.pKey = alloc_aligned_buffer(newKeySize << 1)))
+ if (verusclhasher_key.get() || (verusclhasher_key.reset((unsigned char *)alloc_aligned_buffer(newKeySize << 1)), verusclhasher_key.get()))
{
- verusclhasherrefresh = ((char *)verusclhasher_key.pKey) + newKeySize;
+ verusclhasherrefresh = verusclhasher_key.get() + newKeySize;
verusclhasher_keySizeInBytes = newKeySize;
keyMask = keymask(newKeySize);
}
#endif
}
- void freehashkey()
- {
- // no chance for double free
- if (verusclhasher_key.pKey)
- {
- std::free(verusclhasher_key.pKey);
- verusclhasher_key.pKey = NULL;
- verusclhasherrefresh = NULL;
- }
- verusclhasher_keySizeInBytes = 0;
- keySizeIn64BitWords = 0;
- keyMask = 0;
- }
-
// this prepares a key for hashing and mutation by copying it from the original key for this block
// WARNING!! this does not check for NULL ptr, so make sure the buffer is allocated
inline void *gethashkey()
{
- memcpy(verusclhasher_key.pKey, verusclhasherrefresh, keyMask + 1);
+ unsigned char *ret = verusclhasher_key.get();
+ memcpy(ret, verusclhasherrefresh, keyMask + 1);
#ifdef VERUSHASHDEBUG
// in debug mode, ensure that what should be the same, is
- assert(memcmp((unsigned char *)verusclhasher_key.pKey + (keyMask + 1), (unsigned char *)verusclhasherrefresh + (keyMask + 1), verusclhasher_keySizeInBytes - (keyMask + 1)) == 0);
+ assert(memcmp(ret + (keyMask + 1), (unsigned char *)verusclhasherrefresh + (keyMask + 1), verusclhasher_keySizeInBytes - (keyMask + 1)) == 0);
#endif
- return verusclhasher_key.pKey;
+ return ret;
}
inline uint64_t operator()(const unsigned char buf[64]) const {
- return (*verusclhashfunction)(verusclhasher_key.pKey, buf, keyMask);
+ return (*verusclhashfunction)(verusclhasher_key.get(), buf, keyMask);
+ }
+
+ inline uint64_t operator()(void *key, const unsigned char buf[64]) const {
+ return (*verusclhashfunction)(key, buf, keyMask);
}
};
}\r
verusclhasher_seed = *((uint256 *)seedBytes32);\r
}\r
- memcpy(verusclhasher_key.pKey, verusclhasherrefresh, vclh.keySizeIn64BitWords << 3);\r
+ unsigned char *key = verusclhasher_key.get();\r
+ memcpy(key, verusclhasherrefresh, vclh.keySizeIn64BitWords << 3);\r
\r
#ifdef VERUSHASHDEBUG\r
- uint256 *bhalf1 = (uint256 *)verusclhasher_key.pKey;\r
+ uint256 *bhalf1 = (uint256 *)key;\r
uint256 *bhalf2 = bhalf1 + ((vclh.keyMask + 1) >> 5);\r
printf("New key: %s%s\n", bhalf1->GetHex().c_str(), bhalf2->GetHex().c_str());\r
#endif\r
- return (u128 *)verusclhasher_key.pKey;\r
+ return (u128 *)key;\r
}\r
\r
inline uint64_t IntermediateTo128Offset(uint64_t intermediate)\r
#endif\r
\r
// gen new key with what is last in buffer\r
- GenNewCLKey(curBuf);\r
+ u128 *key = GenNewCLKey(curBuf);\r
\r
// run verusclhash on the buffer\r
- uint64_t intermediate = vclh(curBuf);\r
+ uint64_t intermediate = vclh(key, curBuf);\r
\r
// fill buffer to the end with the result\r
FillExtra(&intermediate);\r
#ifdef VERUSHASHDEBUG\r
printf("intermediate %lx\n", intermediate);\r
printf("Curbuf: %s%s\n", bhalf1->GetHex().c_str(), bhalf2->GetHex().c_str());\r
- bhalf1 = (uint256 *)verusclhasher_key.pKey;\r
+ bhalf1 = (uint256 *)key;\r
bhalf2 = bhalf1 + ((vclh.keyMask + 1) >> 5);\r
printf(" Key: %s%s\n", bhalf1->GetHex().c_str(), bhalf2->GetHex().c_str());\r
#endif\r
\r
// get the final hash with a mutated dynamic key for each hash result\r
- (*haraka512KeyedFunction)(hash, curBuf, ((u128 *)verusclhasher_key.pKey) + IntermediateTo128Offset(intermediate));\r
+ (*haraka512KeyedFunction)(hash, curBuf, key + IntermediateTo128Offset(intermediate));\r
\r
/*\r
// TEST BEGIN\r
uint256 testHash1 = *(uint256 *)hash, testHash2;\r
FillExtra((u128 *)curBuf);\r
u128 *hashKey = ((u128 *)vclh.gethashkey());\r
- uint64_t temp = verusclhash_port(verusclhasher_key.pKey, curBuf, vclh.keyMask);\r
+ uint64_t temp = verusclhash_port(key, curBuf, vclh.keyMask);\r
FillExtra(&temp);\r
haraka512_keyed((unsigned char *)&testHash2, curBuf, hashKey + IntermediateTo128Offset(intermediate));\r
if (testHash1 != testHash2)\r
u128 *hashKey = (u128 *)vh2->vclh.gethashkey();
// run verusclhash on the buffer
- intermediate = vh2->vclh(curBuf);
+ intermediate = vh2->vclh(hashKey, curBuf);
// fill buffer to the end with the result and final hash
vh2->FillExtra(&intermediate);
printf(" hash: %s\n val: %s \ntarget: %s\n\n", hashStr.c_str(), validateStr.c_str(), hashTarget.GetHex().c_str());
printf("intermediate %lx\n", intermediate);
printf("Curbuf: %s%s\n", bhalf1->GetHex().c_str(), bhalf2->GetHex().c_str());
- bhalf1 = (uint256 *)verusclhasher_key.pKey;
+ bhalf1 = (uint256 *)verusclhasher_key.get();
bhalf2 = bhalf1 + ((vh2->vclh.keyMask + 1) >> 5);
printf(" Key: %s%s\n", bhalf1->GetHex().c_str(), bhalf2->GetHex().c_str());
#else