What security measures would you *add* to PPC's staking protocol?

As we all know (well those not drinking the coolaid), PPC is a very secure coin and platform for other coins to base off of, but nothing is perfect.
I outlined a two areas I believe that PPC, and clones of, have some potential security issues/ability for someone to really mess with the chain. (timedrift problems & Is Staking Protocol Too Predictable

I am the HyperStake developer, and plan to use our testnet to test some improvements to the code that will make it more secure - which could also help give some insights to any ideas you folks might have for PPC, since they use the same staking code. So my question to you PPC veterans, is what would you do to make PPC itself more secure? (if your answer is that PPC is perfect and that checkpoint servers blah blah, then please don’t respond).

My thoughts:

  • timedrift to 60 seconds
  • add the previous best block hash to your PoS hash, as this will make your stake hash change as each new block is added to the chain
  • add a cap to weight. This is an idea I have had with a few folks, that could help against someone that has a few large utxo’s that they keep until max weight day, and then unload onto the network, thus giving them significant weight and more chances to produce multiple blocks in a row. A cap would have to be tied to money supply so that it does not become outdated and too small.

Any other ideas?

- add the previous best block hash to your PoS hash, as this will make your stake hash change as each new block is added to the chain
I think that it could reintroduce „stake grinding attack”.

[quote=“kac-, post:2, topic:3348”]

- add the previous best block hash to your PoS hash, as this will make your stake hash change as each new block is added to the chain

I think that it could reintroduce „stake grinding attack”.[/quote]

To my limited understanding, the ability of successful stake grinding relies on the high variability of the inputs being hashed. Adding the last block hash gives more variance to the hashes, seeing as they don’t remain the same through perpetuity (which is why I think you replied as you did). But at the same time, if you are reducing PPC drift down to 60 seconds, or a smaller window, you are reducing variability greatly on that front. Also if this is done in conjunction with the cap on weight I mention above, it adds another limitation to the mix for the attacker.
I think that this new cocktail could be a bit stronger than the old cocktail, but it will take more analysis.

I am mostly going by your post here:

[quote=“kac-, post:12, topic:2502”]I would make SG that way:

  1. Prepare stake
    a) buy old minting keys
    b) buy old not-minting keys and mint blocks for 16 days (64 6 hour long stakeModifier intervals)
  2. Create 64 tuples (stake-selected-by-modifier, signature1, signature2), signatures that give different first bit of block hash
  3. Brute-force this 64 bit space:
    a) re-create chain w/ new signature
    b) mint on top of it for next stake modifier interval
    c) choose best/satisfying chain trust, remove oldest (block, sig,sig) tuple from 64 set, add new one
    d) repeat from (a)

    e) optimize, pray for more trusted chain, if not- take next ~bit combination and goto 3.a)

Can core-dev verify this flow? May run parallel.

Or go full-random and mix and mint till you win.

Attacker needs 7200+ outputs, to cover whole 64 bit space he needs (2^64 - 1) * 7 200 = 1.32 * 10^23 (10^8 peta) stake-hash / calc-sec, right? With time he’ll narrow his initial search space but to fight-the-random he’ll need to create computation branches from his best chains. IDK, leaving this thread until someone optimize it.[/quote]

Let’s assume a scenario where blockhash is added to the PoS hash, and timedrift is changed to 60 seconds. An attack psuedo code would look something like this:

ss << nTimeBlockFrom << nTxPrevOffset << txPrev.nTime << prevout.n << nTimeTx << bestBlockHash;
hashProofOfStake = Hash(ss.begin(), ss.end());
if hash meets target wrap it up into a new block and get the block hash without sending to network
2)
create next PoS hash, hope that you can hit the target (attack becomes less likely here)
target hit? create block and get the hash and move to the next iteration of the process

How large of a chain could you realistically create with this process? For each given time period you would have 60 hashes per utxo (as is the case with any 60 second drift allowance). The difference here is that you get a fresh set of tries each iteration. I suppose you could theoretically go through this process until you have created a good chain of blocks, but it increasingly becomes less likely each iteration.

The other question of this is whether you could insert this attack into the past, and create a chain that would be re-orged to. I tend to think it would be much more difficult, because blocks will be coming in much more tight on the main chain so it would be extremely hard to create an alternate chain with as much chain trust.

As sigmike pointed out, when you start a timedrift attack you gain 3600x2 times advantage to other minters because you can see into the future by 2hours. But after that you only gain one new second per second just like everyone else. You have no advantage after the first second. You could however turn off your wallet after the first second and turn it on again after two hours, having a 7200 times advantage for a second again. But on average you don’t have any advantage.

