Once an output has been spent, the public key of output’s receiving address is made public. This allows an attacker wishing to damage a user’s privacy to generate new addresses with the same public key and send near-dust to those new addresses. Bitcoin Core (as of version 0.19.0.1) won’t recognize the dust as reusing an old address, but the attacker knows that the pair of addresses are owned by the same wallet.
I made a new wallet, and ran getnewaddress
three times to get three different addresses: one legacy, one p2sh-segwit, and one bech32:
> getnewaddress legacy legacy # m/0'/0'/0' : mgF6uW48rMAtBDfMuNUyYhLZ14srr19vwG
> getnewaddress p2sh-segwit p2sh-segwit # m/0'/0'/1' : 2MtjDh43Fkot1AgA8cn7XScpvVkJYYbaMvf
> getnewaddress bech32 bech32 # m/0'/0'/2' : bcrt1qgsr7w7qnagsk540e24sq4l3hvvu0ccq53nlzak
I sent 1 BTC to each of these addresses, and then spent those 3 BTC to a throwaway address.
I then used a 3rd party took to look up the other types of addresses for these public keys, ending up with 9 addresses (three for each of the public keys):
legacy p2sh-segwit bech32
---------------------------------- ----------------------------------- --------------------------------------------
m/0'/0'/0' mgF6uW48rMAtBDfMuNUyYhLZ14srr19vwG 2Mu4jiTgDhqMsRm2AtjjF1TX6winUDUiS3P bcrt1qqlu238za6fcpm3n0cdl3qmaxc9xvpz96y3xzhk
m/0'/0'/1' mhj1WrEcTvn1ZyLoxZuFPk95Yqh9P9jkKw 2MtjDh43Fkot1AgA8cn7XScpvVkJYYbaMvf bcrt1qrqm7u7v65lz32ej5azn8ucpn973w7hsjgegs3a
m/0'/0'/2' mmifiHnhw1zcxQTCLmgPDaDKVvaHyTWnmA 2NFifAoVUxTvCPdR5NJ6WpNs2VbBSJNwEYc bcrt1qgsr7w7qnagsk540e24sq4l3hvvu0ccq53nlzak
I then sent coins to each of these 9 addresses to see which ones were recognized as ‘reuse’:
> listunspent 0 0 | jq -cM '[.[] | {reused,amount,address}] | sort_by(.amount)[]'
{"reused":true,"amount":1,"address":"mgF6uW48rMAtBDfMuNUyYhLZ14srr19vwG"}
{"reused":false,"amount":2,"address":"2Mu4jiTgDhqMsRm2AtjjF1TX6winUDUiS3P"}
{"reused":false,"amount":3,"address":"bcrt1qqlu238za6fcpm3n0cdl3qmaxc9xvpz96y3xzhk"}
{"reused":false,"amount":4,"address":"mhj1WrEcTvn1ZyLoxZuFPk95Yqh9P9jkKw"}
{"reused":true,"amount":5,"address":"2MtjDh43Fkot1AgA8cn7XScpvVkJYYbaMvf"}
{"reused":false,"amount":6,"address":"bcrt1qrqm7u7v65lz32ej5azn8ucpn973w7hsjgegs3a"}
{"reused":false,"amount":7,"address":"mmifiHnhw1zcxQTCLmgPDaDKVvaHyTWnmA"}
{"reused":false,"amount":8,"address":"2NFifAoVUxTvCPdR5NJ6WpNs2VbBSJNwEYc"}
{"reused":true,"amount":9,"address":"bcrt1qgsr7w7qnagsk540e24sq4l3hvvu0ccq53nlzak"}
Only 3 of the 9 were recognized as reuse - the 3 which I had been originally given by getnewaddress
, whereas for all intents and purposes all 9 are really reuse; an attacker can send dust to any of them and gain information when the dust is spent.
Note: to get the same keys as I used in this example, you can use the following hdseed:
> createwallet wallet_name=test blank=true avoid_reuse=true
> sethdseed true cNonYmUoYqZ2Qyuk3McU3D65p2bMgHNH4cgmu9xdt6b2GXawiTxT
Edit: To show that the pubkeys are the same for these addresses:
$ for addr in mgF6uW48rMAtBDfMuNUyYhLZ14srr19vwG 2Mu4jiTgDhqMsRm2AtjjF1TX6winUDUiS3P bcrt1qqlu238za6fcpm3n0cdl3qmaxc9xvpz96y3xzhk \
> mhj1WrEcTvn1ZyLoxZuFPk95Yqh9P9jkKw 2MtjDh43Fkot1AgA8cn7XScpvVkJYYbaMvf bcrt1qrqm7u7v65lz32ej5azn8ucpn973w7hsjgegs3a \
> mmifiHnhw1zcxQTCLmgPDaDKVvaHyTWnmA 2NFifAoVUxTvCPdR5NJ6WpNs2VbBSJNwEYc bcrt1qgsr7w7qnagsk540e24sq4l3hvvu0ccq53nlzak
> do
> bcrt getaddressinfo $addr | jq -crM '{pubkey,hdkeypath,address}'
> done
{"pubkey":"02dc7bd5438c460e74faf57a63c98937bf381eff623977fce9ec8c099434087047","hdkeypath":"m/0'/0'/0'","address":"mgF6uW48rMAtBDfMuNUyYhLZ14srr19vwG"}
{"pubkey":"02dc7bd5438c460e74faf57a63c98937bf381eff623977fce9ec8c099434087047","hdkeypath":"m/0'/0'/0'","address":"2Mu4jiTgDhqMsRm2AtjjF1TX6winUDUiS3P"}
{"pubkey":"02dc7bd5438c460e74faf57a63c98937bf381eff623977fce9ec8c099434087047","hdkeypath":"m/0'/0'/0'","address":"bcrt1qqlu238za6fcpm3n0cdl3qmaxc9xvpz96y3xzhk"}
{"pubkey":"024cd5841775e7dc334d3739ef52fc2a7e01ef8eaaa1fc503803711a0602107d54","hdkeypath":"m/0'/0'/1'","address":"mhj1WrEcTvn1ZyLoxZuFPk95Yqh9P9jkKw"}
{"pubkey":"024cd5841775e7dc334d3739ef52fc2a7e01ef8eaaa1fc503803711a0602107d54","hdkeypath":"m/0'/0'/1'","address":"2MtjDh43Fkot1AgA8cn7XScpvVkJYYbaMvf"}
{"pubkey":"024cd5841775e7dc334d3739ef52fc2a7e01ef8eaaa1fc503803711a0602107d54","hdkeypath":"m/0'/0'/1'","address":"bcrt1qrqm7u7v65lz32ej5azn8ucpn973w7hsjgegs3a"}
{"pubkey":"028c4e68ac42a9d0bc7c11591768b8bdbd25e5c7b666e96d452c9756b0d1acd28b","hdkeypath":"m/0'/0'/2'","address":"mmifiHnhw1zcxQTCLmgPDaDKVvaHyTWnmA"}
{"pubkey":"028c4e68ac42a9d0bc7c11591768b8bdbd25e5c7b666e96d452c9756b0d1acd28b","hdkeypath":"m/0'/0'/2'","address":"2NFifAoVUxTvCPdR5NJ6WpNs2VbBSJNwEYc"}
{"pubkey":"028c4e68ac42a9d0bc7c11591768b8bdbd25e5c7b666e96d452c9756b0d1acd28b","hdkeypath":"m/0'/0'/2'","address":"bcrt1qgsr7w7qnagsk540e24sq4l3hvvu0ccq53nlzak"}