The PRGA (Pseudo Random Generation Algorithm) of zx8 (ps) explained step by step ================================================================================ A simplified approach in order to visualise how the algorithm itself works. Example source code as well a test results can be found here http://www.freecx.co.uk/zx8/ A step-by-step example of the PRGA right after the KSA has being finished can be found here http://www.freecx.co.uk/zx8/docs/zx8_PRGA__Step_by_Step_from_zero.txt In short terms it uses two arrays of S-Boxes (z,x) which has to be imagined one below the other. That way we can calculate the sum of S-Box elements from both rows (z,x) in column (a) for example into the index pointer (n1) and the S-Box elements in column (b) into the index pointer (n2). As we later see the whole cipher algorithm is row and column based and the elements regarding the calculated index pointer are either swapped, used in further calculations or their value is used to select the next element from which a value is drawn. The values (a) and (b) are the column marker, where (a) is updated in a pseudo-random fashion and (b) increased by 1. So (a) jumps around and (b) moves straight forward and cycles around to 0 when it reaches over the right end. The values of (n1,n2) are used later in further calculations but moreover they are also making sure that the two lookup tables never get in a synchronised state, which is consider very important. (n1,n2) are used in very different ways but maintain their initial values over the generation of every byte output in a local scope only. 1) they are important to keep both lookup tables in a stable, balanced and unsynchronised state 2) they are accessed several times in different calculations and as lookup index pointers 3) in each calculation they are involved the way they are used is never the same, either they are added, involved in a exclusive-or-calculation or acting as index pointer Another important point is first to swap elements of (z,x) at column (a) and then calculate new values for (a,b) before swapping elements of (z,x) at column (b) in order to take an additional step breaking up any kind of correlation between the column values. This situation below can occur haphazardly at any time after several former calls of the PRGA All arithmetic is performed modulo 256 #================================================================# a = 3 b = 35 0 a=3 b=35 255 | | | | +---------------------------------------------------------------+ z | 23|198| 7| 30|202| ... | 67| 15| 0| 71| 39|162| ... | 89| +---------------------------------------------------------------+ x |221| 4|224| 9| 45| ... | 8| 19| 1|193|252| 77| ... |235| +---------------------------------------------------------------+ 39 34 #***************************# n1 = z[a] + x[a] n2 = z[b] + x[b] #***************************# n1 = 30 + 9 n2 = 15 + 19 n1 = 39 n2 = 34 #================================================================# 0 a=3 n1=39 255 | | | | +---------------------------------------------------------------+ z | 23|198| 7| 30|202| ... | 67| 15| 0| 71| 39|162| ... | 89| +---------------------------------------------------------------+ x |221| 4|224| 9| 45| ... | 8| 19| 1|193|252| 77| ... |235| +---------------------------------------------------------------+ | | a=3 n2=34 #***************************# swap(z[a], z[n1]) swap(x[a], x[n2]) #***************************# 30 <==> 162 9 <==> 8 0 a=3 n1=39 255 | | | | +---------------------------------------------------------------+ z | 23|198| 7|162|202| ... | 67| 15| 0| 71| 39| 30| ... | 89| +---------------------------------------------------------------+ x |221| 4|224| 8| 45| ... | 9| 19| 1|193|252| 77| ... |235| +---------------------------------------------------------------+ | | a=3 n2=34 #================================================================# a = 3 b = 35 n1 = 39 n2 = 34 #***************************# a = a + b + (n1 XOR n2) b = b + 1 #***************************# a = 3 + 35 + (39 XOR 34) b = 35 + 1 a = 43 b = 36 #================================================================# 0 b=36 n1=39 a 255 | | | | | +---------------------------------------------------------------+ z | 23|198| 7|162|202| ... | 67| 15| 0| 71| 39| 30| ... | 89| +---------------------------------------------------------------+ x |221| 4|224| 8| 45| ... | 9| 19| 1|193|252| 77| ... |235| +---------------------------------------------------------------+ | | n2=34 b=36 #***************************# swap(z[b], z[n1]) swap(x[b], x[n2]) #***************************# 0 <==> 30 1 <==> 9 0 b=36 n1=39 255 | | | | +---------------------------------------------------------------+ z | 23|198| 7|162|202| ... | 67| 15| 30| 71| 39| 0| ... | 89| +---------------------------------------------------------------+ x |221| 4|224| 8| 45| ... | 1| 19| 9|193|252| 77| ... |235| +---------------------------------------------------------------+ | | n2=34 b=36 #================================================================# 0 n1=39 255 | | | +---------------------------------------------------------------+ z | 23|198| 7|162|202| ... | 67| 15| 30| 71| 39| 0| ... | 89| +---------------------------------------------------------------+ x |221| 4|224| 8| 45| ... | 1| 19| 9|193|252| 77| ... |235| +---------------------------------------------------------------+ | n2=34 #***************************# y = z[n1] XOR x[n2] #***************************# y = 0 XOR 1 y = 1 #================================================================# n1 = 39 n2 = 34 #***************************# m = n1 + n2 #***************************# m = 39 + 34 m = 73 #================================================================# 0 x[y]=4 255 | | | +---------------------------------------------------------------+ z | 23|198| 7|162|202| ... | 67| 15| 30| 71| 39| 0| ... | 89| +---------------------------------------------------------------+ x |221| 4|224| 8| 45| ... | 1| 19| 9|193|252| 77| ... |235| +---------------------------------------------------------------+ | y=1 x[y] = x[1] = 4 z[4] = 202 #***************************# z[x[y]] = 202 #***************************# #================================================================# m = 73 #***************************# output = z[x[y]] XOR m #***************************# output = 202 XOR 73 output = 131 #================================================================# # /* zx8 (ps) - Stream Cipher Algorithm/Source Code */ # # /* # Copyright (c) 2012, Karl-Uwe Frank # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # #** zx8 (ps) algorithm developed by Karl-Uwe Frank # */