Re: [bitcoin-dev] Tainting, CoinJoin, PayJoin, CoinSwap

2020-06-10 Thread Mr. Lee Chiffre via bitcoin-dev
Thought provoking. In my opinion bitcoin should be designed in a way to
where there is no distinction between "clean" bitcoins and "dirty"
bitcoins. If one bitcoin is considered dirty then all bitcoins should be
considered dirty. Fungibility is important. And bitcoin or its users
should not be concerned with pleasing governments. Bitcoin should be or
remain neutral. The term "clean" or "dirty" is defined by whatever
government is in power. Bitcoin is not to please government but to be
independent of government control and reliance on government or any other
centralized systems. To act as censorship resistant money to give people
freedom from tyranny. I'm just saying that if anyone can determine if a
bitcoin is clean or dirty then I think we are doing something wrong. What
is great with certain protocols like coinjoin coinswap and payjoin there
is that plausible deniability that hopefully would spread the entire
"taint" of bitcoin collectively either for real or just as a possibility 
to any blockchain analysis entities (with no real way to tell or interpret
with accuracy).

Bitcoin should be designed in a way where the only way to stop "dirty"
bitcoins is to reject all bitcoins.

If "dirty" bitcoins is actually a real thing then I guess I could have fun
by polluting random peoples bitcoin addresses with "dirty" coins right? No
way to prove if it is a self transfer or an unsolicited "donation".  I
just do not see how any bitcoin UTXO censorship could work because of
plausible deniability.

If any company actually used UTXO censorship then customers can just use
services that are respecting of freedom and do not use censorship.

___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


Re: [bitcoin-dev] Time-dilation Attacks on the Lightning Network

2020-06-10 Thread ZmnSCPxj via bitcoin-dev
Good morning Antoine and Gleb,

One thing I have been idly thinking about would be to have a *separate* 
software daemon that performs de-eclipsing for your Bitcoin fullnode.

For example, you could run this deeclipser on the same hardware as your Bitcoin 
fullnode, and have the deeclipser bind to port 8334.
Then you set your Bitcoin fullnode with `addnode=localhost:8334` in your 
`bitcoind.conf`.

Your Bitcoin fullnode would then connect to the deeclipser using normal P2P 
protocol.

The deeclipser would periodically, every five minutes or so, check the latest 
headers known by your fullnode, via the P2P protocol connection your fullnode 
makes.
Then it would attempt to discover any blocks with greater blockheight.

The reason why we have a separate deeclipser process is so that the deeclipser 
can use a plugin system, and isolate the plugins from the main fullnode 
software.
For example, the deeclipser could query a number of plugins:

* One plugin could just try connecting to some random node, in the hopes of 
getting a new connection that is not eclipsed.
* Another plugin could try polling known blockchain explorers and using their 
APIs over HTTPS, possibly over Tor as well.
* Another plugin could try connecting to known Electrum servers.
* New plugins can be developed for new mitigations, such as sending headers 
over DNS or blocks over mesh or etc.

Then if any plugin discovers a block later than that known by your fullnode, 
the deeclipser can send an unsolicited `block` or `header` message to your 
fullnode to update it.

The advantage of using a plugin system is that it becomes easier to prototype, 
deploy, and maybe even test new de-eclipsing mitigations.

At the same time, by running a separate daemon from the fullnode, we provide 
some amount of process isolation in case some problem with the plugin system 
exists.
The deeclipser could be run by a completely different user, for example, and 
you might even run multiple deeclipser daemons in the same hardware, with 
different non-overlapping plugins, so that an exploit of one plugin will only 
bring down one deeclipser, with other deeclipser daemons remaining functional 
and still protecting your fullnode.

Finally, by using the P2P protocol, the fullnode you run could be a 
non-Bitcoin-Core fullnode, such as btcd or rust-bitcoin or whatever other 
fullnode implementations exist, assuming you actually want to use them for some 
reason.

What do you think?

Regards,
ZmnSCPxj

___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


Re: [bitcoin-dev] Tainting, CoinJoin, PayJoin, CoinSwap

2020-06-10 Thread ZmnSCPxj via bitcoin-dev
Good morning nopara73 and Chris,


> One way to resist a likely taint analysis attack is to involve other
> parts of the bitcoin economy in your transactions. For example our
> exchange thief could deposit and then withdraw his stolen coins through
> a Bitcoin Casino or other bitcoin service hot wallet. His coins might no
> longer be 100% tainted from the exchange hack but perhaps have 5%
> exchange hack, 5% bitcoin ATM, 5% mined coins, etc etc. The numbers are
> made up and they depend on the exact algorithm but the main point is
> that involving the rest of the bitcoin economy in your transaction is
> one practical way to stop taint analysis being a useful attack against
> on you.
>
> Another important point is that taint isn't part of bitcoin's code
> anywhere. It is an external reality that surveillance companies impose
> on users. The only reason taint has any influence is because of
> censorship, for example an exchange which uses the services of a
> surveillance company has the power to freeze funds (i.e. censor a
> transaction) if they believe the user's deposit transaction is tainted.

Adding on to this, we can consider the *economics* of taint.

Tainted coins are less valuable than untainted coins.

However, as pointed out as well, taint is not a consensus among all Bitcoin 
users.
There are no cryptographic underpinnings that would allow all nodes to agree on 
their individual taint analysis.

The people knocking on doors often have limited amounts of reach: there are 
real economic barriers to the knock-on-doors people being shipped to the other 
side of the Earth (fuel costs, ammunition costs, sociopolitical knock-on 
effects).

Thus, suppose I am a miner with N coins.
As the coins have no history, they are "completely clean", as it were.

As a miner, I exist somewhere in the universe.
It is possible that I exist in some location on Earth (we cannot know; please 
ignore scurrilous slander that I am somehow existent outside of time and space).

Now suppose you have some tainted coins.
As noted, those coins are tainted only within some jurisdiction.
Outside that jurisdiction, however, they have no taint (taint is not a global 
consensus).

If I happen to live outside the jurisdiction where your coins are tainted, and 
I have some clean freshly-mined coins, I can offer this deal to you:

* Give me N+1 tainted coins for my N clean coins.

