Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:everitoken/evtjs into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
ceeji committed Aug 16, 2018
2 parents ec86d72 + 35bb201 commit 06e7796
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 158 deletions.
113 changes: 67 additions & 46 deletions lib/apiCaller.js
Original file line number Diff line number Diff line change
Expand Up @@ -2142,26 +2142,30 @@ var defaultSignProvider = function defaultSignProvider(apiCaller, config) {

case 6:
if (!(keys.length === 1 && keys[0].private)) {
_context25.next = 10;
_context25.next = 12;
break;
}

pvt = keys[0].private;
ret = signHash(buf, pvt);
return _context25.abrupt("return", ret);
_context25.next = 10;
return signHash(buf, pvt);

case 10:
ret = _context25.sent;
return _context25.abrupt("return", ret);

case 12:

// Multiple signature support
Logger.verbose("[defaultSignProvider] get required_keys, available keys: " + (0, _stringify2.default)(keys.map(function (key) {
return key.public;
}), null, 4));
_context25.next = 13;
_context25.next = 15;
return apiCaller.__chainGetRequiredKeys({ transaction: transaction, available_keys: keys.map(function (key) {
return key.public;
}) });

case 13:
case 15:
apiRes = _context25.sent;
required_keys = apiRes.required_keys;

Expand All @@ -2185,7 +2189,7 @@ var defaultSignProvider = function defaultSignProvider(apiCaller, config) {
_iteratorNormalCompletion5 = true;
_didIteratorError5 = false;
_iteratorError5 = undefined;
_context25.prev = 21;
_context25.prev = 23;


for (_iterator5 = (0, _getIterator3.default)(required_keys); !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
Expand All @@ -2194,102 +2198,119 @@ var defaultSignProvider = function defaultSignProvider(apiCaller, config) {
_loop(requiredKey);
}

_context25.next = 29;
_context25.next = 31;
break;

case 25:
_context25.prev = 25;
_context25.t0 = _context25["catch"](21);
case 27:
_context25.prev = 27;
_context25.t0 = _context25["catch"](23);
_didIteratorError5 = true;
_iteratorError5 = _context25.t0;

case 29:
_context25.prev = 29;
_context25.prev = 30;
case 31:
_context25.prev = 31;
_context25.prev = 32;

if (!_iteratorNormalCompletion5 && _iterator5.return) {
_iterator5.return();
}

case 32:
_context25.prev = 32;
case 34:
_context25.prev = 34;

if (!_didIteratorError5) {
_context25.next = 35;
_context25.next = 37;
break;
}

throw _iteratorError5;

case 35:
return _context25.finish(32);
case 37:
return _context25.finish(34);

case 36:
return _context25.finish(29);
case 38:
return _context25.finish(31);

case 37:
case 39:
if (!(missingKeys.length !== 0)) {
_context25.next = 39;
_context25.next = 41;
break;
}

throw new Error("missingKeys for required_key");

case 39:
case 41:
sigs = [];
_iteratorNormalCompletion6 = true;
_didIteratorError6 = false;
_iteratorError6 = undefined;
_context25.prev = 43;
_context25.prev = 45;
_iterator6 = (0, _getIterator3.default)(pvts);

for (_iterator6 = (0, _getIterator3.default)(pvts); !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
_pvt = _step6.value;

sigs.push(signHash(buf, _pvt));
case 47:
if (_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done) {
_context25.next = 57;
break;
}

_context25.next = 51;
_pvt = _step6.value;
_context25.t1 = sigs;
_context25.next = 52;
return signHash(buf, _pvt);

case 52:
_context25.t2 = _context25.sent;

_context25.t1.push.call(_context25.t1, _context25.t2);

case 54:
_iteratorNormalCompletion6 = true;
_context25.next = 47;
break;

case 47:
_context25.prev = 47;
_context25.t1 = _context25["catch"](43);
case 57:
_context25.next = 63;
break;

case 59:
_context25.prev = 59;
_context25.t3 = _context25["catch"](45);
_didIteratorError6 = true;
_iteratorError6 = _context25.t1;
_iteratorError6 = _context25.t3;

case 51:
_context25.prev = 51;
_context25.prev = 52;
case 63:
_context25.prev = 63;
_context25.prev = 64;

if (!_iteratorNormalCompletion6 && _iterator6.return) {
_iterator6.return();
}

case 54:
_context25.prev = 54;
case 66:
_context25.prev = 66;

if (!_didIteratorError6) {
_context25.next = 57;
_context25.next = 69;
break;
}

throw _iteratorError6;

case 57:
return _context25.finish(54);
case 69:
return _context25.finish(66);

case 58:
return _context25.finish(51);
case 70:
return _context25.finish(63);

case 59:
case 71:
return _context25.abrupt("return", sigs);

case 60:
case 72:
case "end":
return _context25.stop();
}
}
}, _callee25, this, [[21, 25, 29, 37], [30,, 32, 36], [43, 47, 51, 59], [52,, 54, 58]]);
}, _callee25, this, [[23, 27, 31, 39], [32,, 34, 38], [45, 59, 63, 71], [64,, 66, 70]]);
}));

