I think it is great that Jef is working on a steganography implementation, but IMO the notion of "random offsets" is so fundamentally misguided that I hope he will reconsider.
I already did - the offsets idea was my second thought, permutation is third. I'm a big fan of the rigidly separated software tools approach. Just look at the pbmplus tookkit. But I also think it's perfectly ok to combine functions when there's a good enough reason. I think this is such a case. The problem is the length field - you've got to have it, and it's recognizable because it begins with a run of 0s. So the stego program should hide it. Mac Stego hides it by XORing with the 2nd-to-lsb of the following 32 bytes - that's a hack, and it won't slow an attacker down for a microsecond. jsteg, if I remember right, does some variable field width encoding - better, but it also remains recognizable to some extent. My solution is to store the file's bits in a specified pseudorandom permutation of the image's available bit positions. It's kind of like the frequency hopping of spread spectrum radio. This hides the length field very thoroughly. It also happens to hide anything else recognizable about the original file. Yes, you should use Stealth PGP for complete security, and my man page will tell you this. However, even with regular PGP the permutation will give you good security against casual attacks, perhaps even commercial attacks. Now, if you can think of a natural, simple interface for a standalone file permutation generator, I'll be happy to separate that part out, and make pnmstego just read bits and stick them in the image in order. The problem with separating it is the bits you want to leave alone. Either the file permutation generator has to generate *trinary* output, which seems gross, or the stego pipeline will have to include an initial DEstego step to extract the unmodified bits from the image. Either of those possibilities is more complicated than just building the permuter into pnmstego. --- Jef