Fix for latest nan and secp256k1-node

Fixes #10
This commit is contained in:
Kagami Hiiragi 2015-11-08 16:28:45 +03:00
parent e57608d1ad
commit 55d7c343dd
3 changed files with 42 additions and 23 deletions

32
ecdh.cc
View File

@ -67,39 +67,37 @@ error:
#undef CHECK #undef CHECK
NAN_METHOD(Derive) { NAN_METHOD(Derive) {
NanScope(); if (info.Length() != 2 ||
!node::Buffer::HasInstance(info[0]) || // privkey_a
if (args.Length() != 2 || !node::Buffer::HasInstance(info[1])) { // pubkey_b
!node::Buffer::HasInstance(args[0]) || // privkey_a return Nan::ThrowError("Bad input");
!node::Buffer::HasInstance(args[1])) { // pubkey_b
return NanThrowError("Bad input");
} }
char* privkey_a = node::Buffer::Data(args[0]); char* privkey_a = node::Buffer::Data(info[0]);
size_t privkey_a_len = node::Buffer::Length(args[0]); size_t privkey_a_len = node::Buffer::Length(info[0]);
char* pubkey_b = node::Buffer::Data(args[1]); char* pubkey_b = node::Buffer::Data(info[1]);
size_t pubkey_b_len = node::Buffer::Length(args[1]); size_t pubkey_b_len = node::Buffer::Length(info[1]);
if (privkey_a == NULL || if (privkey_a == NULL ||
privkey_a_len != PRIVKEY_SIZE || privkey_a_len != PRIVKEY_SIZE ||
pubkey_b == NULL || pubkey_b == NULL ||
pubkey_b_len != PUBKEY_SIZE || pubkey_b_len != PUBKEY_SIZE ||
pubkey_b[0] != 4) { pubkey_b[0] != 4) {
return NanThrowError("Bad input"); return Nan::ThrowError("Bad input");
} }
uint8_t* shared = (uint8_t *)malloc(PRIVKEY_SIZE); uint8_t* shared = (uint8_t *)malloc(PRIVKEY_SIZE);
if (shared == NULL || if (shared == NULL ||
derive((uint8_t *)privkey_a, (uint8_t *)pubkey_b, shared)) { derive((uint8_t *)privkey_a, (uint8_t *)pubkey_b, shared)) {
free(shared); free(shared);
return NanThrowError("Internal error"); return Nan::ThrowError("Internal error");
} }
NanReturnValue(NanBufferUse((char *)shared, PRIVKEY_SIZE)); info.GetReturnValue().Set(
Nan::NewBuffer((char *)shared, PRIVKEY_SIZE).ToLocalChecked());
} }
void InitAll(Handle<Object> exports) { NAN_MODULE_INIT(InitAll) {
exports->Set( Nan::Set(target, Nan::New<String>("derive").ToLocalChecked(),
NanNew<String>("derive"), Nan::GetFunction(Nan::New<FunctionTemplate>(Derive)).ToLocalChecked());
NanNew<FunctionTemplate>(Derive)->GetFunction());
} }
NODE_MODULE(ecdh, InitAll) NODE_MODULE(ecdh, InitAll)

View File

@ -61,13 +61,30 @@ function equalConstTime(b1, b2) {
return res === 0; return res === 0;
} }
function pad32(msg){
var buf;
if (msg.length < 32) {
buf = new Buffer(32);
buf.fill(0);
msg.copy(buf, 32 - msg.length);
return buf;
} else {
return msg;
}
}
/** /**
* Compute the public key for a given private key. * Compute the public key for a given private key.
* @param {Buffer} privateKey - A 32-byte private key * @param {Buffer} privateKey - A 32-byte private key
* @return {Buffer} A 65-byte public key. * @return {Buffer} A 65-byte public key.
* @function * @function
*/ */
var getPublic = exports.getPublic = secp256k1.createPublicKey; var getPublic = exports.getPublic = function(privateKey) {
assert(privateKey.length === 32, "Bad private key");
// See https://github.com/wanderer/secp256k1-node/issues/46
var compressed = secp256k1.publicKeyCreate(privateKey);
return secp256k1.publicKeyConvert(compressed, false);
};
/** /**
* Create an ECDSA signature. * Create an ECDSA signature.
@ -80,7 +97,9 @@ exports.sign = function(privateKey, msg) {
return new promise(function(resolve) { return new promise(function(resolve) {
assert(msg.length > 0, "Message should not be empty"); assert(msg.length > 0, "Message should not be empty");
assert(msg.length <= 32, "Message is too long"); assert(msg.length <= 32, "Message is too long");
resolve(secp256k1.sign(privateKey, msg)); msg = pad32(msg);
var sig = secp256k1.signSync(msg, privateKey).signature;
resolve(secp256k1.signatureExport(sig));
}); });
}; };
@ -96,7 +115,9 @@ exports.verify = function(publicKey, msg, sig) {
return new promise(function(resolve, reject) { return new promise(function(resolve, reject) {
assert(msg.length > 0, "Message should not be empty"); assert(msg.length > 0, "Message should not be empty");
assert(msg.length <= 32, "Message is too long"); assert(msg.length <= 32, "Message is too long");
if (secp256k1.verify(publicKey, msg, sig) === 1) { msg = pad32(msg);
sig = secp256k1.signatureImport(sig);
if (secp256k1.verifySync(msg, sig, publicKey)) {
resolve(null); resolve(null);
} else { } else {
reject(new Error("Bad signature")); reject(new Error("Bad signature"));

View File

@ -49,11 +49,11 @@
"mocha": "*" "mocha": "*"
}, },
"dependencies": { "dependencies": {
"elliptic": "^5.0.0", "elliptic": "^6.0.2",
"es6-promise": "^3.0.2", "es6-promise": "^3.0.2",
"nan": "^2.0.9" "nan": "^2.1.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"secp256k1": "^1.1.4" "secp256k1": "^2.0.2"
} }
} }