Libsec Panel
Speakers: Jonas Nick, Tim Ruffing, Lloyd Fournier, Jesse Posner, Rijndael, NVK
Date: September 8, 2023
Transcript By: fjahr via review.btctranscripts.com
Tags: Libsecp256k1, Schnorr signatures, Threshold signature
Media: https://www.youtube.com/watch?v=8Z79CeBw3Nc
Intros
NVK: I have an absolute rock star team here. So why don’t I start introducing the panel? Tim, hello! Do you want to tell a very brief what do you do?
Tim: Yes, so my name is Tim Ruffing. I am a maintainer of the libsecp256k1
library. I do work for Blockstream, who pay me to do this and also who pay me to do research on cryptography and all kinds of aspects related to Bitcoin.
NVK: Very cool. So full time cryptographer, implementer.
Tim: Yep.
NVK: Living the dream, sir.
Tim: Full stack cryptographer.
NVK: There you go. Amazing. We’re going to get into it. Jesse Posner.
Jesse: Hello. I am Jesse and I’m an open source Bitcoin developer. I’m currently working on a implementation of a threshold signing system called FROST in the libsecp256k1-zkp
repo.
NVK: Hello, sir. And Jonas.
Jonas: Hello. Similar to Tim, I work at the Blockstream Research Group. And as he said, we work on the full stack from research papers over to BIP specifications like MuSig, Taproot, Schnorr signatures, etc. And then we also implement these things in one of our libraries like libsecp256k1
and variants thereof.
NVK: Very cool. Lloyd.
Lloyd: G’day, guys. I’m Lloyd. I’m another Bitcoin cryptography enjoyer. I have my own little secp256k1 library in Rust, in pure Rust, that I try and implement the stuff that Jonas and Tim come up with and other things, yeah.
NVK: Very cool. Rijndael, welcome back.
Rijndael: Hey, great to be here. Yeah, I work on end user applications, mostly around custody and privacy. I’m kind of downstream of all these guys. I consume the stuff and I work on, you know, how do we use various like threshold signature schemes for better and more accessible self-custody tooling? And how do we use things like signature adaptors to do interesting off-chain protocols?
NVK: And I guess me in this case is just I am a libsecp256k1
consumer. We moved to libsecp256k1
on code card and just general thankful for having a sane, well-reviewed, well-implemented library. So I wanted to do this and talk to you guys. So I guess, why don’t we start from the beginning here?
Importance of libsecp
NVK: Why is it so important to have a, let’s call it like a master or more used crypto library for the Bitcoin primitives? Who wants to take that one? Go for it, Jesse.
Jesse: I mean for one, if your crypto library fails, it’s a fairly catastrophic event. It probably has like the most security critical or among the most security critical code paths that are used in Bitcoin. Your Bitcoin is only secure as your private keys and if those leak you’re in trouble So we really want our cryptography to work and to be well reviewed and highly scrutinized and battle tested and all that stuff.
NVK: Great.
Rijndael: Yeah, I think also like getting cryptography implementations right is really hard. You know, the math is really complicated, but also there’s a lot of implementation details that can be really subtle. So, you know, if you use some hand-rolled or less reviewed cryptography library, it might get the details of the actual underlying algorithm correct, but there might be something where, you know, like the compiler optimizes away some constant time operation and now you’re like leaking bits of your key or bits of your nonce out through some timing or you know, differential power side channel or something. So you really want to have, you know, a relatively small number of commonly used crypto primitives that everybody focuses all of their scrutiny on. And we kind of scare out all of the weird implementation details so that we have a high degree of confidence that it’s correct and that it’s going to operate in an adversarial environment.
NVK: Would you say that the most industry standards is for most vendors to share the same crypto library and build their business logic on top so that if you have competing vendors using the same library, everybody sort of gains from that?
Rijndael: I mean, that’s definitely what you hope. It doesn’t always work out that way, like there was… Tim can probably give the details. There was a recent libsecp256k1
update that fixed a potential side channel that was caused a GCC optimization, right? So there’s little things like that, that if you have some small homespun crypto library that three developers are working on and nobody’s looking at, like you’re never going to find stuff like that. The cryptography behind Bitcoin is probably the most battle-tested, I’d argue the most battle-tested ECC library in the world at this point. There’s a really, really big bug bounty out there for finding issues in it. And so having lots of people use that library means that everybody benefits from that half trillion dollar bug bounty.
NVK: Yeah, we’ll get into the details. So let’s just start with a little bit of prehistory here. So who wants to speak to how was ECDSA done before on Bitcoin Core and why is it that was not sort of like something that other people could use because it was part of Bitcoin Core? Guys, feel free to jump in. Don’t be afraid of interrupting and coming on.
Jonas: I mean, before libsecp256k1
, the cryptography side, in particular, ECDSA in Bitcoin Core was handled by OpenSSL. And that was a thing that Satoshi started out with, but it turned out that this approach has quite a few problems. One of the most important ones would be that OpenSSL was not built for consensus critical applications, because these sort of applications did not really exist before Bitcoin, at least not to an extent that Bitcoin introduced. So it could happen that in a patch release of OpenSSL or a minor release, that there are some incompatibilities which usually might not in normal applications will not really have an effect because this thing would fix some sort of edge case that no one would ever stumble on but as soon as you use these things in Bitcoin it could happen that there would be a fork, a chain split between users of the newer OpenSSL library and users of the older OpenSSL library and that was one of the reasons why libsecp256k1
was created. And I want to push a little bit back on the idea that this is sort of a master library or whatever for the Bitcoin ecosystem. I think maybe it’s turned out that way, but initially it was just for Bitcoin Core. And this is also why this is such a trusted library, because there’s a lot of effort, of course, going into review.
Tim: Yeah, I think at the moment it’s a bit of both. So we are a subproject of Bitcoin Core, so our main customer in a sense is Bitcoin Core itself, but on the other hand, we want to target basically everybody who can make use of a C library. Because we think that it’s a really good library. I also wouldn’t call it, I don’t know, master or anything like that. We believe it’s high quality and that’s why we want people to use it.
NVK: I mean, in classic Bitcoin matter, we don’t want to say anything is the standard, the default or the master per se. But, you know, that’s us just sort of being Bitcoiners and you guys being humble. But realistically speaking, this this is becoming - the master is the wrong word to use because it implies that it must be used - but it is the default library that people should seek to use.
Rijndael: Well, it’s a reference implementation, right? And like, I spent a lot of time working in Rust. I use the Rust bindings for libsecp256k1
because I need to interoperate with Bitcoin. And you know, if it uses the same library as Bitcoin Core, like I’m probably going to be producing signatures that are going to be validated correctly by Bitcoin Core. Right, like it’s the reference implementation.
Why libsecp256k1
was invented
Jonas: Yeah, right. And the other reason why libsecp256k1
was invented sort of mainly by Pieter Wuille, Greg Maxwell and Andrew Polstra was that, so OpenSSL is a library that is very flexible and has implementations of various different cryptographic schemes, including different curves. And this group of Bitcoin wizards, they realized, well, if we only focus on one curve, then maybe we can make it much faster. Verification and signing in the case of ECDSA. And of course, verification is extremely important. That’s what all nodes do. That is impacts decentralization, it impacts resource requirements. And well, it turned out that their hypothesis was correct. So libsecp256k1
is much, much faster for these operations than OpenSSL.
Tim: And it’s not only about performance. I think it’s also about simplicity, right? So if you focus on a few primitives and try to get them right with exactly one curve, so basically exactly what is needed within Bitcoin Core and maybe a bit of divider ecosystem. Then also you can focus much more on code quality because there’s fewer things to maintain and APIs get simpler. And yeah, OpenSSL is just a different beast because it’s larger and it’s a, as Jonas said, a bunch of different use cases.
Lloyd: Out of interest, do you have actual benchmarks of how much faster is now than it was when it was on OpenSSL?
Tim: Oh, I mean, I guess we had those. I can’t tell you right now, but it’s, I don’t know. I’m not going to say a number. A lot faster, maybe Jonas knows more. I don’t know.
Jonas: Yeah, same here. It feels a lot faster.
NVK: OpenSSL is an absolute disaster too, right? I mean, it’s like this massive, massive library that is very hard to review, very hard to maintain, and it could have a lot of blind spots there.
Tim: No, I mean, it would be careful to call it a disaster, right? It has a different, not really, I mean, it has a different audience. It’s a huge code base, it’s older, and it was for a very long time, it was underfunded.
NVK: Fair enough.
Tim: They all, we all have the same problems. It looks like I guess we were lucky, but also because we didn’t have really vulnerabilities so far, or real actual vulnerabilities, except for maybe a few constant time issues that we quickly patched out. But in the end, we all have the same techniques, right? So we have less code and it’s easier maybe to review and we have spent more time on review, but the OpenSSL guys are writing a good library.
Rijndael: I think it’s also easier to use correctly, right? Like OpenSSL is like a big library. It does lots of things and it can be really difficult to use, you know, APIs correctly and like know what the right set of options are. Having a library that’s really targeted at kind of the Bitcoin use case gets rid of a lot of foot guns in the usage of it
NVK: Yeah, I don’t know. Like I feel like a lot of this very massive crypto libraries tend to be messed with by state actors, not in terms of just like, you know, adding a hole to it. That’s not the point. They don’t, well, they try to do that, but they don’t accomplish that that often, but they master them on a social level. They try to fuzz some of the consensus finding between maintainers and there’s more room for things to happen. But like moving on to libsecp256k1
, I mean, you know, it is nice that, you know, originally you guys only had to do a ECDSA and now, you know, we’ve added Schnorr.
The process of adding Schnoor
NVK: How was the process? How do you guys feel the process was like adding this second big crypto primitive in there?
Jonas: So luckily the Schnorr implementation is not all that difficult once you have an implementation of the curve that you can trust. So a lot of effort went into writing the specification and the BIP, maybe much more than the implementation itself, because for the BIP already, you need to define what exactly are the Schnorr signatures, how do they look like, there are a lot of possibilities for bike shedding of course, And also you already have to think about all the different edge cases that can occur because in these BIBs, there’s often also a reference implementation that we had to do. The one in BIP Schnorr is in Python. And we also have a set of test vectors that wasn’t that easy to create, because that one really tries to exercise as many edge cases as possible, because of course we want the BIP to be written in a way such that it’s very hard to mess up when you actually implement this. And this also helps us, of course, if we implement it in libsecp256k1
later.
Tools and testing
NVK: What tools do you guys use when you’re sort of exercising and testing every part that you’re implementing?
Tim: I think one possible answer here is that our main tool is called Review. I think this is maybe what makes the library stand out a bit is the effort and time we spend on reviewing code is probably very high even for a crypto library. So we, I don’t know, sometimes we spent hours and hours on, I don’t know, 10 lines of code. For example, we spent some hours on the Schnorr implementation even when the BIP was mostly done. As Jonas said, this is not a lot of code actually but we keep thinking about it and look at it, comment and try to improve things before we merge it. But if you ask about real tools we do a lot of simple testing mostly on CI but also locally so we have automated testing but also local testing on our development machines and one notable thing maybe there is that we target on a wide range of platforms. We test on different operating systems, we test on different CPU architectures, we test with different compilers. And on top of that we use a few tools like static or dynamic analysis tools for example, Valgrind is a tool that targets binaries that helps us to find memory issues and also constant time issues and we have a tiny bit of formal verification in the library for example some of our formulas for the curve are actually formally verified, but that’s only a tiny bit. We try to add a bit more, or at the moment we’re trying to add a bit more formal verification, but at the moment it’s mostly pure code review and higher development standards.
NVK: What are some of the, oh go ahead Jesse.
Jesse: Yeah I was just gonna say I think the Valgrind tests are particularly interesting because as far as I know I don’t think Valgrind was built to test for constant time, but for memory issues, it can check whether you’re branching on uninitialized memory. But it turns out, that’s also what you need to check for constant time. So you can set a secret value as uninitialized in your Valgrind test and then check if there’s any branching on it. But I’m not sure if that’s used anywhere else for Valgrind or if that’s just like a libsecp256k1
thing.
Tim: No, no. That’s used in other libraries too. I mean, I think we maybe do the most testing in that respect because we use it on different platforms, etc. But this is nowadays a pretty well-known trick and it works exactly as you described it. So, Valgrind is actually a memory checker and what it can do, it can tell you when your code, your final binary branches on uninitialized data. So, if there’s an if statement that depends on memory which is not initialized. And of course this is a problem in production. The trick now is you can tell it to consider any memory uninitialized. So you can tell it not to report branches on uninitialized data, but also branches on secret data. And this is exactly what you want to avoid in this constant time programming, to make sure you don’t have timing side channels. And this is kind of an abuse of Valgrind but it’s basically from the technical point of view, it just does its job and we place the word uninitialized by secret and everything works out.
NVK: Very cool. For the people that don’t know, libsecp256k1
is written in C, which does require more memory management, but you gain everything else that C gets you. Jonas, you were going to comment there?
Jonas: Yeah, I wanted to mention maybe a few other tools. So one thing that is also important for us is that when we run the test suite, that basically all lines and all branches of the code are covered and exercised by this test suite. So we use a tool or a set of tools in the coverage for coverage analysis, which shows us, okay, with this set of tests, we’ve actually reached these lines, etc. And we try to reach as many lines as possible. Some lines of code are not really possible to reach. They are cryptographically impossible. It would be hard to find such an input or impossible, presumably, or hopefully even to find such an input. And then we look, okay, how good is this test? Or do we need an additional test to exactly exercise this line? And how would we create this test? So this is called coverage analysis. And another way to also produce test vectors is through Fuzz testing. So we don’t have a Fuzz testing harness right now that you could run and just Fuzz test certain functions, but some of the test vectors were generated with fast testing, also using coverage analysis to find interesting test vectors and then just hard code them into the library. And then one other thing that comes to mind is what we call exhaustive tests. So on the curve secp256k1 there are of course a lot of points and that means there are a lot of public keys and secret keys and we cannot really test all of them. Of course that will be impossible, but it turns out there’s a smaller curve that we can use that can also exercise most of our code. So it works on most of our code, but the difference is that there are only very few points on that curve, like depending on their multiple such curves, like could be seven, say there are seven points, and then of course you can test all public keys, Can they create a signature and can such a signature be verified, which I think is also a very interesting test that you can do.
Tim: And this is, by the way, something that only we do. I haven’t seen this in another library. We mentioned this a few times to other library developers and they’re interested, but I’ve never seen anyone else use that technique. So that’s kind of, yeah, signature of libsecp256k1
.
NVK: Very cool. I mean, Bitcoin is a unique project, right? I mean, it’s very rare that you’re going to have a whole network be based on something and the validation be done by every peer. And you be verifying signatures of every single interaction that every peer has on the network. It’s kind of crazy when you think about it.
Most interesting thing writing the library
NVK: Guys, what’s the most interesting thing that you found writing this library? So like for each of you, so Tim.
Tim: Whoa, that’s an interesting question.
Jonas: I have something if you want you can get some time to think.
Tim: Yeah, give me some time. I’m not sure if I can come up with something.
NVK: Go ahead, Jonas.
Jonas: So one of the interesting things that I find is that there are still better algorithms that have recently come out for relatively primitive operations. So you would think that taking an inverse of a number in a field is sort of a solved problem for many years. And there’s one algorithm that you just use and that’s the fastest one and presumably there’s no has not been a faster one in the last 30 years and similar for taking a square root of a number or something because it sounds so easy but actually that is something that we’ve continuously made progress on. That’s amazing. Finding faster algorithms for these primitive operations and implementing them.
NVK: That’s a very interesting thing. I did not think of that. You would think that the square root has been resolved like an optimized to death, but clearly hasn’t. Go ahead Lloyd.
Lloyd: I had a question just on that point. Like, so all these little interesting, fascinating improvements come out in various parts of the arithmetic in the elliptic curve cryptography. Given that the library is so crucial for Bitcoin, do you sometimes hesitate about using that latest paper to do that, that optimization, or you’re like, no, this is from what it looks like, it looks like you guys go, okay, that looks good. And then you write your SageMath proof out and then you become confident and then you go. So it’s a bit more responsible than what I was suggesting Just wondering how you approach that problem.
Jonas: Right. Yeah, that is a good question. And I think, again, it comes down to these multiple things that are into play where we have a lot of code review and testing. And also for these particular things, especially in the past year, there were also some of these formal verification efforts where you can prove that a certain algorithm has certain properties that will terminate and that will actually output the inverse of something. And if you see a proof, a computational proof that you could run on a computer, not written down on a piece of paper, then that seems to be pretty convincing that this algorithm actually works.
Tim: But yeah, it’s indeed a very interesting question, I think, because the code base is very well tested and we have a bunch of contributors who come up regularly with nice performance improvements, including Pieter himself, but also Peter Dettman, who is a maintainer of Bouncy Castle, the Java crypto library. And yeah, it’s an interesting trade-off, right? You get like, okay, maybe you get a potential 2% performance improvement, but you need a lot of time to understand the algorithm before you’re confident to replace the old algorithm. And that’s why we had, like Jonas mentioned, in recent big overhauls we really used formal verification for example and the safe GCD implementation, one algorithm for GCDs we had support from Russell O’Connor who wrote a Coq proof that shows that the algorithm is correct, which run for a month, I think, before it terminate. So before Coq, the proof assistant terminated and told us that the algorithm was hopefully correct. That’s a huge amount of effort. And also the algorithm came with us. So Pieter wrote the code, but he also wrote a very long markdown document detailing all the implementation choices and basically from building up the algorithm in Python or in pseudocode from the bare algorithm to all the tiny optimizations such in the end, you only need to understand the Python optimizations in the end, check that the Python matches the C code. So that was really a huge effort there.
Jesse: I’m really interested in this kind of formal verification in terms of thinking about the future of tooling. I remember Jonas gave a great talk on hacspec, and it’s, I think, interesting to contemplate how we might write this code in the future because there’s a work or hacspec is a is a subset of Rust and it you can have a really interesting workflow where you write a cryptographic specification in hacspec and then you can implement the component in a special language that allows you to prove that the implementation meets the specification and then the verified code can be compiled to high performance like C code and so you can get this really nice assurance that the code you’re writing is actually consistent with the specification that you’re trying to implement.
Jonas: Yes, right. I think formal verification that’s a very important topic and you mentioned the future of tooling. It would be really nice if that was the future of tooling. Right now, these tools are still very hard to use. And I mean, there are a lot of specification to actually produce proofs that your program actually matches some sort of specification. And hacspec, this subset of Rust that you mentioned, doesn’t do all that much. It’s just a language for writing a specification, which can be read not only by proof engineers, experts in Coq or whatever, but it can be read by regular programmers, hopefully. And you can use this specification and you can compile it down to languages that are suited for formal verification, such as Coq. And then you could try to prove that the C implementation that you have actually matches this Coq specification that was compiled from the hacspec. Right now, the way this would work is that, or at least according to the work that Russel O’Connor has been done on the library, you have some C code and he writes a specification in Coq what the C code is supposed to do and then he proves that these two are equivalent. And he’s done that for some small parts of the library so far. And hacspec would give you this additional ability to have something that is readable for the average programmer, or maybe slightly above average programmer, I don’t know. But at least it doesn’t mean that we have to add Coq to our specifications. But I think it’s an improvement over having Python in the specifications like BIP Schnorr right now or BIP MuSig.
Wrappers and vendors integrating libsecp
NVK: So how do you guys feel about all the wrappers and the stack that people use on top of libsecp256k1
? I mean, we have a Python wrapper, LibNgU. For example, there is like all the JavaScript kids doing, I think it goes to Rust and then JavaScript and then WASM. And there is a lot of serializing, deserializing, serializing, serializing that happens in some of these. And I guess like a lot of the attack surface comes from people using the APIs correctly and not leaking things as they come in and out of the library. Do you guys interact a lot with vendors integrating libsecp256k1
?
Tim: Basically not at all, which is a bit sad. Not at all, I guess, is wrong. Sometimes we often don’t even know our users. And also we often don’t know what bindings exist. And sometimes I stumble upon projects that use lipsecp256k1
and then I see that they have some strange hacks to get our code working and I then think, okay, why didn’t you just talk to us, open an issue and maybe we could have looked into it. So really, I would, of course it means work for us, but I would appreciate if actually users and also other libraries, wrappers, whatever, talk more to us and reach out to us if they think something could be improved or there needs a certain API or whatever. That’s my feeling at least.
NVK: So you want to interact, but within a limit. It’s like, I want to know what you’re doing, but please don’t email me too much. Some conundrum of library makers, right?
Tim: Yeah, a colleague at Blockstream told me, oh, don’t have users, don’t do that. It’s a mistake. So, well, you know.
Jonas: The answer for me is the same as Tim’s, but also when I look at these wrappers, it often is the case that they wrap very old versions of libsecp256k1
, which is in general maybe not such a big problem, except of course they miss features, maybe improvements, but faster than the newer versions. But we already mentioned that there was a potential side, two potential side channel issues in the last six months. And we tried to communicate this as good as we could. We made a release, we wrote an email to the bitcoin-dev mailing list and then we later realized no one had really updated yet. So either they didn’t know or they didn’t think that this could actually be a problem or they don’t care or these wrappers are unmaintained. And it is still the case, I think, that a lot of wrappers have not updated yet. So I think this could be potentially a problem in using these wrappers for accessing libsecp256k1
, especially if you use more than one wrapper, like Rust, JavaScript, that sounds a bit insane.
NVK: That’s a lot of wallets out there. So like, have any conversation happened in terms of like maybe developing more sane bindings or wrappers for different languages?
Jonas: Yeah, you need to find people to maintain it. I think that’s the main problem. So, I mean, even the Rust libraries hadn’t really updated. I’m not sure if they have yet the Rust wrappers for lipsecp256k1
. So I would have said that this is a sane wrapper and it presumably still is, but just maintaining these things of course that takes effort and it’s also annoying that you have to update all the time whenever there’s a libsecp256k1
update, although we try to make a libsecp256k1
update only every three months now.
NVK: Yeah, I mean, the least amount of update, as somebody who pulls and watches libsecp256k1
, I mean, the least amount of updates is the best. Please do it once a year, max, unless there’s a vulnerability.
Tim: I mean, the good thing is, I hope that’s a good thing that we now have releases finally, right
NVK: That helps too, a lot.
Tim: It’s true, In its first eight or nine years, or even 10, I don’t know, I guess eight years or something like that, didn’t have a single release. So people were using…
NVK: We just had to watch the commits.
Tim: Yeah, right. And so I hope that that’s a step forward for users.
NVK: So would you say for somebody listening right now, we have like a very, very high quality, lower level guy who can build a good binding wrapper library for say, Python or for Rust or even maybe JavaScript. If the issue is funding, I mean, like, you know, there’s OpenSats, there’s Brink, there’s a bunch of foundations now that can fund this work full-time, long-term. Is this a call to action that you guys would like to put out there? Is it worth to have somebody who’s like really doing this full time and interacting with you guys who are writing the libraries?
Jonas: I’m not sure if this would be a full-time job, but yeah, I think that that would be cool. It seems like there’s a lot of people who use these wrappers. And as I said, I don’t think they’re always high quality. So it would be really nice to improve the state here.
Tim: Another issue maybe that prevents people from using the library or wrapping it is that, I think we could have a bit of, sometimes more features. Even Bitcoin Core does a bit of key handling and tweaking keys, separate tweaking and so on. In their code base and not using the library. Maybe it’s also one problem of our library in a sense that the API is very restricted. Of course, it’s a design choice because we want to have a very safe API that you can’t really abuse. But if you need that tiny feature that we can’t offer, then of course, you wouldn’t choose our library, right? So you would use something else, even though the quality may be lower. So this is something where we may be able to improve, but on the other hand, then we again need that kind of feedback. So I’m always interested to hear what people, what use cases are and what people need in practice.
Side-channel attacks
NVK: Cool. So like switching gears a little bit, here’s a question for you guys. How do you guys test for side-channel attacks? How do you guys explore that path without going to actual, say, hardware out there and test everything out, right? Like, it’s sort of like a fuzzy out there problem that you can try to do your best, but it’s nearly impossible to fully curb it all. Like, how do you guys approach this problem?
Tim: So we already touched upon this. We have those, yeah, we use Valgrind and we can also use another tool to do basically the same that can tell us if we branch on secret data and this is basically what we mean by constant timecode. So we want to avoid branches on secret data because branches could mean that the code path behind those two branches take a different amount of time. And so are visible if you have a watch clock or if you can observe timing. So this is our methodology. The problem here is we can’t test this on the binaries that we produce. So it really depends on what the compiler does. So if you build a hardware wallet or something like that, we would also encourage you to try to get this running on your specific hardware or maybe an emulator on the exact same architecture, exact same compiler, just to make sure that the final binary that is produced doesn’t have side channel leakage because we try to cover wide space of architectures and compilers and then maybe even compiler flags and so on. But in the end, everything which is embedded, for example, is a bit niche by definition. So, yes, it’s hard. I mean, writing constant time code is still a bit of a black magic. We don’t really have compiler support for this. So, crypto people tell this to compiler engineers for years that we would like to have features where we tell the compiler, okay, please don’t put a branch here. They are aware of the problem, but they’re not going to spend time on it. At least that’s the state of the things. So as long as we don’t have it, it’s really a bit of a black magic. You write some code, you hope that the compiler doesn’t turn it into a branch. And the only way to figure out is basically either you look at the assembly output by the compiler, which is of course super difficult and hard and doesn’t really scale, or you run tools such as Valgrind to test that automatically. But again, you can only test on the binary that you produce. So it’s also limited.
Testing
NVK: Have you guys thought about maybe having like, you know, either a person or a group of people who maybe test some of the like most common use embedded implementations out there, because that’s really where a lot of the stuff ends up, right?
Tim: We haven’t really thought about this. And I think this is something that should be done on the manufacturer or on the consumer side, because it’s hard to cover everything. Of course, we can try to test on, as I said, on the most basic things. Like, for example, we can test on ARM and we can test on Intel CPUs. And maybe those are similar to the ones used on embedded systems. But it’s kind of hard to really test on all the hardware devices.
NVK: Yeah, I mean, I feel like having the tasks done in sort of like most of the embedded platforms, like at least on the say ARM side, it’s already very helpful, right? We do a bunch of checks internally as well, but, and we have some assembly capabilities internally, but it’s like an endless rabbit hole, right? And realistically speaking, when it comes to runtime code, you have all kinds of other side-channel issues too, just based on the hardware. Because, you know, once it’s in memory, it’s in memory and it could be attacked that way. Go ahead Jonas.
Jonas: Yeah, I just wanted to add to what Tim said and exemplify the issue a bit more maybe is that these side-channel issues that we talked about that appeared in the last six months, the two, they were not because we introduced new code or because we had better tooling suddenly. We still use the same Valgrind tooling that we explained. It’s just that there was a new compiler version that we hadn’t tested before that came out and that optimized out our constant timeless protections and that’s something that we cannot really test. We don’t know what compilers will do in the future, so there will never be a perfect protection against compilers optimizing out these constant time defenses. And therefore it’s just really hard to protect against this.
Tim: One thing where we improved here is that now we test on unreleased compiler snapshots. So we now test our code even on unreleased clang development snapshots or on unreleased GCC development snapshots. So hopefully we can catch bugs now before the compiler gets released. But yeah, all the mentioned limitations that we talked about still apply, of course.
Jonas: Right. And then it continues to be a cat and mouse game. We will find that there’s an issue with a new compiler, then we try to find new constant-timers protections and then hope that they don’t optimize it away in future versions.
NVK: Yeah, I mean, when it comes to much deeper issues with code, like security code, or much more advanced attack, like advanced adversaries. You know, it really comes down to compilers, right? Trust your compilers really is where the rubber meets the road until you really get down to the hardware issues. So it’s just nice to see that so much attention is put into that. Rijndael, I assume you were having some connection issues there like me. Do you have questions?
Hacspec
Rijndael: Yeah, I was going to ask a question about hacspec a while ago, right when my connection dropped out. I don’t know if anybody knows if it actually validates the C implementation or not. Like one of the big problems with a lot of formal modeling tools is you end up with this conformance gap between the specification and the actual implementation. Like I’ve done some work in like TLA+ or P which are both for modeling concurrent systems or modeling like state machines. So it’s a different category of tool. But in a lot of these tools, if you don’t have something that can actually validate the implementation, then you can have a formally proven algorithm, but still have like implementation issues. So do you guys know if the Coq spec that comes out of this ends up actually going against like a SAT solver for your C code or something else? Or is it just still a problem?
Jonas: So hacspec doesn’t help with that at all. It’s just a language that you can compile to Coq basically. It’s just a better way to view Coq programs. And the state of the art for these formal verified things is still not great. It’s often like sort of it’s coming more into practical reality, but a lot of that stuff is still academic or just very weird, old proprietary stuff. For example, the way that Russell O’Connor does the formal verification of these libsecp256k1
primitives is that he takes the C code and then he hopes that this C code actually lies in a subset of C that’s called verifiable C. And this verifiable C, there’s a proprietary compiler. We have a license at Blockstream for that, for doing analysis with that compiler on libsecp256k1
. And you take this verifiable C code, and then you can translate it into Coq. And then you hope that this translation is correct. And then you have the Coq code and then you can make proofs over this code. So as long as the translation is correct, you have a proof over that code, but that doesn’t mean that, for example, the GCC or clang compiler doesn’t introduce, doesn’t interpret the C code differently than this propriety compiler. It’s called CompCert.
NVK: Yeah, that makes sense.
Signature types in research
NVK: What other primitives do you guys have in research right now on ZKP?
Jonas: What do you mean by primitives?
NVK: What other signature types are coming and what other? So, for example, we have aggregated signatures coming at some point. What other research is happening on that field?
Jonas: So I think one of the interesting things is this whole work on adaptor signatures. So adaptor signatures have been around, at least the idea, for quite a while. Lloyd wrote a paper on it, proving its properties. And we’re currently working on an implementation for adaptor signatures working with Schnorr signatures because that is something that might be used in Lightning PTLC’s point-time locked contracts because there is the possibility of either using adaptor signatures with Schnorr or using MuSig adaptor signatures. The former we already have and the latter is something we add and then we let the Lightning people experiment what they like best.
Cross input aggregation
NVK: Cool. I have a question here from Vivek. What is the process of standardizing new primitives such as how things behave on the stack for future SegWit versions?
Jonas: I’m not sure I fully understand the question.
NVK: Vivek is on the chat so he can clarify a few ones.
Jonas: Oh yeah, he mentioned cross-input aggregation. So right, there’s this whole field of signature aggregation schemes and the idea would be you have many signatures right now, one for every input, the transaction, or more even for per input of the transaction. Would be nice if you had only one signature per transaction or even one signature per block and you hope that this signature would be smaller than the size of the sum of the signatures. So there are many possible ways for how to do this and even many cryptographic schemes. But for future SegWit versions, yeah, I think that would be something that could be potentially added in particular there’s the scheme that is often called half aggregation that is relatively simple would be easy to do you could edit relatively easy on the transaction level where instead of having a signature per input, you would have one half aggregated signature per transaction. And the size of the signature is half of the size of the individual signatures. And the nice thing about this is that there are security proofs for this, which is, I think, very important if we want to add something to Bitcoin. And second, it is non-interactive. So unlike MuSig or whatever, you don’t have these multiple nonce rounds that could go all wrong and a lot of secret data that you need to share and replay a text etc. You just produce a signature and then someone else can take two signatures and produce a half aggregated signature very easily. Of course, that doesn’t reduce the size of the signatures to some constant size, but at least we save half of the size of the signatures, which I think is attractive given that it’s relatively simple to do.
Deciding on what is included in the libsecp256k1
release
NVK: So how do you guys decide on what’s ready to move from either dev or ZKP to the main release of libsecp256k1
?
Tim: So in libsecp256k1
itself we don’t really have a dev branch or something like that. We have a master branch where all the development happens and if we cut a release it’s hopefully just the current state of the master branch. Of course there can be exceptions where we are not sure about the API, for example, we may add more experimental modules, but at the moment, all of our modules are non-experimental. And maybe that’s a good thing because it’s a bit hard to declare something as experimental. Because what does it signal to the users? Should I use that? Shouldn’t I use this? It’s kind of unclear. What are the stability guarantees across versions? It’s all a bit undefined, so maybe we can get away without those things, without those experimental modules in the future.
NVK: So what’s the role of ZKP?
Tim: That’s a really good question and also one that has been debated among developers even because for some while and maybe still at the moment it’s a bit unclear what the exact distinction or scope of libsecp256k1
and libsecp256k1-zkp
should be. So libsecp256k1-zkp
for those who don’t know is a code fork of libsecp256k1
. It’s maintained by Blockstream. And the reason why Blockstream forked libsecp256k1
is that we use it at Blockstream in our elements or Liquid sidechain. So elements is the open source version, basically the code base and the actual chain is Liquid. And so we needed more cryptographic features. So we forked the library. What happened later is that it was also used maybe as a testbed for more like experimental features. For example, there are multiple implementations but the MuSig2 implementation that Jonas and I produced lives there in libsecp256k1-zkp
. And this is kind of unclear whether it should live there because it’s relevant, or I believe it’s relevant to the wider Bitcoin ecosystem and not only to the Liquid and Elements ecosystem. So I believe that should be part of libsecp256k1
and probably we will open the PR that merges it into the, or if accepted, we’ll add it to the main libsecp256k1
library. So this is still an ongoing debate, but if you ask me, my opinion is that libsecp256k1
should contain features that are relevant for the Bitcoin ecosystem and this is not necessarily limited to features used in Bitcoin Core. Of course, if it’s used in Bitcoin Core, then we should have it because it’s strictly necessary. But we can also have features that are well aware to the Bitcoin ecosystem and are not directly used in Bitcoin Core. Of course, you still need to maintain them. We have to commit on spending work and doing review and so on. But as long as we do and think careful about what features we need, or we want to add, we can add features there.
NVK: Do you think there is a possibility of becoming sort of feature creep and end up at like OpenSSL where, you know, because like that’s essentially like what happened to Core way back then, right? I mean, Bitcoin used to be just called Bitcoin. And it was like the wallet and the consensus, everything together. And then Gavin, you know, sort of pushed for us to split their wallet from the consensus code, which is very tricky. And then it became the Clusterfuck after, like in terms of like the drum around and all that stuff, but let’s ignore that for a second. Do you think that we could, so for example, have a libsecp256k1
core, right? That’s like essentially like the true, very tight, very few things in there. And then we have sort of like this slightly separate release that is maintained together and all, but has non-core features that are needed by the industry, but they are not necessarily, they’re not as broad, right, by all vendors, for example.
Tim: Yeah, I mean, first of all, of course, feature creep can be a problem, but I don’t think it will be a problem in libsecp256k1
because we add features very slowly at the moment, also because our bandwidth is limited. So we don’t even have the time to get into feature creep issues. But yeah, I mean, what you suggested is one possible way to have a library where you have parts of it relevant to Bitcoin Core and parts of it not relevant to Bitcoin Core. I’m not sure if this is the optimal way forward. For example, we have this existing module system that I mentioned. We could also just have modules that are relevant to Core and modules that are not relevant to Bitcoin Core. And if Bitcoin Core compiles the code, they can just disable the other modules. And that’s another kind of interesting and unresolved question is, how do we allow others to add features? Because there’s certainly things that we don’t want to have in libsecp256k1
. And the prime example is a lot of stuff that is in libsecp256k1-zkp
, just because it’s relevant in the elements of Liquid ecosystem. Of course, we won’t add this to libsecp256k1
. But then the question is, what is the easiest way? At the moment, the way libsecp256k1
is, ZKP is maintained as a cold fork, but that has all kinds of issues. So we were thinking about maybe adding some more modularity, maybe have a kind of a middle layer that exposes some low-level operations that then others can use too, including Blockstream, but also everyone in the ecosystem who knows what they’re doing basically to implement their own primitives on top of the curve code, for example, as exposed by some low-level library. But we haven’t really made progress on this question so far.
Rijndael: Yeah, there’s some stuff in ZKP that I think would definitely make sense to have in the upstream libsecp256k1
, right? There’s like ECDSA adaptor signatures. I think there’s like MuSig too in there, but there’s also things like, you know, Peterson commitments and like range proofs for doing CT. And like, I think you could make the argument either way about whether or not that should be in the upstream one. Do you think it’s a sort of a review gap of, you know, we need to have more review on these additional features before they can get folded into the upstreamed libsecp256k1
or is it just like intent? Is it rebasing time? Like, what do you think is the thing that’s keeping these libraries really apart.
Tim: Maybe also Jonas has thoughts on this, but if you ask me, yeah, review is part of the reason, but I don’t think it’s the main reason. It was just historically that also we just thought, okay, maybe it’s easier to get some experimental stuff integrated in libsecp256k1-zkp
because we at Blockstream, we just control it, we control the process. And of course, the quality standard is very high, but it’s still, I would say, a bit lower than in upstream lipsecp256k1
. So it was the easy choice to implement schemes like MuSig2 and lipsecp256k1-zkp
. Now in hindsight, maybe if you ask me, I think the proper separation between those projects should be that just libsecp256k1
focuses on the Bitcoin ecosystem and libsecp256k1-zkp
focuses on the Elements Liquid ecosystem.
NVK: And that, you know, is this like a sort of like a wishful thinking or is this sort of like a realistic path that is worth exploring?
Tim: I think it’s realistic. So as I said, we plan to open a pull request that will, hopefully, add a MuSig to the Bitcoin Core libsecp256k1
, so that would be one step to move one of those features that probably belongs to the Core libsecp256k1
to that library. And maybe the same is true for ECDSA, adaptor signatures and other features we need to see. But I think the first feature where we want to try this is MuSig too.
Are there enough contributors?
NVK: You know, in the fear of, you know, what is it, nine mothers don’t make a baby go faster, right? It still needs nine months of a single mother. Oftentimes having less maintainers and less developers is the best course of action for critical software. Having more reviewers on the other hand is always a great thing. Do you guys feel like this library could use more people, has enough people on the development side and what do you feel about also the review side?
Jonas: I just wanted to add to the previous point that I’m not 100% convinced that libsecp256k1
should contain everything that might be potentially interesting to the Bitcoin ecosystem because although there’s not a huge risk that this will become bloatware, it still adds a maintenance burden if you add these new modules. Of course, if you want to do refactors across the code base, having more code just makes that harder. I think it’s still an open question and I think there’s a spectrum of which one to take. I think it makes sense to move MuSig into libsecp256k1
, also because I think Core wants to use this and there are a lot of other projects. NVK mentioned that there’s this potential world where there’s some Core libsecp256k1
library and some additional library that has additional things. That’s sort of how it is right now with libsecp256k1-zkp
as far as I understand it. The only problem would be that libsecp256k1-zkp
is sort of controlled by Blockstream as Tim said. So it doesn’t have the best decentralized governance that maybe libsecp256k1
has. And one additional thing that I think is important, so for adding stuff to libsecp256k1
since NVK you asked about requirements, I think one requirement is that the thing we add has a specification. I think these requirements, they have not been officially stated. This is something informal, stuff that I would like to see. So something has a specification, it has a security proof and ideally it has shown some interest in the Bitcoin ecosystem. So for example, for MuSig, all of the three things apply. So that is something we can move into libsecp256k1
. There’s clearly people using MuSig right now in production and securing quite a few Bitcoin already. And so next thing will be, how do we do that with FROST; FROST is now a pull request to libsecp256k1-zkp
. And there exists security proofs. What is missing is a reviewed implementation and interest beyond just saying that there’s interest and a specification.
MuSig2
NVK: You know, it’s interesting that you brought up MuSig2, because, you know, like or unlike the bigo, this guy is secure, you know, an ungodly amount of Bitcoin. So, you know, having those bitcoins secured and ideally using a library that that is good, that is reviewed, it gives Bitcoin confidence, right? If those funds are not stolen under that technology, even though it will likely be their own fault in terms of implementation. So, I mean, that really proves demand, right? If you have a large percentage of the coins in the network being secured by a type of Bitcoin technology, like MuSig2, it’s nice that that is secured by the best library around. Is there any sort of timeline or intention on when MuSig2 would be on libsecp256k1
?
Jonas: Two weeks. I think we want to open the pull requests relatively soon.
Governance
NVK: It’s interesting that you brought a bit of governance and formalization and all that stuff in because, you know, traditionally the true hard software It’s often written and maintained by very few people who are incredibly talented and should not be wasting their time sort of like interacting too much with the rest of the world who have not necessarily the most constructive feedback, but at the same time, Bitcoin is a very unique project. So governance and both the true decentralization of it and also the perception of decentralization of it matters incredibly. Right. That’s what brings confidence to a lot of what we do every day in this space. So what is the current structure, even if it’s not like very well defined, like standardized, like what is the current way in which libsecp256k1
is maintained? Like how many people are involved on it, like full-time or, you know, full-time as I say, like major maintainers. How many people sort of like help manage it? How many people help review it? So people get a sense of like the scope of this project.
Tim: The main maintainers are Pieter, Jonas and me. And there is a handful of other contributors, though often their contributions are not as regular as those of the maintainers but even among the maintainers it’s often that we don’t do this full-time. Of course we all get paid for it, that’s a good thing, but we also get paid to do other stuff. So there may be weeks with very high activity and there are weeks with very low activity in the codebase. One issue maybe is that reviewer capacity is pretty limited. You hear the same from the Bitcoin Core project but I think in our case it’s maybe even a bit worse because if you do critical changes like adding a new algorithm or doing a performance optimization, all of that is pretty critical code and we want to have a lot of eyes on it. So usually in those kind of changes, all of the maintainers will be involved. And then, yeah, if someone is just not present at the time, we cannot make progress on a thing.
Funding
NVK: You know, there is a development that happened in the last couple of years. I mean, there’s a lot of funding now available for people to work full-time on core. So is this something you guys are looking for? Are you guys looking for funding to just work on this? Are you guys looking for new people coming in to do review full-time on this?
Tim: I think funding is often a problem. It’s not a problem of the current maintenance. It may be what stops other people looking into it more.
Contributing
Tim: But what I often see is that if people start to get in touch with the Bitcoin Core project, they of course, when they start, they look at the actual Bitcoin Core project and they end up doing development there. And it’s a bit of, I think, one aspect is because it’s the obvious first choice. But another aspect is that sometimes people are a bit scared away by the cryptographic code because it’s kind of critical, but other aspects are also critical. It’s also something one can learn. The common saying is that you shouldn’t roll your own crypto but of course that sentence doesn’t apply to everyone. Because if no one does, then we won’t have any cryptography. So I think it’s a space where we could benefit from a bit of a more development bandwidth. And it’s also not just on the cryptographic side. Of course, this is the interesting, very interesting stuff, but also, as I said, a bit of the scary stuff. But we also have issues and problems that every software project has, right? Like maintaining tests, CI, build systems, documentation, all of that stuff. Also, refactors. You can easily refactor code, and even if you don’t understand what it’s doing, right? As long as you’re sure that the old code is the same as the new code, you don’t necessarily have to understand the underlying algorithm. And so we could benefit on both sides. More people who are actually are interested in the math are willing to look at cryptographic details and learn something there, but also just more standard software development and software maintenance stuff. Not sure what your thoughts are.
NVK: Okay, so essentially what you’re saying, just kidding, is that people shouldn’t even bother looking at Bitcoin Core to work on, it’s political, it’s too difficult, it’s like, you know, I’m just kidding, it’s a great project. But like, you know, if they wanna just focus on great implementation, C, and, you know, cryptographic primitives and how to do like new algos for improving it. They should just come work on libsecp256k1
, right? I mean, come full time on libsecp256k1
. It’s a lot less political. Come review it. There is funding available. It’s a much smaller group of people and you can keep your sanity.
Tim: Right. And maybe in particular, if you think you’re more kind of the person that likes mathematics or the underlying stuff and it’s not that into, like, doesn’t feel it’s the greatest programmer in the world. We often don’t need that, right? Because we have people who can look at the C specifics and see if something is wrong. But just people who are willing to understand the schemes and the cryptography behind it, that’s really helpful for us.
NVK: Plus, I mean, if you’re a C programmer and you don’t want to touch that yucky C++, you can come work full time on C, which is the one true language.
Tim: That’s also true, yeah. C89, yeah, come.
NVK: That’s right. You know, like, if you care about memory, this is the project. Yeah, go ahead. Who was…
Jonas: Just wanted to emphasize that you can really learn this cryptographic stuff. So this year we had a Summer of Bitcoin project for implementing these Schnorr adaptor signatures that I mentioned. And the project proposal that we put out was very difficult, in my opinion, to understand even. Because, for example, these terms in the adaptor signature world, they vary wildly and you have these x-only things and there’s a lot of weird stuff going on, but we still received 30 applications and I would say 20 of them were really, really good and it was very hard to decide which one to take. So that just shows that it’s actually possible to learn these things and to like from very from very basic start to build out these systems and understand them and figure out how they work. Because in the end it’s mathematics which means there is some truth to it. There is a way to figure it out. You just need to have the patience maybe and the motivation to do it.
Tim: Yeah, totally. Very, very important point. You don’t need a PhD for that stuff and don’t be scared off by the cryptography. It’s something that can be learned and we all have to learn it. It’s possible.
Lloyd: If you have autism.
NVK: Yeah, it’s probably better, I mean not better, but like I feel like if you’re just like an incredibly talented C programmer, there is a lot of use for your skills in a project like this, even if you don’t have all that experience with cryptography itself.
Security proofs for FROST
NVK: So Lloyd and Jesse, I mean you guys are more on the cutting edge stuff. When security proofs for FROST?
Lloyd: I think Jonas and Tim have just been on that as well. So it’s more questions for them, we just published a paper on that.
NVK: I guess that’s true.
Jesse: We’ve got a lot of security proofs at this point, right? I mean, there’s been, there’s original FROST paper, there’s a bunch of follow-ups. There’s, I think Tim co-authored a recent paper that has a simplification of the DKG. It seems like it’s been pretty well scrutinized in the last few years in terms of security proofs.
Nested MuSig FROST proofs
NVK: Vivek wants to know about nested MuSig Frostproof.
Tim: Ah, that’s an interesting question.
NVK: Oh boy, is this a nerd sniping question?
Lloyd: I love this topic. How deep do you want to go? How nested are we here?
Rijndael: Well, yeah, because like Jesse, I think your original FROST implementation did nested MuSig and then didn’t because you wanted to like lean on the security proof from the original paper and then I think you’re doing it again, right?
Jesse: Well, no the original implementation used the MuSig API’s for the nonce generation and the signing, and it created a MuSig aggregate key along with the FROST key. I started to see all these overlaps between FROST and MuSig, so I just got interested in seeing how well I could meld these two systems together on the implementation and protocol side. But that wasn’t nesting. Nesting is where one of the MuSig keys would itself have been produced, one or both, with a FROST DKG. And so you have a FROST-produced key inside of MuSig, which is potentially… Well there’s a few places where that could be useful, but one I think most notable is with lightning, because we don’t really have a good way to do lightning multisig for the funding key without nesting. One cool thing about taproot channels is they’ll be able to pay out to FROST keys in the outputs without any nesting or new security proofs or anything like that. But for the funding key, whenever you sign a new channel state update, if we wanted to have multisig there, we could theoretically nest FROST inside of MuSig. And that’s something we know works algebraically, or in other words, we know it works to produce a signature that verifies. We don’t know if it’s secure or there’s also a few different ways it could be done. Some probably secure, others not so. We also have some issues in terms of the Lightning use case where even if we could figure that out, that just deals with the key management. You still have the issue of state management. So let’s say you had an offline signer that’s part of your FROST MuSig. When that offline signer comes online, they need to get to some consensus about the state of the channel. Otherwise they could easily be tricked into signing a revoked state. To do that, you probably need some kind of BFT consensus for the offline signer to be able to figure out what channel state is the latest state. There’s also open questions about how revocation can be handled. We have some discussion on Matrix, there’s like an L2 multisig channel where we’ve kind of been discussing some ideas there and how it might work, but it’s still pretty early on and kind of speculative whether or not we’ll be able to get something like that working.
Lloyd: Interesting story: it was yesterday or the day before, I was talking to, as far as I know, the first mainnet FROST user custodying people’s Bitcoin. There’s a guy named Kgothatso and he runs a service called Machankura. He’s using our FROST implementation, as experimental as it is, to actually do the custody for his users’ funds. It’s like an SMS service in Africa, so you can SMS people, send Bitcoin via SMS. He’s got a few thousand users. This is actually happening. It’s a risky choice, at this stage, but I mean, it saves in transaction fees and it’s more like an internal thing. So it’s not interacting with other users. It’s like interacting with other locations, his own servers and spread around different locations to just split up the key and do signatures when withdrawals are requested. He has this problem: he can split up his FROST key, but now he wants to split up his Lightning Node because he also offers lightning payments via SMS. So now you’ve decentralized your on-chain funds, but you haven’t decentralized the lightning node, which is fully custodial in one location and can easily be rug pulled by a physical attacker who managed to get into the server. And so, it’s actually a real problem that someone has right now. So I’m looking forward to our solution we come up with here. So my personal preference on this thing is just to use more textbook cryptography with this MuSig and FROST nesting idea and just use multi-party computation, interactive multi-party computation to do the FROST bit. And in other words, don’t quite use FROST, but use multi-party computation where you split up the key and split up the nonces as well and compute the result of the signature, the result of the MuSig signature as if it was computed by one computer, but split amongst several computers.
Nonce sharing
NVK: That’s something I personally have questions and still don’t have good answers; what’s going to be the best way for sharing like a batch of nonces? One is like, it has to be a secure way of sharing those nonces. And, you know, there’s a good chance that you cannot convene offline in a single location to do that as well. Say, for example, you have two company servers, they’re different countries. You know, maybe you have a guy traveling with a CD. But what do you guys think would be like, you know, some paths we could take to do that initial nonce batch sharing and also not reusing those nonces?
Jesse: Well, the thing is, you’re still going to have to collect a partial signature from the signers. So adding a nonce round isn’t necessarily that big of a deal. There’s some interaction that’s already taking place to retrieve data from the signer, and you could potentially just repeat that to do the nonce, which then you don’t have to worry about pre-generation and already using the right nonces or already using the wrong ones. And of course, the alternative to that is to pre-generate the nonces and then you just need to have a secure way to figure out which ones have already been used. But yeah, I think it’s not necessarily as impractical as it might seem to just add another round to get that nonce for the signature.
NVK: Yeah, there’s like two sort of like separate use-cases here that are very clear. One is, you have servers online and the interactivity between them is fairly simple to make it happen in mini rounds. The other case scenario is where I’m thinking in terms of like bunker coin, right? Like, a coldcard, I have it in, say, like a safe in some country, and then I have another one in another place and none of them are online. And I’m using Sneakernet. That’s when having a pre-made batch of nonces would come into play because you don’t have the luxury of doing another round of interactivity because that’s another flight. How do you guys think about that scenario?
Lloyd: Yes, that is, I mean, that’s what we think about a lot because we’re working on a hardware device called the FrostSnap currently. <FrostSnap.com>.
NVK: I saw that, it’s a very cool one.
Lloyd: Yeah, it’s a fun little project at the moment in the kind of proof of concept stage. And what we do here at the moment, we’re not doing anything too special, but yeah, we do the batch at the same time as key generation. So this Sneakernet thing, one drawback that’s very difficult to get around, I don’t think is a deal breaker, is that when you’re generating the key, the devices have to be online together, or at least they need to do two rounds of communication, at least, to generate the actual key. And so at that point, we generate the nonces at the same time. And then we replenish the nonces every time you do a signature. So every time you do a signature, you’re also putting on however many nonces you consumed during that signature back to a central coordinator. So the coordinator, who’s the device that sort of initiates the signing has like this list of nonces for all the other devices. And that’s how we manage that problem.
NVK: Yeah, I was thinking in terms of that, like you have a central coordinator that keeps track of the nonces so nothing gets reused. But the other lags, the other signers, they only essentially have one round of interactivity. It’s just one time sign. And you never have to see them again for a few more years. I don’t know, it’s an interesting problem, but it really improves security a lot, having this schema like that.
Demystifying libsecp
NVK: So guys, we are approaching, I kind of lost track here of the time because I had to reboot, so I only see one hour on my thing, but I imagine we’re like over an hour and a half, almost two hours. I know some of you might have a time to go. So in this sort of like last 20 minutes, of course we can extend depending on how you guys feel about it. But what do you guys sort of like would like to leave here in terms of like de-obscuring such a cool project and sort of like shedding some light on what’s done, how it’s done, and what could be done better. You know, I love to hear like each of you sort of like maybe comment on a little bit of that. So why don’t I start here? I’ll start from the bottom. So, Jesse, what are your thoughts on this?
Jesse: Well, like I said, I’m excited for the future of cryptographic tooling with formal verification. I’m interested in how generative AI might make it easier to implement some of this complex tooling or take out some of the tedium that’s involved in the proof systems and make it more practical for us to implement these things. I also want to underscore something that Tim and Jonas mentioned about kind of encouraging people to try to learn some cryptography or work in libsecp256k1
. I don’t have a cryptography PhD. I didn’t study it in school. I learned it on the job when I was working at Coinbase. And it’s absolutely something that you can learn a lot from online resources and from other people. And it’s just so intellectually stimulating and I think some of the most creative and fun kind of engineering work that’s out there. And definitely being able to work with some world-class cryptographers like Tim and Jonas who can review the code and make sure you’re not committing catastrophic bugs to the code base is a really amazing opportunity. So if anyone at all is curious or interested, I would definitely encourage folks to go for it. And please feel free to reach out to me on Twitter. I’m more than happy to help people get into this or provide some introductory resources to learn how to contribute and learn how to understand these algorithms and these systems and maybe even invent a few new ones along the way.
NVK: Lloyd, same question.
Lloyd: Yeah, sure. The magic, the magic is made… I mean, cryptography seems like magic, I guess, until you, until it just seems like hard work when you’re working on it. For my my advice like if you want to get into this field like I would actually buy books like just go start at basics and do the kind of textbook kind of workflow through them and use, I recommend using the Rust programming language and just sort of working through examples and learning how to think about it, which is more important than the actual day-to-day engineering, at least for me. I’m more enjoyed thinking about things than the implementation bit. But then, once you’ve got an idea and you want to see something work, it becomes easy. And once you’ve got the background and the skills, it becomes a lot of fun to go and implement those new schemes that you read about in these papers that are published on the internet. And so that’s my life. I recommend it for you if it suits you. And if you love Bitcoin, because there’s a lot of fun to be had, I guess, in Bitcoin. Yeah.
NVK: That’s great. Jonas.
Jonas: Yes, so Lloyd outlined one way to get into this field. Another way would be, I think, to try and use the software, for example, by trying to build a FROST wallet or something like that, and then just see what you don’t like about it and try to fix it. And this could be in many different areas of these libraries from the build system to documentation and other things. And also don’t be afraid to reach out. We have an IRC channel for libsecp256k1
that can be used for questions. You can also email me directly. My Twitter DMs are open. We have GitHub discussions on libsecp256k1
. So there are many ways to reach out in case you really want to contribute. And as for things I’m excited about, I think we’ve talked for years already about FROST, so I’d be I really like to make progress on this and review Lloyd’s, Jesse’s PR, try to work together for a specification and finally get this into the hands of users, because after all, this will improve privacy, hopefully, of the users, which I think is of great importance in Bitcoin. And the other part I’m excited about, which is not that much in the Bitcoin field right now, but we’re also working on the zero knowledge proofs, the Bulletproofs++ scheme in particular in libsecp256k1-zkp
. And this is also something that we would really like to make progress on for range proofs, but also for general zero knowledge proofs, arithmetic circuits, et cetera. A bit far out still, but I think that’s gonna be really interesting in the future.
NVK: Neat. Tim.
Tim: Yeah, so first of all, I agree with everything that has been said so far and yet another great tip for not maybe reaching out to us directly but for asking questions really is Bitcoin StackExchange or Cryptography StackExchange. You really get very high quality answers there to all kinds of questions and often also in a timely manner. So this is really one possible place to go when you’re learning and you feel stuck and have a question. And yeah, what I’m excited about, also of course, FROST, because yeah, it’s as Jonas said, we’re looking into this for multiple years now and happy to start working on this again. Actually we have started two weeks ago to spend a little bit more time on that now. But I’m also very excited to see the PR of MuSig2 to lipsecp256k1
what we mentioned earlier, because it’s basically the same as with FROST, just we are in a different stage. We worked forever on the paper, we worked on the specification, put a lot of time into the specification, put a lot of time into the implementation and libsecp256k1-zkp
and to see this now used in practice is just very motivating. And the final step for me would be to move this to lipsecp256k1
proper, yeah. And this would also be a nice conclusion of that work. Of course, then people will hopefully continue to use it. But at least I hope that the work on our side is done then for that project.
NVK: Very nice. Rijndael, I guess it’s the same questions, but from the vendor side.
Rijndael: Well, I was going to say, just hitting on something that other people have said, in addition to the libsecp, there’s also Lloyd maintains a really excellent Rust library called Secp256kfun, which is for doing fun things. And like all of Bitcoin programming is fun, but there’s some kind of more bleeding edge features. So it’s had FROST for a little while. I think Nick Farrow wrote that implementation. It has MuSig signature adaptors in there. So if you want to like play with this stuff while it’s getting reviewed and getting kind of ironed out for the implementation that’s going to get rolled into core. It’s a really great library to play with more cutting edge features and things that are more experimental. If you want to do coin swaps using signature adaptors or if you want to build a Nostr shitpost DAO using FROST or something. It’s a really great library to pick up and play with and like have fun with. So I don’t know. And then on the vendor side, yeah, the point that was raised earlier about it would be great if more vendors reached out to either of these libraries and just let them know what they’re doing to maybe collaborate on like interfaces or, you know, pain points, whatever. Like it might be that, you know, everybody who’s building FFI bindings need, you know, maybe everybody like needs some common abstraction out of libsecp256k1
. And that would be just really great feedback for the folks working on the project.
NVK: Neat. I second everything you guys said. So guys, with this pod, I’m trying something kind of weird and different, which is, so we have a fairly like, say half very technical audience and a lot of people who sort of like are Bitcoin technically curious. So we kind of go back and forth between the nitty gritty and the low level and sometimes for the math. But it’s sort of like kind of go back to high level a lot. So it’s like this sort of like very schizophrenic sort of back and forth conversations, which it seems to sort of like give context and clarify and sort of inform people about some of the things that make up the solutions that they use or some of the code that they pull, some of the libraries they use. What do you guys think we lack getting the word out to people who are building vendor clients, who are working on things, the makers, not the talkers. I don’t know if you guys listen to pods, but what do you wish got more out there in terms of like information about projects and some of that stuff that is not as sexy as macro. None of that crap, essentially. What can we get out more that you guys think it’s missing out there.
Lloyd: Is this in terms of like in general feelings and thoughts we wish Bitcoin has understood more or is this like in particular like software projects that you want to advertise?
NVK: I think both because, in a way or another, the code is what makes Bitcoin, happen. So projects affect Bitcoin economically as well. I prefer to approach this from the makers side, right? From the people who actually write the code. And it’s often not clear what would be interesting for people or beneficial to the industry to get out. And I’m sort of like trying to do this. For example, we did a FROST episode. We did a Segwit episode. And those seem to really hit well, like in terms of like people felt like they’ve learned this thing and it’s not just some acronym that people are using around. And it was beneficial to businesses to also learn about the fact that there is this new things they could use. There’s a lot of dapps out there that they are working more on the business logic level. So they don’t like fully understand how much is happening in this. So just like exposing some of the stuff that’s happening on the underground of Bitcoin to them sort of seems beneficial?
Lloyd: The only thing I can come up with there on for me is that, Bitcoin engineering is very hard, I find, and it gets pretty damn complicated.
NVK: Yes.
Lloyd: And so what I would just encourage people to do and when they’re looking at software projects and looking at projects to invest in, invest their time in, their money in going forward, is like: how can you, and the tools you’re using, how can you make this whole ecosystem and experience simpler and not like more complicated than it already is? Because I feel like there are some projects that are going and trying to make this whole Bitcoin system like exciting and cool, but maybe quite a bit more complex. And there are some that are just like trying to get to the roots of it and are really pushing to just simplify the shit out of everything so that people can have easy user experience and stuff. I try and do the latter, try and focus on tools that do the latter. I can give a shout out to the BitcoinDevKit, which is something that I contribute to and work on. It’s like a rust library for doing Bitcoin, is going through a massive overhaul right now to try and really radically simplify the whole architecture. There’s the LightningDevKit as well that has a very similar goal for Lightning, have composable tools that allow you to implement the Lightning protocol in your stack, giving a simpler experience for your users because you’re not having to run some extra node, it’s like integrated into the app. And they’re trying to really make it easy for developers to do that. So like, look out for those projects, look out for those people who are trying to make things simpler. That’s the only thing I would like to get out.
NVK: Rijndael’s got a drop. So Rijndael, any final thoughts?
Rijndael: No, just plus one to everything Lloyd said. And then, I don’t know, like the other maybe high level takeaway, if you’re not really into this and you’re just like listening to the pod, is that libsecp256k1
, libsecp256k1-zkp
and the fund variant are all like very alive projects, right? Like we talked about, finding new ways to do like GCD or to take a square root or something, like things are getting faster, safer all the time. And then also, taproot adding Schnorr signatures gave us a lot of capability in terms of being able to do interesting signature aggregation. And, having reference implementations or really high quality implementations of things like FROST or MuSig or adaptor signatures means that those capabilities become more accessible to more developers. And, we’ll hopefully see more applications leveraging those new capabilities as they get kind of upstreamed into the common libraries.
NVK: Yeah, I second that. Our job is making a hadware wallet and like doing all the business logic and all the harder work to make it secure. But I do not want in any way to touch or write crypto primitives ourselves. So, the more stuff that has demand that is on libsecp256k1
, the more likelihood we have to expose that to the customers, right? And we would never expose anything that is not on main libsec. We don’t integrate ZKP because we have to build the bindings and everything else, and we don’t know what’s going to have demand. It’s tricky as a vendor to know how far you go there. Tim and Jonas, are there any other topics that I should bring up and maybe have two, three people who are the experts on it and should come on to talk about that maybe the market, the industry is not sort of aware of, or that, you know, just out of fun, you know, devs out there should know about?
Tim: Nothing that comes to my mind right now. But I just want to second what you said. I think we can also, in libsecp256k1
but also in other projects, we can improve on the basic things. We often work on the fancy, interesting ideas because they’re cool and fascinating, but there is also more we can do on the simple things and just get more reliable, good implementations out there to people to empower them to build applications on top of that. And yeah, I would like to do and see more of that.
Jonas: Go ahead, Jonas. Yep. So Vivek mentioned cross-input signature aggregation. I think if you haven’t covered that yet, that will be certainly an interesting topic, but it’s a little bit different.
NVK: That’s a date, we’re gonna do it.
Jonas: Because then we need to talk about consensus changes potentially. Whereas here we had the luxury of only talking about signatures and off-chain things.
NVK: Okay, we’re gonna talk more, and you guys now have my contact, feel free to bring up topics and things and we’re gonna put the effort on making it happen. That’s the sole purpose of this pod, is to make Bitcoin win and not talk about macros. So the more interesting shit that’s happening on the dev side and on the consensus side and things that I think that really matter, that could be sort of like talked and exposed to people, I think the better it is. Listen, guys, I am extremely, extremely thankful that you guys work on this project. I know for a fact that hundreds of thousands of people out there are more secure through our devices because of this library. I know that a lot of the market does use this library and more will be using this library. This is, it’s a mission, true mission critical stuff. I don’t think we could be moving forward with Bitcoin being worth even more without something like this. So, my gratefulness towards this library is bigger than you think. So thank you for working on it. And thank you for wasting two hours of your time talking about it on this pod. Hopefully we did manage to put everybody to sleep. And for the two people who are left still listening, thank you for listening. So with that, I think it’s time to close this up. Thank you so much.