189 lines
7.1 KiB
C++
189 lines
7.1 KiB
C++
//
|
|
// Created by wolverindev on 14.10.17.
|
|
//
|
|
|
|
#include <iostream>
|
|
#include <openssl/sha.h>
|
|
#include <ThreadPool/Thread.h>
|
|
#include <vector>
|
|
#include <ThreadPool/Mutex.h>
|
|
#include <zconf.h>
|
|
#include "misc/base64.h"
|
|
#include "Identity.h"
|
|
|
|
#define ECC_TYPE_INDEX 5
|
|
|
|
#define USE_OPENSSL_SHA1
|
|
using namespace std::chrono;
|
|
using namespace std;
|
|
namespace ts {
|
|
|
|
inline int calculateSecutityLevel(uint8_t* hashBuffer, uint8_t* bufferToHash, int length){
|
|
register int zeroBits = 0;
|
|
register int bit;
|
|
register int i;
|
|
|
|
SHA1(bufferToHash, length, hashBuffer);
|
|
|
|
//Leading zero bits
|
|
for(i = 0; i < SHA_DIGEST_LENGTH; i++)
|
|
if(hashBuffer[i] == 0) zeroBits += 8;
|
|
else break;
|
|
if(i < SHA_DIGEST_LENGTH)
|
|
for(bit = 0; bit < 8; bit++)
|
|
if((hashBuffer[i] & (1 << bit)) == 0) zeroBits++;
|
|
else break;
|
|
|
|
return zeroBits;
|
|
}
|
|
|
|
inline void increaseNumBuffer(char* buffer, int numOffset, int* length){
|
|
int index = *length - 1;
|
|
|
|
while(true){
|
|
if(buffer[index] == '9'){
|
|
if(index - 1 < numOffset) {
|
|
buffer[index] = '1';
|
|
buffer[*length] = '0';
|
|
*length += 1;
|
|
return;
|
|
}
|
|
buffer[index--] = '0';
|
|
} else {
|
|
buffer[index] += 1;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
#define MaxUlongString 20
|
|
bool Identity::improveSecurityLevelMultithreaded(int target, int nthread, size_t nblockSize, size_t baseOffset, bool verbose) {
|
|
if(this->getSecurityLevel() >= target)
|
|
return false;
|
|
|
|
vector<threads::Thread*> threads;
|
|
|
|
auto publicKey = this->publicKey();
|
|
|
|
size_t currentBlockIndex = max(max(this->lastCheckedOffset, this->keyOffset), baseOffset);
|
|
threads::Mutex blockIndexLock;
|
|
|
|
auto activeDigging = new bool(true);
|
|
threads::Thread* thread;
|
|
for(int threadId = 0; threadId < nthread; threadId++){
|
|
thread = new threads::Thread([&](){
|
|
size_t offset = 0;
|
|
size_t endOffset = 0;
|
|
size_t bestOffset = 0;
|
|
|
|
char shaHashBuffer[SHA_DIGEST_LENGTH];
|
|
char hashBuffer[publicKey.length() + MaxUlongString];
|
|
memcpy(hashBuffer, publicKey.data(), publicKey.length());
|
|
|
|
#ifndef SLOW
|
|
//Setup some stuff
|
|
size_t pubKeyLength = publicKey.length();
|
|
|
|
#endif
|
|
while(*activeDigging){
|
|
//Get next range
|
|
blockIndexLock.lock();
|
|
offset = currentBlockIndex;
|
|
endOffset = currentBlockIndex + nblockSize;
|
|
currentBlockIndex += nblockSize;
|
|
blockIndexLock.unlock();
|
|
|
|
int bestLevel = this->getSecurityLevel(hashBuffer, publicKey.length(), this->keyOffset);
|
|
#ifdef SLOW
|
|
while(offset < endOffset){
|
|
int currentLevel = getSecurityLevel(hashBuffer, publicKey.length(), offset);
|
|
if(currentLevel >= best){
|
|
bestOffset = offset;
|
|
best = currentLevel;
|
|
}
|
|
offset++;
|
|
}
|
|
blockIndexLock.lock();
|
|
if(best > this->getSecurityLevel()){
|
|
if(verbose) cout << "Improved -> " << best << "/" << target << endl;
|
|
this->lastCheckedOffset = bestOffset;
|
|
this->keyOffset = bestOffset;
|
|
cout << "Got level: " << best << endl;
|
|
|
|
if(best >= target){
|
|
cout << "Done!" << endl;
|
|
*activeDigging = false;
|
|
}
|
|
}
|
|
blockIndexLock.unlock();
|
|
if(verbose) cout << "round done: highest -> " << best << endl;
|
|
#else
|
|
|
|
string strStartOffset = to_string(offset);
|
|
ssize_t roundsLeft = nblockSize;
|
|
|
|
auto hashBufferLength = static_cast<int>(publicKey.length() + strStartOffset.length());
|
|
memcpy(&hashBuffer[pubKeyLength], strStartOffset.c_str(), strStartOffset.length());
|
|
|
|
while(roundsLeft-- >= 0){
|
|
auto level = calculateSecutityLevel(reinterpret_cast<uint8_t *>(shaHashBuffer), reinterpret_cast<uint8_t *>(hashBuffer), hashBufferLength);
|
|
if(level > bestLevel){
|
|
{
|
|
threads::MutexLock l(blockIndexLock);
|
|
|
|
auto strOffset = string(&hashBuffer[pubKeyLength], hashBufferLength - pubKeyLength);
|
|
bestOffset = stoull(strOffset);
|
|
auto got = this->getSecurityLevel();
|
|
if(got >= level) {
|
|
cout << "Already got bedder level! (" << got << ")" << endl;
|
|
bestLevel = got;
|
|
continue;
|
|
}
|
|
|
|
if(verbose) cout << "Improved -> " << level << "/" << target << " [" << strOffset << "]" << endl;
|
|
this->lastCheckedOffset = bestOffset;
|
|
this->keyOffset = bestOffset;
|
|
bestLevel = level;
|
|
|
|
if(bestLevel >= target){
|
|
cout << "Done! (" << bestLevel << ")" << endl;
|
|
*activeDigging = false;
|
|
}
|
|
}
|
|
}
|
|
increaseNumBuffer(hashBuffer, pubKeyLength + 1, &hashBufferLength);
|
|
}
|
|
#endif
|
|
}
|
|
});
|
|
thread->name("IdentityHashDigger #" + to_string(threadId));
|
|
threads.push_back(thread);
|
|
}
|
|
|
|
if(verbose){
|
|
thread = new threads::Thread([&](){
|
|
auto lastIndex = currentBlockIndex;
|
|
while(*activeDigging){
|
|
for(int count = 0; count < 1000 && *activeDigging; count++)
|
|
usleep(1000);
|
|
|
|
blockIndexLock.lock();
|
|
cout << "Current level = " << this->getSecurityLevel() << " at " << this->keyOffset << endl;
|
|
cout << "Current offset index: " << currentBlockIndex << " block size: " << nblockSize << endl;
|
|
cout << "speed: " << (currentBlockIndex - lastIndex) / 1000 / 1000.f << " Mio. attemps/sec" << endl;
|
|
lastIndex = currentBlockIndex;
|
|
blockIndexLock.unlock();
|
|
}
|
|
});
|
|
thread->name("Status printer");
|
|
threads.push_back(thread);
|
|
}
|
|
|
|
for(auto elm : threads){
|
|
if(elm->state() == threads::ThreadState::RUNNING)
|
|
elm->join();
|
|
delete elm;
|
|
}
|
|
return true;
|
|
}
|
|
} |