Fair point, although 256-bit client seeds is way overkill. Not only would a malicious server have to guess which way you're going to bet (hi or lo), it would have to do a comprehensive search of client seeds for each server-seed it wants to test and then see if there's any statistical deviation. This is already out of the realm of possibility for an 80 bit seed, let alone bigger.
Furthermore, the statistically deviation drops off rapidly with a large amount of client seeds. Even with 40 bit client seeds, I can't imagine it's possible for a malicious operator to brute force a server seed that even has a 0.1% uplift over a randomly selected server seed.
Plus the reality is that for real provably fair validation, you don't want to trust the client anyway so the client seed complexity is pretty meaningless anyway.
I don't really think any of the large actors are doing anything malicious. Smaller operations might try to implement something like what is discussed here:
https://bitcointalksearch.org/topic/breaking-shuffle-based-provably-fair-implementations-can-cheat-players-proof-1494470. Utilizing a nonce would not preclude that type of attack. That said, complex client seeds wouldn't either.
In any case, my argument for client seed complexity is to prevent a class of attack that I haven't seen discussed much but certainly exists. I'll again reference Primedice, not to suggest they're doing anything malicious, but it's an easy example. They generate a client seed as such:
parseInt(Number(new Date) * Math.random() * 10)
This happens whenever the Change Seed modal is opened (or closed, this is probably a bug.) One problem is that in major browser implementations, Math.random() is implemented using xorshift128+ and is predictable. Another is that the value of the date object is easily guessable. Again, I'm not stating that Primedice is doing anything wrong, but when the client seed generation code is called, a call to Facebook's Pixel Events service is also made that easily identifies the fact that the user has opened that modal. If Primedice were to collect the results of just a few calls to Math.random(), and they don't even need to be consecutive, then it would be trivial for them to predict the generated client seed.
Generating a 256-bit hex string would not fix this, the same attack could be used. Using a csrng would fix this, until the site decides to overwrite that code in a targeted attack against a high-roller. The player producing their own complex seed will fix this problem.
Thank you for pointing out this shortcoming by PD. This is the whole point of all of this, to encourage an informed discussion that pushes all of us forward. Indeed this is something I will raise with our developers. Perhaps this is also an argument that there should be a 'standard' for provably fair cause otherwise one website can use ultra strong fairness and other sham fairness and still claim to be 'provably fair'. Maybe it's time to create a new term for a strong standard.
I really don't mean to place such a focus on Primedice, but in addition to the above, I also noticed that the client seed never changes when the user attempts to randomize. Upon opening the relevant modal, the component components.ModalsWrap.Modals.Seed.Seed.newClientSeed has its defaultValue attribute set to the new random value. However, it doesn't look like the component's state is ever updated, so the component is never rerendered. When the Change Seed button is clicked, the currently rendered value in this component is used, rather than the new random value. In effect, this causes the user to always have the same seed unless they enter their own.