Now, again, the premise here is that there exists no global knock-on-doors 
people who can come to my datacenter and start asking questions to the sysads 
administering my computational substrate.

In that case, you might very well take the deal:

* You have not lost economic power, because the tainted coins, in your 
jurisdiction, are of lower value than N+1 anyway, and might even have value 
below that of N clean coins.
* I have gained economic power, because the tainted coins, in my jurisdiction, 
are not tainted and have the same cleanliness as my fresh mined coins.

This is a simple example of gains from trade, this time from jurisdictional 
arbitrage, thus such deals will exist.

--

But that is specious, as it assumes that there exists no global knock-on-doors 
people.
Obviously, there could exist one or more entities who are able to ship 
knocks-on-doors people all over the globe, taking advantage of economies of 
scale and reinvestment (more knock-on-doors people to knock on doors of people 
they can extract more economic power from to hire more knock-on-doors people) 
to achieve practically global coverage.

Against this, we must remember that ultimately censorship resistance of the 
coin is what can protect against such an attacker, which can impose its own 
non-consensual-but-pretty-damn-important view of taint practically globally.

Censorship resistance requires that owners of coins have control of the keys 
(your keys your coins) and that they can offer bribes to miners to get their 
transactions committed (mining fees).
Custodiality makes it easier for fewer knock-on-doors people to need to be 
shipped to stop certain activities.

Now, the Bitcoin Casino example is of course an example of not your keys not 
your coins i.e. custodiality.

For the purpose of mixing, the "Bitcoin Casino" here is simply aggregating 
multiple UTXOs and then sending them back out to many other new UTXOs.

This is in fact the same operation that CoinJoin does, it aggregates multiple 
UTXOs and creates many new UTXOs to different clients with shared taint.
The advantage is that CoinJoin is still your keys your coins, you still own the 
keys with which to sign the CoinJoin transaction, and thus improve censorship 
resistance of your mixing operation.

For CoinSwap as well, we can consider that a CoinSwap server could make 
multiple CoinSwaps with various clients.
This leads to the CoinSwap server owning many small UTXOs, which it at some 
point aggregates into a large UTXO that it then uses to service more clients 
(for example, it serves many small clients, then has 

Re: [bitcoin-dev] Tainting, CoinJoin, PayJoin, CoinSwap

2020-06-10 Thread Chris Belcher via bitcoin-dev
Hello nopara73,

On 10/06/2020 13:32, nopara73 via bitcoin-dev wrote:
> The problem with CoinJoins is that desire for privacy is explicitly
> signalled by them, so adversaries can consider them "suspicious." PayJoin
> and CoinSwap solve this problem, because they are unnoticeable. I think
> this logic doesn't stand for scrutiny.
> 
>>From here on let's use the terminology of a typical adversary: there are 3
> kinds of coin histories: "clean", "dirty" and "suspicious".
> The aftermath of you using a "dirty" coin is knocks on your door. You using
> a "suspicious" coin is uncomfortable questions and you using a "clean" coin
> is seamless transfer.
> 
> In scenario 1, you start out with a "clean" history. By using CoinJoins you
> make your new coin's history "suspicious" so you have no incentive to
> CoinJoin. By using CoinSwap/PayJoin your new coin can be either "clean" or
> "dirty". What would a "clean" coin owner prefer more? Take the risk of
> knocking on the door or answering uncomfortable questions?
> 
> In scenario 2, you start out with a "dirty" history. By using CoinJoins you
> make your new coin's history "suspicious" so you have an incentive to
> CoinJoin. By using CoinSwap/PayJoin your new coin can either be "clean" or
> "dirty". What would a "dirty" coin owner prefer more? And here's an
> insight: you may get knocks on your door for a dirty coin that you have
> nothing to do with. And you can prove this fact to the adversary, but by
> doing so, you'll also expose that you started out with a "dirty" coin to
> begin with and now the adversary becomes interested in you for a different
> reason.
> 
> You can also examine things assuming full adoption of PJ/CS vs full
> adoption of CJ, but you'll see that full adoption of any of these solves
> the tainting issue.
> 
> So my current conclusion is that PJ/CS does not only not solve the taint
> problem, it just alters it and ultimately very similar problems arise for
> the users. Maybe the goal of unobservable privacy is a fallacy in this
> context as it is based on the assumption that desiring privacy is
> suspicious, so you want to hide the fact that you desire privacy. And the
> solution to the taint issue is either protocol change or social change
> (decent adoption.)
> 
> PS.: Please try to keep the conversation to the Taint Issue as this email
> of mine isn't supposed to be discussing general pros and cons of various
> privacy techniques.
> 
> Any thoughts?
> 
> 
> ___
> bitcoin-dev mailing list
> bitcoin-dev@lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
> 

There are two concepts here: Taint analysis and the detectableness of
privacy protocols.

Taint analysis is quite an old technique, I remember seeing the
blockchain.info explorer having a tool for calculating a value for taint
back in 2013, long before any widely-used CoinJoin implementations were
created. I think taint was first created to attack the privacy technique
of simply sending coins to yourself multiple times. If those coins were
for example stolen from an exchange's hot wallet then the taint between
the exchange addresses and the later addresses would still be 100% even
if the thief sent the coins to himself multiple times.

A very important point is that it's difficult to reason about taint
analysis algorithms because they are often hypothetical, likely
closed-source, not available to the public for review and changing all
the time. OP talks about the three categories "clean", "dirty" and
"suspicious" which is one possibility. I've read about other taint
analysis algorithms which result in a numerical score out of 100.
Blockchain.info's algorithm calculated taint as a number expressing the
relation between any two addresses, so it wouldn't make sense to say "an
address" is tainted, instead you have to talk about a pair of addresses
being tainted with each other. So even though it's hard to reason about
the exact algorithm we can still talk about likely situations, and
imagine what an adversary could do in the worst case or best case.

One way to resist a likely taint analysis attack is to involve other
parts of the bitcoin economy in your transactions. For example our
exchange thief could deposit and then withdraw his stolen coins through
a Bitcoin Casino or other bitcoin service hot wallet. His coins might no
longer be 100% tainted from the exchange hack but perhaps have 5%
exchange hack, 5% bitcoin ATM, 5% mined coins, etc etc. The numbers are
made up and they depend on the exact algorithm but the main point is
that involving the rest of the bitcoin economy in your transaction is
one practical way to stop taint analysis being a useful attack against
on you.

Another important point is that taint isn't part of bitcoin's code
anywhere. It is an external reality that surveillance companies impose
on users. The only reason taint has any influence is because of
censorship, for example an exchange 

Re: [bitcoin-dev] Question about PayJoin effectiveness

2020-06-10 Thread Chris Belcher via bitcoin-dev
On 10/06/2020 05:01, Mr. Lee Chiffre via bitcoin-dev wrote:
> I am trying to learn about payjoin. I have a couple concerns on its
> effectiveness. Are my concerns valid or am I missing something?
> 
> concern 1
> If it is known to be a payjoin transaction anyone could determine the
> sender the recipient and amount right?
> 
> Lets assume that everyone has a single utxo because payjoin becomes common
> use and payjoin consolidates utxos through "snowballing". If Alice has a
> UTXO of 0.05 btc and Bob has a UTXO of 1.15 btc. Bob can be assumed to
> have more balance because he is a merchant and his customers payjoin him
> payments alot.
> 
> If Alice and Bob do a payjoin with Alice paying 0.01 btc to Bob, it would
> probably look like this right?
> 
>  0.05---> |>1.16
>  1.15---> |>0.04
> 
> It is very obvious here the amount sent and the sender.  Even if Alice did
> combine another input it would still be very obvious. In this case Alice
> has another utxo with 0.4 BTC
> 
>  0.40---> |
>  0.05---> |>1.16
>  1.15---> |>0.44
> 
> This is still obvious that Alice paid Bob 0.01 BTC isn't it?
> 
> 
> 
> concern 2
> If there is just one consolidated utxo after each payjoin, would it  be
> easy to break the privacy of transaction chains?
> 
> Alice---payjoin--->Bob
> Clark---payjoin--->Bob
> 
> or
> 
> Alice---payjoin--->Bob---payjoin--->Clark
> 
> For exmaple, lets say that Alice payjoins to Bob. Then later on Clark
> payjoins with Bob. Based on the payjoin between Clark and Bob, Clark now
> knows what UTXO was actually Bob's. And can then know which one was
> actually Alices. By transacting a payjoin with someone, they could decloak
> the payjoins before them right? If so, how far back the chain can they go?
> 
> The issue is not that someone knows the utxos of themselves and the entity
> they payjoined with. The issue is that someone can figure out the payjoins
> of others before them with the same entity.
> 
> 
> I surely must be missing something here. What am I not understanding?
> 

Adding to what other people have written, it's an important point that
PayJoin breaks the common-input-ownership heuristic. I.E. if PayJoins
become even moderately popular then it will no longer be a safe
assumption that all the inputs to a transaction are owned by the same
entity (taking away all the obvious breaks like equal-output-coinjoins).

This assumption is a huge reason why blockchain surveillance is so
effective. A good paper on that is here:
https://arxiv.org/abs/1605.06369 (The Unreasonable Effectiveness of
Address Clustering Harrigan, Martin & Fretter, Christoph. (2016))

