Steganography

The goal

The goal of our steganography is to hide a byte array in a image, the method must be robust to compression. The first problem is that exists a trade-off between compression level, image quality, hidden information amount. Who see the image should not be able to notice that it has been manipulated.

A second requirement is to make hard the reconstruction of the byte array without a key knowed only by client and server, in order to prevent attacks from third people to the communication.

We tried a lot of tecniques to hide the information: spread spectrum like tecniques and compression dependent tecniques. Spread spectrum like techniques work well but they have the issue that are not robust to compression. Compression dependent techniques works well despite the compression but they are hard to implement and the artefacts are quite visible.

Jpeg compression

The jpeg compression works dividing the bitmap colors in a matrix of luminance and two matrices of chrominance. Luminance is less visible by eyes so it is decimated of a factor of two. In order to compress pixels matrices are divided in blocks 8x8, and the DCT of each block is computated. A quantization matrix allows to requantize the coefficients in function of a compression level. In this way a lot of coefficinets being zero or similar, and it's easy to compress them using an RLE algorithm. Quantized coefficients are read with a zig-zag indexing when they are passed to RLE compression.

We started from ffjpeg source code that allows to compress and decompress jpeg files and we have edit the library in order to have a fast jpeg compression and decompression suitable for real time communications.

Proposed steganography algorithm

The proposed steganography algorithm works by edit the quantized DCT coefficients, only in the luminance matrix. The quantized DCT coefficients are lossless compressed so any changes is preserved as long as the image is decompressed. In order to hide the artefacts a random noise is applyed to some coefficients that doesn't contains messagge information, in this way the artifacts will appear like sensor noise, and will be difficult to recognize for a person who watch the video.

In each luminance 8x8 block one DCT quantization level is edited, we choose to change the coefficient in position 36 (of the zig-zag indexing) and we set it's value to +1 or -1, this is because experimentally we notice that it has a bit decay of quality of the image. This works well only for real photos, where the noise is hard to notice, for artificial image the noise added is visible, but in webcam recording it works well. The luminance blocks which contains the hidden information are chosen randomly. The element 36 of unchosen block are set also randomly to +1 or -1.

In the figure you can see the element number 36 of the zig-zag indexing indicated by a red cross.

Simple encryption

Server and client share a seed that allow them to synchronize our random number generators. The audio message is hidden in the image and can be reconstructed only knowing the seed and the frame number. This is because the bits of the audio mesage are in only some luminance block, others are random.

A C function generate a random vector of luminance blocks position. This function starts from an array s0 of M elements, where M is the number of luminance block in the image. This array is shuffled in order to make a distinct random position sequence from 0 to M-1. A second array s1 is initialized to 0 and we set the N elements indexed by the first N number of s0 to 1. Where N is the number of bits of the audio message. In this way we get an array of N < M distinct positions set to 1. These positions are the position where audio mssage bits will be write.

The position are calculated for each frame so without the seed it's very difficult to distinguish the bit that contains the audio message from the bits set randomly.

Mersenne Twister

Random is used for a lot of parts of the program. And the encryption depens on the random quality. Thus we use a Mersenne Twister random that it's fast and safe enough. We have chosen the Mersenne random implemetnation of the library mersenne-random-pure64 that is a famous implementation for the Haskell language.

Future improvement

In literature exist other ways to edit the jpeg DCT coefficients that reduce artefacts and noise and should be used to improve the video quality. Also the encryption method can be improve, in fact we can also encrypt the message with an algorithm like AES, instead of encrypt only the positions of the bits.