diff -uNr a/bitcoin/src/init.cpp b/bitcoin/src/init.cpp --- a/bitcoin/src/init.cpp 29fbb8792c3462ced61b4a0284360122f72c4fef7fb5fb84e5399967ab6474cd83ccf3a60eb3c425e183b1b95fb9ca71fc23bb791316d762034559df293f8bb0 +++ b/bitcoin/src/init.cpp 971b82be435c99a1af9d5cacc9c05af7616f4af7ee1466efacd46d41eddc1c4d7da2fdb4a302aab7c99933d33ad2d613f3bfbe76fec67a71c6d4d1fe14ac142d @@ -177,6 +177,8 @@ " -verifyall \t\t " + _("Forbid the skipping of ECDSA signature verification between checkpoints.\n") + " -setverstring \t\t " + _("Set a custom version string.\n") + " -setvernum \t\t " + _("Set a custom version number.\n") + + " -highs \t\t " + _("Set all transactions to have DER 'S' Value set to 'high'.\n") + + " -lows \t\t " + _("Set all transactions to have DER 'S' Value set to 'low'.\n") + " -logtimestamps \t " + _("Prepend debug output with timestamp\n") + " -printtoconsole \t " + _("Send trace/debug info to console instead of debug.log file\n") + " -rpcuser= \t " + _("Username for JSON-RPC connections\n") + @@ -200,6 +202,14 @@ fDaemon = GetBoolArg("-daemon"); fCanEat = GetBoolArg("-caneat"); fVerifyAll = GetBoolArg("-verifyall"); + fHighS = GetBoolArg("-highs"); + fLowS = GetBoolArg("-lows"); + + if (fHighS && fLowS) + { + printf("Error: '-highs' and '-lows' can not be set at the same time.\n"); + return false; + } if (mapArgs.count("-setverstring")) { diff -uNr a/bitcoin/src/key.h b/bitcoin/src/key.h --- a/bitcoin/src/key.h 6b2389129dec411d013d754eaebc169a23f60b2169dc41cced21248a603ced46dfdc64e016c082a154af87784049333be75c91fb08265306a3bdc2bc0af2e6c5 +++ b/bitcoin/src/key.h afe71ade56fae65b970ff3dfb3f14edacee0af497ae57e2d2502c9a4b4f49f3336f9d3794b72a87d185b92fc01f1a5077e1ccd63a61ac4fa9c4464c6224fd1e4 @@ -291,12 +291,46 @@ bool Sign(uint256 hash, std::vector& vchSig) { vchSig.clear(); - unsigned char pchSig[10000]; - unsigned int nSize = 0; - if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey)) + ECDSA_SIG *sig = ECDSA_do_sign((unsigned char *) &hash, sizeof(hash), pkey); + + if (sig == NULL) + { + printf("ERROR, ECDSA_sign failed in key.h:Sign()\n"); return false; - vchSig.resize(nSize); - memcpy(&vchSig[0], pchSig, nSize); + } + + BN_CTX *ctx = BN_CTX_new(); + BN_CTX_start(ctx); + const EC_GROUP *group = EC_KEY_get0_group(pkey); + BIGNUM *order = BN_CTX_get(ctx); + BIGNUM *halforder = BN_CTX_get(ctx); + EC_GROUP_get_order(group, order, ctx); + BN_rshift1(halforder, order); + + if (fHighS && (BN_cmp(sig->s, halforder) < 0)) + { + // enforce high S values + BN_sub(sig->s, order, sig->s); + } + + if (fLowS && (BN_cmp(sig->s, halforder) > 0)) + { + // enforce low S values + BN_sub(sig->s, order, sig->s); + } + + BN_CTX_end(ctx); + BN_CTX_free(ctx); + unsigned int nSize = ECDSA_size(pkey); + vchSig.resize(nSize); // Make sure it is big enough + unsigned char *pos = &vchSig[0]; + nSize = i2d_ECDSA_SIG(sig, &pos); + //printf("DEBUG DER R: 0x%s\n", BN_bn2hex(sig->r)); + //printf("DEBUG DER R: %s\n", BN_bn2dec(sig->r)); + //printf("DEBUG DER S: 0x%s\n", BN_bn2hex(sig->s)); + //printf("DEBUG DER S: %s\n", BN_bn2dec(sig->s)); + ECDSA_SIG_free(sig); + vchSig.resize(nSize); // Shrink to fit actual size return true; } diff -uNr a/bitcoin/src/util.cpp b/bitcoin/src/util.cpp --- a/bitcoin/src/util.cpp 72641fcb9bce1f705246cf52f08b3ece4b8df65e07ca10a32db860d4a120532a911fc62549960ccfdfc020fd1a5ef8baf0fcf181b861e0903c65b044899fc008 +++ b/bitcoin/src/util.cpp 66a8ac388136aceac7d24bd73c18b06445c2580849dd6c548d6684b5f1e9c19eafd3f71427476fd982383dcfd0425f34ce524eac1d8320fd990a28a1e4933288 @@ -32,6 +32,8 @@ string strMiscWarning; bool fNoListen = false; bool fLogTimestamps = false; +bool fLowS = false; +bool fHighS = false; std::string CLIENT_NAME(DEFAULT_CLIENT_NAME); diff -uNr a/bitcoin/src/util.h b/bitcoin/src/util.h --- a/bitcoin/src/util.h d7e407108638c11f75b5bed04dc455ac78a96debc0776cd0e71871001c5886fd1472ae060e7a2334fcf3e323b7ad0a1b4fb68757392cc45a1b09721eb67415d1 +++ b/bitcoin/src/util.h f0c21c349b56516feac63c9cf8018c82b26583ad290a4b3610965e5a5a703d116671b1ef270395b8289c170b603630b5b7e493725e420e187ba1fbd326061ff5 @@ -122,6 +122,8 @@ extern bool fNoListen; extern bool fLogTimestamps; extern std::string CLIENT_NAME; +extern bool fLowS; +extern bool fHighS; void RandAddSeed(); void RandAddSeedPerfmon();