forked from EasyX-Community/node8-multi-hashing
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathkaspa.cc
More file actions
142 lines (107 loc) · 3.73 KB
/
kaspa.cc
File metadata and controls
142 lines (107 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "kaspa.h"
#include "blake2b/blake2b.h"
// Kaspaのコンセンサスパラメータ
#define KASPA_BLOCK_HEADER_SIZE 184
#define KASPA_TARGET_BITS 255
#define KASPA_DIFFICULTY_WINDOW 960
// PoWハッシュ計算用の定数
#define KASPA_POW_MAX_NONCE 0xFFFFFFFF
#define KASPA_POW_TARGET_SPACING 1
#define KASPA_POW_NO_RETARGETING false
void kaspa_hash(const char* input, char* output, uint32_t len) {
// Blake2bの初期化
blake2b_state S;
blake2b_init(&S, 32);
// 入力データのハッシュ化
blake2b_update(&S, input, len);
uint8_t hash[32];
blake2b_final(&S, hash, 32);
memcpy(output, hash, 32);
}
void kaspa_pow(const char* input, char* output, uint32_t len) {
if (len != KASPA_BLOCK_HEADER_SIZE) {
memset(output, 0, 32);
return;
}
// ブロックヘッダーから必要なフィールドを抽出
uint32_t version;
uint8_t previous_hash[32];
uint8_t merkle_root[32];
uint64_t timestamp;
uint32_t bits;
uint32_t nonce;
memcpy(&version, input, 4);
memcpy(previous_hash, input + 4, 32);
memcpy(merkle_root, input + 36, 32);
memcpy(×tamp, input + 68, 8);
memcpy(&bits, input + 76, 4);
memcpy(&nonce, input + 80, 4);
// ハッシュ計算用のバッファ
uint8_t hash_buffer[KASPA_BLOCK_HEADER_SIZE];
memcpy(hash_buffer, input, KASPA_BLOCK_HEADER_SIZE);
// Blake2bの初期化
blake2b_state S;
blake2b_init(&S, 32);
// PoWハッシュの計算
blake2b_update(&S, hash_buffer, KASPA_BLOCK_HEADER_SIZE);
uint8_t hash[32];
blake2b_final(&S, hash, 32);
memcpy(output, hash, 32);
}
#include <node.h>
#include <node_buffer.h>
#include <v8.h>
void init(v8::Handle<v8::Object> exports) {
NODE_SET_METHOD(exports, "kaspa", method_kaspa);
NODE_SET_METHOD(exports, "kaspa_pow", method_kaspa_pow);
}
void method_kaspa(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
if (args.Length() < 1) {
isolate->ThrowException(v8::Exception::TypeError(
v8::String::NewFromUtf8(isolate, "Wrong number of arguments")));
return;
}
v8::Local<v8::Object> buffer = args[0]->ToObject(isolate);
if (!node::Buffer::HasInstance(buffer)) {
isolate->ThrowException(v8::Exception::TypeError(
v8::String::NewFromUtf8(isolate, "Argument should be a buffer object.")));
return;
}
char* input = node::Buffer::Data(buffer);
size_t input_len = node::Buffer::Length(buffer);
char output[32];
kaspa_hash(input, output, input_len);
v8::Local<v8::Value> returnValue = node::Buffer::Copy(
isolate,
output,
32).ToLocalChecked();
args.GetReturnValue().Set(returnValue);
}
void method_kaspa_pow(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
if (args.Length() < 1) {
isolate->ThrowException(v8::Exception::TypeError(
v8::String::NewFromUtf8(isolate, "Wrong number of arguments")));
return;
}
v8::Local<v8::Object> buffer = args[0]->ToObject(isolate);
if (!node::Buffer::HasInstance(buffer)) {
isolate->ThrowException(v8::Exception::TypeError(
v8::String::NewFromUtf8(isolate, "Argument should be a buffer object.")));
return;
}
char* input = node::Buffer::Data(buffer);
size_t input_len = node::Buffer::Length(buffer);
char output[32];
kaspa_pow(input, output, input_len);
v8::Local<v8::Value> returnValue = node::Buffer::Copy(
isolate,
output,
32).ToLocalChecked();
args.GetReturnValue().Set(returnValue);
}
NODE_MODULE(kaspa, init)