Proof of Stake (PoS) coins are generally considered safer than PoW coins, which are subject to 51% attacks. However, PressTab, the primary developer over at Hyperstake(HYP), has discovered a possible vulnerability that affects most PoS coins.
Can you tell me a little bit about how PoS coins work?
Contrary to popular belief, Proof of Stake is not all that different from Proof of Work. When you are mining a PoW coin, your goal is typically to create a hash that has a value below a certain threshold. Your miner continuously hashes inputs until it produces a hash under the target threshold, and then announces the hash to all its peers, which scan the information and ensure it meets the rules. When it is confirmed that it met the rules, everyone moves on to the next block in the chain.
Proof of Stake also tries to produce a hash that is below a certain target. The target is different for each peer (but governed by the same rules), instead of the same target network-wide as is the case for PoW. The target is equal to coin weight multiplied by the bits in the block (bits is difficulty inversed). Coin weight is calculated a little bit differently for each PoS coin, but for a simple example we can say that coin weight is equal to the coin group (technically called UTXO, but also known as “pile”, “coin block”, etc.) multiplied by how many days old it is.
So if I have a group of 1,000 coins that is two days old, I would have a weight of 2,000. In order for this to “stake”, or to mine a new block, I would need to create a hash that is less than 2,000 multiplied by nBits. If nBits is equal to something like 100, then I would need to produce a hash that is less than 2,000 * 100 = 200,000. As you can see, the more weight I have, the easier the target is. If that group of coins was five days old, I would have to produce a hash less than 5,000 * 100 = 500,000.
The primary goal of Proof of Stake is to prevent a Proof of Work style system where the most hashing equipment you have, the more likely you will hit the target first. So in order to avoid someone from hooking up miners and hashing to create a PoS block first, the protocol only allows one hash to be created per UTXO per second. So if I were to be hashing on my desktop here and also have a server hashing the same wallet, they would create identical hashes and I would not have any extra advantage by hashing with more power at once.
If I have one UTXO held by my wallet, I am limited to 1 new hash per second. However, if I have 10 UTXOs in my wallet, I will have ten unique hashes I can create per second. Hashing is entirely random, so often you may have a large coin weight, but since you are only creating one hash per second, it does not have good odds of staking right away. This is why man people that understand the staking protocol will prefer 10 UTXOs of 1,000 coins instead of 1 UTXO of 10,000 coins.
What is the timedrift parameter?
The timedrift parameter is put into the code to allow peers with out of sync clocks to still submit mined blocks to the network and be accepted.
A “timewarp” attack will use the drift parameter only to choose when to give the attack chain to the network. An attacker will create a block well into the future without announcing it to peers. This block will be so far into the future that it will significantly lower the difficulty. The attacker will then have to generate a large chain of blocks and then introduce the side chain to the peer network at a point in time when it will be within the timedrift allowance. The main network will see this chain as the legitimate chain and reorganize to the attack chain.
Coming back to the Proof of Stake world, I think it has always been known that peers could generate PoS blocks in the future as far as the timedrift will allow. What I do not think was realized is how dangerous even 5-15 minutes of timedrift allowance can be. To my knowledge, most of the previous concerns over timedrift for PoS coins has been centered around the difficulty being increased significantly, rather than network-wide decreases in difficulty.
For example, TEKcoin in the past suffered from a timewarp attack that completely stopped any PoS coins from being generated. TEK has a timedrift allowance of two hours into the future and a peer created a block almost exactly two hours into the future. When the difficulty code tried to adjust on the next block, it calculated that the last block took two hours to create. The next difficulty adjustment calculated that the last block took -2 hours to create.
This caused some major errors in the code and made PoS difficulty so unrealistically high that it was essentially impossible to create another PoS block. This form of timewarp attack was patched up by some code that simply reassigned any negative time change to 0. Many other coins had experienced this same attack before TEKcoin, but I use it as an example because I am more familiar with it.
It is worth noting that Blackcoin and some of the clones thereof, adjusted their timedrift parameter from 10 minutes to 15 seconds clear back when their updated staking protocol was released. Unfortunately, their protocol update whitepaper did not expand on why they made this change. Coins like Peercoin (currently top 20 in market capitalization), Novacoin, and other big name PoS coins still have absurdly high timedrift parameters of up to 2 hours in the future.
How did you discover this exploit? Are other coins vulnerable to this?
I set out to completely redesign the implementation of the stake hashing code. Peercoin’s reference implementation that almost every wallet uses is extremely ugly code that eats up a lot of your CPU for no good reason. As I mentioned earlier, you can only create one hash UTXO per second. The Peercoin hashing code will hash your UTXO 60 seconds into the future so that you establish a group of 60 hashes at once instead of one hash every second.
Each second that goes by, the code will then hash the same 59 hashes that it did one second ago, adding one new hash to the end that reflects the time changing. This becomes a burden on the CPU, and there is no reason to hash the same exact hash over and over.
My “liteStake” hashing code takes this into mind and tells your wallet to hash much less than before, only updating your set of hashes every 30 seconds or so, or when a new block is added to the chain thus changing your entire hash set.
I have seen “cheaters” on several blockchains creating blocks well into the future, it is easy to spot, and the rules allow it if it is within the timedrift parameters. I thought that it would be a good idea to take the edge away from these cheaters and give the ability to hash your blocks up to the maximum timedrift allowance.
Why would you want to hash into the future to begin with? The answer is simple; you have a dramatically higher chance of staking if you hash up to the maximum timedrift. For example, for HyperStake (before we forked it) the allowance was 15 minutes into the future.
This means that before the code tweak, we would create 60 hashes at a time, but after my code tweak we could all create 900 hashes at a time. This radically increased our chances of staking by 1400%. If we were to use my code on Peercoin, we would enhance our chance of staking by 11900%.
Did any incidents occur before this exploit was patched?
I thought that with this new code we would create more blocks, difficulty would shoot up, and block creation would stay approximately normal. What I failed to realize is that creating blocks into the future could significantly screw up difficulty.
Difficulty for PoS only looks at the difference in time between the two previous blocks. With my new code, we would often see things like block # 1000’s time at 2:30PM & block # 1001’s time at 2:45PM. They would be added to the network seconds apart from each other, but since the timestamps are being tweaked the difficulty code would think that we were taking 15 minutes to produce a valid stake hash. The target time to produce a valid hash is 90 seconds, so the difficulty would significantly drop. This kept happening time and time again, and our network difficulty went from 15+ to 3 overnight.
While our network difficulty dropped like crazy, we were producing way more blocks than we are supposed to. If you look at the charts provided, you will see that we added more than 2 times the coin supply than what we usually add in a day because we produced more than 2 times the number of stakes.
If we let this continue on the same path we would have ended up with severe hyperinflation (which is the last thing that a coin with an already high stake rate needs), and difficulty near zero. In my opinion, this combination would kill just about any coin.
The primary difference between this exploit and previous timewarp exploits is that this exploit is less about a single person targeting wealth (although it could be used for that too), but is an exploit that could be used by competing coins to ruin each other. For this to have the effect, it did on HYP; it needs to have a moderate amount of blocks being generated using the tweaked code.
If I wanted to destroy one of my competing PoS coins, I could release a wallet with this updated code that gives full use of the timedrift hashing and post the wallet in the public domain. I have a hard time believing that most people would not use a wallet that increases their chances of staking by more than one thousand percent.
What has HYP done to protect the network from this exploit?
The fix is as simple as making the timedrift parameter really narrow. We decided to change from 15-minute allowance to a one-minute allocation. We felt like this was a fair compromise between security and the inflexibility of a 15 second drift that coins like Blackcoin has. If someone tries to generate a block outside of our 60 minute window, it is simply rejected by the network. This change has returned HYP’s network to normal, and our difficulty is now 10+ again.
Thank you for your time presstab! Hopefully other coins follow your footsteps and patch this exploit in their coins as soon as possible.
Photo Sources: HyperStake
PoS coin owners, are you concerned? How will this effect your coin? Let us know in the comments below!