Skip to content

Commit

Permalink
is_canonical from EOSIO/eos ECC_IMPL secp256k1 (elliptic_secp256k1.cpp)
Browse files Browse the repository at this point in the history
  • Loading branch information
James Calfee committed Jun 4, 2018
1 parent 94aa854 commit 09c823a
Showing 1 changed file with 40 additions and 16 deletions.
56 changes: 40 additions & 16 deletions src/signature.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -202,29 +202,53 @@ Signature.signHash = function(dataSha256, privateKey, encoding = 'hex') {
privateKey = PrivateKey(privateKey) privateKey = PrivateKey(privateKey)
assert(privateKey, 'privateKey required') assert(privateKey, 'privateKey required')


var der, e, ecsignature, i, lenR, lenS, nonce; // EOSIO/eos ECC_IMPL secp256k1 (elliptic_secp256k1.cpp)
i = null; // compact_signature private_key::sign_compact
nonce = 0;
e = BigInteger.fromBuffer(dataSha256); let nonce = 0;
const buf = new Buffer(65);
const e = BigInteger.fromBuffer(dataSha256);

while (true) { while (true) {
ecsignature = ecdsa.sign(curve, dataSha256, privateKey.d, nonce); const ecsignature = ecdsa.sign(curve, dataSha256, privateKey.d, nonce);
der = ecsignature.toDER();
lenR = der[3]; // elliptic_openssl.cpp compact_signature private_key::sign_compact
lenS = der[5 + lenR]; // const der = ecsignature.toDER();
if (lenR === 32 && lenS === 32) { // const lenR = der[3];
i = ecdsa.calcPubKeyRecoveryParam(curve, e, ecsignature, privateKey.toPublic().Q); // const lenS = der[5 + lenR];
i += 4; // compressed // const canonical = lenR === 32 && lenS === 32
i += 27; // compact // 24 or 27 :( forcing odd-y 2nd key candidate)
break; // buf.writeUInt8(i, 0);
ecsignature.r.toBuffer(32).copy(buf, 1);
ecsignature.s.toBuffer(32).copy(buf, 32);

if(!isCanonical(buf)) {
nonce++;
continue
} }
if (nonce % 10 === 0) {
if (nonce > 5) {
console.log("WARN: " + nonce + " attempts to find canonical signature"); console.log("WARN: " + nonce + " attempts to find canonical signature");
} }
nonce++;
let i = ecdsa.calcPubKeyRecoveryParam(curve, e, ecsignature, privateKey.toPublic().Q);
i += 4; // compressed
i += 27; // compact
return Signature(ecsignature.r, ecsignature.s, i);
} }
return Signature(ecsignature.r, ecsignature.s, i);
}; };


function isCanonical(c) {
// https://steemit.com/steem/@dantheman/steem-and-bitshares-cryptographic-security-update
//
// EOSIO/eos public_key::is_canonical
//
return !(c[1] & 0x80)
&& !(c[1] == 0 && !(c[2] & 0x80))
&& !(c[33] & 0x80)
&& !(c[33] == 0 && !(c[34] & 0x80));
}

Signature.fromBuffer = function(buf) { Signature.fromBuffer = function(buf) {
var i, r, s; var i, r, s;
assert(Buffer.isBuffer(buf), 'Buffer is required') assert(Buffer.isBuffer(buf), 'Buffer is required')
Expand Down

0 comments on commit 09c823a

Please sign in to comment.