- add a cap to weight. This is an idea I have had with a few folks, that could help against someone that has a few large utxo's that they keep until max weight day, and then unload onto the network, thus giving them significant weight and more chances to produce multiple blocks in a row. A cap would have to be tied to money supply so that it does not become outdated and too small.

You can calculate how many coins you will need to mount an attack with, say, 50% chance to succeed in a month. Then split the coins into N transactions and see if your chance changes. I think you will find that the most efficient way to attack is not by releasing a few large stakes (hence the weigh cap is of less effectiveness to fend off attacks). See a real-life example of finding 6 blocks in a roll with a half million coins.

As sigmike pointed out, when you start a timedrift attack you gain 3600x2 times advantage to other minters because you can see into the future by 2hours. But after that you only gain one new second per second just like everyone else. You have no advantage after the first second. You could however turn off your wallet after the first second and turn it on again after two hours, having a 7200 times advantage for a second again.[size=12pt] But on average you don’t have any advantage. [/size][/quote]

So once you mint what’s eligible to be minted you now have wait another 30 days (just like everyone else) to start earning stake. So this isn’t considered an big exploit. No one is getting rich off of a 1 second minting advantage (due to the 30 day wait period to re-earn coinage again)

While we are at it, please also answer the following question:

“Have you stopped beating your wife?”

As sigmike pointed out, when you start a timedrift attack you gain 3600x2 times advantage to other minters because you can see into the future by 2hours. But after that you only gain one new second per second just like everyone else. You have no advantage after the first second. You could however turn off your wallet after the first second and turn it on again after two hours, having a 7200 times advantage for a second again. But on average you don’t have any advantage.[/quote]

Publishing blocks 2 hours into the future and screwing up difficulty adjustment is a big security flaw.

Also just to reiterate (not directed to anyone in general), I am looking for additional things that you think is a security risk that could be patched, if you don’t have something to add please refrain from clogging up the thread:

[quote=“presstab, post:1, topic:3348”]So my question to you PPC veterans, is what would you do to make PPC itself more secure? (if your answer is that PPC is perfect and that checkpoint servers blah blah, then please don’t respond).
[/quote]

I am sure there has to be a few things that some of you PPC veterans have had in the back of your mind as a potential security flaw?

Difficulty is adjusted every block and is calculated using blocks found in 7 days (correct me if I am wrong). I don’t see how releasing several blocks can mess up difficulty.

If somehow the totoal number of minting unspent outputs drops to less than 520 for the whole network, the blockchain will stop, because all outputs will be locked in the “staked” mode after finding a block, not being able to find new blocks unless released. But to released them new blocks will be needed. This means that only a few nodes might not be enough to run the network. This could be relevant to situations of 1) recovery from network split , 2) a low adoption (usually in the initial stage of a coin), 3) private blockchain such as peershares (I don’t know if the peershares template has changed the 520 parameter).

Difficulty is adjusted every block and is calculated using blocks found in 7 days (correct me if I am wrong). I don’t see how releasing several blocks can mess up difficulty.[/quote]

The code only looks at the last two blocks and the previous difficulty.

My reading of the code, and anyone feel free to jump in when I am wrong:

int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime();

nActualSpacing would equal 7200 (2 hours).

Get previous difficulty (lets assume it equals 1 for the sake of seeing how this will change)

bnNew.SetCompact(pindexPrev->nBits)
int64 nTargetSpacing = fProofOfStake? STAKE_TARGET_SPACING

nTargetSpacing = 600 (10 minutes)

int64 nInterval = nTargetTimespan / nTargetSpacing;

nInterval = 604800 / 600 = 1008

bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing);

bnNew = 1 *((1008-1) * 600 + 7200 + 7200) = 618600

bnNew /= ((nInterval + 1) * nTargetSpacing);

bnNew = 618600 / ((1008+1) * 600) = 1.0218

Note that this isn’t the actual human readable diff, and moves inversely of what we would expect. But we can see here, that even if we minted this block 1 second after the previous staked block, it would cause 2.18% decrease in difficulty.

Hmmm I did just notice a benefit in PPC code that many other coins with smaller targets cannot have. And that is that PPC has room for negative time. On most PoS coins a negative nActualSpacing is not allowed, because it can make difficulty so high that it will stop the chain. With PPC it looks like this condition is not needed, and the code can adjust much better to a block published in the future and the one published in the present after it.

This actually happened to HyperStake in its first couple of weeks. Went a day or two without the chain moving.

Probably wouldn’t be a problem for PPC itself because it still retains the PoW chain to move things along, but definitely a worry for PoS only coins.

What would I change in PPC to improve security? I would address this issue, in which POS minters can orphan POW blocks. http://www.peercointalk.org/index.php?topic=936