 Well, completely unplanned, but one of my favorite talks actually, who of you knows what Bitcoin is? What's that? Who knows how Bitcoin mining works? Well, few hands less actually. So maybe there's a part in the audience that's kind of a target for this talk. I always wonder whether there's kind of a way to explain in simple terms, what that means using Python, obviously, how Bitcoin mining works. Don't confuse this illustration with the real world there, but at least the algorithms and everything that is behind that are kind of really accessible by the use of Python actually. It all rests on hashing, what is hashing actually? A hash is a function, any function that can be used to map data of arbitrary size, with a text document thing of binary file or whatsoever to data of a fixed size. So it's kind of a mapping. The values returned have different names, so that might be a little bit of confusion, but it's all the same hash value, hash code, hash sum, or hash, simply a hash. Let's have a look what hashes are. Python fortunately provides us with hashlib, where you can do simple hashing. If we import that, we can use MD5. This is not what Bitcoin uses, so we will come to that in a second. And here as egocentric as I am, I'm using my name as an example. And you see, enlarge that a little bit, see it maybe a little better. Using hashlib, MD5, my name is a string object and do the hex digest. I see I get an output, so this is a fixed length actually. I change that, I add a number two to it, and I get another output. Same length. And then I make my complete name, Dr. E, if you're honest with me, it's kind of a long German name with a doctor in front of it, and the size of the output is still the same. So this all might look random, given the output, but be assured that this is kind of a deterministic procedure. And the clue behind that, and it's a reason this might already, the first two arrays might look like a password, and that's the way passwords are typically stored, but not with MD5 hopefully these days anymore. But it's pretty simple to get from the password itself to the hashcode or from any kind of input to the hashcode, but the opposite operation is a very hard one. To have the hashcode usually shouldn't allow you to recover what was used as the input. So that's the basic idea when it gets to storing passwords as a hashcode. So not even an administrator should be able to recover your password. But I use this as an example of how a password cracking with ProodForce might work. So I'm importing here the string library just to access the lowercase sets from A2Set. Actually, and I'm using this to here generate simple permutations of size one, which means I iterate from the first step to the last one. There are other ways to do that, but I will use permutations later on to generate passwords or to do the ProodForce. And you see A, B, C, D, the single characters lowercase, they all generate hashes of the same size. Again, it seems random, but it's a deterministic procedure. Now, if we do... Oh, well, I can leave it that way. It should be all enough. And now if you want to wire ProodForce, which means going through all thinkable combinations, we want to crack the password. If four characters lowercase, we need to check all the different permutations here. See, I'm starting with one character size password, go to four actually in this case. And you see there is one point in time where I'm successful. So going through all the possible combinations, I end up here with the correct hash code and I have cracked my simple easy password. Never use four character passwords, obviously. So here you see it's only with Python, which is not that fast, but here obviously fast enough is a third of a second. Now, let us enlarge the character set. I'm adding here now the numbers as well. So the space gets much larger. And this is actually what the second example is. We know already and I'm using this here in a sense that it's a little bit of a social hack. I know five and the combination is lowercase and numbers and I do the permutations. And this, as you can see, I run now until five characters, or this kind of a typo. And you see this already takes 30 seconds here in this proved force case, so a lot longer. And I'm using here already kind of meter information, which I typically wouldn't have a way with. There could be special characters, capital characters, and so forth, and this all increases. So when you read something or the website requires you to sort a path which has a minimum of one number, a minimum of one special character, and so forth, a minimum length of eight and so forth, you know now why this is the case. It makes it much harder to crack. The basic idea behind mining. Now I'm working with the SHA-256 code, which is actually the one that is used by the Bitcoin algorithm as well. So I see a lot more, which means twice as many characters for the output, 64 characters we have here. So it's considered to be much more secure when it gets to this cracking idea behind it. And yeah, same holds true. Different input, same length output. The idea behind mining now is, this doesn't fit anymore. Well, almost it fits. The idea behind mining now is to find a hash code. You don't see the left. I see it here. It is to find a hash code that is small enough. And small enough here means with a certain number of leading zeros. This is not completely correct, but for us human beings it's kind of the easiest way to crack the idea. The number of leading zeros, the more number of leading zeros, the smaller the hash code number actually. And here I'm working with C struct. Don't care if you don't know what it is. Think just in terms of numbers and leading zeros given the fixed size of the string. This is kind of the idea. This is easily illustrated that I'm looking for a hash code which is small enough. So here taking my hash code and this example from before, this is not small enough. So here I'm giving my target. I get back a false. Obviously my hash code number is not small enough. Now, and here you see already kind of a solution, one solution, not the only one. I'm now adding in front of Eve for characters. I'm adding a couple of numbers. And you see what I end up with is something that is now indeed small enough. So changing the input, changing the input step by step by step, or here I've figured it out and simply put it in here. I can find a combination which is indeed small enough. And in an application this would mean, so I presented the result so to say first, that I iterate over my string, my input string, adding numbers, numbers, numbers, increasing the numbers, it's called nouns in the algorithm. And I'm always checking by adding a number and recalculating the hash code, recalculating whether it's small enough or not. So it's simply a brute force algorithm. I see here I'm iterating 2.5 million times and so forth. And here you see this is the solution I presented first and I'll find the first one. And here you see there is another solution right after that. And later on below I have a third one and I end my algorithm here at 55 million iteration. I see this takes one minute, takes 10 seconds. So it's similar to the brute force algorithm. It's different but still similar in terms of that. It's just brute force that I use in order to come up with a solution here. Here the solution doesn't need to be exact. I just need something that is small enough. And this is actually the basic idea. There is no guarantee that this is finished after one minute, 10 seconds. So in the first example it was finished after one minute, 10 seconds and I got three solutions. I only need one to accomplish it but I got in one minute brute force input, I got three solutions here. I'm now changing the starting string to my first name and last name and you see I can go to 55 million and ending up with no solution at all. So again it's kind of, not only did I say well I always when I put in five minutes of effort to put it simple, I will find the solution. No, this is kind of an uncertain thing because there are so many combinations in this deterministic hash function that there is no guarantee that you will see anything anytime soon actually. These are already the basic, it's the basic idea behind mining a Bitcoin block. Now let us get to Bitcoin. I will skip over because of the lightning talk well too long already. I usually have like 10, 15 minutes for that. Skipping the unimportant parts. The important part here is the Bitcoin block which is comprised of certain inputs. Think of the whole thing as lots of components. Think of this whole thing with the transaction data below and so forth as kind of the input. Whether before, no matter how large the input we always end up with something of fixed length. My examples were simple strings with a couple of characters here. The input is a little bit larger. But this is the only difference if you like. Now the translation into Python codes. Again, details are not relevant but I translate the data into my Python world and do a little bit of number crunch. This is just to look up a couple of things not that important. And here, this is important for this particular block that I'm working with and I got this from a blog post I provided the reference here. The website. For this particular block, the target number was like that. Many, many leading zeros or many more than in my previous example. So this is kind of the threshold which we must pass. We must find a code that is smaller than this particular target hex string. This is just struct. This is more or less technique. This is the nouns I'm starting with. So typically what I would do is start at zero, and go through all the things. I did it before 55 million and so forth. Here we will find something below one billion and above 850. That's the reason why I'm starting here. Otherwise it takes so long on my machine with Python. And in principle now we have reached the point of the real mining procedure. This is indeed kind of how the algorithm looks. This is not more than what I presented before. Start with the nouns of zero. I increase the noun, not zero. Typically I would start with zero. Here in my example I started at 850 million. I increase it one by one. Do the packing of my new string, so to say if you like. Do the hashing and the hash algorithm here is two times char 256. You see here the header is first hashed and then hashed for a second time. So two layers if you like. And the rest is only to check whether the hash string is smaller than the target string. That's the complete idea. If my value is small enough then I'm successful. I have mined a bit cumplock. And you see here it goes from 850 million and I'm successful here. This is also not kind of a convergent way. The more I put in I see that something converges. In that sense the algorithm is kind of random, stochastic. Although the mechanism is deterministic and you see here at this particular iteration announce value I am successful and since I started kind of in a sophisticated fashion it's only 25 seconds. So this is all if you understand the hashing and what I presented before this is what this whole thing looks like. Finally the Merckler hash this is kind of an end note because it's the one thing is the mining, the other one is that all the transactions I pay you for something, get something from you and so forth is embedded in this block as well and you see in this block I think there have been 100 transactions embodied themselves by a SHA-256 code and they are all encoded in the Merckler hash and the Merckler hash works in a way that if you have 100 transactions you have 50 pairs and these two are put together and hashed. Then you have half the number, then again two pairwise things like a pyramid and you end up with a single thing but there are many many hash operations on one layer as well as layering up on top of that. Since the algorithm is already really hard to crack for a single input value you see through this layering it gets more and more complicated and the computational effort to reverse the procedure is kind of immense and huge and you see here with this function that you have seen it's a very small Python code you can aggregate all the transactions, be them 10, 50, 500 into a single hash and this is part of the block and gets hashed again. So we have every instance we have hashing and this is in principle how Bitcoin mining works and don't try it with Python they have now these ASICs available to circuits that are algorithm specific which means you can do a giga hash per second or multiple giga hashes per second where we are able here to do maybe a couple of 100,000 hashes per second but this is how Bitcoin mining works explained based on Python.