The assumption is mentioned by Satoshi in the whitepaper where he
laments that the privacy loss is unavoidable. (One of the few outright
errors in the paper, perhaps the only error). The fact that we have
technology to break this assumption is a massive deal, and that's a big
value-add of PayJoin.

___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


Re: [bitcoin-dev] Tainting, CoinJoin, PayJoin, CoinSwap

2020-06-10 Thread Greg Sanders via bitcoin-dev
A major point of defeating the common input heuristic and others is to make
"super-clusters". A small number of users that "don't care" about possibly
touching tainted coins can render many chain analysis techniques unworkable
in practice for enforcement. You don't need 100% coverage to defeat the
heuristic.

On Wed, Jun 10, 2020 at 9:40 AM nopara73 via bitcoin-dev <
bitcoin-dev@lists.linuxfoundation.org> wrote:

> The problem with CoinJoins is that desire for privacy is explicitly
> signalled by them, so adversaries can consider them "suspicious." PayJoin
> and CoinSwap solve this problem, because they are unnoticeable. I think
> this logic doesn't stand for scrutiny.
>
> From here on let's use the terminology of a typical adversary: there are 3
> kinds of coin histories: "clean", "dirty" and "suspicious".
> The aftermath of you using a "dirty" coin is knocks on your door. You
> using a "suspicious" coin is uncomfortable questions and you using a
> "clean" coin is seamless transfer.
>
> In scenario 1, you start out with a "clean" history. By using CoinJoins
> you make your new coin's history "suspicious" so you have no incentive to
> CoinJoin. By using CoinSwap/PayJoin your new coin can be either "clean" or
> "dirty". What would a "clean" coin owner prefer more? Take the risk of
> knocking on the door or answering uncomfortable questions?
>
> In scenario 2, you start out with a "dirty" history. By using CoinJoins
> you make your new coin's history "suspicious" so you have an incentive to
> CoinJoin. By using CoinSwap/PayJoin your new coin can either be "clean" or
> "dirty". What would a "dirty" coin owner prefer more? And here's an
> insight: you may get knocks on your door for a dirty coin that you have
> nothing to do with. And you can prove this fact to the adversary, but by
> doing so, you'll also expose that you started out with a "dirty" coin to
> begin with and now the adversary becomes interested in you for a different
> reason.
>
> You can also examine things assuming full adoption of PJ/CS vs full
> adoption of CJ, but you'll see that full adoption of any of these solves
> the tainting issue.
>
> So my current conclusion is that PJ/CS does not only not solve the taint
> problem, it just alters it and ultimately very similar problems arise for
> the users. Maybe the goal of unobservable privacy is a fallacy in this
> context as it is based on the assumption that desiring privacy is
> suspicious, so you want to hide the fact that you desire privacy. And the
> solution to the taint issue is either protocol change or social change
> (decent adoption.)
>
> PS.: Please try to keep the conversation to the Taint Issue as this email
> of mine isn't supposed to be discussing general pros and cons of various
> privacy techniques.
>
> Any thoughts?
>
> --
> Best,
> Ádám
> ___
> bitcoin-dev mailing list
> bitcoin-dev@lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>
___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


