From a7ef60945a76ad4a7609a5960f39b5971e320326 Mon Sep 17 00:00:00 2001 From: miketout Date: Sun, 12 Aug 2018 15:17:58 -0700 Subject: [PATCH] used hellcatz interface and tests and enabled optimized hash --- binding.gyp | 19 +++ crypto/haraka.c | 2 +- crypto/verus_hash.cpp | 4 +- crypto/verus_hash.h | 4 +- package.json | 24 ++-- test.js | 53 ++++++-- verushash.cc | 276 +++++++++++++++--------------------------- 7 files changed, 173 insertions(+), 209 deletions(-) diff --git a/binding.gyp b/binding.gyp index 6594b99..9728cf0 100644 --- a/binding.gyp +++ b/binding.gyp @@ -26,6 +26,25 @@ "-fexceptions", "-Ofast", "-march=native", + "-msse4", + "-msse4.1", + "-msse4.2", + "-mssse3", + "-mavx", + "-maes", + ], + "cflags": [ + "-Wl,--whole-archive", + "-fPIC", + "-fexceptions", + "-Ofast", + "-march=native", + "-msse4", + "-msse4.1", + "-msse4.2", + "-mssse3", + "-mavx", + "-maes", ], "link_settings": { "libraries": [ diff --git a/crypto/haraka.c b/crypto/haraka.c index d611b9a..8b3e5ba 100644 --- a/crypto/haraka.c +++ b/crypto/haraka.c @@ -25,7 +25,7 @@ Optimized Implementations for Haraka256 and Haraka512 */ #include -#include "crypto/haraka.h" +#include "haraka.h" u128 rc[40]; u128 rc0[40] = {0}; diff --git a/crypto/verus_hash.cpp b/crypto/verus_hash.cpp index aeae971..f62dda6 100644 --- a/crypto/verus_hash.cpp +++ b/crypto/verus_hash.cpp @@ -9,8 +9,8 @@ inputs only, Verus Hash takes any length of input and produces a 256 bit output. */ #include -#include "crypto/common.h" -#include "crypto/verus_hash.h" +#include "common.h" +#include "verus_hash.h" void (*CVerusHash::haraka512Function)(unsigned char *out, const unsigned char *in); diff --git a/crypto/verus_hash.h b/crypto/verus_hash.h index 23ca8fc..d385e51 100644 --- a/crypto/verus_hash.h +++ b/crypto/verus_hash.h @@ -15,8 +15,8 @@ This provides the PoW hash function for Verus, enabling CPU mining. extern "C" { -#include "crypto/haraka.h" -#include "crypto/haraka_portable.h" +#include "haraka.h" +#include "haraka_portable.h" } class CVerusHash diff --git a/package.json b/package.json index 984e3dc..cd19cb5 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,15 @@ -{ "name" : "verushash" -, "author" : "miketout" -, "version" : "0.0.5" -, "scripts" : - { "preinstall" : "node-waf configure" - , "install" : "node-waf build" - , "test" : "node test.js" - } -, "main" : "build/default/verushash" -, "engines" : [ "node" ] +{ + "name": "verushash", + "author": "hellcatz", + "version": "0.0.6", + "scripts": { + "test": "node test.js" + }, + "main": "verushash", + "bundleDependencies": true, + "dependencies": { + "bindings": "*", + "nan": "*", + "node-gyp": "*" + } } diff --git a/test.js b/test.js index 039431d..e4ef988 100644 --- a/test.js +++ b/test.js @@ -1,16 +1,43 @@ -var crypto=require("./verushash.cc"); -var sys=require("sys"); -var fs=require("fs"); -var test=require("mjsunit"); +var cluster = require('cluster'); +var vh = require('bindings')('verushash.node'); +var reverseBuffer = function (buff) { + var reversed = Buffer.alloc(buff.length); + for (var i = buff.length - 1; i >= 0; i--) + reversed[buff.length - i - 1] = buff[i]; + return reversed; +}; +var reverseHex = function (hex) { + return reverseBuffer(Buffer.from(hex, 'hex')).toString('hex'); +}; -// Test hashing -var a0 = (new verushash.Hash).init("verus").update("Test123").digest("hex"); -var a1 = (new verushash.Hash).init("verus").update("Test123").digest("binary"); -var a3 = (new verushash.Hash).init("verus").update("Test123").digest(); // binary - -// Test multiple updates to same hash -var h1 = (new verushash.Hash).init("verus").update("Test123").digest("hex"); -var h2 = (new verushash.Hash).init("verus").update("Test").update("123").digest("hex"); -test.assertEquals(h1, h2, "multipled updates"); +var numWorkers = require('os').cpus().length; +numWorkers = 20; +if (cluster.isMaster) { + + var workers = []; + var gbtCount = 0; + for (var i = 0; i < numWorkers; i++){ + var worker = cluster.fork({ + workerType: 'VerusHasher', + forkId: i + }); + workers.push(worker); + } + +} else { + + var output = vh.hash(Buffer.from('Test1234','utf8')); + console.log(process.pid,'Output', reverseHex(output.toString('hex')), '\n'); + output = vh.init().update(Buffer.from('Test','utf8')).update(Buffer.from('123','utf8')).update(Buffer.from('4','utf8')).digest(); + console.log(process.pid,'Output', reverseHex(output.toString('hex')), '\n'); + for (var i=0; i<100; i++) { + vh.reset(); + vh.update(Buffer.from('Test','utf8')); + vh.update(Buffer.from('123','utf8')); + vh.update(Buffer.from('4','utf8')); + output = vh.digest(); + console.log(process.pid,'Output', reverseHex(output.toString('hex')), '\n'); + } +} diff --git a/verushash.cc b/verushash.cc index d9e3a0a..1af2bb0 100644 --- a/verushash.cc +++ b/verushash.cc @@ -1,201 +1,115 @@ +#include #include -#include -#include -#include +#include +#include +#include +#include + +#include "crypto/verus_hash.h" using namespace v8; -using namespace node; -void hex_encode(unsigned char *md_value, int md_len, char** md_hexdigest, int* md_hex_len) { - *md_hex_len = (2*(md_len)); - *md_hexdigest = (char *) malloc(*md_hex_len + 1); - for(int i = 0; i < md_len; i++) { - sprintf((char *)(*md_hexdigest + (i*2)), "%02x", md_value[i]); - } -} +CVerusHash* vh; +bool initialized = false; -#define hex2i(c) ((c) <= '9' ? ((c) - '0') : (c) <= 'Z' ? ((c) - 'A' + 10) : ((c) - 'a' + 10)) -void hex_decode(unsigned char *input, int length, char** buf64, int* buf64_len) { - *buf64_len = (length/2); - *buf64 = (char*) malloc(length/2 + 1); - char *b = *buf64; - for(int i = 0; i < length-1; i+=2) { - b[i/2] = (hex2i(input[i])<<4) | (hex2i(input[i+1])); - } +void verusInit(const v8::FunctionCallbackInfo& args) { + vh = new CVerusHash(); + vh->init(); + initialized = true; + + args.GetReturnValue().Set(args.This()); } -class Hash : public ObjectWrap { - public: - static void - Initialize (v8::Handle target) - { - HandleScope scope; - - Local t = FunctionTemplate::New(New); - - t->InstanceTemplate()->SetInternalFieldCount(1); - - NODE_SET_PROTOTYPE_METHOD(t, "init", HashInit); - NODE_SET_PROTOTYPE_METHOD(t, "reset", HashReset); - NODE_SET_PROTOTYPE_METHOD(t, "update", HashUpdate); - NODE_SET_PROTOTYPE_METHOD(t, "digest", HashDigest); - - target->Set(String::NewSymbol("Hash"), t->GetFunction()); - } - - bool HashInit (const char* hashType) - { - initialised = true; - return true; - } - - bool HashReset () - { - if (!initialised) - return false;; - vh.Reset(); - return true; - } - - int HashUpdate(char* data, int len) { - if (!initialised) - return 0; - vh.Write((const unsigned *)data, len) - return 1; - } - - int HashDigest(unsigned char** md_value, unsigned int *md_len) { - if (!initialised) - return 0; - vh.Finalize(*md_value); - *md_len = 32; - return 1; - } - - protected: - - static Handle - New (const Arguments& args) - { - HandleScope scope; - - Hash *hash = new Hash(); - hash->Wrap(args.This()); - return args.This(); - } - - static Handle - HashInit(const Arguments& args) { - Hash *hash = ObjectWrap::Unwrap(args.This()); - - HandleScope scope; - - if (args.Length() == 0 || !args[0]->IsString()) { - return ThrowException(String::New("Must give hashtype string as argument")); +void verusUpdate(const v8::FunctionCallbackInfo& args) { + Isolate* isolate = Isolate::GetCurrent(); + HandleScope scope(isolate); + if (initialized == false){ + isolate->ThrowException( + Exception::TypeError(String::NewFromUtf8(isolate, "call init() first!")) + ); } - - String::Utf8Value hashType(args[0]->ToString()); - - // only support verus v1 now - if (strcmp(hashType, "verus")) { - return ThrowException(String::New("Only verus is supported as a hashType")); + if (args.Length() < 1) { + isolate->ThrowException( + Exception::TypeError(String::NewFromUtf8(isolate, "Wrong number of arguments")) + ); + return; } - - bool r = hash->HashInit(*hashType); - - return args.This(); - } - - static Handle - HashReset(const Arguments& args) { - Hash *hash = ObjectWrap::Unwrap(args.This()); - - HandleScope scope; - bool r = hash->HashReset(); - - return args.This(); - } - - static Handle - HashUpdate(const Arguments& args) { - Hash *hash = ObjectWrap::Unwrap(args.This()); - - HandleScope scope; - - enum encoding enc = ParseEncoding(args[1]); - ssize_t len = DecodeBytes(args[0], enc); - - if (len < 0) { - Local exception = Exception::TypeError(String::New("Bad argument")); - return ThrowException(exception); + Local buffer = args[0]->ToObject(); + if(!node::Buffer::HasInstance(buffer)) { + isolate->ThrowException( + Exception::TypeError(String::NewFromUtf8(isolate, "Invalid buffer objects.")) + ); + return; } + + const char *buff = node::Buffer::Data(buffer); + vh->Write((const unsigned char *)buff, node::Buffer::Length(buffer)); + + args.GetReturnValue().Set(args.This()); +} - char* buf = new char[len]; - ssize_t written = DecodeWrite(buf, len, args[0], enc); - assert(written == len); - - int r = hash->HashUpdate(buf, len); - - return args.This(); - } - - static Handle - HashDigest(const Arguments& args) { - Hash *hash = ObjectWrap::Unwrap(args.This()); - - HandleScope scope; - - unsigned char* md_value; - unsigned int md_len; - char* md_hexdigest; - int md_hex_len; - Local outString ; - - int r = hash->HashDigest(&md_value, &md_len); - - if (md_len == 0 || r == 0) { - return scope.Close(String::New("")); +void verusDigest(const v8::FunctionCallbackInfo& args) { + Isolate* isolate = Isolate::GetCurrent(); + HandleScope scope(isolate); + if (initialized == false){ + isolate->ThrowException( + Exception::TypeError(String::NewFromUtf8(isolate, "call init() first!")) + ); } + char *result = new char[32]; + vh->Finalize((unsigned char *)result); + args.GetReturnValue().Set(Nan::NewBuffer(result, 32).ToLocalChecked()); +} - if (args.Length() == 0 || !args[0]->IsString()) { - // Binary - outString = Encode(md_value, md_len, BINARY); - } else { - String::Utf8Value encoding(args[0]->ToString()); - if (strcasecmp(*encoding, "hex") == 0) { - // Hex encoding - hex_encode(md_value, md_len, &md_hexdigest, &md_hex_len); - outString = Encode(md_hexdigest, md_hex_len, BINARY); - free(md_hexdigest); - } else if (strcasecmp(*encoding, "binary") == 0) { - outString = Encode(md_value, md_len, BINARY); - } else { - fprintf(stderr, "verushash-node : Hash .digest encoding " - "can be binary or hex\n"); - } +void verusReset(const v8::FunctionCallbackInfo& args) { + Isolate* isolate = Isolate::GetCurrent(); + HandleScope scope(isolate); + if (initialized == false){ + isolate->ThrowException( + Exception::TypeError(String::NewFromUtf8(isolate, "call init() first!")) + ); } - free(md_value); - return scope.Close(outString); + vh->Reset(); + args.GetReturnValue().Set(args.This()); +} - } +void verusHash(const v8::FunctionCallbackInfo& args) { + Isolate* isolate = Isolate::GetCurrent(); + HandleScope scope(isolate); + if (args.Length() < 1) { + isolate->ThrowException( + Exception::TypeError(String::NewFromUtf8(isolate, "Wrong number of arguments")) + ); + return; + } + Local buffer = args[0]->ToObject(); + if(!node::Buffer::HasInstance(buffer)) { + isolate->ThrowException( + Exception::TypeError(String::NewFromUtf8(isolate, "Invalid buffer objects.")) + ); + return; + } - Hash () : ObjectWrap (), vh() - { - initialised = false; - } + const char *buff = node::Buffer::Data(buffer); - ~Hash () - { - } + char *result = new char[32]; + + if (initialized == false) { + CVerusHash::init(); + initialized = true; + } + verus_hash(result, buff, node::Buffer::Length(buffer)); + + args.GetReturnValue().Set(Nan::NewBuffer(result, 32).ToLocalChecked()); +} - private: - CVerusHash vh; - bool initialised; -}; -extern "C" void -init (Handle target) -{ - HandleScope scope; - Hash::Initialize(target); +void Init(Handle exports) { + NODE_SET_METHOD(exports, "init", verusInit); + NODE_SET_METHOD(exports, "update", verusUpdate); + NODE_SET_METHOD(exports, "digest", verusDigest); + NODE_SET_METHOD(exports, "reset", verusReset); + NODE_SET_METHOD(exports, "hash", verusHash); } + +NODE_MODULE(verushash, Init)