From 1b5d1fadba50f5ce795a58b38efb30db652fa693 Mon Sep 17 00:00:00 2001
From: Daniel Cousens <dcousens@users.noreply.github.com>
Date: Wed, 26 Sep 2018 10:30:28 +1000
Subject: [PATCH 1/7] README: use https

---
 CHANGELOG.md | 2 +-
 README.md    | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 907c6d5..451a168 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,7 +19,7 @@ __added__
 
 __changed__
 - `ECPair.prototype.sign` now returns a 64-byte signature `Buffer`, not an `ECSignature` object (#1084)
-- `ECPair` (and all ECDSA code) now uses [`tiny-secp256k1`](http://github.com/bitcoinjs/tiny-secp256k1), which uses the [`libsecp256k1` library](https://github.com/bitcoin-core/secp256k1) (#1070)
+- `ECPair` (and all ECDSA code) now uses [`tiny-secp256k1`](https://github.com/bitcoinjs/tiny-secp256k1), which uses the [`libsecp256k1` library](https://github.com/bitcoin-core/secp256k1) (#1070)
 - `TransactionBuilder` internal variables are now `__` prefixed to discourage public usage (#1038)
 - `TransactionBuilder` now defaults to version 2 transaction versions (#1036)
 - `script.decompile` now returns `[Buffer]` or `null`, if decompilation failed (#1039)
diff --git a/README.md b/README.md
index e8866c9..07c5ca4 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,7 @@ Mistakes and bugs happen, but with your help in resolving and reporting [issues]
 - Easy to audit and verify,
 - Tested, with test coverage >95%,
 - Advanced and feature rich,
-- Standardized, using [standard](http://github.com/standard/standard) and Node `Buffer`'s throughout, and
+- Standardized, using [standard](https://github.com/standard/standard) and Node `Buffer`'s throughout, and
 - Friendly, with a strong and helpful community, ready to answer questions.
 
 ## Documentation
@@ -45,9 +45,9 @@ If in doubt, see the [.travis.yml](.travis.yml) for what versions are used by ou
 
 ### Browser
 The recommended method of using `bitcoinjs-lib` in your browser is through [Browserify](https://github.com/substack/node-browserify).
-If you're familiar with how to use browserify, ignore this and carry on, otherwise, it is recommended to read the tutorial at http://browserify.org/.
+If you're familiar with how to use browserify, ignore this and carry on, otherwise, it is recommended to read the tutorial at https://browserify.org/.
 
-**NOTE**: We use Node Maintenance LTS features, if you need strict ES5, use [`--transform babelify`](https://github.com/babel/babelify) in conjunction with your `browserify` step (using an [`es2015`](http://babeljs.io/docs/plugins/preset-es2015/) preset).
+**NOTE**: We use Node Maintenance LTS features, if you need strict ES5, use [`--transform babelify`](https://github.com/babel/babelify) in conjunction with your `browserify` step (using an [`es2015`](https://babeljs.io/docs/plugins/preset-es2015/) preset).
 
 **WARNING**: iOS devices have [problems](https://github.com/feross/buffer/issues/136), use atleast [buffer@5.0.5](https://github.com/feross/buffer/pull/155) or greater,  and enforce the test suites (for `Buffer`, and any other dependency) pass before use.
 

From b273deb265c2f58cdc1c7fa3af2cf2c2ff27a6a3 Mon Sep 17 00:00:00 2001
From: Daniel Cousens <dcousens@users.noreply.github.com>
Date: Wed, 26 Sep 2018 11:03:21 +1000
Subject: [PATCH 2/7] README: add crypto is hard disclaimer

---
 README.md | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/README.md b/README.md
index 07c5ca4..2541b3b 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,7 @@ Mistakes and bugs happen, but with your help in resolving and reporting [issues]
 - Standardized, using [standard](https://github.com/standard/standard) and Node `Buffer`'s throughout, and
 - Friendly, with a strong and helpful community, ready to answer questions.
 
+
 ## Documentation
 Presently,  we do not have any formal documentation other than our [examples](#examples), please [ask for help](https://github.com/bitcoinjs/bitcoinjs-lib/issues/new) if our examples aren't enough to guide you.
 
@@ -42,6 +43,27 @@ If in doubt, see the [.travis.yml](.travis.yml) for what versions are used by ou
 
 
 ## Usage
+Crypto is hard.
+
+When working with private keys, the random number generator is fundamentally one of the most important parts of any software you write.
+For random number generation, we *default* to the [`randombytes`](https://github.com/crypto-browserify/randombytes) module, which uses [`window.crypto.getRandomValues`](https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues) in the browser, or Node js' [`crypto.randomBytes`](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback), depending on your build system.
+Although this default is ~OK, there is no simple way to detect if the underlying RNG provided is good enough, or if it is **catastrophically bad**.
+You should always verify this yourself to your own standards.
+
+This library uses [tiny-secp256k1](https://github.com/bitcoinjs/tiny-secp256k1), which uses [RFC6979](https://tools.ietf.org/html/rfc6979) to help prevent `k` re-use and exploitation.
+Unfortunately, this isn't a silver bullet.
+Often, Javascript itself is working against us by bypassing these counter-measures.
+
+Problems in [`Buffer (UInt8Array)`](https://github.com/feross/buffer), for example, can trivially result in catastrophic fund loss without any warning.
+It can do this through undermining your random number generation, accidentally producing a duplicate `k` value, sending Bitcoin to a malformed output script, or any of a million different ways.
+Running tests in your target environment is important and a recommended step to verify continuously.
+
+Finally, **adhere to best practice**.   We aren't an authorative source for best practice, but, at the very least:
+
+* Don't re-use addresses.  Privacy is important, but, .... TODO
+* Don't share BIP32 extended public keys. They are a liability, and [as shown in our examples](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/crypto.js#L68), it only takes 1 mistake until **catastrophic failure**.
+* TODO, anythign else of importance here?
+
 
 ### Browser
 The recommended method of using `bitcoinjs-lib` in your browser is through [Browserify](https://github.com/substack/node-browserify).

From e514bc73643ff63863c43896ea83f8a62fb72f8f Mon Sep 17 00:00:00 2001
From: Daniel Cousens <dcousens@users.noreply.github.com>
Date: Wed, 26 Sep 2018 17:26:04 +1000
Subject: [PATCH 3/7] README: add extra suggestions for best practice

---
 README.md | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/README.md b/README.md
index 2541b3b..f2b2c8d 100644
--- a/README.md
+++ b/README.md
@@ -55,14 +55,18 @@ Unfortunately, this isn't a silver bullet.
 Often, Javascript itself is working against us by bypassing these counter-measures.
 
 Problems in [`Buffer (UInt8Array)`](https://github.com/feross/buffer), for example, can trivially result in catastrophic fund loss without any warning.
-It can do this through undermining your random number generation, accidentally producing a duplicate `k` value, sending Bitcoin to a malformed output script, or any of a million different ways.
+It can do this through undermining your random number generation, [accidentally producing a duplicate `k` value](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/crypto.js#L14), sending Bitcoin to a malformed output script, or any of a million different ways.
 Running tests in your target environment is important and a recommended step to verify continuously.
 
-Finally, **adhere to best practice**.   We aren't an authorative source for best practice, but, at the very least:
+Finally, **adhere to best practice**.
+We are not an authorative source of best practice, but, at the very least:
 
-* Don't re-use addresses.  Privacy is important, but, .... TODO
-* Don't share BIP32 extended public keys. They are a liability, and [as shown in our examples](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/crypto.js#L68), it only takes 1 mistake until **catastrophic failure**.
-* TODO, anythign else of importance here?
+* [Don't re-use addresses](https://en.bitcoin.it/wiki/Address_reuse).
+* Don't share BIP32 extended public keys ('xpubs'). [They are a liability](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/crypto.js#L68), and it only takes 1 misplaced private key (or a buggy implementation!) and you are vulnerable to **catastrophic fund loss**.
+* [Don't use `Math.random`](https://security.stackexchange.com/questions/181580/why-is-math-random-not-designed-to-be-cryptographically-secure) - in any way - don't.
+* Enforce that users always verify (manually) a freshly-decoded human-readable version of their intended transaction before broadcast.
+* Don't *ask* users to generate mnemonics, or 'brain wallets',  humans are terrible random number generators.
+* Lastly, if you can, use [Typescript](https://www.typescriptlang.org/) or similar.
 
 
 ### Browser

From 5fc673a8d6e7acd4b5767f1f0b633538d2c69429 Mon Sep 17 00:00:00 2001
From: Daniel Cousens <dcousens@users.noreply.github.com>
Date: Wed, 26 Sep 2018 17:28:15 +1000
Subject: [PATCH 4/7] README: link to external explanations

---
 README.md                  |   7 +--
 test/integration/crypto.js | 103 -------------------------------------
 2 files changed, 2 insertions(+), 108 deletions(-)
 delete mode 100644 test/integration/crypto.js

diff --git a/README.md b/README.md
index f2b2c8d..8a0885c 100644
--- a/README.md
+++ b/README.md
@@ -55,14 +55,14 @@ Unfortunately, this isn't a silver bullet.
 Often, Javascript itself is working against us by bypassing these counter-measures.
 
 Problems in [`Buffer (UInt8Array)`](https://github.com/feross/buffer), for example, can trivially result in catastrophic fund loss without any warning.
-It can do this through undermining your random number generation, [accidentally producing a duplicate `k` value](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/crypto.js#L14), sending Bitcoin to a malformed output script, or any of a million different ways.
+It can do this through undermining your random number generation, [accidentally producing a duplicate `k` value](https://www.nilsschneider.net/2013/01/28/recovering-bitcoin-private-keys.html), sending Bitcoin to a malformed output script, or any of a million different ways.
 Running tests in your target environment is important and a recommended step to verify continuously.
 
 Finally, **adhere to best practice**.
 We are not an authorative source of best practice, but, at the very least:
 
 * [Don't re-use addresses](https://en.bitcoin.it/wiki/Address_reuse).
-* Don't share BIP32 extended public keys ('xpubs'). [They are a liability](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/crypto.js#L68), and it only takes 1 misplaced private key (or a buggy implementation!) and you are vulnerable to **catastrophic fund loss**.
+* Don't share BIP32 extended public keys ('xpubs'). [They are a liability](https://bitcoin.stackexchange.com/questions/56916/derivation-of-parent-private-key-from-non-hardened-child), and it only takes 1 misplaced private key (or a buggy implementation!) and you are vulnerable to **catastrophic fund loss**.
 * [Don't use `Math.random`](https://security.stackexchange.com/questions/181580/why-is-math-random-not-designed-to-be-cryptographically-secure) - in any way - don't.
 * Enforce that users always verify (manually) a freshly-decoded human-readable version of their intended transaction before broadcast.
 * Don't *ask* users to generate mnemonics, or 'brain wallets',  humans are terrible random number generators.
@@ -140,11 +140,8 @@ Some examples interact (via HTTPS) with a 3rd Party Blockchain Provider (3PBP).
 - [Create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L88)
 - [Create (and broadcast via 3PBP) a Transaction where Alice and Bob can redeem the output at any time](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L144)
 - [Create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L190)
-- [Recover a private key from duplicate R values](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/crypto.js#L14)
-- [Recover a BIP32 parent private key from the parent public key, and a derived, non-hardened child private key](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/crypto.js#L68)
 - [Generate a single-key stealth address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L72)
 - [Generate a single-key stealth address (randomly)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L91)
-- [Recover parent recipient.d, if a derived private key is leaked (and nonce was revealed)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L107)
 - [Generate a dual-key stealth address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L124)
 - [Generate a dual-key stealth address (randomly)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L147)
 
diff --git a/test/integration/crypto.js b/test/integration/crypto.js
deleted file mode 100644
index 3a40f6c..0000000
--- a/test/integration/crypto.js
+++ /dev/null
@@ -1,103 +0,0 @@
-const { describe, it } = require('mocha')
-const assert = require('assert')
-const BN = require('bn.js')
-const bitcoin = require('../../')
-const bip32 = require('bip32')
-const crypto = require('crypto')
-const tinysecp = require('tiny-secp256k1')
-
-describe('bitcoinjs-lib (crypto)', function () {
-  it('can recover a private key from duplicate R values', function () {
-    // https://blockchain.info/tx/f4c16475f2a6e9c602e4a287f9db3040e319eb9ece74761a4b84bc820fbeef50
-    const tx = bitcoin.Transaction.fromHex('01000000020b668015b32a6178d8524cfef6dc6fc0a4751915c2e9b2ed2d2eab02424341c8000000006a47304402205e00298dc5265b7a914974c9d0298aa0e69a0ca932cb52a360436d6a622e5cd7022024bf5f506968f5f23f1835574d5afe0e9021b4a5b65cf9742332d5e4acb68f41012103fd089f73735129f3d798a657aaaa4aa62a00fa15c76b61fc7f1b27ed1d0f35b8ffffffffa95fa69f11dc1cbb77ef64f25a95d4b12ebda57d19d843333819d95c9172ff89000000006b48304502205e00298dc5265b7a914974c9d0298aa0e69a0ca932cb52a360436d6a622e5cd7022100832176b59e8f50c56631acbc824bcba936c9476c559c42a4468be98975d07562012103fd089f73735129f3d798a657aaaa4aa62a00fa15c76b61fc7f1b27ed1d0f35b8ffffffff02b000eb04000000001976a91472956eed9a8ecb19ae7e3ebd7b06cae4668696a788ac303db000000000001976a9146c0bd55dd2592287cd9992ce3ba3fc1208fb76da88ac00000000')
-
-    tx.ins.forEach(function (input, vin) {
-      const { output: prevOutput, pubkey, signature } = bitcoin.payments.p2pkh({ input: input.script })
-
-      const scriptSignature = bitcoin.script.signature.decode(signature)
-      const m = tx.hashForSignature(vin, prevOutput, scriptSignature.hashType)
-      assert(bitcoin.ECPair.fromPublicKey(pubkey).verify(m, scriptSignature.signature), 'Invalid m')
-
-      // store the required information
-      input.signature = scriptSignature.signature
-      input.z = new BN(m)
-    })
-
-    const n = new BN('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 16)
-
-    for (var i = 0; i < tx.ins.length; ++i) {
-      for (var j = i + 1; j < tx.ins.length; ++j) {
-        const inputA = tx.ins[i]
-        const inputB = tx.ins[j]
-
-        // enforce matching r values
-        const r = inputA.signature.slice(0, 32)
-        const rB = inputB.signature.slice(0, 32)
-        assert.strictEqual(r.toString('hex'), rB.toString('hex'))
-
-        const rInv = new BN(r).invm(n)
-
-        const s1 = new BN(inputA.signature.slice(32, 64))
-        const s2 = new BN(inputB.signature.slice(32, 64))
-        const z1 = inputA.z
-        const z2 = inputB.z
-
-        const zz = z1.sub(z2).mod(n)
-        const ss = s1.sub(s2).mod(n)
-
-        // k = (z1 - z2) / (s1 - s2)
-        // d1 = (s1 * k - z1) / r
-        // d2 = (s2 * k - z2) / r
-        const k = zz.mul(ss.invm(n)).mod(n)
-        const d1 = ((s1.mul(k).mod(n)).sub(z1).mod(n)).mul(rInv).mod(n)
-        const d2 = ((s2.mul(k).mod(n)).sub(z2).mod(n)).mul(rInv).mod(n)
-
-        // enforce matching private keys
-        assert.strictEqual(d1.toString(), d2.toString())
-      }
-    }
-  })
-
-  it('can recover a BIP32 parent private key from the parent public key, and a derived, non-hardened child private key', function () {
-    function recoverParent (master, child) {
-      assert(master.isNeutered(), 'You already have the parent private key')
-      assert(!child.isNeutered(), 'Missing child private key')
-
-      const serQP = master.publicKey
-      const d1 = child.privateKey
-      const data = Buffer.alloc(37)
-      serQP.copy(data, 0)
-
-      // search index space until we find it
-      let d2
-      for (var i = 0; i < 0x80000000; ++i) {
-        data.writeUInt32BE(i, 33)
-
-        // calculate I
-        const I = crypto.createHmac('sha512', master.chainCode).update(data).digest()
-        const IL = I.slice(0, 32)
-
-        // See bip32.js:273 to understand
-        d2 = tinysecp.privateSub(d1, IL)
-
-        const Qp = bip32.fromPrivateKey(d2, Buffer.alloc(32, 0)).publicKey
-        if (Qp.equals(serQP)) break
-      }
-
-      const node = bip32.fromPrivateKey(d2, master.chainCode, master.network)
-      node.depth = master.depth
-      node.index = master.index
-      node.masterFingerprint = master.masterFingerprint
-      return node
-    }
-
-    const seed = crypto.randomBytes(32)
-    const master = bip32.fromSeed(seed)
-    const child = master.derive(6) // m/6
-
-    // now for the recovery
-    const neuteredMaster = master.neutered()
-    const recovered = recoverParent(neuteredMaster, child)
-    assert.strictEqual(recovered.toBase58(), master.toBase58())
-  })
-})

From a908e909d1841500b5eeed4bee7a44240fc53b4c Mon Sep 17 00:00:00 2001
From: Daniel Cousens <dcousens@users.noreply.github.com>
Date: Wed, 26 Sep 2018 17:40:45 +1000
Subject: [PATCH 5/7] README: rm stealth address examples

---
 README.md                   |   4 -
 test/integration/stealth.js | 167 ------------------------------------
 2 files changed, 171 deletions(-)
 delete mode 100644 test/integration/stealth.js

diff --git a/README.md b/README.md
index 8a0885c..23dce36 100644
--- a/README.md
+++ b/README.md
@@ -140,10 +140,6 @@ Some examples interact (via HTTPS) with a 3rd Party Blockchain Provider (3PBP).
 - [Create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L88)
 - [Create (and broadcast via 3PBP) a Transaction where Alice and Bob can redeem the output at any time](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L144)
 - [Create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L190)
-- [Generate a single-key stealth address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L72)
-- [Generate a single-key stealth address (randomly)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L91)
-- [Generate a dual-key stealth address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L124)
-- [Generate a dual-key stealth address (randomly)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L147)
 
 If you have a use case that you feel could be listed here, please [ask for it](https://github.com/bitcoinjs/bitcoinjs-lib/issues/new)!
 
diff --git a/test/integration/stealth.js b/test/integration/stealth.js
deleted file mode 100644
index dd99d63..0000000
--- a/test/integration/stealth.js
+++ /dev/null
@@ -1,167 +0,0 @@
-const { describe, it } = require('mocha')
-const assert = require('assert')
-const bitcoin = require('../../')
-const ecc = require('tiny-secp256k1')
-
-function getAddress (node, network) {
-  return bitcoin.payments.p2pkh({ pubkey: node.publicKey, network }).address
-}
-
-// vG = (dG \+ sha256(e * dG)G)
-function stealthSend (e, Q) {
-  const eQ = ecc.pointMultiply(Q, e, true) // shared secret
-  const c = bitcoin.crypto.sha256(eQ)
-  const Qc = ecc.pointAddScalar(Q, c)
-  const vG = bitcoin.ECPair.fromPublicKey(Qc)
-
-  return vG
-}
-
-// v = (d + sha256(eG * d))
-function stealthReceive (d, eG) {
-  const eQ = ecc.pointMultiply(eG, d) // shared secret
-  const c = bitcoin.crypto.sha256(eQ)
-  const dc = ecc.privateAdd(d, c)
-  const v = bitcoin.ECPair.fromPrivateKey(dc)
-
-  return v
-}
-
-// d = (v - sha256(e * dG))
-function stealthRecoverLeaked (v, e, Q) {
-  const eQ = ecc.pointMultiply(Q, e) // shared secret
-  const c = bitcoin.crypto.sha256(eQ)
-  const vc = ecc.privateSub(v, c)
-  const d = bitcoin.ECPair.fromPrivateKey(vc)
-
-  return d
-}
-
-// vG = (rG \+ sha256(e * dG)G)
-function stealthDualSend (e, R, Q) {
-  const eQ = ecc.pointMultiply(Q, e) // shared secret
-  const c = bitcoin.crypto.sha256(eQ)
-  const Rc = ecc.pointAddScalar(R, c)
-  const vG = bitcoin.ECPair.fromPublicKey(Rc)
-
-  return vG
-}
-
-// vG = (rG \+ sha256(eG * d)G)
-function stealthDualScan (d, R, eG) {
-  const eQ = ecc.pointMultiply(eG, d) // shared secret
-  const c = bitcoin.crypto.sha256(eQ)
-  const Rc = ecc.pointAddScalar(R, c)
-  const vG = bitcoin.ECPair.fromPublicKey(Rc)
-
-  return vG
-}
-
-// v = (r + sha256(eG * d))
-function stealthDualReceive (d, r, eG) {
-  const eQ = ecc.pointMultiply(eG, d) // shared secret
-  const c = bitcoin.crypto.sha256(eQ)
-  const rc = ecc.privateAdd(r, c)
-  const v = bitcoin.ECPair.fromPrivateKey(rc)
-
-  return v
-}
-
-describe('bitcoinjs-lib (crypto)', function () {
-  it('can generate a single-key stealth address', function () {
-    // XXX: should be randomly generated, see next test for example
-    const recipient = bitcoin.ECPair.fromWIF('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss') // private to recipient
-    const nonce = bitcoin.ECPair.fromWIF('KxVqB96pxbw1pokzQrZkQbLfVBjjHFfp2mFfEp8wuEyGenLFJhM9') // private to sender
-
-    // ... recipient reveals public key (recipient.Q) to sender
-    const forSender = stealthSend(nonce.privateKey, recipient.publicKey)
-    assert.equal(getAddress(forSender), '1CcZWwCpACJL3AxqoDbwEt4JgDFuTHUspE')
-    assert.throws(function () { forSender.toWIF() }, /Error: Missing private key/)
-
-    // ... sender reveals nonce public key (nonce.Q) to recipient
-    const forRecipient = stealthReceive(recipient.privateKey, nonce.publicKey)
-    assert.equal(getAddress(forRecipient), '1CcZWwCpACJL3AxqoDbwEt4JgDFuTHUspE')
-    assert.equal(forRecipient.toWIF(), 'L1yjUN3oYyCXV3LcsBrmxCNTa62bZKWCybxVJMvqjMmmfDE8yk7n')
-
-    // sender and recipient, both derived same address
-    assert.equal(getAddress(forSender), getAddress(forRecipient))
-  })
-
-  it('can generate a single-key stealth address (randomly)', function () {
-    const recipient = bitcoin.ECPair.makeRandom() // private to recipient
-    const nonce = bitcoin.ECPair.makeRandom() // private to sender
-
-    // ... recipient reveals public key (recipient.Q) to sender
-    const forSender = stealthSend(nonce.privateKey, recipient.publicKey)
-    assert.throws(function () { forSender.toWIF() }, /Error: Missing private key/)
-
-    // ... sender reveals nonce public key (nonce.Q) to recipient
-    const forRecipient = stealthReceive(recipient.privateKey, nonce.publicKey)
-    assert.doesNotThrow(function () { forRecipient.toWIF() })
-
-    // sender and recipient, both derived same address
-    assert.equal(getAddress(forSender), getAddress(forRecipient))
-  })
-
-  it('can recover parent recipient.d, if a derived private key is leaked [and nonce was revealed]', function () {
-    const recipient = bitcoin.ECPair.makeRandom() // private to recipient
-    const nonce = bitcoin.ECPair.makeRandom() // private to sender
-
-    // ... recipient reveals public key (recipient.Q) to sender
-    const forSender = stealthSend(nonce.privateKey, recipient.publicKey)
-    assert.throws(function () { forSender.toWIF() }, /Error: Missing private key/)
-
-    // ... sender reveals nonce public key (nonce.Q) to recipient
-    const forRecipient = stealthReceive(recipient.privateKey, nonce.publicKey)
-    assert.doesNotThrow(function () { forRecipient.toWIF() })
-
-    // ... recipient accidentally leaks forRecipient.d on the blockchain
-    const leaked = stealthRecoverLeaked(forRecipient.privateKey, nonce.privateKey, recipient.publicKey)
-    assert.equal(leaked.toWIF(), recipient.toWIF())
-  })
-
-  it('can generate a dual-key stealth address', function () {
-    // XXX: should be randomly generated, see next test for example
-    const recipient = bitcoin.ECPair.fromWIF('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss') // private to recipient
-    const scan = bitcoin.ECPair.fromWIF('L5DkCk3xLLoGKncqKsWQTdaPSR4V8gzc14WVghysQGkdryRudjBM') // private to scanner/recipient
-    const nonce = bitcoin.ECPair.fromWIF('KxVqB96pxbw1pokzQrZkQbLfVBjjHFfp2mFfEp8wuEyGenLFJhM9') // private to sender
-
-    // ... recipient reveals public key(s) (recipient.Q, scan.Q) to sender
-    const forSender = stealthDualSend(nonce.privateKey, recipient.publicKey, scan.publicKey)
-    assert.throws(function () { forSender.toWIF() }, /Error: Missing private key/)
-
-    // ... sender reveals nonce public key (nonce.Q) to scanner
-    const forScanner = stealthDualScan(scan.privateKey, recipient.publicKey, nonce.publicKey)
-    assert.throws(function () { forScanner.toWIF() }, /Error: Missing private key/)
-
-    // ... scanner reveals relevant transaction + nonce public key (nonce.Q) to recipient
-    const forRecipient = stealthDualReceive(scan.privateKey, recipient.privateKey, nonce.publicKey)
-    assert.doesNotThrow(function () { forRecipient.toWIF() })
-
-    // scanner, sender and recipient, all derived same address
-    assert.equal(getAddress(forSender), getAddress(forScanner))
-    assert.equal(getAddress(forSender), getAddress(forRecipient))
-  })
-
-  it('can generate a dual-key stealth address (randomly)', function () {
-    const recipient = bitcoin.ECPair.makeRandom() // private to recipient
-    const scan = bitcoin.ECPair.makeRandom() // private to scanner/recipient
-    const nonce = bitcoin.ECPair.makeRandom() // private to sender
-
-    // ... recipient reveals public key(s) (recipient.Q, scan.Q) to sender
-    const forSender = stealthDualSend(nonce.privateKey, recipient.publicKey, scan.publicKey)
-    assert.throws(function () { forSender.toWIF() }, /Error: Missing private key/)
-
-    // ... sender reveals nonce public key (nonce.Q) to scanner
-    const forScanner = stealthDualScan(scan.privateKey, recipient.publicKey, nonce.publicKey)
-    assert.throws(function () { forScanner.toWIF() }, /Error: Missing private key/)
-
-    // ... scanner reveals relevant transaction + nonce public key (nonce.Q) to recipient
-    const forRecipient = stealthDualReceive(scan.privateKey, recipient.privateKey, nonce.publicKey)
-    assert.doesNotThrow(function () { forRecipient.toWIF() })
-
-    // scanner, sender and recipient, all derived same address
-    assert.equal(getAddress(forSender), getAddress(forScanner))
-    assert.equal(getAddress(forSender), getAddress(forRecipient))
-  })
-})

From aac228011f9c8c75b17bc9d100bb67534172e366 Mon Sep 17 00:00:00 2001
From: Daniel Cousens <dcousens@users.noreply.github.com>
Date: Wed, 26 Sep 2018 17:44:31 +1000
Subject: [PATCH 6/7] README: rm bad sha256 hash example

---
 README.md                     |  1 -
 test/integration/addresses.js | 11 -----------
 2 files changed, 12 deletions(-)

diff --git a/README.md b/README.md
index 23dce36..28c1b21 100644
--- a/README.md
+++ b/README.md
@@ -109,7 +109,6 @@ Otherwise, pull requests are appreciated.
 Some examples interact (via HTTPS) with a 3rd Party Blockchain Provider (3PBP).
 
 - [Generate a random address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L22)
-- [Generate an address from a SHA256 hash](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L29)
 - [Import an address via WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L40)
 - [Generate a 2-of-3 P2SH multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L47)
 - [Generate a SegWit address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L60)
diff --git a/test/integration/addresses.js b/test/integration/addresses.js
index 4bd71c8..0024410 100644
--- a/test/integration/addresses.js
+++ b/test/integration/addresses.js
@@ -25,17 +25,6 @@ describe('bitcoinjs-lib (addresses)', function () {
     assert.strictEqual(address, '1F5VhMHukdnUES9kfXqzPzMeF1GPHKiF64')
   })
 
-  it('can generate an address from a SHA256 hash', function () {
-    const hash = bitcoin.crypto.sha256(Buffer.from('correct horse battery staple'))
-
-    const keyPair = bitcoin.ECPair.fromPrivateKey(hash)
-    const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey })
-
-    // Generating addresses from SHA256 hashes is not secure if the input to the hash function is predictable
-    // Do not use with predictable inputs
-    assert.strictEqual(address, '1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8')
-  })
-
   it('can import an address via WIF', function () {
     const keyPair = bitcoin.ECPair.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct')
     const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey })

From e1049c1090b329a60e5d31679b77bb568e594b9f Mon Sep 17 00:00:00 2001
From: Daniel Cousens <dcousens@users.noreply.github.com>
Date: Wed, 26 Sep 2018 17:59:04 +1000
Subject: [PATCH 7/7] README: fix emphasis

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 28c1b21..9342696 100644
--- a/README.md
+++ b/README.md
@@ -54,8 +54,8 @@ This library uses [tiny-secp256k1](https://github.com/bitcoinjs/tiny-secp256k1),
 Unfortunately, this isn't a silver bullet.
 Often, Javascript itself is working against us by bypassing these counter-measures.
 
-Problems in [`Buffer (UInt8Array)`](https://github.com/feross/buffer), for example, can trivially result in catastrophic fund loss without any warning.
-It can do this through undermining your random number generation, [accidentally producing a duplicate `k` value](https://www.nilsschneider.net/2013/01/28/recovering-bitcoin-private-keys.html), sending Bitcoin to a malformed output script, or any of a million different ways.
+Problems in [`Buffer (UInt8Array)`](https://github.com/feross/buffer), for example, can trivially result in **catastrophic fund loss** without any warning.
+It can do this through undermining your random number generation, accidentally producing a [duplicate `k` value](https://www.nilsschneider.net/2013/01/28/recovering-bitcoin-private-keys.html), sending Bitcoin to a malformed output script, or any of a million different ways.
 Running tests in your target environment is important and a recommended step to verify continuously.
 
 Finally, **adhere to best practice**.