return function (_x31) {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"dependencies": {
"babel-preset-env": "^1.7.0",
"bigi": "^1.4.2",
"bitcoin-ts": "^1.2.0",
"bs58": "^4.0.1",
"create-hash": "^1.1.3",
"create-hmac": "^1.1.7",
Expand Down
4 changes: 2 additions & 2 deletions src/apiCaller.js
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,7 @@ const defaultSignProvider = (apiCaller, config) => async function ({ sign, buf,
// simplify default signing #17
if (keys.length === 1 && keys[0].private) {
const pvt = keys[0].private;
var ret = signHash(buf, pvt);
var ret = await signHash(buf, pvt);

return ret;
}
Expand Down Expand Up @@ -932,7 +932,7 @@ const defaultSignProvider = (apiCaller, config) => async function ({ sign, buf,

const sigs = [];
for (const pvt of pvts) {
sigs.push(signHash(buf, pvt));
sigs.push(await signHash(buf, pvt));
}

return sigs;
Expand Down
6 changes: 3 additions & 3 deletions src/ecc/api_common.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ ecc.randomKey().then(privateKey => {
@arg {wif|PrivateKey} privateKey
@arg {String} [encoding = 'hex'] - dataSha256 encoding (if string)
@return {string} string signature
@return {Promise<string>} string signature
*/
signHash: (dataSha256, privateKey, encoding = "hex") => {
return Signature.signHash(dataSha256, privateKey, encoding).toString();
signHash: async (dataSha256, privateKey, encoding = "hex") => {
return (await Signature.signHash(dataSha256, privateKey, encoding)).toString();
},

/**
Expand Down
86 changes: 24 additions & 62 deletions src/ecc/signature.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const keyUtils = require("./key_utils");
const PublicKey = require("./key_public");
var ECSignature = require("./ecsignature");
const PrivateKey = require("./key_private");
const bitcoinTs = require ("bitcoin-ts");

let secp256k1 = null;
try {
Expand Down Expand Up @@ -196,6 +197,15 @@ Signature.sign = function(data, privateKey, encoding = "utf8") {
return Signature.signHash(data, privateKey);
};

function toArrayBuffer(myBuf) {
var myBuffer = new ArrayBuffer(myBuf.length);
var res = new Uint8Array(myBuffer);
for (var i = 0; i < myBuf.length; ++i) {
res[i] = myBuf[i];
}
return res;
}

/**
Sign a buffer of exactally 32 bytes in size (sha256(text))
Expand All @@ -205,7 +215,7 @@ Signature.sign = function(data, privateKey, encoding = "utf8") {
@return {Signature}
*/
Signature.signHash = function(dataSha256, privateKey, encoding = "hex") {
Signature.signHash = async function(dataSha256, privateKey, encoding = "hex") {
let time = new Date().valueOf();

if(typeof dataSha256 === "string") {
Expand All @@ -217,71 +227,23 @@ Signature.signHash = function(dataSha256, privateKey, encoding = "hex") {
privateKey = PrivateKey(privateKey);
assert(privateKey, "privateKey required");

// sign the message
if (secp256k1 != null) {
// console.log("[signHash] accelerating supported");

let nonce = 0, canonical = false, sigObj, sigDER;

while (!canonical) {
sigObj = secp256k1.sign(dataSha256, privateKey.toBuffer(), {
noncefn: (message, rivateKey, algo, data, attempt) => {
// console.log("[nonce] attempt:" + nonce);

let ret = new Buffer(32);
ret[31] = nonce++;
return ret;
}
});

sigDER = secp256k1.signatureExport(sigObj.signature);

let lenR = sigDER[3];
let lenS = sigDER[5 + lenR];

canonical = lenR === 32 && lenS === 32;
}
let ecsig = ECSignature.fromDER(sigDER);

time = (new Date().valueOf()) - time;

console.log("[+" + time + "ms] signHash (c binding)");

return Signature(ecsig.r, ecsig.s, sigObj.recovery + 4 + 27);
}
else {
// console.log("[signHash] no accelerating supported");


// use wasm to sign the message (faster)
const secp256k1 = await bitcoinTs.instantiateSecp256k1();
let sig = secp256k1.signMessageHashDER(toArrayBuffer(privateKey.toBuffer()), toArrayBuffer(dataSha256));
let ecsig = ECSignature.fromDER(new Buffer(sig));

var der, e, ecsignature, i, lenR, lenS, nonce;
i = null;
nonce = 0;
e = BigInteger.fromBuffer(dataSha256);

while (true) {
ecsignature = ecdsa.sign(curve, dataSha256, privateKey.d, nonce++);
der = ecsignature.toDER();
lenR = der[3];
lenS = der[5 + lenR];
if (lenR === 32 && lenS === 32) {
i = ecdsa.calcPubKeyRecoveryParam(curve, e, ecsignature, privateKey.toPublic().Q);
i += 4; // compressed
i += 27; // compact // 24 or 27 :( forcing odd-y 2nd key candidate)
break;
}
if (nonce % 10 === 0) {
console.log("WARN: " + nonce + " attempts to find canonical signature");
}
}
// calculate recoveryParam
let e = BigInteger.fromBuffer(dataSha256);
let i = ecdsa.calcPubKeyRecoveryParam(curve, e, ecsig, privateKey.toPublic().Q) + 4 + 27;

time = (new Date().valueOf()) - time;
console.log("__sig:" + JSON.stringify(sig));

console.log("[+" + time + "ms] signHash");
return Signature.fromBuffer(Buffer.concat( [ new Buffer([ i ]) , new Buffer(secp256k1.signatureDERToCompact(sig)) ] ));

return Signature(ecsignature.r, ecsignature.s, i);
}

// der = ecsignature.toDER();
//lenR = der[3];
//lenS = der[5 + lenR];
//if (lenR === 32 && lenS === 32) {
};

Signature.fromBuffer = function(buf) {
Expand Down
Loading

0 comments on commit 06e7796

Please sign in to comment.