Speakers: Andrew Poelstra
Date: May 11, 2019
Transcript By: Michael Folkson
Noded podcast May 10th 2019
Pierre: Welcome to the Noded Bitcoin podcast. I’m your co-host Pierre Rochard with my other co-host Michael Goldstein aka bitstein. How’s it going Michael?
bitstein: It’s going well, I just hope they don’t ban Bitcoin
Pierre: Any day now. We have a very special guest on today, Andrew Poelstra from Blockstream. Andrew, how are you?
Andrew: I’m good. How are you?
Pierre: Great. Did you hear today’s news about the representative in Congress who wanted to ban cryptocurrencies?
Andrew: I heard a bunch of jokes about it. I’m not on Twitter so I don’t get these jokes.
Pierre: They’ve been flooding in because of this democratic lawmaker from California. What I found interesting was his reasoning which was that these cryptocurrencies, their avowed purpose is to undermine fiat currencies and to reduce the foreign policy advantage of having an US dollar reserve, this global standard of value. In any case that’s not why we’re having you on. If you have thoughts about that we’d be interested in hearing them.
Andrew: It has been a while since we’ve heard that from lawmakers. I feel like in the early days there was a lot of that and then they clued in that there was not actually anything to shut down or anybody to arrest.
bitstein: I just like how honest they are about the nature of the Fed. We’ve gone from Ron Paul being a conspiracy theorist bringing up the Federal Reserve to a sitting Congressman announcing to the world that the purpose of the Federal Reserve is to act as this institution for manipulating a currency for the purposes of foreign policy goals.
Andrew: What is really fun is now we have Congressmen making conspiracy theories about us.
bitstein: Just in time we bring on someone from the reptilian crew itself to talk about the conspiracies you guys have been working on. I wanted to bring you on because of conversations we were having at our Austin meetup where you told me about work that was being done on miniscript. Could you rehash to me but also to the listeners about what miniscript is and what it allows.
Andrew: Yeah absolutely. I am super excited about this thing called miniscript. Let me give a bit of context. Probably everybody listening to this podcast is familiar a little bit with Bitcoin script or at least know that Bitcoin script is this thing that exists. What Bitcoin script is is it’s a language that is used in Bitcoin. There’s an interpreter that Bitcoin validators run. They see this bytecode on every single Bitcoin transaction and the way that coin ownership is assigned, we usually think about it as being signed based on private keys. The ownership of private keys corresponding to public keys and all the coins have some sort of public key associated to them. What is actually happening is a tiny bit more complicated. There is a script that every coin has associated to it and that script is doing something very simple. It is saying “Here is a public key that is embedded in the script. Give me a signature that signs the transaction” and then it validates using this public key. It is one step of abstraction above having just a public key and a signature. It is a script request and a signature. The benefit of this is that you can do all sorts of cool, much more complicated spending policies because Bitcoin script supports much more than just asking for signatures. The simplest example is something like a multisignature or a threshold signature where you have like ten public keys and you say “I want a signature with six of these ten”. This way you can have consortiums of people controlling coins. This is used a lot in practice, in particular the 2-of-3 signature is used a lot. It is used in a standard escrow construction where you have two counterparties and an escrow agent and any two of them are able to sign to move the coins. This is also used by companies like BitGo who act as countersigners to other businesses’ transactions. And companies like Blockstream’s Green, is a wallet that does something similar for ordinary users where the idea is that the service will countersign any transaction. Ordinarily you as a user will spend these coins and you need to ask the service to countersign for you and the idea is that if somebody hacks you you can call up the countersigner and say “Please stop”. That’s your 2-of-3. There is a third key that is in cold storage somewhere. If the service goes under or if they become malicious or if somehow you don’t trust them, you can go unfreeze this cold key and then now you have two keys and you can use those to sign. That’s one example of what Bitcoin script can do, it can do multisignatures. It can also request hash preimages, this is something that is used in Lightning. The way that Lightning payment channels are linked together to form these complicated paths, hop, hop, hop is that one party at the end of a path, in order to take their coins actually reveals the preimage to some hash, some secret that everybody agrees on. They reveal the secret and that allows them to take their coins. The next person in the hop copies the secret off the blockchain or actually copies the secret off the copy of this transaction that people are passing around. You can imagine this being published to the blockchain. You copy the secret off the blockchain and then you take your coins. The next party in the hop takes the same secret. Everybody pulls the coins along. They see the secret being revealed on the blockchain. Bitcoin script enables this. The point of supporting this in script is that you can actually use the blockchain to enforce that the secret is published and that the right secret is published. The third big category of things that Bitcoin script supports is these things called timelocks where you can say the coins are not allowed to move until some amount of time has passed. Finally you can compose these in various ways. You can have this set of signers or a certain amount of time goes by and then this set of signers sign. You can have backups or emergency clauses in your transactions where you have a happy path where multiple people are signing but if somehow those people can’t come to agreement, after a while you get this unhappy path that is allowed to be used. The truth is that not a lot of people are using these in any creative ways. There are a couple of templated special purpose instances of this that are used. Bitcoin Core supports ordinary addresses that you and I think about where there is a single public key that somebody signs. It also supports multisignatures and a couple of other fairly special cases. And then you have something like BitGo’s service which requires multisigning. Or Blockstream’s Liquid which has this giant 11-of-15 multisignature going on with an emergency timelocked backup clause. All of these services have their own individual adhoc code that is handling this particular Bitcoin script and it is figuring out how to arrange the signatures for this particular Bitcoin script. So even though we have this very general thing, this script system that can do all sorts of complicated things, in fact what people actually do is they find some very specific script that they write out, they manually verify that this script makes sense, they manually write a bunch of code that forms this specific script. The result is basically a bunch of fixed templates. The reason for this, I’m finally going to get into what miniscript is here. The reason that the situation is so primitive and clumsy is that it is really hard to reason about Bitcoin script. Bitcoin script was designed with analyzability or ease of reasoning in mind. You can see this in the fact that Bitcoin script does not have unbounded loops, it does not have goto, it does not have various forms of unbounded computation are not part of script. The reason is that you should be able to take a given script and in a finite amount of time be guaranteed to be able to reason about all the different ways it can be satisfied and figure out at most how much a transaction spending these coins cost me or how large could it be. You should be able to do that in a finite amount of time. There are other systems, most notably Ethereum that throw that out the window. They say “screw analyzability, let’s just do everything that’s possible and that way we can write and compile from Javsascript and nobody is going to reason about this because nobody reasoned about it anyway. We’ll just yolo it.” What we’ve seen in practice is that Ethereum developers deploy this and then there are bugs in their code and $50 million is gone. This has happened multiple times.
bitstein: And then they don’t merely talk about re-orgs that they don’t end up doing because it is not possible. They actually go ahead.
Andrew: There are many, many layers of bizarreness to the Ethereum ecosystem that I could talk about but the one specifically I want to talk about is the scripting system being not designed to be analyzed in a tractable way. The thing is that Bitcoin people love to talk about this. We have this simpler script system, it is designed to be analyzable, you can do it in a finite time. In principle all these wonderful things are true but in practice it is actually really hard to reason about Bitcoin script because you can do some pretty absurd things in it. You can have a script that interprets a signature as a boolean where if you have an empty signature that’s considered false, if you have any other signature that’s considered true. You can interpret these booleans as numbers. You can rearrange the stack based on what these numbers are. You can have a script that takes a signature, interprets it as a boolean, branches based on that, reinterprets the boolean as a number and then rearranges that stack element. I’m just making stuff up here but you can do arbitrarily complicated things. I shouldn’t say arbitrarily complicated. While it is finitely complicated it is still tractable. If you try to write a piece of software that will actually reason about these things you’re going to have a bad time. What miniscript is is this whole new language and I’ll explain how it relates to Bitcoin script in a second, it is really quite magical. But basically it is a language for describing spending policies where as first class primitives you have signature checks, you put a public key and to spend the coins you need a signature on the transaction. You have hash preimage checks and you have timelocks. Exactly the three things I talked about Bitcoin being able to do. And then you can combine these in various combinations. You can have ANDs of these, both of these have to be true, ORs, one or both, or you can even have thresholds. You can say three of these five different conditions need to be true. The way miniscript is encoded…. There are two ways to represent miniscript. One is as this tree of ANDs and ORs and thresholds and stuff where you’ve got all these signatures and hash preimage requirements and timelocks and all this kind of stuff. When it is in this tree form it is actually super easy to reason about what’s possible and what’s not. If you want to say “I’m a countersigner and I want to make sure there’s no way that you can spend this miniscript without my signature involved” you can go through every single branch of this script and check that your key is in every single branch. That is very easy to do. When you see an AND you only need to be on one side. If it is an OR you need to be on both sides as either one can be taken. With thresholds it is a bit more complicated but this is very straightforward. This is actually tractable, it is easy to write software to do this. I actually have written software to do this that I might talk about a bit later and we’re starting to use this in Liquid to replace some of our adhoc Bitcoin scripting stuff. So you get all of this nice analyzability, what does it have to do with Bitcoin? There is a second way to encode miniscript and this encoding is actually in the form of Bitcoin script. The resulting script is semantically equivalent to the miniscript. I’m talking about miniscript like it is this tree of ANDs and ORs and policies and stuff but there is actually a way to encode this in the form of Bitcoin script. When you do this there are a whole bunch of different ORs. If you’re reading a miniscript you might be like “Why there is this cascade OR and this boolean OR and all these different kind of ORs, they’re all just ORs.” The reason is that in Bitcoin script there are many ways to do ORs corresponding to the many different OP codes that are available. In some contexts some are more efficient than others. Some might require fewer bytes to encode and the script pubkey and the public key associated to the coins. Others might require fewer bytes to actually spend. Some might require you to put a 0 or 1 to indicate which branch of an OR you want to take. Others might do something more interesting where they try to take the first branch and if that fails then they’ll try to take the second one. That’s what you want to do if you have a happy branch and an unhappy branch. You want to default to taking the happy branch because you want that to be super cheap. With the unhappy one you’re already not happy that you’re taking it so it’s ok if you have to do some inefficient things to access that branch. So being able to encode into Bitcoin script is great. It means we can use miniscript in Bitcoin because you just define this miniscript describing your policy and then you encode it into Bitcoin script, you put that on the blockchain and you’re off to the races. Now you have all this great analyzability that we don’t get from Bitcoin script but that we’ve been promised for Bitcoin script for the last ten years. Suddenly you get that. But the flipside of this is actually super cool. You can even decode Bitcoin script to miniscript and this is where things get exciting. I can take an arbitrary, not quite arbitrary, but all the common script pubkeys on the blockchain. I can take the one that’s used by Liquid, I can take the one that’s used by BitGo, I can take the one that’s used by Green, I can take ones that are used by various escrow services like Bitrated and so on. I can take all of these various complicated scripts that people are using for various reasons and I can decode those as miniscripts. One reason that miniscript has so many different kind of ORs and ANDs and thresholds and so forth is to make sure that all the different constructions in use today are valid miniscripts. Now I can take a script. Remember I just said that if you give me an arbitrary script what can I do with it? Who knows what it is going to do? It might be interpreting signatures as booleans and doing impossible things to break my analysis software. I can just decode it into a miniscript. If that works that’s great. If it doesn’t then it was probably something pretty pathological. One big exception is Lightning HTLCs which are kind of pathological. What they do is they interpret a hash preimage as a public key under some situations and that’s the kind of crazy Bitcoin scripting thing that makes it hard to analyze. Lightning HTLCs need to keep their own adhoc code. But all these more typical long term custody solutions where you have some coins. You have a policy for spending them and you just want to encode that. All of these as they are implemented today, the script pubkeys are valid miniscripts. Now you can take something and this is what I’ve been doing for the last couple of weeks and this is what I was talking to Michael about at this get together recently. You can take some existing script such as the one used in Liquid. You can decode that as a miniscript. Now you have this tree like structure describing all the different spending policies. Now using miniscript software you can say “How do I sign this?”. These are the public keys that I need signatures for and you give it signatures for all of those public keys. It figures out how to arrange them. It figures out how to choose the smallest signatures that are available to optimize the spending witness. If you’ve got too many signatures you can throw some away. You might as well throw away the big ones. If you’re doing stuff like spending the unhappy path, Liquid has an unhappy path that is used if the system shuts down. Miniscript knows how to handle those signatures and knows how to arrange them. This is something that before we had all of this really special purpose adhoc code parsing Bitcoin scripts as byte strings and doing search and replace on it. And manually rearranging stack elements. It was very frustrating, very finicky code. We had a tremendous amount of unit tests doing things like checking the individual length had been encoded properly and there weren’t weird edge cases and stuff. Now we can throw all of that code away and just link to the Rust miniscript library. We can decode our existing system, our existing script pubkey as a miniscript and then for free we know how to satisfy it, we know how to satisfy it in the unhappy case, we know how to estimate how large an input will be when we spend it. Once we put all the signatures in place how big will that be? We need to know this for fee estimation. That is now super easy. We don’t need our own special code for that, we just use the miniscript code. Once we have signatures we can choose the optimal set of them and it will just work. If we want to change the set of participants in Liquid. We have got this giant 11-of-15 multisignature. If we wanted to change the set of participants we would want to guarantee something like the new set of participants needs to be able to sign for the old coins. At least temporarily. Maybe you do multiple shifts or something. The reason being that when you transition a network to a new spending policy, you can’t do it all at once because the coins are actually on Bitcoin, they are real Bitcoins. They need to move. You don’t know how quickly your transactions are going to confirm. Soon they won’t be instant, it will be at least until the next block. You need a transition period to get all of the incoming coins to confirm on Bitcoin and then sweep those incoming coins so they’re controlled by the new policy rather than the old one. I don’t know how we were hoping to enforce this before we started working on miniscript. The problem here is I wanted to make an arbitrary script describing this new consortia. They might be doing really elaborate things. I want to say “The signers who control this script need to be able to control this other script.” I want to be able to say that for arbitrary scripts. With miniscript this is actually very easy to do believe it or not. You just decode both script pubkeys as miniscripts and now you’ve got this tree-like structure it is easier to do this kind of analysis. We can be assured that this is true. Before that we would’ve had to write some really finicky templating code. It probably would’ve been buggy, it probably would’ve done weird stuff. It would have been very difficult for us to write and assure ourselves that it was correct. With miniscript we get this high level assurance. We get the kind of assurance, now I’m not speaking as Blockstream, I’m the Bitcoin community, we in the Bitcoin community have been promising people for years. When we talk down these really complicated, Turing complete scripting systems as being intractable and impossible to analyze, this is in some sense unjustified because we didn’t have that kind of tooling for Bitcoin. It was just in principle possible.
Pierre: This reminds me of two projects that came to mind as I heard this description. One was Simplicity. I wanted to see how miniscript relates to Simplicity because I’m not very familiar with either one. And then Ivy which was also a Bitcoin script compiler that I’ve heard of. Do you want to comment on this?
Andrew: Yeah absolutely. When we talk about why Turing completeness is a bad idea. What this is a symptom of is that there are these two different ways of looking at computation that you can take. You can think of computation in terms of execution, this is known as imperative programming, you have an instruction followed by an instruction followed by an instruction. When you think “I should make this Turing complete” what you’re doing is saying “I want to be able to execute anything that is possible to execute”. Another way you can look at computation is in terms of verification where instead of saying “I have an instruction followed by an instruction followed by an instruction” you say “I have an outcome that I want.” Somehow the computer needs to take some input data, we call this the witness, it is auxiliary data that helps guide the computation and you want some specific outcome to come out of this. This is strictly less powerful than the execution model in a very strong sense. In the sense that when you think in terms of execution you can produce programs where it is impossible to say whether that program is going to complete in finite time given arbitrary inputs. Whereas when you think in terms of verification this is not true. Your verification process is fundamentally simpler than the execution process and you lose a lot of power doing that. You no longer get unbounded loops, you no longer get branches where you can’t tell which one is going to be taken without just executing the code. The thing is that you don’t want that much power on a blockchain. That power serves no purpose whatsoever on a blockchain because when you are spending coins on a blockchain you aren’t asking the blockchain to execute a bunch of code, you are asking the blockchain to verify that you have the authority to move these coins. If you’re just trying to verify something, you’re trying to verify that you have the authority to spend these coins, that is a strictly simpler problem. So you have the ability to use these strictly simpler systems which then you give you all these benefits in terms of simpler analyzability. That’s the theory but the practical problem that you get when trying to use execution oriented languages such as Ethereum and actually such as Bitcoin script, that’s just a series of instructions, is that what you are actually trying to accomplish is verification oriented. You’re actually trying to prove that the coins don’t move unless they were supposed to be allowed to move. Your poor programmers, your poor smart contractors are taking this series of executions and trying to convince themselves that this series of executions somehow cannot lead to a place where these constraints aren’t satisfied. This is just fundamentally impossible. What miniscript gets you is a way of describing programs in this verification oriented sense. Miniscript is very limited, it is very simple. All it supports are signatures, hash preimages and timelocks and it supports arbitrary trees of those. If that’s all you want to support then you’ve got a pretty easy problem ahead of you. But in fact you can support verifying arbitrary computations in principle. To do this you would use something much more powerful than this check some public keys, check some signatures. Fundamentally you need a way to check something like if I add two bits I want the result to correspond to the bit addition formula. If I have two bit strings and I add them in some sense I want the result to correspond to what I know binary addition actually is. This is where Simplicity comes in. Simplicity is a fully general smart contracting programming language that is verification oriented. There are many ways to think about a Simplicity program. One is as the final state of a given computation. A state attached to what the computation is, all of the different paths that might be taken. To spend the coins controlled by a Simplicity program you reveal what branch of this program that you took and also provide witnesses, this auxiliary data that is needed to satisfy what everybody’s conditions of the branch are. If you want to add two numbers rather than saying something like “Here’s two numbers, execute this ADD op-code” what instead you have is a Simplicity program which itself describes the operation of addition going down to the lowest level in terms of bits. Actually it goes even lower than bits. You actually define a bit as being one of two abstract objects. You provide witnesses showing that it is actually possible to instantiate this program in a way that the result is accepting. You get the benefits of this verification oriented paradigm in that it is possible tractably to prove whatever statements you might have to prove. The example I gave is that a countersigner may want to prove that they are involved in every possible execution. Or a person participating in an atomic swap or something like that might want to prove that their counterparty can’t claw back their coins until some timelock has expired. Or anybody who has any coins in some sort of complicated contract will probably want to be able to bound the cost of spending those coins, be able to prove that there is no way anyone can get me into a position where it is going to take some massive multi megabyte transaction to spend. Those are the kind of questions that you can very efficiently answer about Simplicity programs. But because Simplicity is so powerful and so low level it is actually very difficult to use directly. In fact what you typically do is you have somebody like Russell O’Connor, the inventor of Simplicity, defining these addition operators, all these low level things, elliptic curve operations and then he knows using all these magic theorem proving assistants and programs that he has from the verifiable computing world how to rigorously mathematically prove that his Simplicity program is actually equivalent to the mathematical operation you want it to correspond to. Then you get something similar to Bitcoin script where you have these OP codes, they aren’t really OP codes, they’re really full Simplicity programs. You’re just taking them as black boxes. You’re saying “This has been formally proven to be equivalent to the operation I want so I’m going to use that.” This brings us to the third thing you mentioned which is Ivy. Ivy is a much more high level smart contracting language. Ivy is similar in some ways to miniscript, it is a bit more general than miniscript in my understanding. You can do more complicated things than just checking signatures and timelocks and hash preimages. As a result of being a bit more complicated it is harder to answer some of the specific questions that I answered but it achieves a lot of the same high level goals. Ivy compiles to Bitcoin’s script. Here’s the biggest difference between Ivy and miniscript. Ivy compiles to Bitcoin script and in principle it could compile to Simplicity as well. You’ve got some sort of computer program and compiler, that’s taking your Ivy program and it is actually determining an equivalent Bitcoin script program that will have the same semantics. If you want to be sure what the compiler is doing, you’ve got to really squint at it and do all your usual code analysis and rigorous review and many eyes make all bugs shallow, all that good stuff. The code is really well written, it is awesome code but you’ve got to verify and compilers are big and complicated. Miniscript does not compile to Bitcoin script, miniscript is Bitcoin script. It is encoded to Bitcoin script so your translation phase from this abstract tree thing in miniscript to Bitcoin script is you take the tree and you write it down. You see a boolean OR in miniscript. The way you write that down is you encode the left branch, you encode the right branch and use the bool OR operator. You encode that byte, I forget what that byte is, you just stick that byte after your encoding. If you see a signature check in miniscript you encode that by writing the corresponding public key in Bitcoin script followed by the CHECKSIG operator. In some contexts you might use CHECKSIGVERIFY. It is really just an encoding, there is no intelligence, you can do this by hand if you want. If you want to verify that a given miniscript corresponds to a given Bitcoin script you can literally do it by inspection. You can do it by hand, you can write your own software to do it, it is very straightforward. So you get some very high assurance. We really got a lot of value out of limiting miniscript to be such an incredibly simple language. We got this compatibility with existing scripts and we also got this you can translate script into miniscript and back by hand if you’re patient and familiar with miniscript.
Pierre: You’ve mentioned that the use case you’re addressing with miniscript currently is with Liquid and I don’t think we have actually explained what Liquid is and how it works on this podcast. Do you mind giving us the high level summary of Liquid? I don’t want to force you into a two hour lecture about Liquid.
Andrew: Yeah I can definitely talk a bit about Liquid. Liquid is fun. Some days I think it is the most boring thing ever and some days I think it is the most exciting thing ever. I’ll explain why it is boring because that is the short answer. Liquid is a sidechain, it is a separate blockchain, independent of the Bitcoin chain. All of the blocks are signed by a consortium of members who are in charge of maintaining the chain’s forward progress. What makes it a sidechain rather than an altcoin or a private blockchain, whatever things people are using blockchains for, is that it supports what’s called a cryptographic peg. If you want a token on Liquid, a L-BTC you can actually move your Bitcoin from the Bitcoin network onto the Liquid network. The way you do that is that the Liquid consortium, the people responsible for signing these blocks are also jointly cusotodying a whole bunch of Bitcoins. There’s all these L-BTC tokens that are actually proxy Bitcoins and the Liquid consortium is backing all of these. To move coins into the Liquid network you think up an address on Liquid that you want to send coins to, you take the Liquid functionary of consortium members, the Liquid functionary operator’s address, you take all of their public keys and you tweak them in a way that you turn their public keys into a cryptographic commitment to your address. Then you send your coins to this tweaked Liquid address. You publish that to Bitcoin, you wait for it to be confirmed, we require 100 blocks, Bitcoin tends to re-org and sometimes people try to make it re-org in big ways. Then on the Liquid sidechain you make what is called the claim transaction. You say “Hey I want to send these coins somewhere. I don’t actually have coins on Liquid but I have these coins controlled by some address and here is the reference to a Bitcoin transaction where I transferred control of the coins to the federation. Now they should be mined. In doing so, I committed to this address. What happens is that these coins on the Bitcoin blockchain that you moved into the network are basically treated as honorary coins on the Liquid network. In this claim transaction you were providing a cryptographic proof that you did this and then you were spending the coins and moving them to somewhere else. Moving the coins out of the system is much less cryptographically interesting. You do what’s called a peg-out request on the Liquid sidechain where you say “I’m basically burning these coins. I want them back on Bitcoin. Send them to this Bitcoin address please.” Then the consortium who actually controls the Bitcoin will then sign a transaction sending them over to you. That is how Liquid is boring. It is just a giant multisignature, that’s what I was saying internally when people were talking about developing it. I was like “Guys it is just a multisignature. That’s no fun. That’s not why I joined Blockstream to do multisignatures.” I say after spending half an hour talking about miniscript which really is just a giant multisignature (laughs). What is exciting about Liquid is what you get on this blockchain. For the Liquid blockchain, by virtue of being signed you get one minute blocks, you don’t have to worry about re-orgs, that’s nice, it’s kind of cool, business people seem to like that. The cool thing that you get out of Liquid is something called confidential transactions, an extension of confidential assets. On the Liquid blockchain every input and output amount, rather than being an explicit visible amount like it is on Bitcoin, is replaced by a cryptographic object called the Pedersen commitment. This is what’s called a homomorphic commitment. The word homomorphic means that you can add. Verifiers can add up all the input commitments and add up all the output commitments and check that those are equal. When they do so they verify that the commitments are equal so they learn that the transaction did not create or destroy any Bitcoins. It does one better. You have these arbitrary issued assets, you have these other tokens that people can issue on the Liquid network and you can say with any transaction that the validators can confirm that no asset was created or destroyed or transmuted or anything like that but they learn nothing about how many different assets were in play, they learn nothing about the amounts of the individual asset classes and they learn nothing about what this transaction is doing. This means that you can’t identify which outputs are changed which makes a lot of chain analysis much harder. This is something that a lot of your listeners may be familiar with because this technology is in Monero, it is in Mimblewimble, the Grin blockchain which implements Mimblewimble has this confidential transaction stuff. There are a few other random altcoins out there that have this confidential transaction stuff. It originated with Liquid. Blockstream developed confidential transactions for Liquid and then we extended it to the multi-asset case in case you want to do things like atomic swaps, on the same blockchain, of multiple assets preserving this kind of privacy.
Pierre: I think one of the questions at this point that someone in our audience would have would be why don’t we have confidential transactions onchain with Bitcoin but we can have it on the Liquid blockchain?
Andrew: That’s a great question. There are two reasons. One is the efficiency of confidential transactions, the verifier efficiency. For Bitcoin it takes quite a while to sync. If you start up a new node assuming you have a fast internet connection to download the blocks, it is going to take you several hours on a good machine to verify the whole Bitcoin blockchain. It will take you much longer to verify Liquid because you have to verify all these confidential transactions. The verification equation for confidential transactions is much more complicated than the crypto required… there’s not even any crypto required to check the Bitcoin transaction balance. You see the amounts, you add them up, you subtract them. Computers are good at subtraction, they’re not so good at cryptography. In our initial version of confidential transactions we had these objects called the range proofs that were 2.5 kilobytes in size and they would take several milliseconds to verify. I think it was like 4 or 5 milliseconds. They couldn’t really be batch validated so when you have to verify hundreds of them you just have a hundred times as much work. Later we developed with our friends at Stanford, Benedikt Bünz and Dan Boneh and Jonathan Bootle at UCL, a more efficient form of range proof called the bulletproof which gets us down from multiple kilobytes to like 700 bytes and gets us up from 32 bit values which kind of suck, that’s only 600 Bitcoin max, up to 64 bits which is you can have all the Bitcoins in one output. And it’s much smaller and it’s faster to verify. It goes down to 2.5 milliseconds instead of 4 or 5. And you get batch validation so if you have a hundred in a row, the first one will cost you 2.5 milliseconds but all the ones after that will only cost you a few hundred microseconds which is pretty cool. But that is still too slow for Bitcoin. That’s the first reason. There’s a bunch of extra blockchain space required and it’s slow to verify.
Pierre: If they’re willing to pay for that block space then isn’t it acceptable? There’s a market cost.
Andrew: That’s a good question. In principle we could make this optional. We could let people use this if they were willing to pay for privacy. The problem is that in practice ordinary people are not usually willing to pay for privacy. It is easy to talk about how you should be able to go to the store without your credit card company knowing all the groceries that you’re buying, advertisers not knowing where you live and what you’re buying, what you’re interested in and what your politics are. Being able to do have this incredibly rich surveillance infrastructure based on your spending patterns, the truth is that when people are trying to pay their rent, trying to pay for groceries, trying to live their lives, they don’t feel the privacy loss that they’re encountering by using the traditional banking system. Even to the extent that they do feel it, they don’t have the spare money, they can’t add a whole bunch of extra fees to paying their rent just to preserve their privacy in some sense. The result is that if you have a system where privacy is optional, the only people using it are people who are voluntarily using it and willing to pay. The result is that you have a very small anonymity set that consists of people who have very acute privacy needs. People who have political or personal or whatever reasons for needing a lot of privacy. They get correspondingly less privacy because now they’re sharing, when you look at the blockchain you’ll only see maybe 1% of transactions, this is literally what it was on Zcash for the longest time, 1% of transactions are private and you know that 1% of transactions consists of the people who you can get a lot of results out of trying to deanonymize them. Whereas when you have a system where privacy is built in like in Liquid or in Monero or in Mimblewimble, there’s no way to opt out of it, rather if you opt out of it you don’t get some massive benefit, it is not super cheap so people will just use it. Then your anonymity set is now everybody. Not only does everybody get this privacy and you no longer have the ability to create this massive surveillance infrastructure but the people who really need it for acute reasons because they’re hiding from some subset of society that is trying to persecute them, those people now have a much wider net and much more plausible deniability for using this kind of privacy technology. The final reason is that I don’t think you would get a lot of buy-in from the Bitcoin community for optional privacy. I think that there are a lot of very vocal people in this space who are concerned about this and would argue quite passionately that optional privacy is more or less as good as no privacy at all. We’ve seen this in practice with Zcash.
Pierre: We have a listener question which is related to this question of privacy and cost. Stephan asks which upgrades to the Bitcoin protocol have to be made to make coinjoin transactions cheaper than regular transactions. I would generalize that question to you’re explaining how privacy costs more than non-privacy. Are there situations that you can foresee in future where privacy will be less expensive than non-privacy?
Andrew: Absolutely. Right now I think coinjoin is a little cheaper than not using coinjoin because you amortize the version and a couple of other fields. You save like 8 bytes doing that. That’s not real, nobody cares about saving 8 bytes enough to use coinjoin software. There are some future technologies that absolutely will make coinjoin cheaper than non-coinjoin. The one that Stephan might be hinting at here is something called signature aggregation. This is a technology where if we had a more flexible and expressive signature scheme than the ECDSA signatures that Bitcoin uses today, it would be possible to aggregate them. With a Bitcoin transaction, what this means is that when you’re spending multiple inputs and you have a different signature on every single input, you can combine these all into one signature that simultaneously has the effect of all the original signatures. So the resulting transaction would be much smaller because you have one signature instead of one for every input. And much cheaper to verify. And you get more benefit the larger your transaction is because if you can aggregate what is in a transaction of course you can combine all the signatures from all your inputs but you can’t aggregate across transactions. There’s no way to do that efficiently. There are some ways to do it inefficiently like break caching, it causes a lot of trouble when you try to do this. The only way to aggregate is what’s in a transaction interactively. That’s exactly what coinjoin is doing is aggregating all these transactions. Coinjoin does it for privacy reasons to try to eliminate the input/output mapping that is inherent in any transaction. The transaction is an atomic unit, it has some inputs, it has some outputs. If we had signature aggregation then people would be incentivized to use coinjoin even if they didn’t care about privacy at all because it would be materially cheaper for them to do so. To get signature aggregation into Bitcoin, unfortunately that is going to be quite a long time coming. The first step would be for Bitcoin to support something like Schnorr signatures rather than the ECDSA signatures that they use today. The second step would be coming up with a design for the signature aggregation that was simple enough that it could get through the community review process.
Pierre: Schnorr right now is at the BIP stage where we’ve had one proposal come out very recently from your co-worker at Blockstream, Pieter Wuille. But the signature aggregation, that’s pre BIP research. Is that being worked on today by some people in the Bitcoin developer community?
Andrew: Indirectly, yes. All of the work on efficient Schnorr multisignatures and threshold signatures which we will get with ordinary Schnorr signatures, all of the work on that will directly apply to signature aggregation. But we need to complete that work. We need to figure out how to even do regular multisignatures and threshold signatures in a way that is robust against limited hardware and signing in contexts where it is difficult to otherwise have robust protocols. You might have a hardware wallet that doesn’t have any memory. So you can unplug it and replug it halfway through a signing session. You don’t want to be able to replay data against it. You don’t want to be able to give it stale data. There are difficult problems around this that we’re working on now. Those need to be solved before we can start directly working on signature aggregation.
bitstein: This ties into something you were telling me the other day which was that a lot of people get confused about Schnorr because they think Schnorr is just this big package that includes everything and really Schnorr is just a specific signature scheme and the rest of it are things that are built on top of that that require Schnorr as a prerequisite.
Andrew: I can elaborate on that a bit. As you say Schnorr is just a type of digital signature, it is an alternative to ECDSA. By itself, Schnorr is not very interesting. It is a little faster to verify but not very much faster. You can batch verify it but you can batch verify a variant of ECDSA. It has some nice linearity properties that you can do some cool stuff with but those cool things are not Schnorr. If you get excited by Schnorr by itself you might do something like the Bcash folks did and go implement Schnorr signatures as a drop and replacement for ECDSA except that you don’t do it for multisignatures because you haven’t solved the multisignature related problem you need to solve to get the cool benefits. The result is silly. You’re hard forking for the sake of hard forking and demonstrate some sort of weird power trip about how you can make coins unspendable. On Bitcoin you can’t just make them spendable again and have some governance model, that’s what trustless means. If your goal is to make insane claims like that, Bcash has got Schnorr signatures to help out. But if your goal is any of the cool things that we’ve been talking about and the media that has been associated with Schnorr, those are things that require Schnorr to work. There are extensions, there are things that build on Schnorr but they themselves are not Schnorr. Let me talk about the big one that we recently had a BIP draft or proposal for BIP published to the Bitcoin mailing list by Pieter…
bitstein: That was going to be my next question so perfect.
Andrew: This is a joint work. It is primarily Pieter Wuille, Greg Maxwell, AJ Towns and Johnson Lau are the big people behind this. I every so often pop up and whine about things, complain that it is moving too slow and interject with “Why can’t you change all these things?”. Russell O’Connor does this as well, there are a whole bunch of us that pop in and do this. It is mostly those four. Pieter, Greg, AJ and JL. What taproot is is it is a proposal to create a new SegWit output version or a new Bitcoin output version, I shouldn’t say SegWit. It is just a new version of Bitcoin outputs using the versioning system that SegWit introduced where every output instead of being described by a script, remember I was just talking about Bitcoin script being able to do all these cool things, instead of having a script you have a public key. To spend the coins you have to produce a signature with the public key. This brings us to the intuitive model that most people have of Bitcoin where every coin has a key. To spend the coins you need to sign with the key. But wait you might be saying. If that’s what we’re reducing these outputs to that’s ridiculous. You just spent half an hour talking about miniscript and how it can do all these cool things. How can you do that if now you’re just producing signatures. The cool thing is that it is possible to efficiently, interactively produce Schnorr signatures. So you can have a Schnorr signature that has a public key that if jointly controlled by multiple people you could have this 2-of-3 output that are very common for various escrow and countersigning services. You can have the three counterparties or two counterparties and some cold key somewhere. You jointly create a key that’s a combination of all of these. It’s a single key. You can interactively create what’s called a threshold signature where any pair of those three people can come together and interactively produce a signature that will verify with the original key. It’s just an ordinary Schnorr signature. What the signature will be from the perspective of the blockchain verifier is the same as an ordinary person spending their coins. One public key and one signature. You can get thresholds this way. You can get arbitrary combinations, arbitrary ANDs and ORs of different signature requirements just using these interactive signature generation schemes, This by itself gets you some of the power of Bitcoin script, the most common part of Bitcoin script. It gets you this in a very scalable, private way. You can get a huge benefit from using taproot to do this rather than using ordinary Bitcoin script. Because the resulting signature is the same as an ordinary single signer signature, it has the same size and verification cost as any other signature. It is much cheaper and you also get a privacy benefit. People verifying the blockchain can no longer distinguish signatures that were produced by a single person spending their coins from signatures that were produced by a 2-of-3 escrow type service from signatures that are 11-of-15 Liquid spends. You can distinguish Liquid transactions in a lot of ways but you can’t do it this way now. Or signatures that are countersigned by BitGo or other companies like Casa. You can imagine a service that wants to do countersigning but their customers don’t want to reveal that they are using this countersigning service. For people who are widely known targets. You can do this in a way where it would be invisible to the blockchain that you were using this service. You get the scalability benefits and you get the privacy benefits. That’s multisignatures but there are other things Bitcoin script can do. What about hash preimages? I mentioned how Lightning works where you have one party reveals some sort of secret to the blockchain and then the other party copies it off the blockchain and transfers it. It turns out you can do this with taproot as well. There is something called an adapter signature. I’m not using the words Schnorr signature. Before I was talking about threshold signatures, not I’m talking about adapter signatures. These all look to the blockchain like they are Schnorr signatures but they are produced in fundamentally different ways. An adapter signature is a type of multisignature where you have two parties. You can generalize this. Adam Gibson has a way to do this with many parties. In the two party case which is the most straightforward where one party contributes to a signature that is going to hit the blockchain and they do so in a way where the other party promises them that when they complete the signature and publish to the blockchain, by completing the signature they reveal some secret. The way they do this is there’s an interactive protocol where the first party thinks of some secret, they encrypt the signature to their final signature and pass that to the first party. At this point the original party is free to sign it. “Ok you can have your coins. I will sign it and give you your coins”. It is part of the protocol where you don’t want to give the other guy his coins unless you know you’re going to get this hash preimage. But because the other guy gave you the encrypted version of this hash preimage you’re fine. You sign and you give him his coins, you give him a signature. He makes his own signature, adds that to the final signature, publishes it to the blockchain. You look at the blockchain, you see this signature, you do this crazy algebra and you’re able to extract the secret. This works like a hash preimage. You get a secret out of the signature. You can then use that to produce a different signature and go to the chain and link a whole bunch of Lightning transactions. Doing it this way instead of using hash preimages has a bunch of other benefits other than privacy benefits. You can reblind it at every step. Even if you have the same party in multiple parts of a Lightning path that party can’t then link the payments and be able to deanonymize people that way. Now we have hash preimages. We’ve got multisignatures and arbitrary signatures, we’ve also got hash preimages that you can also do where the result is just a single signature. Now you can do much more elaborate things. You can not only do escrow and multisignatures but you can also do Lightning in a way that the resulting outputs just have a key. You spend them with a signature. We’ve offloaded all of this script kind of stuff just into these signatures. The third piece of what people use Bitcoin script for are these timelocks. Doing these in a purely signature sense is very difficult and I don’t really have time to go into some of the research into how to do this. Let’s say you can’t do it, you have to use script. Or let’s say that you don’t want to produce signatures interactively because you have somebody with a key in a safe and they can only access the safe at midnight on a full moon with three werewolves present at a specific cemetery.
bitstein: How did you find out my keys? I’m going to have to go fix my security now.
Andrew: You are.
Pierre: Opsec has been compromised.
Andrew: There was dirt on the back of your shoe and I was able to recognize that exact….
Pierre: Lizards can do mind reading as well so it all makes sense.
Andrew: We’re not supposed to talk about that.
bitstein: Why don’t you guys control Bitcoin so you know where all the coins are?
Andrew: Knowing where all the Bitcoins are even when they’re buried in a cemetery. That’s hard. That’s the one way to hide your coins from Blockstream. To bury it in a haunted cemetery.
Pierre: The interactivity
Andrew: Let me get back to what I was saying. You don’t want to use interactivity because you’ve got people with their signing keys in cold storage. It is difficult to access it and maybe not everybody can access it at the same time. Or maybe you want auditability. You want individual signatures on the blockchain so you can see who exactly signed. This annoys me because you’re using blockchain space but people want to do this. You need to go back to Bitcoin script. Here is the cool innovation of taproot, the second half of what is cool about taproot. The first half is look you can do all these things and you just need a signature. The second half is we can take an arbitrary script, a miniscript or we have a slight extension to Bitcoin’s script called tapscript where we fixed a couple of warts we didn’t like in script. You can take your public key and you can turn that into a commitment to this ultimate script. If you have some coins where you’re willing to do the interactive thing but you need a timelock. You need to say that after some amount of time, maybe the counterparty has disappeared and we need to do this backup thing, then you can reveal the script, you can prove that this public key committed to this script, you didn’t just make it up. You aren’t just stealing the coins. The script has all the semantics you need, it has the timelock, it has the alternate keys, it has whatever weird branches and stuff that you have in the unhappy case. You reveal this script and you satisfy it just the same as ordinary Bitcoin. But if you don’t need to use this, if everybody is online and willing to sign at the same time interactively then you don’t reveal the script and nobody even learns that the script was there at all. For things like Lightning where you need to have some sort of script for this backup emergency policy, you can still have it there, you have it committed inside of the taproot key and you just never reveal it unless you’re doing an uncooperative close. You get the expressivity and the flexibility of having these explicit scripts but you still retain all of your privacy in the case that you don’t have to use it. In most cases there is a happy case where everybody is online at the same time and you don’t need to reveal it.
Pierre: Choose your peers carefully. Find reliable peers for doing cooperative closes.
Andrew: Exactly. The case of cold wallets where you aren’t really moving coins very often anyway so the added inefficiency of revealing this script is not as big a cost to you and the added privacy loss is not the biggest cost to you. All of your day-to-day transactions are happening on the Lightning Network and those transactions never reveal this alternate script, they never reveal that they’re Lightning payments versus any other kind of payment. That’s what taproot is. It gives us a way to do all of the things that people are using script for where in the most common cases all of these different applications of script all turn into just a public key and a signature. They’re indistinguishable from applications where people aren’t using script. That’s very exciting for scalability and verifier efficiency and it is also super exciting for privacy and fungibility. It means that all of the coins that are actively moving around, once people start using this, will be basically indistinguishable from each other, aside from the amount.
Pierre: This does go to one other question from our audience. With what you’re discussing, is privacy a solved problem? You mentioned some of the limitations. By and large would you agree that this solves privacy?
Andrew: No. It solves half of the problem of privacy. That’s a complicated question, I’m not going to try to quantify how much it solves. There are a few major privacy losses or vectors for fingerprinting in Bitcoin. One of which is the way wallets create transactions, how they order their change outputs, what they set their sequence numbers to, a bunch of dumb stuff like that. It is on wallets to try to be homogeneous. Another is the signing policy…
Pierre: Would miniscript help with that if everyone is using one library that is doing everything? How do we get to a world like that? It seems unlikely…
Andrew: Miniscript will actually probably make it worse because it will make it possible to do more creative things. Right now people are doing boring things because doing anything exciting is really hard to do in a robust way. But miniscript will make it possible to do in a robust way and suddenly you’re going to see a lot more complicated policies and stuff like this. In conjunction with taproot and tapscript which I didn’t talk about but that is the Bitcoin script that taproot has committed to, then you’ll be able to do these complicated things but then not still retain the privacy. The aspect of privacy that taproot improves is privacy of what your spending policy is. That’s what we’re touching on with miniscript here. This is not so easy. It is not a matter of improving your wallet software or generating your transaction in a more clever way. If you have coins that are controlled by a specific policy right now you have to reveal that to the Bitcoin network and you have to reveal how you’re using that policy. Taproot eliminates that vector for privacy loss which is great. It means that you’re no longer revealing to the world that BitGo was your countersigner so if people want to attack you they should attack BitGo. Or you’re using some specific wallet who is countersigning or you’re using a complicated sidechain with a consortium of coins. It solves that aspect of privacy. There are two other major privacy losses that taproot does not help with. One is the amounts that are in Bitcoin transactions. Right now when you send coins to people, you create a transaction, you typically send some fairly round number of coins to somebody and then you have to spend a bunch of whole inputs so there will be a specific number that you give back to yourself in the form of change and some other small number that you give to miners in the form of fee. It is very visible what is an actual output going somewhere and what is change. You can develop a very accurate picture of the transaction graph of where all the coins are moving. It’s nice that you can no longer identify people by their spending policies but you can still build the graph and if you know some address belongs to some user of an exchange, say because you work for that exchange or you work for a government that has imposed data requirements on said exchange then you can link some part of the transaction graph to an individual. Because it is a graph you can connect all sorts of other transactions. Taproot doesn’t do anything about that. To improve amount privacy which would mean hiding how much is being sent and what’s changing and what’s not and make coinjoins a lot more effective, you would need something like confidential transactions. That’s a long way away, both for the efficiency reason I mentioned but also for another reason I didn’t get into, if you change the inflation soundness of Bitcoin from the current situation where you can look at every transaction and add up the amounts and make sure they balance to a situation where you have to trust some cryptographic assumption, I would guess that would be a hard pill to swallow for a lot of the Bitcoin community. I personally get kind of uncomfortable with that. Any confidential transaction scheme is going to have to deal with that. There is a third big area of privacy loss and that is the transaction graph itself which is what coins are being spent in an individual transaction. Monero makes some headway on this by using ring signatures but unfortunately at massive scalability cost because you can’t tell what coins have been spent so everyone has to maintain this every growing list of coins that might have been spent and keep referring to it. Or Zcash does a much stronger thing. You choose an individual coin and spend it in zero knowledge. It isn’t one of these three or one of these seven, it is one of any of the coins at some specific block height that you have to refer to. But they have the same problem. You have this ever growing accumulator that everybody has with a huge scalability hit there. Mimblewimble tries to solve this by making Coinjoin super effective but there’s a lot of logistical difficulties with that because now everybody has to coordinate to do these coinjoins and if anybody sees the original transaction before they were joined that’s potentially a privacy loss. And on Bitcoin you can do coinjoins as well, we’ve talked about how these aren’t strongly incentivized.
Pierre: Have you looked at software like Wasabi wallet? Do you have a view on that software or any coinjoin software out there?
Andrew: Not in too much detail. I haven’t really looked at Wasabi, I’ve looked at Joinmarket a little more but not very. I can tell you a limitation of both of these. One reason why they are not widely used beyond the incentive structure not being great is that to use these you have to move your coins into these wallets and these are written by fairly small teams of very privacy focused, very passionate people who are solid programmers and know what they are doing to be clear, but they are still small teams whose code is not super widely used and has been reviewed by massive players with massive amounts of money to spend reviewing code and this is something that scares people. You don’t want to move a tonne of coins into some wallet, being a wallet is this annoying thing that they have to be and not what they want to focus on, they want to focus on being coinjoin clients. The reason that you have to do this is because if you want to produce a coinjoin then you need to connect all these transactions together and then you need to be able to sign the combined transaction. You need to be able to recognize your own inputs and make sure you’re not being tricked into signing for inputs that you didn’t want to include in there. You need to recognize your own outputs and make sure all of those are appearing. That means basically that you have to be interacting with the same software that you’re using. This is the one-two punch of miniscript and something called PSBT. I keep throwing in new terms and we’re already over time. PSBT is an interchange format, stands for partially signed Bitcoin transactions. For transactions that multiple parties have to throw signatures onto. If we’re trying to do a coinjoin we agree on this big transaction, I put it in a PSBT, I attach my signatures, you attach your signatures, Pierre attaches his signatures and one of us needs to take those signatures and put them into the right places of all the inputs. PSBT makes this a little bit less adhoc because now we have a standard format for passing things around but of course we still need to understand how to assemble the signatures, the outputs need to be some specific format that we all recognize and know how to work with. With miniscript suddenly every possible policy that people might be using falls under the purview of scripts that we know how to deal with. Now, maybe I’m doing some weird, complicated thing, I’ve got BitGo countersigning my transactions and I’ve got a Ledger somewhere and we have an emergency back out and all this crazy stuff and I want to coinjoin a transaction spending those coins with you. You meanwhile have a completely separate infrastructure. We combine the transactions. We all attach our signatures and then somebody needs to recognize which signatures go to what output, in what order and whether they need to push 0s or 1s to indicate which branch of some complicated script is being taken. Or recognize whether a timelock has expired and if that’s available. Right now there’s no general purpose software that can do that. You can only coinjoin with the same software which means if you want to coinjoin you need to be using Joinmarket and coinjoin with Joinmarket users or you need to be using Wasabi and coinjoin with Wasabi users. In future you’ll be able to have whatever signing structure you want. Just attach your signatures to a PSBT and then anyone participating who acts in the role of a PSBT finalizer if I’m getting the different roles in a PSBT. The finalizer using miniscript software recognizes what signatures are needed, recognizes when inputs have been satisfied, recognizes how to assemble them and just bang, bang, bang puts them all in the right order and ships it out. It doesn’t matter that everybody involved has their different complex policies. Nobody individually understands each other’s policies, everybody is still able to interoperate in this way. I have very high hopes that as miniscript is more developed… right now to be clear there is a draft on Pieter’s website and I have a Rust library that I keep changing every five minutes, this is really early stage software. We’re using it in Liquid and I’m developing the library in parallel to my use in Liquid’s internal development branch. This will be something that’s much more publicly visible and promoted in the next few weeks and months once taproot has settled down a little bit. I’m very excited about how that is going to change the surface of wallet interoperability and make things like coinjoin a lot more possible for people to do in a compatible way with their….
Pierre: We lost him. Michael are you there?
bitstein: He revealed too much
Pierre: They cut him off, the CIA intervened. Andrew can you hear us?
Andrew: Am I back?
Pierre: Yeah you revealed too much.
Andrew: A tab crashed on me. The last statement was I am excited about miniscript for improving the interoperability of the different wallet software.
bitstein: The one thing I do want to mention is you were saying that it is early stage software but if people didn’t pick up on this I’ll make it explicit, this is barely an encoding and decoding system. It is just software that encodes the script into miniscript and back and because of that it has nothing to do with any consensus steps. You can go use it today. Obviously it is extremely beta software or alpha, whatever you want to call it. This is stuff that can be rolled out as quickly as the software becomes production ready.
Andrew: It is actually even better than not being consensus. The coolest thing is because it is designed so that common scripts can be decoded to miniscript, even as it evolves and we add new things and new features and change things around, the chances are that even if it completely changes you’ll still be able to decode your same old script to whatever the new version of miniscript is. It is actually very robust to changes in the underlying language. As things settle out it is unlikely to break any users as we add things and rearrange things.
bitstein: Excellent. What is the next bit of voodoo that you are going to be working on?
Andrew: I have been spending all my time lately doing miniscript which is so much fun but it is not voodoo at all, it is just Bitcoin script. I would like to get back to working on threshold signatures and adapter signatures. I talked a bit about this. These are ways you can do multisignatures and hash preimages and hide them in transactions. That is something that at Blockstream primarily Jonas Nick has been working on and Tim Ruffing. I would like to get back to helping those guys work on that. What we’re doing there is making these interactive signing protocols more robust to constraints in signing environments. One particular difficulty we have is how do we work with hardware wallets that have very low memory and which can’t necessarily preserve state across multiple signing sessions. How do we prevent doing replay attacks on them where we convince them to give us a nonce and then we’re like “You gave me this nonce, please give me a signature.” And then five minutes later you tell it again “You gave me this nonce please give me a signature” and you’re lying, you’re providing the same nonce twice. This is something that will probably be a research paper that we publish this year, probably in 2020. We have a way to generate nonces deterministically and have the hardware wallet prove I guess to the host but ultimately back to itself that it generated this nonce deterministically. There’s no longer any way that you can replay nonces on signatures on different messages because of the zero knowledge proof tying the nonce derivation to this specific message. This makes a lot of multi-signing protocols much more robust. It makes signing software more robust to things like VM forking and it makes interaction with hardware wallets much more robust to things like plug, unplug glitching or the various ways you can use replay attacks against hardware wallets. There’s a lot of cool new crypto involved in that. Coming up with an efficient zero knowledge proof that is small enough so that it can be produced and verified by a hardware wallet and also accomplishes this goal of being able to generate a uniformly random nonce deterministically without any of the biases that would allow that to cause key loss. I can’t give a timeline on when you are going to hear more about this, it is probably more than six months out because taproot is so exciting and miniscript is so exciting. That is the next thing on my horizon.
bitstein: We’ll have to have you back on in six months time. You’re always welcome.
Andrew: Awesome, I always enjoy doing this.
Pierre: Thanks for taking the time to educate and communicate because it can be challenging sometimes to read proposals and figure out how do I as a human and a node operator, what should I be looking at because I don’t know math and there’s a lot of math involved.
Andrew: Yes there is.
bitstein: So where can people go to learn more about miniscript? My recommendation would be reading BitcoinOps, searching for miniscript in that. Is there a BIP?
Andrew: There is not a BIP. I think we probably will propose one once we finalize it. It would be one of those weird BIPs like BIP 32 where there are no consensus requirements, like BIP 49 which I think is just a word list. It is just a BIP because that is where you write it down. The Bitcoin Optech newsletter is the place to follow it if you want to watch it change. You can show up on IRC and bug myself. I’m not going to say bug Pieter because he gets mad when I tell the public to do that but come bug me. I always love talking about this. Or also you can see this demo of a compiler that Pieter wrote from this high level policy language in miniscript. You can find that on his website bitcoin.sipa.be/miniscript/miniscript.html. If you go there you can play with this and see what miniscript looks like, what the script fragments are and how they all fit together.
bitstein: We’ll include that in the show notes.
Andrew: Wait until probably it is in Bitcoin Optech when we have some more public ready stuff to show.
bitstein: I know they have mentioned it already so there is some literature that people can look at. Beyond that where can people find you online? Where on IRC?
Andrew: I am andytoshi on IRC. I am on a bunch of Bitcoin related channels on Freenode including #bitcoin #rust. I am on irc.mozilla.org for as long that lasts which is like two weeks. I’m on OFTC on the Rust channel, I think that’s it, I think that’s all the servers I’m on. My nick is andytoshi that’s probably the only way to find me online.
bitstein: It is apoelstra on GitHub correct?
Andrew: Yes that’s my GitHub. You can watch my development of the Rust miniscript library there.
Pierre: Can I fit in one more question? Why did you pick Rust?
Andrew: That’s a big question. Rust is very fun to write code in. When you’re writing Rust code it feels very explicit what you’re doing. Stuff like conversions between integer types or casts or duplicating data is very explicit. You have to explicitly promote integers to wider integers. You have to explicitly copy complicated data. You have to explicitly convert a hex string into a script or into a byte string or whatever you might be doing or into JSON. You don’t have to see a whole bunch of types everywhere in front of you. The type system is extremely expressive. You have in the programming language world, you talk about sum types and product types. A sum type is something where you have a structure that might be one of multiple alternatives. A product type is just like a struct where you have a whole bunch of things all packed together. The result is a language that feels extremely expressive but where you have all of the information in front of you when reading code and none of the information that you don’t want in front of you. There’s even some ways that it does similar things like having every variable constant and immutable by default. If you’re worried about what a variable is doing, you can glance up to where it is defined and your function signature as an argument, you see the word “mutable” is not there, it is not changing on me. I don’t need to scan the rest of the function to see where it changed or anything like that. If I have an if statement I know that what goes into that if is a boolean, it is not a number which is false if its zero. In C, the literal zero is a valid instance of every single built in type in C. It is a valid integer, it is a valid enum, enums are not built in, it is a valid pointer, it is a valid float. It is absurd, it is absolutely absurd. Software uses zero as a return code so if you were trying to detect an error and you try to compare against zero, you’ve spent all your time trying to convince the compiler to not let you silently convert every single other type to the number zero and have it signal bugs. It is very fiddly. I feel like Rust simultaneously will prevent those kind of annoying bugs. It will make you enforce all the invariants that you want to be enforced to be able to read your code and be confident in your understanding of it whilst still feeling super expressive. It is very easy to express ideas and you don’t feel that you’re always writing hundreds of lines of code to build infrastructure that you feel ought to be built in. People talk about the compiler haranguing them all the time but I find that once you get over that learning curve and internalize the memory model that it uses it feels like it is very easy to read code and very easy to reason about code.
Pierre: That’s a great sales pitch. This podcast brought to you by Rust. Go try out Rust and that way you can help contribute to miniscript.
Andrew: Contributions are welcome. I love to find people using this.