parent
e57608d1ad
commit
55d7c343dd
32
ecdh.cc
32
ecdh.cc
|
@ -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)
|
||||||
|
|
27
index.js
27
index.js
|
@ -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"));
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user