miketout
6 years ago
7 changed files with 173 additions and 209 deletions
@ -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": "*" |
|||
} |
|||
} |
|||
|
@ -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'); |
|||
} |
|||
} |
|||
|
@ -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…
Reference in new issue