{"number":146,"title":"Dealing with signature encoding malleability","authors":["Johnson Lau","Pieter Wuille"],"status":"Closed","type":"Specification","layer":"Consensus (soft fork)","created":"2016-08-16","license":"PD","requires":[],"replaces":[],"replacedBy":[],"discussion":[],"abstract":"This document specifies proposed changes to the Bitcoin transaction validity rules to fix signature malleability related to ECDSA signature encoding.","eli5":"Tightens the rules on how digital signatures may be formatted, so a third party cannot slightly alter a signature's encoding and thereby change a transaction's ID. Removing this form of malleability makes it more reliable to track and build upon unconfirmed transactions.","categories":["consensus","security","validation"],"filename":"bip-0146.mediawiki","githubUrl":"https://github.com/bitcoin/bips/blob/master/bip-0146.mediawiki","format":"mediawiki","readingMinutes":4,"inbound":2,"revisions":11,"impact":61,"core":false,"references":[],"lastModified":"2025-10-08","html":"<h2 id=\"abstract\">Abstract</h2>\n<p>This document specifies proposed changes to the Bitcoin transaction validity rules to fix signature malleability related to ECDSA signature encoding.</p>\n<h2 id=\"motivation\">Motivation</h2>\n<p>Signature malleability refers to the ability of any relay node on the network to transform the signature in transactions, with no access to the relevant private keys required. For non-segregated witness transactions, signature malleability will change the <code>txid</code> and invalidate any unconfirmed child transactions. Although the <code>txid</code> of segregated witness (<a href=\"https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki\">BIP141</a>) transactions is not third party malleable, this malleability vector will change the <code>wtxid</code> and may reduce the efficiency of compact block relay (<a href=\"https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki\">BIP152</a>).</p>\n<p>Since the enforcement of Strict DER signatures (<a href=\"https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki\">BIP66</a>), there are 2 remaining known sources of malleability in ECDSA signatures:</p>\n<ol><li>\n<strong>Inherent ECDSA signature malleability</strong>: ECDSA signatures are inherently malleable as taking the negative of the number S inside (modulo the curve order) does not invalidate it.\n</li></ol>\n<ol><li>\n<strong>Malleability of failing signature</strong>: If a signature failed to validate in <code>OP_CHECKSIG</code> or <code>OP_CHECKMULTISIG</code>, a <code>FALSE</code> would be returned to the stack and the script evaluation would continue. The failing signature may take any value, as long as it follows all the rules described in BIP66.\n</li></ol>\n<p>This document specifies new rules to fix the aforesaid signature malleability.</p>\n<h2 id=\"specification\">Specification</h2>\n<p>To fix signature encoding malleability, the following new rules are applied to pre-segregated witness and segregated witness scripts:</p>\n<h3 id=\"low-s\">LOW_S</h3>\n<p>We require that the S value inside ECDSA signatures is at most the curve order divided by 2 (essentially restricting this value to its lower half range). Every signature passed to <code>OP_CHECKSIG</code><sup class=\"footnote-ref\"><a href=\"#fn-1\" id=\"fnref-1\">[1]</a></sup>, <code>OP_CHECKSIGVERIFY</code>, <code>OP_CHECKMULTISIG</code>, or <code>OP_CHECKMULTISIGVERIFY</code>, to which ECDSA verification is applied, MUST use a S value between <code>0x1</code> and <code>0x7FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 5D576E73 57A4501D DFE92F46 681B20A0</code> (inclusive) with strict DER encoding (see <a href=\"https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki\">BIP66</a>).</p>\n<p>If a signature passing to ECDSA verification does not pass the Low S value check and is not an empty byte array, the entire script evaluates to false immediately.</p>\n<p>A high S value in signature could be trivially replaced by <code>S' = 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 - S</code>.</p>\n<h3 id=\"nullfail\">NULLFAIL</h3>\n<p>If an <code>OP_CHECKSIG</code> is trying to return a <code>FALSE</code> value to the stack, we require that the relevant signature must be an empty byte array.</p>\n<p>If an <code>OP_CHECKMULTISIG</code> is trying to return a <code>FALSE</code> value to the stack, we require that all signatures passing to this <code>OP_CHECKMULTISIG</code> must be empty byte arrays, even the processing of some signatures might have been skipped due to early termination of the signature verification.</p>\n<p>Otherwise, the entire script evaluates to false immediately.</p>\n<h2 id=\"examples\">Examples</h2>\n<p>The following examples are the combined results of the LOW_S and NULLFAIL rules.<sup class=\"footnote-ref\"><a href=\"#fn-2\" id=\"fnref-2\">[2]</a></sup></p>\n<p>Notation:</p>\n<p>CO       : curve order = 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141   HCO      : half curve order = CO / 2 = 0x7FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 5D576E73 57A4501D DFE92F46 681B20A0   P1, P2   : valid, serialized, public keys   S1L, S2L : valid low S value signatures using respective keys P1 and P2 (1 ≤ S ≤ HCO)   S1H, S2H : signatures with high S value (otherwise valid) using respective keys P1 and P2 (HCO < S < CO)   F        : any BIP66-compliant non-empty byte array but not a valid signature</p>\n<p>These scripts will return a <code>TRUE</code> to the stack as before:</p>\n<p>S1L P1 CHECKSIG   0 S1L S2L 2 P1 P2 2 CHECKMULTISIG</p>\n<p>These scripts will return a <code>FALSE</code> to the stack as before:</p>\n<p>0 P1 CHECKSIG   0 0 0 2 P1 P2 2 CHECKMULTISIG</p>\n<p>These previously <code>TRUE</code> scripts will fail immediately under the new rules:</p>\n<p>S1H P1 CHECKSIG   0 S1H S2L 2 P1 P2 2 CHECKMULTISIG   0 S1L S2H 2 P1 P2 2 CHECKMULTISIG   0 S1H S2H 2 P1 P2 2 CHECKMULTISIG</p>\n<p>These previously <code>FALSE</code> scripts will fail immediately under the new rules:</p>\n<p>F P1 CHECKSIG   0 S2L S1L 2 P1 P2 2 CHECKMULTISIG   0 S1L F   2 P1 P2 2 CHECKMULTISIG   0 F   S2L 2 P1 P2 2 CHECKMULTISIG   0 S1L 0   2 P1 P2 2 CHECKMULTISIG   0 0   S2L 2 P1 P2 2 CHECKMULTISIG   0 F   0   2 P1 P2 2 CHECKMULTISIG   0 0   F   2 P1 P2 2 CHECKMULTISIG</p>\n<h2 id=\"deployment\">Deployment</h2>\n<p>This BIP will be deployed by \"version bits\" <a href=\"https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki\">BIP9</a>. Details TBD.</p>\n<p>For Bitcoin mainnet, the BIP9 starttime will be midnight TBD UTC (Epoch timestamp TBD) and BIP9 timeout will be midnight TBD UTC (Epoch timestamp TBD).</p>\n<p>For Bitcoin testnet, the BIP9 starttime will be midnight TBD UTC (Epoch timestamp TBD) and BIP9 timeout will be midnight TBD UTC (Epoch timestamp TBD).</p>\n<h2 id=\"compatibility\">Compatibility</h2>\n<p>The reference client has produced LOW_S compatible signatures since v0.9.0, and the LOW_S rule has been enforced as relay policy by the reference client since v0.11.1. As of August 2016, very few transactions violating the requirement are being added to the chain. For all scriptPubKey types in actual use, non-compliant signatures can trivially be converted into compliant ones, so there is no loss of functionality by these requirements.</p>\n<p>Scripts with failing <code>OP_CHECKSIG</code> or <code>OP_CHECKMULTISIG</code> rarely happen on the chain. The NULLFAIL rule has been enforced as relay policy by the reference client since v0.13.1.</p>\n<p>Users MUST pay extra attention to these new rules when designing exotic scripts.</p>\n<h2 id=\"implementation\">Implementation</h2>\n<p>Implementations for the reference client is available at:</p>\n<p><a href=\"https://github.com/bitcoin/bitcoin/blob/35fe0393f216aa6020fc929272118eade5628636/src/script/interpreter.cpp#L185\">https://github.com/bitcoin/bitcoin/blob/35fe0393f216aa6020fc929272118eade5628636/src/script/interpreter.cpp#L185</a></p>\n<p>and</p>\n<p><a href=\"https://github.com/bitcoin/bitcoin/pull/8634\">https://github.com/bitcoin/bitcoin/pull/8634</a></p>\n<h2 id=\"footnotes\">Footnotes</h2>\n<ol class=\"footnotes\"><li id=\"fn-1\">Including pay-to-witness-public-key-hash (P2WPKH) described in BIP141 <a href=\"#fnref-1\" class=\"footnote-back\" aria-label=\"Back to text\">↩</a></li><li id=\"fn-2\">Please note that due to implementation details in reference client v0.13.1, some signatures with S value higher than the half curve order might pass the LOW_S test. However, such signatures are certainly invalid, and will fail later due to NULLFAIL test. <a href=\"#fnref-2\" class=\"footnote-back\" aria-label=\"Back to text\">↩</a></li></ol>\n<h2 id=\"acknowledgements\">Acknowledgements</h2>\n<p>This document is extracted from the previous <a href=\"https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki\">BIP62</a> proposal which had input from various people.</p>\n<h2 id=\"copyright\">Copyright</h2>\n<p>This document is placed in the public domain.</p>","toc":[{"id":"abstract","title":"Abstract","level":2},{"id":"motivation","title":"Motivation","level":2},{"id":"specification","title":"Specification","level":2},{"id":"low-s","title":"LOW_S","level":3},{"id":"nullfail","title":"NULLFAIL","level":3},{"id":"examples","title":"Examples","level":2},{"id":"deployment","title":"Deployment","level":2},{"id":"compatibility","title":"Compatibility","level":2},{"id":"implementation","title":"Implementation","level":2},{"id":"footnotes","title":"Footnotes","level":2},{"id":"acknowledgements","title":"Acknowledgements","level":2},{"id":"copyright","title":"Copyright","level":2}],"history":{"totalCommits":11,"firstCommit":"2016-08-16T19:43:53+00:00","lastUpdated":"2025-10-08T14:59:36-07:00","events":[{"sha":"24e96e870fffaa257b465ce1f0370c14aac588e8","date":"2025-10-08T14:59:36-07:00","author":"Murch","message":"process: Created ↦ Assigned","url":"https://github.com/bitcoin/bips/commit/24e96e870fffaa257b465ce1f0370c14aac588e8","kind":"edit"},{"sha":"5207ef92a52d0b8902895b0dbb40823a4d698ec9","date":"2025-04-11T20:08:17-07:00","author":"Murch","message":"process: Author ↦ Authors","url":"https://github.com/bitcoin/bips/commit/5207ef92a52d0b8902895b0dbb40823a4d698ec9","kind":"edit"},{"sha":"59730dec4fb641a41589aa1b91d3c452f13e0e36","date":"2025-04-11T20:05:13-07:00","author":"Murch","message":"process: Remove Comments-URI and -Summary","url":"https://github.com/bitcoin/bips/commit/59730dec4fb641a41589aa1b91d3c452f13e0e36","kind":"edit"},{"sha":"a233bde4af52c6a11269e2e6dd9707abce441ffe","date":"2025-04-11T18:19:21-07:00","author":"Murch","message":"process: Standards Track ↦ Specification","url":"https://github.com/bitcoin/bips/commit/a233bde4af52c6a11269e2e6dd9707abce441ffe","kind":"edit"},{"sha":"66defbdc03ad64ccddfd373e1c59af9a41ab990f","date":"2025-04-11T18:11:55-07:00","author":"Murch","message":"process: Deferred/Obsolete/Rejected/Replaced/Withdrawn ↦ Closed","url":"https://github.com/bitcoin/bips/commit/66defbdc03ad64ccddfd373e1c59af9a41ab990f","kind":"status"},{"sha":"fd02fa4bb7ab2238e51fc943ba2d64d33655baf9","date":"2020-06-25T05:11:46+00:00","author":"Luke Dashjr","message":"Mark BIP 146 as Withdrawn","url":"https://github.com/bitcoin/bips/commit/fd02fa4bb7ab2238e51fc943ba2d64d33655baf9","kind":"status"},{"sha":"959fecc15bdad070afa63455468b1dba54655fa6","date":"2016-11-30T09:47:31+00:00","author":"Luke Dashjr","message":"Promote BIP 2 Draft->Active, and implement it","url":"https://github.com/bitcoin/bips/commit/959fecc15bdad070afa63455468b1dba54655fa6","kind":"status"},{"sha":"72f18918a8ae655212ea2700b30f0dc4d758b843","date":"2016-11-30T09:45:33+00:00","author":"Luke Dashjr","message":"Promote BIP 123 Draft->Active, and implement it","url":"https://github.com/bitcoin/bips/commit/72f18918a8ae655212ea2700b30f0dc4d758b843","kind":"status"},{"sha":"40ba92af28fe7f60c3fd438994a018cf0f588eb3","date":"2016-09-02T15:15:48+08:00","author":"Johnson Lau","message":"BIP146: title and content changed","url":"https://github.com/bitcoin/bips/commit/40ba92af28fe7f60c3fd438994a018cf0f588eb3","kind":"edit"},{"sha":"003cf078ff126a6fbb30a4575f8c2c28848c69ff","date":"2016-08-17T19:57:01+08:00","author":"Johnson Lau","message":"BIP146: change title and add NULLDUMMY rules","url":"https://github.com/bitcoin/bips/commit/003cf078ff126a6fbb30a4575f8c2c28848c69ff","kind":"edit"},{"sha":"55ea8052120c3e06993dd75b9f38d71d36565764","date":"2016-08-16T19:43:53+00:00","author":"Luke Dashjr","message":"Assign BIP 146: Low S values signatures","url":"https://github.com/bitcoin/bips/commit/55ea8052120c3e06993dd75b9f38d71d36565764","kind":"edit"}]}}