Skip to content
Permalink
Browse files

is_canonical from EOSIO/eos ECC_IMPL secp256k1 (elliptic_secp256k1.cpp)

  • Loading branch information...
James Calfee
James Calfee committed Jun 4, 2018
1 parent 94aa854 commit 09c823ac4c4fb4f7257d8ed2df45a34215a8c537
Showing with 40 additions and 16 deletions.
  1. +40 −16 src/signature.js
@@ -202,29 +202,53 @@ Signature.signHash = function(dataSha256, privateKey, encoding = 'hex') {
privateKey = PrivateKey(privateKey)
assert(privateKey, 'privateKey required')

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

let nonce = 0;
const buf = new Buffer(65);
const 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;
const ecsignature = ecdsa.sign(curve, dataSha256, privateKey.d, nonce);

// elliptic_openssl.cpp compact_signature private_key::sign_compact
// const der = ecsignature.toDER();
// const lenR = der[3];
// const lenS = der[5 + lenR];
// const canonical = lenR === 32 && lenS === 32

// 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");
}
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) {
var i, r, s;
assert(Buffer.isBuffer(buf), 'Buffer is required')

0 comments on commit 09c823a

Please sign in to comment.
You can’t perform that action at this time.