If I am understanding you correctly, you are taking the master public key (I'll just call it M) and a nonce N, and concatenate them together like this: [M N]
That is correct.
and hashing it all with SHA256 to get the child key?
Hashing is used just to get a number that is then added to this master public key. I could just increment my master public key, but then everyone would be able to link all of those addresses together, so that is why hashing is used, to get some deterministic offset from this master public key.
First it is trivial to derive the child key several numbers apart, so that the security of all of the keys depends on how well you safeguard the master private key.
If you have master public key, then it is trivial to derive other public keys that are deeper in the tree. But finding private keys is impossible (as far as I know), because you only know that master public key and the offset from this key if you know the nonce. Also, going to previous public keys in the tree seems to be impossible.
By contrast, a BIP32 HD wallet has several different layers of "nonces" (paths actually) so it would be slightly harder to find some child key if the master private key was compromised, assuming you used a non-standard derivation path.
In my scheme, you always just derive child keys from public keys, it is possible to create any path you want. So, you can just have one master public key and increment your nonce, but you can also do it in a different way and create paths like "15/32/5/7". Just take 15th (starting from zero) public key, derive 32th public key from it, then 5th key from this key and finally the 7th key from this key.
You can mitigate this by using a random 256-bit nonce
Nonce cannot be random, because the whole wallet have to be deterministic. You need to get nonce somehow, you can use a hash of something as a nonce, but then you need that data. So, for example if you use a hash of username, you have to know that username to derive keys properly. But if you use hash of some data as a nonce, you have to make sure that this data is unique (usernames have to be unique).
or even ditch it all together and just SHA256 M to get the first key, SHA256 it again to get the next one and so on
Getting any key should be as fast as possible. So, if some user has 1,000,000 th key, it should not be forced to calculate SHA-256 1,000,000 times, just once.
And second, the message length of SHA256 is 512 bits, this means that SHA256 actually hashes blocks of 512 bits at once - but of course spits out a 256-bit result - so if you just start from "0" and someone breaks a couple rounds of SHA256 for one of these inputs, then theoretically that can be used to break those rounds for all other [M N] combinations with different nonces as well, and that's because if an input isn't a multiple of 512 bits it's extended by a one bit followed by a bunch of zero bits to extend it to a multiple of 512. So from SHA256's point of view, the first couple child keys are dangerously close to M with no nonce at all!
Why? Any hashed message is always 512-bits aligned, you have 256-bit public key and 256-bit nonce. Then, the second block in SHA-256 always looks like this:
80000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000200But as you don't know the offset of the master public key if you received only derived public key, you have no idea what SHA-256 output you should start with when trying to reverse it.