Skip to content

Instantly share code, notes, and snippets.

@Kagami
Last active August 29, 2015 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kagami/e15186b5d73224ca8c47 to your computer and use it in GitHub Desktop.
Save Kagami/e15186b5d73224ca8c47 to your computer and use it in GitHub Desktop.
POW
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <openssl/sha.h>
#define HASH_SIZE 64
#define HEX(c) (((c)>='a')?(c)-'a'+10:((c)>='A')?(c)-'A'+10:(c)-'0')
#define NTOHLL(x) ( ( (uint64_t)(ntohl( (unsigned int)((x << 32) >> 32) )) << 32) | ntohl( ((unsigned int)(x >> 32)) ) )
int main(void)
{
unsigned char message[HASH_SIZE+sizeof(uint64_t)];
unsigned char digest[HASH_SIZE];
uint64_t i;
uint64_t* nonce;
uint64_t* trial;
SHA512_CTX sha;
// Prepare.
// static const uint64_t target = 309503935734;
// static const char initialHash[] = "c9653e53abf582d69d3d2c4506457ebc99d2e4ce0145dfcdd37d33658697ad20f73ff07219dadd5102ec1d286e0073df3bce1368e0be76b55ffbf951f5af87cc";
static const uint64_t target = 297422593171;
static const char initialHash[] = "8ff2d685db89a0af2e3dbfd3f700ae96ef4d9a1eac72fd778bbb368c7510cddda349e03207e1c4965bd95c6f7265e8f1a481a08afab3874eaafb9ade09a10880";
for (i = 0; i < HASH_SIZE; i++) {
message[i+sizeof(uint64_t)] = \
HEX(initialHash[i*2]) * 16 + HEX(initialHash[i*2+1]);
}
// Calculate POW in a loop.
nonce = (uint64_t *)message;
trial = (uint64_t *)digest;
i = 0;
while (1) {
*nonce = NTOHLL(i);
SHA512_Init(&sha);
SHA512_Update(&sha, message, HASH_SIZE+sizeof(uint64_t));
SHA512_Final(digest, &sha);
SHA512_Init(&sha);
SHA512_Update(&sha, digest, HASH_SIZE);
SHA512_Final(digest, &sha);
if (NTOHLL(*trial) <= target) {
break;
}
i++;
}
// Result.
printf("nonce = %ld, trial = %ld <= %ld target\n",
NTOHLL(*nonce), NTOHLL(*trial), target);
printf("Resulting hash is: ");
for (i = 0; i < HASH_SIZE; i++) {
printf("%02x", digest[i]);
}
printf("\n");
return 0;
}
// Source: https://github.com/grant-olson/bitmessage-powfaster/blob/master/fastcpu/bitmsghash.cpp
// bitmessage cracker, build with g++ or MSVS to a shared library, use included python code for usage under bitmessage
#ifdef WIN32
#include "Windows.h"
#include "Winsock.h"
#define uint64_t unsigned __int64
#else
#include <arpa/inet.h>
#include <pthread.h>
#include <stdint.h>
#endif
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "openssl/sha.h"
#define HASH_SIZE 64
#define BUFLEN 16384
#if defined(__GNUC__)
#define EXPORT __attribute__ ((__visibility__("default")))
#define UINT intptr_t
#elif defined(WIN32)
#define EXPORT __declspec(dllexport)
#define UINT unsigned int
#endif
#define ntohll(x) ( ( (uint64_t)(ntohl( (unsigned int)((x << 32) >> 32) )) << 32) | ntohl( ((unsigned int)(x >> 32)) ) )
unsigned long long max_val;
unsigned char *initialHash;
int numthreads = 8;
unsigned long long successval = 0;
#ifdef WIN32
DWORD WINAPI threadfunc(LPVOID lpParameter) {
DWORD incamt = (DWORD)lpParameter;
#else
void * threadfunc(void* param) {
UINT incamt = (UINT)param;
#endif
SHA512_CTX sha;
unsigned char buf[HASH_SIZE+sizeof(uint64_t)] = {0};
unsigned char output[HASH_SIZE] = {0};
memcpy(buf+sizeof(uint64_t), initialHash, HASH_SIZE);
unsigned long long tmpnonce = incamt;
unsigned long long * nonce = (unsigned long long *)buf;
unsigned long long * hash = (unsigned long long *)output;
while (successval == 0) {
tmpnonce += numthreads;
(*nonce) = ntohll(tmpnonce); /* increment nonce */
SHA512_Init(&sha);
SHA512_Update(&sha, buf, HASH_SIZE+sizeof(uint64_t));
SHA512_Final(output, &sha);
SHA512_Init(&sha);
SHA512_Update(&sha, output, HASH_SIZE);
SHA512_Final(output, &sha);
if (ntohll(*hash) < max_val) {
successval = tmpnonce;
}
}
return NULL;
}
extern "C" EXPORT unsigned long long BitmessagePOW(unsigned char * starthash, unsigned long long target)
{
successval = 0;
max_val = target;
initialHash = (unsigned char *) starthash;
# ifdef WIN32
HANDLE* threads = (HANDLE*)calloc(sizeof(HANDLE), numthreads);
# else
pthread_t* threads = (pthread_t*)calloc(sizeof(pthread_t), numthreads);
# endif
for (UINT i = 0; i < numthreads; i++) {
# ifdef WIN32
threads[i] = CreateThread(NULL, 0, threadfunc, (LPVOID)i, 0, NULL);
# else
pthread_create(&threads[i], NULL, threadfunc, (void*)i);
# endif
}
# ifdef WIN32
WaitForMultipleObjects(numthreads, threads, TRUE, INFINITE);
# else
for (int i = 0; i < numthreads; i++) {
pthread_join(threads[i], NULL);
}
# endif
free(threads);
return successval;
}
var poolSize = 8;
window.runPow = function(max) {
console.time("pow");
var workers = [];
var worker;
for (var i = 0; i < poolSize; i++) {
worker = new Worker("worker.browserify.js")
worker.onmessage = onmessage;
worker.postMessage([i, poolSize, max]);
workers.push(worker);
}
function onmessage(e) {
console.timeEnd("pow");
console.log("Result nonce: " + e.data);
workers.forEach(function(w) {w.terminate();});
}
};
var createHash = require("sha.js");
var target = 297422593171;
var initialHash = Buffer("8ff2d685db89a0af2e3dbfd3f700ae96ef4d9a1eac72fd778bbb368c7510cddda349e03207e1c4965bd95c6f7265e8f1a481a08afab3874eaafb9ade09a10880", "hex");
function sha512(buf) {
return createHash("sha512").update(buf).digest();
}
function pow(nonce, poolSize, max) {
// TODO: nonce >= 2^32
max = max || 4294967295; // 2^32 - 1
var message = Buffer(72);
message.fill(0);
initialHash.copy(message, 8);
var targetHi = Math.floor(target / 4294967296);
var targetLo = target % 4294967296;
var digest, trialHi, trialLo;
while (1) {
if (nonce > max) {
return -1;
}
message.writeUInt32BE(nonce, 4, true);
digest = sha512(sha512(message));
trialHi = digest.readUInt32BE(0, true);
if (trialHi <= targetHi) {
if (trialHi < targetHi) {
return nonce;
}
trialLo = digest.readUInt32BE(4, true);
if (trialLo <= targetLo) {
return nonce;
}
}
nonce += poolSize;
}
};
onmessage = function(e) {
postMessage(pow(e.data[0], e.data[1], e.data[2]));
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment