Browse Source

used hellcatz interface and tests and enabled optimized hash

master
miketout 6 years ago
parent
commit
a7ef60945a
  1. 19
      binding.gyp
  2. 2
      crypto/haraka.c
  3. 4
      crypto/verus_hash.cpp
  4. 4
      crypto/verus_hash.h
  5. 24
      package.json
  6. 53
      test.js
  7. 276
      verushash.cc

19
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": [

2
crypto/haraka.c

@ -25,7 +25,7 @@ Optimized Implementations for Haraka256 and Haraka512
*/
#include <stdio.h>
#include "crypto/haraka.h"
#include "haraka.h"
u128 rc[40];
u128 rc0[40] = {0};

4
crypto/verus_hash.cpp

@ -9,8 +9,8 @@ inputs only, Verus Hash takes any length of input and produces a 256
bit output.
*/
#include <string.h>
#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);

4
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

24
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": "*"
}
}

53
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');
}
}

276
verushash.cc

@ -1,201 +1,115 @@
#include <nan.h>
#include <node.h>
#include <node_events.h>
#include <assert.h>
#include <string.h>
#include <node_buffer.h>
#include <v8.h>
#include <stdint.h>
#include <vector>
#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<Value>& args) {
vh = new CVerusHash();
vh->init();
initialized = true;
args.GetReturnValue().Set(args.This());
}
class Hash : public ObjectWrap {
public:
static void
Initialize (v8::Handle<v8::Object> target)
{
HandleScope scope;
Local<FunctionTemplate> 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<Value>
New (const Arguments& args)
{
HandleScope scope;
Hash *hash = new Hash();
hash->Wrap(args.This());
return args.This();
}
static Handle<Value>
HashInit(const Arguments& args) {
Hash *hash = ObjectWrap::Unwrap<Hash>(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<Value>& 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<Value>
HashReset(const Arguments& args) {
Hash *hash = ObjectWrap::Unwrap<Hash>(args.This());
HandleScope scope;
bool r = hash->HashReset();
return args.This();
}
static Handle<Value>
HashUpdate(const Arguments& args) {
Hash *hash = ObjectWrap::Unwrap<Hash>(args.This());
HandleScope scope;
enum encoding enc = ParseEncoding(args[1]);
ssize_t len = DecodeBytes(args[0], enc);
if (len < 0) {
Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
return ThrowException(exception);
Local<Object> 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<Value>
HashDigest(const Arguments& args) {
Hash *hash = ObjectWrap::Unwrap<Hash>(args.This());
HandleScope scope;
unsigned char* md_value;
unsigned int md_len;
char* md_hexdigest;
int md_hex_len;
Local<Value> 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<Value>& 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<Value>& 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<Value>& 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<Object> 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<Object> target)
{
HandleScope scope;
Hash::Initialize(target);
void Init(Handle<Object> 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)

Loading…
Cancel
Save