read.cash Log in

@cpacia

Joined 5 January 2020 · 2 posts

Lead dev BCHD/OpenBazaar

120 KT

0 KT · $76.75 received · 0 KT · $2.70 given

Posts

@cpacia

New MuSig Implementation in BCHD We've implemented the MuSig aggregate signature scheme (developed by Blocksteam) in BCHD. In this post we'll explain what it is, how to use it, and how we might use this in BCH in the future. https://github.com/gcash/bchd/blob/master/bchec/musig.go https://blockstream.com/2019/02/18/en-musig-a-new-multisignature-standard/ Last May we activated Schnorr signatures on the Bitcoin Cash network. Schnorr signatures have a unique property in that you can create a `m of m` multisig address that looks indistinguishable from a standard Pay-to-Pubkey-Hash address. To understand this consider that Schnorr allows you to add public keys together: `AggregatePubkey = AlicePubkey + BobPubkey` The funds can simply be sent to an address built from the aggregate public key and then when Alice and Bob want to release the funds they each create a signature using their key and just add the `R` and `s` values from their signatures together to produce an aggregate signature. This aggregate signature is valid for the `AggregatePubkey`. The problem with the scheme above is it can be insecure if done improperly. Consider if Alice generates her public key and sends it to Bob, then Bob can set his public key to: `BobPubkey = BobPubkey - AlicePubkey` Then when the keys are added together you get: `AggregatePubkey = AlicePubkey - AlicePubkey + BobPubkey` Which just equals `BobPubkey` and would allow Bob to spend the funds by himself. To get around this problem you have to add more rounds of communication between Alice and Bob where both parties first share the hashes of their public keys and then the public keys themselves. Likewise they have to also share hash commitments for the `R`values in their signatures before revealing the actual values themselves. Last year Mark Lundeberg, Checksum0, and I made a 3 of 3 Schnorr multisig transaction using this scheme. However, the MuSig construction allows users to drop the initial public key commitment round and just share the public keys directly. This makes the scheme easier to use and requires less rounds of communication between parties. You can find an example in Go here. Unfortunately we still need to share `R` commitments because there's a theoretical attack that Bob can do where if he can chose the message to be signed and has access to the Alice's `R` pubkey he can forge an aggregate signature in something like 2^32 operations depending on the number of signatures Alice made. https://news.bitcoin.com/bitcoin-cash-devs-publish-the-first-3-of-3-multi-sig-schnorr-transaction/ https://gist.github.com/cpacia/3dc7d543638f25467a14da59ba74a16a Towards 1 signature per transaction What we would love to do with this is use the MuSig to move Bitcoin Cash from using one signature per input to one signature per transaction. If we used the naive signature aggregation scheme that I mentioned above to aggregate signatures across inputs we would make it possible for anyone to spend anyone else's coins. However, MuSig prevents this by nature of how the aggregate public key is constructed. Consider how a current signature script looks: `<signature <sighash>> <pubkey>` The signature is appended with a one byte sighash flag which tells the interpreter how to hash the transaction. One way we could do this would be to introduce a new sighash flag ― `SigHashAggregate`. When using this flag the signature script would look like: `<sighashAggregate> <pubkey>` So the signature data push would contain only one byte which would be the new sighash flag. The `OP_CHECKSIG` and `OP_CHECKMULTISIG` opcodes would then have to return `true` to the stack without actually validating any signatures. The major change this causes is the interpreter would then need to not only return whether or not the script was valid but it would also need to return any public keys that need to be aggregated and validated using the transaction's aggregate signature. This is a major change to the script dynamics because right now each input is validated independently of all other inputs. This change would mean that is no longer the case and the transaction needs to be validated as a whole. Once the interpreter returns all the public keys, we aggregate them using the MuSig algorithm, then validate the aggregate signature using the aggregate public key against a hash of the entire transaction (minus the aggregate signature). Where Do We Put The Signature? In my opinion it would be ideal to just add an extra field into the transaction: The downside of doing this is it would change how the transaction ID is calculated (because there's an extra field) and any wallets that calculate transaction ID based off raw transactions would need to upgrade to know how to calculate the new ID. But then if we're changing the transaction format why don't we throw in everything plus the kitchen sink into the new format? This could easily get complicated and difficult to get consensus for in a hurry. Alternatively we could just stick the aggregate signature in the first input. It would be backwards compatible but a very hacky solution. Benchmarks Obviously the big win here would be smaller transactions, less bandwidth usage and less storage. In other words, we can pack more transactions into a block of the same size. But what about CPU usage? Musig requires point multiplication when calculating the aggregate public key so it isn't per se faster. It depends on the number of signatures in the transaction. My benchmarks showed MuSig was something like 15% slower for a 2 input transaction and 8% slower for a 3 input transaction. However, 4 input transactions and up are faster to validate using MuSig. The gains increase as the number of inputs increase. I scanned through the last few weeks of blocks in the chain and for transactions which had more than one input, the average was exactly 4. So this would suggest widespread use of MuSig would result in a small to modest improvement in CPU usage. What do you think?

@cpacia