[bitcoin-dev] Tainting, CoinJoin, PayJoin, CoinSwap

2020-06-10 Thread nopara73 via bitcoin-dev
The problem with CoinJoins is that desire for privacy is explicitly
signalled by them, so adversaries can consider them "suspicious." PayJoin
and CoinSwap solve this problem, because they are unnoticeable. I think
this logic doesn't stand for scrutiny.

>From here on let's use the terminology of a typical adversary: there are 3
kinds of coin histories: "clean", "dirty" and "suspicious".
The aftermath of you using a "dirty" coin is knocks on your door. You using
a "suspicious" coin is uncomfortable questions and you using a "clean" coin
is seamless transfer.

In scenario 1, you start out with a "clean" history. By using CoinJoins you
make your new coin's history "suspicious" so you have no incentive to
CoinJoin. By using CoinSwap/PayJoin your new coin can be either "clean" or
"dirty". What would a "clean" coin owner prefer more? Take the risk of
knocking on the door or answering uncomfortable questions?

In scenario 2, you start out with a "dirty" history. By using CoinJoins you
make your new coin's history "suspicious" so you have an incentive to
CoinJoin. By using CoinSwap/PayJoin your new coin can either be "clean" or
"dirty". What would a "dirty" coin owner prefer more? And here's an
insight: you may get knocks on your door for a dirty coin that you have
nothing to do with. And you can prove this fact to the adversary, but by
doing so, you'll also expose that you started out with a "dirty" coin to
begin with and now the adversary becomes interested in you for a different
reason.

You can also examine things assuming full adoption of PJ/CS vs full
adoption of CJ, but you'll see that full adoption of any of these solves
the tainting issue.

So my current conclusion is that PJ/CS does not only not solve the taint
problem, it just alters it and ultimately very similar problems arise for
the users. Maybe the goal of unobservable privacy is a fallacy in this
context as it is based on the assumption that desiring privacy is
suspicious, so you want to hide the fact that you desire privacy. And the
solution to the taint issue is either protocol change or social change
(decent adoption.)

PS.: Please try to keep the conversation to the Taint Issue as this email
of mine isn't supposed to be discussing general pros and cons of various
privacy techniques.

Any thoughts?

-- 
Best,
Ádám
___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


Re: [bitcoin-dev] Design for a CoinSwap implementation for massively improving Bitcoin privacy and fungibility

2020-06-10 Thread Chris Belcher via bitcoin-dev
Hello ZmnSCPxj,

On 10/06/2020 11:58, ZmnSCPxj wrote:
> Good morning Chris,
> 
>>> Let me propose an alternative: swap-on-receive+swap-on-change.
>>
>> That's an interesting point, thanks for the thought. This scheme might
>> not be appropriate for every threat model and use case.
>> For example, if someone wants to use bitcoin just as a foreign currency
>> for its privacy and censorship-resistant properties. So for example if
>> they want to pay for a VPN anonymously, so they buy bitcoins and
>> immediately send all of them to the VPN merchant. The swap-on-receive
>> wouldn't be appropriate for them because they'll be doing a coinswap
>> straight away to the VPN merchant. So perhaps this plan could be an
>> optional mode of operation (which may or may not be the default). The
>> scheme obviously is useful when bitcoin is being used more as a
>> day-to-day money.
> 
> 
> No, I think you misunderstand my proposal.
> 
> If the user is doing swap-on-receive, the user already has an anonymous UTXO, 
> they can just transfer it directly in full to the VPN without using a 
> CoinSwap.
> 
> The number of CoinSwaps involved is the same: one.
> 
> So the difference is:
> 
> * swap-on-receive:
>   * I get some coins from an exchange, giving them my contact information and 
> bank information and all the places I have ever inhabited in my entire 
> existence and an unfertilized egg sample and an archive of my diary and let 
> them invasively scan my cognitive substrate.
>   * I send the coins to my CoinSwap wallet.
>   * The CoinSwap wallet automaticaly CoinSwaps the coins into a new UTXO.
> * One CoinSwap.
>   * I tell the CoinSwap wallet to send it all to the VPN.
> * My CoinSwap wallet knows my coins are already cleaned, so it creates a 
> plain 1-input 1-output transaction directly to the VPN address.
> 
> * swap-on-pay:
>   * I get some coins from an exchange, giving them my contact information and 
> bank information and all the places I have ever inhabited in my entire 
> existence and an unfertilized egg sample and an archive of my diary and let 
> them invasively scan my cognitive substrate.
>   * I send the coins to my CoinSwap wallet.
>   * I tell the CoinSwap wallet to send it all to the VPN.
> * My CoinSwap wallet automatically arranges a CoinSwap into the VPN 
> address.
>   * One CoinSwap.
> 
> So in both cases the same expected number of CoinSwaps is done, i.e. one.
> 
> Note that there are still details like how much onchain fees are and how much 
> CoinSwap maker fees are and etc etc but they exist for both flows anyway.
> So I would still be buying slightly more than my target amount, and if there 
> is any change I could just designate it to be added to the mining fees or a 
> donation to ZmnSCPxj, because ZmnSCPxj is so awesome.
> 
> What swap-on-receive+swap-on-change instead does is just amortize the timing 
> of the CoinSwaps, so that you CoinSwap as soon as you receive, instead of as 
> soon as you have to pay, so that sending payments is as fast as non-CoinSwap 
> onchain wallets.
> 
> 
> Regards,
> ZmnSCPxj
> 

Right, I get it. Good explanation.

