stegcryp.mws
Stegano
crypto
graphy
with Maple
8
Czeslaw Koscielny
2003
University of Zielona Gora, Poland
Institute of Control and Computation Engineering
e mail: c.koscielny@issi.uz.zgora.pl
As it is generally known,
steganography
is used to prevent confidential messages from being seen
or discovered, by concealing them in neutral messages, while
steganocryptography
attend to hide
cryptograms in the same manner. Majority of steganographic programs hide various types of messages
of rather small size in much greater harmless contents, usually in picture or music files. It has been shown
in this worksheet that, in practice, any type of file may serve as an envelope for hidden message of an arbitrary
size - one only ought to exactly know the structure of the envelope file. For instance, hiding messages in *. exe files
seems to be very interesting and promising (e. g. preventing unauthorized use of programs, protected by copyright).
Presented here steganographic concept is very simple: at the transmitter, a file to be hidden is converted,
as simple as possible, to a file of control ASCII characters having numbers from 0 to 15, next it is enciphered
by means of byte-oriented quasigroup based symmetric-key (as a secret key, in this case, encrypting
and decrypting 256-element quasigroups are used) synchronous stream cipher and placed on the end of the
envelope file, named here "a costume". Obtained in this manner steganocryptogram behaves, more or less,
as an envelope file and its size is two times greater than the size of secret message file. So, one can say that
steganocryptogram puts on a costume and imitates the envelope file, the more exactly the better. The recipient
"destegs" (steganographically recovers) cryptogram from envelope, deciphers it using the same secret key
(quasigroups) and the same keystream bytes
as at the transmitter (a costume file), and finally reads the
confidential message.
This Maple worksheet, named
stegcryp.mws,
is accompanied by the following files:
-
edqfr := proc(fp::string, n::posint);
procedure
,
which reads tables of operation
in ecrypting/decrypting quasigroups of order
n
, placed in the file named
fp
,
-
edq256.bin
,
a file, where tables of operation in
ecrypting/decrypting quasigroups are stored,
-
encipher := proc(message, costume, stegcryptogram:: string) ... end;
procedure producing stegcryptogram of a message to be hidden, its actual parameters are names
of the appropriate files (or paths to),
-
decipher := proc(stegcryptogram, costume:: string) ... end;
deciphers and destegs stegocryptograms (named
stegcryptogram
), simulating
costume
files.
In principle, in this procedure the only one formal parameter,
stegcryptogram
, may be used,
the second parametrer,
costume,
facilitates the programming work,
-
bach.exe, ckos1.dvi, ckos2.ps, rhythm.wav, unizg.jpg,
files which will be used
in several examples as secret messages of costumes. Their contents are, respectively:
-
very old (XT PC) music, short introduction to symmetric-key synchronous quasigroup-based stream-ciphers,
a method of generating cryptographically good sequences of integers which are powers of primes, several bars
of musical accompaniment and a photo of building where I work. I hope, the second and third files should be
useful not only as elements of examples, but also ought to be read by some people, not familiarized with the
concept of quasigroup-based ciphers.
You now are ready to experiment with steganocryptography. Place above specified files in current directory, please,
and let's begin.
Part 1. Preliminary works
It is important to be sure that all necessary files are in the same directory - it considerably simplifies invocation of procedures
used during producing steganocryptograms and recovering secret messages.
It is now certainly possible to see the code of procedures residing in the memory - it suffices to execute instructions:
>
interface(verboseproc = 1);
print(edqfr); print(encipher);
print(decipher);
Next you ought to declare global variables, storing the tables of operations in encrypting/decrypting quasigroups, and
to read the values of these tables from the file
edq256.bin:
> |
eq := array(1..256, 1..256):
dq := array(1..256,1..256):
edqfr("edq256.bin",256):
|
Quasigroup
eq
is used in an ecryption procedure.
You can observe an arbitrary fragment of table of operation
in the quasigroup
eq:
> |
for i from 241 to 256 do
for k from 3 to 18 do printf("%4d",eq[i,k]) od;
printf("\n")
od:
|
24 79 191 83 209 177 230 3 59 125 99 189 13 151 147 160
31 219 102 226 57 212 220 216 48 70 126 122 55 65 214 173
129 240 233 252 53 180 181 64 37 98 207 88 118 35 239 63
126 144 140 184 170 160 84 73 79 40 172 76 88 107 38 187
103 182 80 207 189 239 174 137 114 20 85 141 166 61 233 72
188 99 127 22 74 18 133 140 101 144 204 164 84 137 40 168
47 10 161 94 186 53 239 215 6 2 221 59 112 185 189 127
134 148 44 151 244 80 24 49 201 141 159 108 219 255 89 60
179 87 13 185 58 132 47 93 233 114 130 201 253 217 108 98
130 69 46 254 82 104 221 91 29 218 66 68 145 6 34 245
87 223 170 15 216 246 10 195 135 200 69 211 2 208 143 243
236 106 144 6 223 96 130 40 168 83 177 90 81 233 210 17
157 250 239 107 125 60 126 112 148 67 252 20 196 48 180 133
182 34 222 157 138 36 164 228 200 225 129 55 76 193 135 199
18 146 206 23 185 35 225 149 122 62 205 214 135 158 61 12
199 201 167 133 172 93 51 185 115 213 63 39 48 188 176 80
Similarly, a quasigroup
dq
is used in a decryption procedure, and it is also possible to observe an arbitrary part
of a table
of operation in
the quasigroup
dq
:
> |
for i from 5 to 20 do
for k from 1 to 16 do printf("%4d",dq[i,k]) od;
printf("\n")
od:
|
233 50 176 147 83 205 14 12 109 152 62 228 172 225 125 51
50 198 146 224 177 32 64 51 117 196 13 214 20 9 60 66
83 177 167 212 19 251 131 206 144 175 246 198 114 183 57 249
25 213 235 136 0 10 237 203 168 154 161 21 145 133 231 192
7 25 156 48 100 164 127 110 227 170 26 217 4 209 194 203
81 98 110 61 23 118 86 78 239 11 68 77 19 36 128 147
220 54 32 246 238 36 70 223 250 61 79 33 190 193 12 115
37 70 133 130 47 71 79 57 88 74 147 29 239 30 32 208
97 36 25 109 224 140 71 98 195 214 124 125 163 37 112 189
219 128 182 90 248 178 110 123 11 131 10 28 207 112 240 49
122 152 115 50 195 135 48 90 36 112 232 3 230 200 162 69
4 145 117 139 120 250 212 205 92 236 128 132 228 201 104 32
151 5 199 143 201 147 113 132 110 182 174 220 96 115 13 211
6 37 209 216 113 91 129 36 102 89 78 171 33 106 205 57
132 211 254 91 14 23 207 245 59 114 137 223 162 238 84 201
101 244 60 132 236 12 198 148 104 67 64 172 82 182 163 157
Part 2. Experiments
Example 1e
Stegoencryption of secret messages
ckos1.dvi, ckos2.ps, rhythm.wav, unizg.jpg
,
using as a costume the file
bach.exe
. You can observe that all files of stegocryptograms, namely
cw11.exe, cw21.exe, cw31.exe
and
cw41.exe
imitate the costume file, the file named
bach.exe
.
> |
encipher("ckos1.dvi","bach.exe","cw11.exe"):
encipher("ckos2.ps","bach.exe","cw21.exe"):
encipher("rhythm.wav","bach.exe","cw31.exe"):
encipher("unizg.jpg","bach.exe","cw41.exe"):
|
message file size = 47004 Bytes
costume file size = 27648 Bytes
stegcrypted file size = 121674 Bytes
stegencryption rate = 17005.79 Bytes per second
message file size = 316840 Bytes
costume file size = 27648 Bytes
stegcrypted file size = 661346 Bytes
stegencryption rate = 18666.20 Bytes per second
message file size = 199038 Bytes
costume file size = 27648 Bytes
stegcrypted file size = 425742 Bytes
stegencryption rate = 16210.95 Bytes per second
message file size = 96682 Bytes
costume file size = 27648 Bytes
stegcrypted file size = 221030 Bytes
stegencryption rate = 16012.26 Bytes per second
Now you can verify that the files
cw11.exe, cw21.exe, cw31.exe
and
cw41.exe
play the same role as the costume file.
Example 2e
Stegoencryption of secret messages
bach.exe, ckos2.ps, rhythm.wav, ckos1.dvi,
as costume the file now is
unizg.jpg
is used. It can be seen that all files of stegocryptograms, that is
cw12.exe, cw22.exe, cw32.exe
and
cw42.exe
pretend to be a photo file
unizg.jpg
.
> |
encipher("bach.exe","unizg.jpg","cw12.jpg"):
encipher("ckos2.ps","unizg.jpg","cw22.jpg"):
encipher("rhythm.wav","unizg.jpg","cw32.jpg"):
encipher("ckos1.dvi","unizg.jpg","cw42.jpg"):
|
message file size = 27648 Bytes
costume file size = 96682 Bytes
stegcrypted file size = 151996 Bytes
stegencryption rate = 16941.18 Bytes per second
message file size = 316840 Bytes
costume file size = 96682 Bytes
stegcrypted file size = 730380 Bytes
stegencryption rate = 17956.36 Bytes per second
message file size = 199038 Bytes
costume file size = 96682 Bytes
stegcrypted file size = 494776 Bytes
stegencryption rate = 16002.41 Bytes per second
message file size = 47004 Bytes
costume file size = 96682 Bytes
stegcrypted file size = 190708 Bytes
stegencryption rate = 15236.30 Bytes per second
Example 3e
As above, with a little different secret messages and with the envelope file
ckos2.ps.
> |
encipher("bach.exe","ckos2.ps","cw13.ps"):
encipher("unizg.jpg","ckos2.ps","cw23.ps"):
encipher("rhythm.wav","ckos2.ps","cw33.ps"):
encipher("edq256.bin","ckos2.ps","cw43.ps"):
|
message file size = 27648 Bytes
costume file size = 316840 Bytes
stegcrypted file size = 372154 Bytes
stegencryption rate = 14460.25 Bytes per second
message file size = 96682 Bytes
costume file size = 316840 Bytes
stegcrypted file size = 510222 Bytes
stegencryption rate = 15422.24 Bytes per second
message file size = 199038 Bytes
costume file size = 316840 Bytes
stegcrypted file size = 714934 Bytes
stegencryption rate = 15625.53 Bytes per second
message file size = 131072 Bytes
costume file size = 316840 Bytes
stegcrypted file size = 579002 Bytes
stegencryption rate = 15344.42 Bytes per second
Example 4e
The comment is the same as in previous examples -
stegcryp.mws
is now a costume. In passing,
Maple worksheets are steganocryptography very
friendly.
> |
encipher("bach.exe","stegcryp.mws","cw14.mws"):
encipher("unizg.jpg","stegcryp.mws","cw24.mws"):
encipher("rhythm.wav","stegcryp.mws","cw34.mws"):
encipher("edq256.bin","stegcryp.mws","cw44.mws"):
|
message file size = 27648 Bytes
costume file size = 52401 Bytes
stegcrypted file size = 107715 Bytes
stegencryption rate = 15953.84 Bytes per second
message file size = 96682 Bytes
costume file size = 52401 Bytes
stegcrypted file size = 245783 Bytes
stegencryption rate = 16448.11 Bytes per second
message file size = 199038 Bytes
costume file size = 52401 Bytes
stegcrypted file size = 450495 Bytes
stegencryption rate = 15951.11 Bytes per second
message file size = 131072 Bytes
costume file size = 52401 Bytes
stegcrypted file size = 314563 Bytes
stegencryption rate = 15864.44 Bytes per second
Example 5e
In the last example of stegoencryption the secret messages in the file
rhythm.wav
have been hidden.
> |
encipher("bach.exe","rhythm.wav","cw15.wav"):
encipher("ckos1.ps","rhythm.wav","cw25.wav"):
encipher("unizg.jpg","rhythm.wav","cw35.wav"):
encipher("edq256.bin","rhythm.wav","cw45.wav"):
|
message file size = 27648 Bytes
costume file size = 199038 Bytes
stegcrypted file size = 254352 Bytes
stegencryption rate = 14528.64 Bytes per second
message file size = 170300 Bytes
costume file size = 199038 Bytes
stegcrypted file size = 539656 Bytes
stegencryption rate = 16134.53 Bytes per second
message file size = 96682 Bytes
costume file size = 199038 Bytes
stegcrypted file size = 392420 Bytes
stegencryption rate = 15397.67 Bytes per second
message file size = 131072 Bytes
costume file size = 199038 Bytes
stegcrypted file size = 461200 Bytes
stegencryption rate = 15416.61 Bytes per second
Example 1d
Verifying if stegocryptograms obtained in example 1e are correctly desteged and decrypted.
> |
decipher("cw11.exe","bach.exe"):
decipher("cw21.exe","bach.exe"):
decipher("cw31.exe","bach.exe"):
decipher("cw41.exe","bach.exe"):
|
decrypted and desteged hidden message file name: cw11dec.dvi
stegodecryption rate = 20579.68 Bytes per second
decrypted and desteged hidden message file name: cw21dec.ps
stegodecryption rate = 22663.81 Bytes per second
decrypted and desteged hidden message file name: cw31dec.wav
stegodecryption rate = 19165.91 Bytes per second
decrypted and desteged hidden message file name: cw41dec.jpg
stegodecryption rate = 19232.54 Bytes per second
Example 2d
The comment as in example 1d, but verfication concerns stegocryptograms generated in the example 2e.
> |
decipher("cw12.jpg","unizg.jpg"):
decipher("cw22.jpg","unizg.jpg"):
decipher("cw32.jpg","unizg.jpg"):
decipher("cw42.jpg","unizg.jpg"):
|
decrypted and desteged hidden message file name: cw12dec.exe
stegodecryption rate = 19720.40 Bytes per second
decrypted and desteged hidden message file name: cw22dec.ps
stegodecryption rate = 22062.53 Bytes per second
decrypted and desteged hidden message file name: cw32dec.wav
stegodecryption rate = 19001.24 Bytes per second
decrypted and desteged hidden message file name: cw42dec.dvi
stegodecryption rate = 18549.33 Bytes per second
Example 3d
Interpretation of results obtained in this example is obvious.
> |
decipher("cw13.ps","ckos2.ps"):
decipher("cw23.ps","ckos2.ps"):
decipher("cw33.ps","ckos2.ps"):
decipher("cw43.ps","ckos2.ps"):
|
decrypted and desteged hidden message file name: cw13dec.exe
stegodecryption rate = 20166.30 Bytes per second
decrypted and desteged hidden message file name: cw23dec.jpg
stegodecryption rate = 19270.88 Bytes per second
decrypted and desteged hidden message file name: cw33dec.wav
stegodecryption rate = 19202.89 Bytes per second
decrypted and desteged hidden message file name: cw43dec.bin
stegodecryption rate = 18539.18 Bytes per second
Example 4d
As in previous examples, concerning desteging and decrypting procedures.
> |
decipher("cw14.mws","stegcryp.mws"):
decipher("cw24.mws","stegcryp.mws"):
decipher("cw34.mws","stegcryp.mws"):
decipher("cw44.mws","stegcryp.mws"):
|
decrypted and desteged hidden message file name: cw14dec.exe
stegodecryption rate = 20299.56 Bytes per second
decrypted and desteged hidden message file name: cw24dec.jpg
stegodecryption rate = 19309.37 Bytes per second
decrypted and desteged hidden message file name: cw34dec.wav
stegodecryption rate = 19523.10 Bytes per second
decrypted and desteged hidden message file name: cw44dec.bin
stegodecryption rate = 18306.15 Bytes per second
Example 5d
Comment as in the previous examples.
> |
decipher("cw15.wav","rhythm.wav"):
decipher("cw25.wav","rhythm.wav"):
decipher("cw35.wav","rhythm.wav"):
decipher("cw45.wav","rhythm.wav"):
|
decrypted and desteged hidden message file name: cw15dec.exe
stegodecryption rate = 19307.26 Bytes per second
decrypted and desteged hidden message file name: cw25dec.ps
stegodecryption rate = 19867.01 Bytes per second
decrypted and desteged hidden message file name: cw35dec.jpg
stegodecryption rate = 18711.44 Bytes per second
decrypted and desteged hidden message file name: cw45dec.bin
stegodecryption rate = 18126.40 Bytes per second
It's worth knowing that computations has been performed on PC
with procesor x86 Family 6 Model 4 AuthenticAMD ~896MHz.
Part 3. Conclusions
It has been shown that it is possible to hide very fast very securely encrypted arbitrary secret message
of an arbitrary size in many types of other files, by converting the cryptogram of a secret message onto the file
of control characters numbered from 0 to 15. To do it effectively one must exactly know in which places of
the envelope file the bytes of cryptogram may be placed with impunity. The author the easiest way has chosen
and is placing the entire cryptogram on the end of the costume file. Such approach reduces, of course, the number
of possible types of costume files.
Presented procedures, contained in the file
scipm8.m
, have been iplemented as simple as possible to only
demonstrate the principle of one of may possible steganocryptographic method. Thus, they have several limitations
and imperfections. The procedures are completely non-resistant to input data errors, the secret messages file names
must have at least two characters in the extension part of file name, etc. It is evident that similar procedures, rewritten,
for example, in C or Fortran, can be a few dozen or more faster.
However, the author is convinced of the fact that several advantages of the presented approach will be easily
perceived and that some people will have fun in essaying to familiarize with steganocryptography and quasigroup-based
stream ciphers, either observing exhaustive set of enclosed examples, or preparing own ones. It also seems that
in exploring quasiqroup-based stream cipers the works [3, 4] may be useful.
Bibiography
[1] C. Kocielny
-
Spurious Galois Field
s, Appl. Math. and Comp. Sci., 1995, vol. 5, No. 1, pp. 169 -188.
[2]
C. Kocielny
- A Method of Constructing Quasigroup-Based Stream-Cipher
s, Appl. Math. and Comp. Sci.,
1996, vol. 6, No. 1, pp. 109 - 121.
[3]
C. Kocielny
-
NLPN
Sequences over GF(q
), Quasigroups and Related Systems, Institute of Mathematics,
Academy of Sciences Moldowa, No 4, 1997, pp. 89 - 102
[4] C. Kocielny
- Generating Quasigroups for Cryptographic Application
s, International Journal of Applied
Mathematics and Computer Science, Vol. 12, No 4, 2002, pp.
[5 ] and bibliographic items given in [1 - 4]