The 253rd "Thoughts on developer funding" Article Generally I try to stay out of community drama and I know another "here's my thoughts on the funding proposal" article is really pushing it, but I will weigh in anyway. The point here is to mostly point out what seem to be serious misconceptions in the community about how software development works. **Developers must submit an itemized list of things they intend to work on and the number of hours it will take to complete each item.** By and large this isn't how software development works. It seems like many people are under the impression that software is just "write once and forget". Software is rarely ever "done" in any meaningful sense. Instead it requires continual, on-going maintenance to keep functioning. For a large, complex codebase like full node software this includes bug triage and fixing, refactoring, optimizations, improving test coverage, paying down technical debt, backporting, code review, and documentation. Code review usually being the biggest bottleneck. Especially in a codebase where if you fat finger one line of code you can blow up the whole system. This generally isn't the type of work you create an itemized list and bill for. For example, bugs come up all the time that are unexpected and not planned for. Libraries you are using publish new versions that require updating, often necessitating changes to the code to conform to a new interface. If you set out to improve test coverage you may end up finding that several modules need to be refactored before you can even begin to write more tests, etc, etc etc. In a thread on Reddit one user wrote that for every $1 in development a company usually spends $4 in maintenance. Not sure how accurate that is, but you get the general point. When discussing funding development people seem to be under the impression that the money will go to adding new features which you can track progress towards. While this will account for part of it, most likely 80-90% will just go to general maintenance. People saying that developers asking for money for this are asking for a "slush fund" or viewing the need for code maintenance with extreme skepticism as if we're just making this up to get free money, is actually borderline offensive. This isn't to say development teams are under no obligation to say what the funds will be put towards. Last year I published the BCHD 2019 feature roadmap primarily so that people who are contributing donations or development time would know what to expect. Note that we only completed 4/9 items on the roadmap due to lack of time. But even there, most of our time was spent on just maintenance of the codebase, not features. **Scaling the software requires more developers** Bitcoin Core has something 12-15 full time equivalent developers (this is just a rough guess by eyeballing github). By backporting commits from Core, a codebase like ABC can effectively get another 12-15 full time developers for free. Or at least almost free as the commits still need to be rigorously reviewed and merge conflicts dealt with. But this is clearly not a viable long term strategy if we want to scale the network as Core has no plans on making the changes to their software necessary to scale. At some point the software *needs* to diverge substantially from Core, but that can't happen as long as ABC only has like 3-4 devs working on it. The more the codebase diverges, the less code can be backported and we lose many hours of free development. To be able to scale the software without worrying about diverging too much from Core requires creating a team of developers that would rival Core's in terms of numbers and quality. **Last Year's Fundraiser** I'm hearing a lot of people asking what was wrong with last year's fundraiser. Or more specifically, what is wrong with voluntary donations? Don't get me wrong, I'm personally grateful to everyone who contributed, but there are limits to how much you can expect to get from a fundraiser. For example, few people might remember but the fundraiser was initially pitched as just a "down payment" with the idea that we might need to do these type of fundraisers more frequently. The 800 BCH goal would likely only be enough to pay two full time developers for a year. Maybe even less than two. If that fundraiser were run quarterly I think we would maybe get close to the ballpark of what is needed, but my impression is we likely got everything we were going to get from the community at that point and turning around and starting another fundraiser right as this one ended likely would not have been well received. And personally, I think it's unreasonable to ask average redditors to cough up hundreds of dollars per quarter to keep the lights on. This also says nothing of the uncertainty developers experience wondering if the fundraiser is going to be enough for them to pay their bills or if they are going to have to dip into their retirement savings to pay rent. Or if they should start looking for a another job. Remember many people who work on these projects often make much less than they would working in Silicon Valley for some large tech company. They do it because they believe in Bitcoin Cash's mission and genuinely want to see it succeed. **Very unhealthy dynamics with Bitcoin Unlimited** A long time ago, well before the Cash-Core split, Bitcoin Unlimited received a large anonymous donation to help Bitcoin Unlimited win the scaling battle on BTC. That battle was obviously not won and we had to fork off. But in the intervening years the Bitcoin price has increased dramatically and they now sit on a war chest of something like $6M. Combine this with a very low burn rate and this creates an incentive to oppose and try to block attempts to fund other development teams as they would be lone group remaining if everyone else packed up and left. **Bootstrapping the network** https://medium.com/@bchd.cash/bchd-2019-roadmap-a6f7371fe76f Imagine if Satoshi released Bitcoin without a miner subsidy. After several years of operation it became clear that not enough people were transacting on the network and the transaction fees that were supposed to be used to secure the network were woefully inadequate. Further imagine that some people proposed creating coins out of this air and using them to pay miners to secure the network in the early days until transaction volume was large enough to sustain the network exclusively with fees. What do you think the reaction of the community would be? Judging by the reaction of many people in the BCH community I would expect a number of people to freak out, rage quit, and/or threaten to fork the network. We didn't have to go through this because Satoshi had the foresight to include this subsidy from the beginning. But it's pretty clear that Satoshi didn't have a similar plan for financing development during the bootstrap phase. Did he plan to stay around as lead maintainer forever? Did he plan on using his 1M coins to partially finance development? Did he assume the early developers would get rich enough from early participation that developers could self finance themselves? It's not clear but, of course, none of that happened. Using part of the miner reward to finance development while the network is bootstapping seems like a reasonable extension of the original concept. The subsidy should not be permanent as at some point one would expect that if the network gets big enough there will be enough large businesses making donations that development would be adequately funded. In fact the current proposal limits it to only six months. People rightfully have concerns about who is holding the money and how it is to be distributed. Some of the proposals to ameliorate the problem have been pretty decent. But the general opposition, if not outright hostility, to developer financing seems very misguided to me. Show me an alternative financing proposal that has an equally realistic chance of success and I'll seriously consider it. But I haven't seen anything other general hostility and suspicion of the developers.