In your swap-on-receive example the exchange also can't tell how long
your coins remain unspent in your wallet, which they could in
swap-on-pay. This is very useful information for an exchange because it
tells them about what hodlers are doing, and they might trade against
them. (e.g. opening big short positions right after they see many long
term hodl'd coins being moved)

___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


Re: [bitcoin-dev] Design for a CoinSwap implementation for massively improving Bitcoin privacy and fungibility

2020-06-10 Thread Chris Belcher via bitcoin-dev
Hello Lee,

Thanks for the review.

On 10/06/2020 01:43, Mr. Lee Chiffre wrote:
> 
>>
>> === Combining multi-transaction with routing ===
>>
>> Routing and multi-transaction must be combined to get both benefits. If
>> Alice owns multiple UTXOs (of value 6 BTC, 8 BTC and 1 BTC) then this is
>> easy with this configuration:
>>
>>  Alice
>> (6 BTC) (8 BTC) (1 BTC)
>>|   |   |
>>|   |   |
>>v   v   v
>>   Bob
>> (5 BTC) (5 BTC) (5 BTC)
>>|   |   |
>>|   |   |
>>v   v   v
>> Charlie
>> (9 BTC) (5 BTC) (1 BTC)
>>|   |   |
>>|   |   |
>>v   v   v
>> Dennis
>> (7 BTC) (4 BTC) (4 BTC)
>>|   |   |
>>|   |   |
>>v   v   v
>>  Alice
>>
> 
> 
> 
> 
> 
> 
> Great work Chris and you have my respects for your contributions to
> Bitcoin. A concern I have with bitcoin is scalability and privacy. Both
> are important. The reasons people bash on Monero is also the same issue
> Bitcoin has. The very large transaction size to achieve acceptable privacy
> on a distributed financial network. Im not shilling Monero here. I am only
> saying that bitcoin transactions with similar privacy properties are at
> least equally as large as Monero transactions. Coinjoin on Monero can be
> compared to ring signatures in Monero from the view of using decoys to
> help conceal the source. From this proposal is this to say that
> transactions will be at least 12 times larger in size to achieve the
> property of privacy that bitcoin is currently missing?
> 
> Another thing to consider is that if coinswaps cannot be sent as a payment
> then a coinswap needs to take place after every transaction to keep the
> privacy and unlinkability from your other bitcoin transactions.
> 
> I always thought that CoinSwap would be and is a very much needed thing
> that needs developed. The ability to swap coins with other people in a
> trustless way and way that is not linkable to the public blockchain. But
> how can this be scalable at all with the multiple branches and layers?
> This is a good idea in theory but my concern would be the scalability
> issues this creates.
> 
> Do you have any comments on this?
> Thank you
> 

You are right to be concerned about scalability.

Here's a few of my thoughts on this:

An issue with Monero (or any cryptocurrency based on the ring signature
input signing scheme) isn't just that transactions are bigger in bytes.
Monero full nodes can't know when a TXO has been spent, so pruning is
impossible in Monero and the list of TXOs perpetually grows, this is
unlike in bitcoin where full nodes know if a UTXO has been spent and so
can delete it in pruning. The storage space needed for Bitcoin's UTXO
set sometimes actually gets smaller.

Note that Monero software actually has a feature called "pruning" so
sometimes the terminology gets confused when people say "wait, Monero
_does_ have pruning". But this pruning doesn't do the same thing as
Bitcoin's pruning, the disk space still grows as O(TXOcount) which is
much faster compared to Bitcoin's O(UTXOcount).

And when designing this CoinSwap system I've been careful to make sure
it doesn't break pruning (or other resources saving features, for
example CoinSwap can be made to work with the blocksonly feature of
Bitcoin Core). So bitcoin-with-CoinSwap's scalability isnt anywhere near
as bad as Monero's.

You're right to talk about decoys. Decoys are not a good way to obtain
privacy because they can be broken by repeated interactions.. I really
like this talk about why decoys are not a good solution to privacy in
many cases:

talk: https://www.youtube.com/watch?v=YgtF7psIKWg=youtu.be=3701
transcript:
https://tokyo2018.scalingbitcoin.org/transcript/tokyo2018/how-much-privacy-is-enough

Equal-output CoinJoins also work with decoys. Like in JoinMarket you
could analyze those CoinJoins to say that the inputs and outputs of the
makers in a CoinJoin are actually just decoys. Fixed-denomination
CoinJoins like in Wasabi or Samourai also use much more block space
because of the reduced divisibility, for example Wasabi coinjoins can
only be done with about 0.1 BTC, so if you want to mix 1 BTC then you
have to do 10 such CoinJoins, costing 10 times the block space.

CoinSwap doesn't work by adding decoys, it improves privacy in the same
way as Lightning: by moving information off-chain.

