The PRGA of zx8 (ps) explained step by step from the first call after the KSA has finished ========================================================================================== A simplified approach in order to visualise how the algorithm itself works right after the key schedule process has being finished and the PRGA is called for the first time. 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 after several calls can be found here http://www.freecx.co.uk/zx8/docs/zx8_PRGA__Step_by_Step.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 right after the KSA has being finished. All arithmetic is performed modulo 256 #================================================================# a = 0 b = 0 0 244 | | +-------------------------------------------------------------------+ z | 23| 98| 7| 30|202| ... | 67| 15| ... |147| 62| ... | 89|...| +-------------------------------------------------------------------+ x |221| 4|224| 8| 45| ... |219| 19| ... | 52|177| ... |235|...| +-------------------------------------------------------------------+ 244 #***************************# n1 = z[a] + x[a] n2 = z[b] + x[b] #***************************# n1 = 23 + 221 n2 = 23 + 221 n1 = 244 n2 = 244 #================================================================# 0 244 | | +-------------------------------------------------------------------+ z | 23| 98| 7| 30|202| ... | 67| 15| ... |147| 63| ... | 89|...| +-------------------------------------------------------------------+ x |221| 4|224| 8| 45| ... |219| 19| ... | 52|177| ... |235|...| +-------------------------------------------------------------------+ | | a,b n1,n2 #***************************# swap(z[a], z[n1]) swap(x[a], x[n2]) #***************************# 23 <==> 89 221 <==> 235 0 244 | | +-------------------------------------------------------------------+ z | 89| 98| 7| 30|202| ... | 67| 15| ... |147| 63| ... | 23|...| +-------------------------------------------------------------------+ x |235| 4|224| 8| 45| ... |219| 19| ... | 52|177| ... |221|...| +-------------------------------------------------------------------+ | | a,b n1,n2 #================================================================# #***************************# a = a + b + (n1 XOR n2) b = b + 1 #***************************# a = 0 + 0 + (244 XOR 244) b = 0 + 1 a = 0 b = 1 #================================================================# 0 b=1 244 | | | +-------------------------------------------------------------------+ z | 89| 98| 7| 30|202| ... | 67| 15| ... |147| 63| ... | 23|...| +-------------------------------------------------------------------+ x |235| 4|224| 8| 45| ... |219| 19| ... | 52|177| ... |221|...| +-------------------------------------------------------------------+ | | b=1 n1,n2 #***************************# swap(z[b], z[n1]) swap(x[b], x[n2]) #***************************# 98 <==> 23 4 <==> 221 0 b=1 244 | | | +-------------------------------------------------------------------+ z | 89| 23| 7| 30|202| ... | 67| 15| ... |147| 63| ... | 98|...| +-------------------------------------------------------------------+ x |235|221|224| 8| 45| ... |219| 19| ... | 52|177| ... | 4|...| +-------------------------------------------------------------------+ | | b=1 n1,n2 #================================================================# 0 244 | | +-------------------------------------------------------------------+ z | 89| 23| 7| 30|202| ... | 67| 15| ... |147| 63| ... | 98|...| +-------------------------------------------------------------------+ x |235|221|224| 8| 45| ... |219| 19| ... | 52|177| ... | 4|...| +-------------------------------------------------------------------+ | n1,n2 n1 = 244 n2 = 244 #***************************# y = z[n1] XOR x[n2] #***************************# y = 98 XOR 4 y = 102 #================================================================# #***************************# m = n1 + n2 #***************************# m = 244 + 244 m = 232 #================================================================# 0 x[y]=219 244 | | | +-------------------------------------------------------------------+ z | 89| 23| 7| 30|202| ... | 67| 15| ... |147| 63| ... | 98|...| +-------------------------------------------------------------------+ x |235|221|224| 8| 45| ... |219| 19| ... | 52|177| ... | 4|...| +-------------------------------------------------------------------+ | y=102 x[y] = x[102] = 219 z[219] = 147 #***************************# z[x[y]] = 147 #***************************# #================================================================# m = 232 #***************************# output = z[x[y]] XOR m #***************************# output = 147 XOR 232 output = 123 #================================================================# # /* 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 # */