You could perhaps analyze CoinSwap as using decoys if you say that the
decoys are almost every other bitcoin transaction happening on the
blockchain, and that can be almost as big as you want. One full block
has about 3000 outputs, so if you wait a day between the CoinSwap
funding and spending transactions then that's 144*3000 = 432000 decoys
(this calculation is simplified, but it's a good starting point). If
CoinJoin or Monero transactions had that 

Re: [bitcoin-dev] Design for a CoinSwap implementation for massively improving Bitcoin privacy and fungibility

2020-06-10 Thread ZmnSCPxj via bitcoin-dev
Good morning Chris,

> > Let me propose an alternative: swap-on-receive+swap-on-change.
>
> That's an interesting point, thanks for the thought. This scheme might
> not be appropriate for every threat model and use case.
> For example, if someone wants to use bitcoin just as a foreign currency
> for its privacy and censorship-resistant properties. So for example if
> they want to pay for a VPN anonymously, so they buy bitcoins and
> immediately send all of them to the VPN merchant. The swap-on-receive
> wouldn't be appropriate for them because they'll be doing a coinswap
> straight away to the VPN merchant. So perhaps this plan could be an
> optional mode of operation (which may or may not be the default). The
> scheme obviously is useful when bitcoin is being used more as a
> day-to-day money.


No, I think you misunderstand my proposal.

If the user is doing swap-on-receive, the user already has an anonymous UTXO, 
they can just transfer it directly in full to the VPN without using a CoinSwap.

The number of CoinSwaps involved is the same: one.

So the difference is:

* swap-on-receive:
  * I get some coins from an exchange, giving them my contact information and 
bank information and all the places I have ever inhabited in my entire 
existence and an unfertilized egg sample and an archive of my diary and let 
them invasively scan my cognitive substrate.
  * I send the coins to my CoinSwap wallet.
  * The CoinSwap wallet automaticaly CoinSwaps the coins into a new UTXO.
* One CoinSwap.
  * I tell the CoinSwap wallet to send it all to the VPN.
* My CoinSwap wallet knows my coins are already cleaned, so it creates a 
plain 1-input 1-output transaction directly to the VPN address.

* swap-on-pay:
  * I get some coins from an exchange, giving them my contact information and 
bank information and all the places I have ever inhabited in my entire 
existence and an unfertilized egg sample and an archive of my diary and let 
them invasively scan my cognitive substrate.
  * I send the coins to my CoinSwap wallet.
  * I tell the CoinSwap wallet to send it all to the VPN.
* My CoinSwap wallet automatically arranges a CoinSwap into the VPN address.
  * One CoinSwap.

So in both cases the same expected number of CoinSwaps is done, i.e. one.

Note that there are still details like how much onchain fees are and how much 
CoinSwap maker fees are and etc etc but they exist for both flows anyway.
So I would still be buying slightly more than my target amount, and if there is 
any change I could just designate it to be added to the mining fees or a 
donation to ZmnSCPxj, because ZmnSCPxj is so awesome.

What swap-on-receive+swap-on-change instead does is just amortize the timing of 
the CoinSwaps, so that you CoinSwap as soon as you receive, instead of as soon 
as you have to pay, so that sending payments is as fast as non-CoinSwap onchain 
wallets.


Regards,
ZmnSCPxj
___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


Re: [bitcoin-dev] Design for a CoinSwap implementation for massively improving Bitcoin privacy and fungibility

2020-06-10 Thread Chris Belcher via bitcoin-dev
Good morning ZmnSCPxj,

On 06/06/2020 02:40, ZmnSCPxj wrote:
> Good morning Chris,
> 
>> I think I'm having trouble understanding this, does it work like this:
>>
>> Say we're in the 2-party coinswap case (Alice and Bob)
>>
>> We have Alice's funding transaction:
>> Alice UTXO ---> 2of2 multisig (Alice+Bob)
>>
>> And we have the regular contract transaction
>> 2of2 multisig (Alice+Bob) ---> Alice+timelock1 OR Bob+hashlock
>>
>> And you propose a second pre-signed transaction?
>> 2of2 multisig (Alice+Bob) ---> Bob+timelock2
> 
> No, it is:
> 
> 2of2 multisig (Alice+Bob) --(nLockTime=locktime1)-> Alice
> 
> The timelock is  imposed as a `nLockTime`, not as an `OP_CLTV` (so not in the 
> output of the tx, but part of the tx), and the backout returns the funds to 
> Alice, not sends it to Bob.
> This transaction is created *before* the contract transaction.
> 
> The order is:
> 
> * Create (but not sign) Alice funding tx (Alice --> Alice+Bob).
> * Create and sign Alice backout transaction (Alice+Bob 
> -(nLockTime=locktime1)-> Alice).
> * Create (but not sign) Bob funding tx (Bob --> Alice+Bob+sharedSecret).
> * Create and sign Bob backout transaction (Alice+Bob+sharedSecret 
> -(nLocktime=locktime2)-> Bob) where timelock2 < timelock1.
> * Sign and broadcast funding txes.
>   * At this point, even if Bob funding tx is confirmed but Alice funding tx 
> is not, Bob can recover funds with the backout, but Alice cannot steal the 
> funds (since there is no hashlock branch at this point).
> * When Alice funding tx is confirmed, create and sign contract transaction 
> (Alice+Bob --> Alice+timelock1 OR Bob+hashlock).
> * When Bob funding tx is confirmed and Bob has received the Alice contract 
> transaction, create and sign Bob contract transaction (Alice+Bob+sharedSecret 
> --> Bob+timelock2 OR Alice+hashlock).
> * Continue as normal.
> 
> In effect, the backout transaction creates a temporary Spilman unidirectional 
> time-bound channel.
> We just reuse the same timelock on the HTLC we expect to instantiate, as the 
> time bound of the Spilman channel; the timelock exists anyway, we might as 
> well reuse it for the Spilman.
> 
> Creation of the contract tx invalidates the backout tx (the backout tx is 
> `nLockTime`d, the contract tx has no such encumbrance), but the backout 
> allows Alice and Bob to fund their txes simultaneously without risk of race 
> loss.
> However, they do still have to wait for (deep) confirmation before signing 
> contract transactions, and Bob has to wait for the incoming contract 
> transaction as well before it signs its outgoing contract transaction.
> 
> The protocol is trivially extendable with more than one Bob.
> 
> The insight basically is that we can split CoinSwap into a "channel 
> establishment" phase and "HTLC forwarding" phase followed by "HTLC 
> resolution" and "private key handover".
> HTLC forwarding and HTLC resolution are "done offchain" in the channels, and 
> channel establishment can be done in any order, including reverse.
> 
> Indeed, the Spilman channel need not have the same timelock as the HTLC it 
> will eventually host: it could have a shorter timelock, since the contract 
> transaction has no `nLockTime` it can be instantiated (with loss of privacy 
> due to the nonstandard script) before the Spilman timeout.
> 
> Regards,
> ZmnSCPxj
> 

Thanks for the explanation. I understand now, and I understand how this
makes it possible for all funding transactions in a coinswap route to be
confirmed in the same block.

However, I think this also breaks private key handover. Here's why:

Recall that in a Alice/Bob coinswap we have two funding transactions
(Alice --> multisig(Alice, Bob) and Bob --> multisig(Bob,Alice)), and
two contract transactions (multisig(Alice, Bob) -->
Alice+OP_CSV_timelock OR Bob+hashlock and multisig(Bob,Alice -->
Bob+OP_CSV_timelock OR Alice+hashlock). After the hashlock preimage
becomes known to all then Alice and Bob give their multisig privkey to
the other party.

Bob now has both privkeys in the multisig(Alice,Bob) so he can sign any
transaction he wants spending from it, but the contract transaction
still exists. So until Bob actually spends from the multisig he must
always be watching the blockchain, and if Alice broadcasts the contract
transaction then Bob must immediately spend from it using the hash
preimage branch. If Bob waits too long and the OP_CSV timelock value
passes then Alice can steal Bob's money by spending with that path. The
OP_CSV timelock only starts ticking when the contract transaction
actually confirms, and this is crucial for making privkey handover
practical because it means the coins in the multisig can stay unspent
indefinitely.

However, I think this does not apply to the scheme you described which
uses nLockTime, because after the privkeys are handed over Alice's
backout transaction (Alice+Bob -(nLockTime=locktime1)-> Alice) still
exists, and Alice could broadcast it. Once locktime1 passes then Alice
can 

Re: [bitcoin-dev] Design for a CoinSwap implementation for massively improving Bitcoin privacy and fungibility

2020-06-10 Thread ZmnSCPxj via bitcoin-dev
Good morning Mr. Lee,


> > === Combining multi-transaction with routing ===
> > Routing and multi-transaction must be combined to get both benefits. If
> > Alice owns multiple UTXOs (of value 6 BTC, 8 BTC and 1 BTC) then this is
> > easy with this configuration:
> >
> >  Alice
> > (6 BTC) (8 BTC) (1 BTC)
> >|   |   |
> >|   |   |
> >v   v   v
> >   Bob
> > (5 BTC) (5 BTC) (5 BTC)
> >|   |   |
> >|   |   |
> >v   v   v
> > Charlie
> > (9 BTC) (5 BTC) (1 BTC)
> >|   |   |
> >|   |   |
> >v   v   v
> > Dennis
> > (7 BTC) (4 BTC) (4 BTC)
> >|   |   |
> >|   |   |
> >v   v   v
> >  Alice
> >
>
> Great work Chris and you have my respects for your contributions to
> Bitcoin. A concern I have with bitcoin is scalability and privacy. Both
> are important. The reasons people bash on Monero is also the same issue
> Bitcoin has. The very large transaction size to achieve acceptable privacy
> on a distributed financial network. Im not shilling Monero here. I am only
> saying that bitcoin transactions with similar privacy properties are at
> least equally as large as Monero transactions. Coinjoin on Monero can be
> compared to ring signatures in Monero from the view of using decoys to
> help conceal the source. From this proposal is this to say that
> transactions will be at least 12 times larger in size to achieve the
> property of privacy that bitcoin is currently missing?

CoinSwap lets you buy privacy at whatever rate is manageable for you.
You can buy a simple non-routed non-multitransaction CoinSwap, for example, 
instead of larger sections like the above, depending on your privacy needs.
Even doing a non-routed non-multitransaction CoinSwap would help fungibility of 
those doing more complex setups, because the tiny CoinSwaps you make are made 
of "the same things" that the more complex CoinSwaps are made of.

>
> Another thing to consider is that if coinswaps cannot be sent as a payment
> then a coinswap needs to take place after every transaction to keep the
> privacy and unlinkability from your other bitcoin transactions.
>
> I always thought that CoinSwap would be and is a very much needed thing
> that needs developed. The ability to swap coins with other people in a
> trustless way and way that is not linkable to the public blockchain. But
> how can this be scalable at all with the multiple branches and layers?
> This is a good idea in theory but my concern would be the scalability
> issues this creates.
>
> Do you have any comments on this?
> Thank you

Overall, multiple mixing techniques cover a wide range of cost and privacy.

* PayJoins are cheap and almost free (you are coordinating with only one other 
participant who is strongly incentivized to cooperate with you, and making a 
single overall tx) but buys you only a small dollop of privacy (transaction can 
be misinterpreted by chain analysis, but probabilistic analysis can be 
"reasonably accurate" for a few transactions).
* Equal-valued CoinJoins are slightly more expensive than PayJoins but give a 
good amount of privacy (you are coordinating with multiple participants, and 
probably paying coordination/participation fees, but *which* output is yours 
will give probabilistic analysis a run for its money, although it is obvious 
that you *did* participate in a CoinJoin).
* CoinSwaps are a good bit more expensive than equal-valud CoinJoins but give a 
significant amount of privacy for their cost (you are coordinating with 
multiple participants and paying coordination/participation fees *and* you run 
the risk of getting your funds timelocked in case of network communications 
problems or active hacking attempts, but it is hard for chain analysis to even 
*realize* that a CoinSwap even occurred, i.e. it is steganographic).

Chris argues that CoinSwap gives better privacy:cost ratios than equal-valued 
CoinJoins, you can wait and see if he gives more supporting arguments regarding 
this, but overall the various mixing tech exists to give choice on how much 
privacy you buy.

Regards,
ZmnSCPxj
___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


Re: [bitcoin-dev] Question about PayJoin effectiveness

2020-06-10 Thread ZmnSCPxj via bitcoin-dev
Good morning again Mr. Lee,

> > I am trying to learn about payjoin. I have a couple concerns on its
> > effectiveness. Are my concerns valid or am I missing something?
> > concern 1
> > If it is known to be a payjoin transaction anyone could determine the
> > sender the recipient and amount right?
> > Lets assume that everyone has a single utxo because payjoin becomes common
> > use and payjoin consolidates utxos through "snowballing". If Alice has a
> > UTXO of 0.05 btc and Bob has a UTXO of 1.15 btc. Bob can be assumed to
> > have more balance because he is a merchant and his customers payjoin him
> > payments alot.


It is also helpful to remember that Bob cannot exist in isolation, and 
therefore, Bob probably has:

* Employees.
* Suppliers.
* Shareholders.

For example, suppose Bob holds in reserve a 0.05 BTC UTXO in a holding wallet.

Then Bob takes the 1.16 UTXO it got from Alice and transfers 1.12 BTC to the 
holding wallet:

Bob merchant wallet 1.16 --___-- 1.17 Bob holding wallet
Bob holding wallet  0.05 --   -- 0.04 Bob merchant wallet

The above looks exactly like one of the "customer pays Bob" transactions, but 
is in fact different.

Then Bob uses the holding wallet to pay out to employees, suppliers, and 
shareholders, such as in a single large batched transaction, and then leaves 
behind another 0.05 BTC in the holding wallet (or some random small number of 
BTC) for the next time Bob has to pay to employees/suppliers/shareholders.

So the transaction below:

1.16 --___-- 1.17
0.05 --   -- 0.04

*could* be interpreted as the 0.05 owner paying to the 1.16 owner, but in fact 
that is just Bob preparing the incoming funds from the merchant front-end for 
processing to send to its own liabilities.

Regards,
ZmnSCPxj
___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


Re: [bitcoin-dev] Question about PayJoin effectiveness

2020-06-10 Thread ZmnSCPxj via bitcoin-dev


Good morning Mr. Lee,

> I am trying to learn about payjoin. I have a couple concerns on its
> effectiveness. Are my concerns valid or am I missing something?
>
> concern 1
> If it is known to be a payjoin transaction anyone could determine the
> sender the recipient and amount right?
>
> Lets assume that everyone has a single utxo because payjoin becomes common
> use and payjoin consolidates utxos through "snowballing". If Alice has a
> UTXO of 0.05 btc and Bob has a UTXO of 1.15 btc. Bob can be assumed to
> have more balance because he is a merchant and his customers payjoin him
> payments alot.
>
> If Alice and Bob do a payjoin with Alice paying 0.01 btc to Bob, it would
> probably look like this right?
>
> 0.05---> |>1.16
> 1.15---> | >0.04


There are multiple interpretations:

* The 0.05 owner is paying the 1.15 owner 0.01 BTC.
* The 1.15 owner is paying the 0.05 owner 1.11 BTC.
* The 0.05 + 1.15 owner is paying an independent user 1.16 BTC using a 
non-PayJoin transaction (because for example the payee currently has no coins, 
i.e. a new user).

It is this fact of multiple interpretations that is what PayJoin buys you in 
practice.

You could argue that paying 0.01 is more likely than paying 1.11 or 1.16, but 
that still does not give you 100% assurance --- the creators of the transaction 
are still getting the `100% - probability_of_paying_0.01` benefit, and reducing 
UTXO set size as well.

Your assertion that this is "very obvious" only exists because you already know 
that Alice is paying 0.01 to Bob, but that is in fact the very thing that is 
being obscured here.


>
> It is very obvious here the amount sent and the sender. Even if Alice did
> combine another input it would still be very obvious. In this case Alice
> has another utxo with 0.4 BTC
>
> 0.40---> |
> 0.05---> |>1.16
> 1.15---> | >0.44


This can be interpreted as well multiple ways:

* 0.05 + 1.15 is the same owner who wants to merge coins, and is paying the 
0.40 owner 0.04 BTC.
* 0.40 + 1.15 is the same owner who wants to merge coins, and is paying the 
0.05 owner 0.39 BTC.
* 0.40 + 0.05 is the same owner who wants to merge coins, and is paying the 
1.15 owner 0.01 BTC.

You should probably be shuffling the inputs and outputs, or using BIP39 
consistently, so that inputs and outputs do not correlate (i.e. do not 
necessarily group together all of Alice inputs).


>
> This is still obvious that Alice paid Bob 0.01 BTC isn't it?
>
> concern 2
> If there is just one consolidated utxo after each payjoin, would it be
> easy to break the privacy of transaction chains?
>
> Alice---payjoin--->Bob
> Clark---payjoin--->Bob
>
> or
>
> Alice---payjoin--->Bob---payjoin--->Clark
>
> For exmaple, lets say that Alice payjoins to Bob. Then later on Clark
> payjoins with Bob. Based on the payjoin between Clark and Bob, Clark now
> knows what UTXO was actually Bob's. And can then know which one was
> actually Alices. By transacting a payjoin with someone, they could decloak
> the payjoins before them right? If so, how far back the chain can they go?
>
> The issue is not that someone knows the utxos of themselves and the entity
> they payjoined with. The issue is that someone can figure out the payjoins
> of others before them with the same entity.

If Clark can hack Alice (even just read-only access to Alice logs), they can go 
by one more transaction.

If Clark cannot hack Alice, then that is the sole extent Clark knows: Clark 
know that Bob transacted with somebody for a resulting N BTC (which is 
relatively uninteresting, obviously somebody who uses BTC is going to be 
transacting with random BTC users in BTC), without being sure that Bob was the 
payer or the payee in that situation.

Regards,
ZmnSCPxj
___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


[bitcoin-dev] Question about PayJoin effectiveness

2020-06-10 Thread Mr. Lee Chiffre via bitcoin-dev
I am trying to learn about payjoin. I have a couple concerns on its
effectiveness. Are my concerns valid or am I missing something?

concern 1
If it is known to be a payjoin transaction anyone could determine the
sender the recipient and amount right?

Lets assume that everyone has a single utxo because payjoin becomes common
use and payjoin consolidates utxos through "snowballing". If Alice has a
UTXO of 0.05 btc and Bob has a UTXO of 1.15 btc. Bob can be assumed to
have more balance because he is a merchant and his customers payjoin him
payments alot.

If Alice and Bob do a payjoin with Alice paying 0.01 btc to Bob, it would
probably look like this right?

 0.05---> |>1.16
 1.15---> |>0.04

It is very obvious here the amount sent and the sender.  Even if Alice did
combine another input it would still be very obvious. In this case Alice
has another utxo with 0.4 BTC

 0.40---> |
 0.05---> |>1.16
 1.15---> |>0.44

This is still obvious that Alice paid Bob 0.01 BTC isn't it?



concern 2
If there is just one consolidated utxo after each payjoin, would it  be
easy to break the privacy of transaction chains?

Alice---payjoin--->Bob
Clark---payjoin--->Bob

or

Alice---payjoin--->Bob---payjoin--->Clark

For exmaple, lets say that Alice payjoins to Bob. Then later on Clark
payjoins with Bob. Based on the payjoin between Clark and Bob, Clark now
knows what UTXO was actually Bob's. And can then know which one was
actually Alices. By transacting a payjoin with someone, they could decloak
the payjoins before them right? If so, how far back the chain can they go?

The issue is not that someone knows the utxos of themselves and the entity
they payjoined with. The issue is that someone can figure out the payjoins
of others before them with the same entity.


I surely must be missing something here. What am I not understanding?

-- 
lee.chif...@secmail.pro
PGP 97F0C3AE985A191DA0556BCAA82529E2025BDE35








___
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev