#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2011
    Posts
    51
    Rep Power
    56

    Zx8 (ps) - Stream Cipher Algorithm/Source Code


    A very basic working encryption/decryption example using this algorithm/source code in ANSI-C and Python is available free for download at

    http://www.freecx.co.uk/zx8/

    Cheers,
    Karl-Uwe


    Code:
    /* 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
    */
    
    
    
    /*
    ------------------------------------------------------------------
     zx8 (ps) Test vectors
    ------------------------------------------------------------------
     Key:        Password
     Keystream:  8A1A89B3221AC4AB9AAB
     Plaintext:  Plaintext
     Ciphertext: DA76E8DA4C6EA1D3EEA1
    --------------------------------------------------------------------
     Key:        SecretKey
     Keystream:  983283BFE117A0B211E5B433FD0799DCBB43
     Plaintext:  Secure my Secrets
     Ciphertext: CB57E0CA937280DF68C5E7569E75FCA8C849
    --------------------------------------------------------------------
     Key:        HQQMG005
     Keystream:  9094D05D6D1F67EAE75C6A6FD59D35
     Plaintext:  Attack at dawn
     Ciphertext: D1E0A43C0E74478B937C0E0EA2F33F
    -------------------------------------------------------------------
     Key:        HQQMG007
     Keystream:  295C7428FC2C329C627ADD05043F76AC
     Plaintext:  Victory is near
     Ciphertext: 7F35175C935E4BBC0B09FD6B615E04A6
    -------------------------------------------------------------------
    */
    
    
    
    //-----------------------------------------
    //
    // zx8_ps  ***** #1 * 23.01.2012 *****
    //
    
    
    //-----------------------------------------
    //
    // Swap Values
    //
    // http://rosettacode.org/wiki/Generic_swap#Works_with:_gcc
    //
    #define swap(X,Y)  do { __typeof__ (X) _T = X; X = Y; Y = _T; } while(0)
    
    
    //-----------------------------------------
    //
    // Global Varaiable Definition
    //
    static unsigned char KeyWord[256]; int KeyLen=0;
    
    
    // Secret State Arrays
    //
    static unsigned char z[256], x[256];
    
    // Global Carry on Array Indices
    //
    static unsigned char a, b;
    
    // function
    unsigned char PRGA();
    
    
    //-----------------------------------------
    //
    // Key Schedule Algorithm (ps)
    //
    void KSA()
    {
      // Key must be at least 12 Characters long
      // and should have >= 60-Bit of Entropy.
      int i;
      unsigned char j, k, n, t;
    
      // Prefill the Arrays
      for (i=0; i<256; i++) {
        z[i] = i;
        x[i] = i;
      }
    
      a=0; b=0; j=0; k=0; n=0;
    
      for (i=0; i<256; i++) {
        k = (i % KeyLen);
    
        for (n=0; n<128; n++) t = PRGA();
        j = (t + j + z[i] + KeyWord[k]);
        swap(z[i], z[j]);
    
        for (n=0; n<128; n++) t = PRGA();
        j = (t + j + x[i] + z[x[j]]);
        swap(x[i], x[j]);
      }
    
      // Reset the Array Indices Start Point
      a=0; b=0;
    }
    
    
    //-----------------------------------------
    //
    // Pseudo Random Generation Algorithm (ps)
    //
    unsigned char PRGA()
    {
      unsigned char n1, n2, y, m;
    
      // Calculate distant Array Element Indices
      n1 = z[a] + x[a];
      n2 = z[b] + x[b];
    
      // First Swap randomly selected Array Element
      swap(z[a], z[n1]);
      swap(x[a], x[n2]);
    
      // Update the global Carry on Array Indices
      a = a + b + (n1^n2);
      b = b + 1;
    
      // Second Swap sequentially cycle over every Array Element
      swap(z[b], z[n1]);
      swap(x[b], x[n2]);
    
      // Calculate the internal State Selector Value
      y = (z[n1] ^ x[n2]);
    
      // Calculate the internal State Protection Value
      m = (n1 + n2);
    
      // Never reveal internal State Values directly
      return (z[x[y]] ^ m);
    }
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2011
    Posts
    51
    Rep Power
    56
    Just a little slimming the KSA listing.

    Cheers,
    Karl-Uwe

    Code:
    //-----------------------------------------
    //
    // Key Schedule Algorithm (ps)
    //
    void zx8_KSA(zx8_CTX *state, size_t keybytes, unsigned char *key)
    {
      int i;
      unsigned char j, bufI[128], bufO[128];
    
      // Prefill the Arrays
      for (i=0; i<256; i++) state->z[i] = state->x[i] = i;
    
      state->a = state->b = 0;
    
      for (i=0; i<256; i++) {
        zx8_PRGA(state, 128, bufI, bufO);
        j += (bufO[127] + state->z[i] + key[(i%keybytes)]);
        swap(state->z[i], state->z[j]);
    
        zx8_PRGA(state, 128, bufI, bufO);
        j += (bufO[127] + state->x[i] + state->z[state->x[j]]);
        swap(state->x[i], state->x[j]);
      }
    
      // Reset the Array Indices Start Point
      state->a = state->b = 0;
    }
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2011
    Posts
    51
    Rep Power
    56
    For convenient testing of very short text sequences using zx8 (ps) I have uploaded a simple Python script at

    http://www.freecx.co.uk/zx8/Python_Tests_STDIN/

    Just place zx8_ps__STDIN.py and zx8_ps_algorithm.py into the same folder, then execute for example

    Code:
    echo "Protected Privacy" | python ./zx8_ps__STDIN.py "SecretKeyWord"
    which will print this result

    Code:
    Keyword    = SecretKeyWord
      (hex)    = 53:65:63:72:65:74:4B:65:79:57:6F:72:64
    
    Plaintext  = 50:72:6F:74:65:63:74:65:64:20:50:72:69:76:61:63:79:0A
    Keystream  = 62:F9:D4:31:2F:63:CC:08:E1:6F:22:C6:0F:68:EB:F2:1B:62
    Ciphertext = 32:8B:BB:45:4A:00:B8:6D:85:4F:72:B4:66:1E:8A:91:62:68
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2011
    Posts
    51
    Rep Power
    56

    # zx8 Stream Cipher Algorithm - Design Rationale


    I like to explain a bit my ideas behind the algorithm of zx8 (ps).

    But first if we look how RC4 was and still is cryptanalysed over time since the algorithm is commonly known, remarkable steps have being made finding a way in breaking it. I like to mention the weak key problem, related key attacks and finally the solution to retrieve the secret key from the known internal state after the initialisation. Even though no practical attack exist in our days.

    When I am designing zx8 (ps) my intention was to avoid as much as possible that any of these known attacks on RC4 can be successful against zx8.

    For example if we look at the KSA of zx8 (ps) it becomes obvious that it take a great effort to fill these two lookup tables from a given key. Including the output of the PRGA within the key schedule process is quite something new to RC4 like stream ciphers, but one of the important steps in order to shuffle away any correlation between key and final internal state as much as possible.

    Furthermore by including the PRGA output a this early stage of recursively filling the two lookup tables a reverting and/or retrieving of the secret key after the KSA has finished become extremely difficult.

    Due to the usage of two separate lookup tables (z,x), a pseudo-random index column pointer (a), a sequential index column pointer (b), three pseudo-random index pointer (n1,n2,y) and an output masking value (m) we can take the advantage in letting the output of the PRGA at an early stage of the key scheduling process influence the complexity of the KSA byte shuffling. In fact it has the great effect that there is no need to drop any byte after the KSA has finished before using the keystream for encryption.

    Even more, if an adversary could ever guess the complete internal state at any time correctly while the encryption process, he has to do a great effort just to calculate the previous keystream (of course he can now generate the future one) or finding the secret key.

    Another important point is not to use just one but instead *two* separate lookup tables, unlike some other RC4 derivatives like RC4A, RC4+ or VMPC. And it is also very important to update these two lookup tables independently, therefore not to mix them up and always keep them independent. Of course this means these two lookup tables need to get initialised and updated in a well balanced way - and exactly that is what I have achieved with zx8 (ps).

    ... more to come.

    Cheers,
    Karl-Uwe
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2011
    Posts
    51
    Rep Power
    56

    # zx8 (ps) - Stream Cipher Visual Example


    I just have made two simplified examples in order to visualise how the algorithm itself works for those interested in order to help understanding the design idea behind.

    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

    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

    Cheers,
    Karl-Uwe
    Last edited by Karl-Uwe Frank; November 5th, 2012 at 07:07 AM. Reason: Updateing the examples
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    2
    Rep Power
    0
    What im doing wrong?
    Code:
    /* 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
    */
    
    /*
    ------------------------------------------------------------------
     zx8 (ps) Test vectors
    ------------------------------------------------------------------
     Key:        Password 
     Key (Hex):  50617373776F7264
     Keystream:  8A1A89B3221AC4AB9AAB   
     Plaintext:  Plaintext
     Ciphertext: DA76E8DA4C6EA1D3EEA1
    --------------------------------------------------------------------
     Key:        SecretKey  
     Key (Hex):  5365637265744B6579
     Keystream:  983283BFE117A0B211E5B433FD0799DCBB43           
     Plaintext:  Secure my Secrets   
     Ciphertext: CB57E0CA937280DF68C5E7569E75FCA8C849
    --------------------------------------------------------------------
     Key:        HQQMG005
     Key (Hex):  4851514D47303035
     Keystream:  9094D05D6D1F67EAE75C6A6FD59D35
     Plaintext:  Attack at dawn
     Ciphertext: D1E0A43C0E74478B937C0E0EA2F33F
    -------------------------------------------------------------------
     Key:        HQQMG007
     Key (Hex):  4851514D47303037
     Keystream:  295C7428FC2C329C627ADD05043F76AC
     Plaintext:  Victory is near
     Ciphertext: 7F35175C935E4BBC0B09FD6B615E04A6
    -------------------------------------------------------------------
     Example:
     echo "Secure my Secrets" | ./zx8_stdio 5365637265744B6579 > ciphertext.out
     cat ciphertext.out  | ./zx8_stdio 5365637265744B6579
    -------------------------------------------------------------------
    */
    
    
    #include <stdlib.h>
    #include <stdio.h> 
    #include <stdint.h>
    #include <string.h>
    
    //-----------------------------------------
    // 
    // Swap Values
    //
    // http://rosettacode.org/wiki/Generic_swap#Works_with:_gcc
    //
    #define swap(X,Y)  do { __typeof__ (X) _T = X; X = Y; Y = _T; } while(0)
    
    
    //-----------------------------------------
    //
    // Global Varaiable Definition
    // 
    typedef struct {
      unsigned char z[256];
      unsigned char x[256];
      unsigned char a, b;
    } zx8_CTX;
    
    
    // Function prototypes
    void zx8_KSA(zx8_CTX *state, size_t keybytes, unsigned char *key);
    void zx8_PRGA(zx8_CTX *state, size_t n, unsigned char *in, unsigned char *out);
    
    
    
    //-----------------------------------------
    // 
    // rm -f zx8_stdio && gcc -O3 -std=c99 zx8_stdio.c -o zx8_stdio
    // 
    //-----------------------------------------
    //
    // ./zx8_stdio $(echo -en 'egN99T8eK6peC2UC' | md5) < Plainfile > CipherFile
    // 
    // ./zx8_stdio 7d0ef66789aca2cfa6c76db7560554 <Plainfile >CipherFile
    //
    // cat CipherFile | ./zx8_stdio 7d0ef66789aca2cfa6c76db7560554 > Plainfile
    //
    
    
    //-----------------------------------------
    //
    
    
    //-----------------------------------------
    // Main 
    //
    int main(int argc, char *argv[]) 
    { 
    
    
      //-----------------------------------------
      //
      // Read the Encryption Keyword
      //
      unsigned char KeyWord[256]; int KeyLen;
      // only char here
      char KeyHash[512]; char hex[3]; 
      int i;
    
      // Make sure the arrays get initialised properly
      // and wipe out anything which might be there
      for (i=0; i<256; i++) KeyWord[i] = 0; KeyWord[256] = '\0';
      for (i=0; i<512; i++) KeyHash[i] = 0; KeyHash[512] = '\0';
      hex[0]=0; hex[1]=0; hex[2]='\0';
    
      // Rebuild KeyWord[] from KeyHash
      strcpy(KeyHash, argv[1]);
      KeyLen = strlen(KeyHash);
      KeyHash[KeyLen] = '\0';
    
      KeyLen = KeyLen/2;
      for (i=0; i<KeyLen; i++) {
        strncpy(hex, KeyHash +(i*2), 2);
        KeyWord[i] = strtol(hex, NULL, 16);
      }
    
       // Debug
      //fprintf(stderr,"Key   = ");
      //for (i=0; i<KeyLen; i++) fprintf(stderr,"%02x", KeyWord[i]);
     // fprintf(stderr,"\n");
      
      
    
      //-----------------------------------------
      // Initialisation of zx8(ps)
      //
      // perform the Key Schedule
      zx8_CTX ctx;
      zx8_KSA(&ctx, KeyLen, KeyWord);
    
    
      /* // Debug
      fprintf(stderr,"State = ");
      for (i=0; i<32; i++) fprintf(stderr,"%02x ", ctx.z[i]);
      fprintf(stderr,"\n\n");
      */
    
      //-----------------------------------------
      //
      // Encrypt/Decrypt Binary File(buffered Read/Write)
      //
      const    int  BUF_SIZE = 16384;
      unsigned char inB[BUF_SIZE], outB[BUF_SIZE];
    
    
    unsigned char plain[16384] = "blablabla";
    
    	zx8_PRGA(&ctx, strlen(plain2), plain, outB);
    printf("outB: %s\nstrlen(outB): %d\nargv[1]: %s\n", outB, strlen(outB), argv[1]);
    
    	zx8_PRGA(&ctx, strlen(outB), outB, inB);
    printf("inB: %s\nstrlen(inB): %d\n", inB, strlen(inB));
    
    
      return 0;   
    } 
    
    
    //-----------------------------------------
    // 
    // Key Schedule Algorithm (ps)
    //
    void zx8_KSA(zx8_CTX *state, size_t keybytes, unsigned char *key)
    {
      int i;
      unsigned char j, bufI[128], bufO[128]; 
    
      // Prefill the Arrays
      for (i=0; i<256; i++) state->z[i] = state->x[i] = i;
       
      state->a = state->b = 0; 
      
      for (i=0; i<256; i++) {
        zx8_PRGA(state, 128, bufI, bufO);
        j += (bufO[127] + state->z[i] + key[(i%keybytes)]);
        swap(state->z[i], state->z[j]);
        
        zx8_PRGA(state, 128, bufI, bufO);
        j += (bufO[127] + state->x[i] + state->z[state->x[j]]);
        swap(state->x[i], state->x[j]);
      } 
    
      // Reset the Array Indices Start Point
      state->a = state->b = 0; 
    }
    
    
    //-----------------------------------------
    //
    // Pseudo Random Generation Algorithm (ps)
    //
    void zx8_PRGA(zx8_CTX *state, size_t len, unsigned char *in, unsigned char *out)
    {
      unsigned char n1, n2, y;
      
      while (len--) {
        // Calculate distant Array Element Indices
        n1 = state->z[state->a] + state->x[state->a];
        n2 = state->z[state->b] + state->x[state->b];
      
        // First Swap randomly selected Array Element
        swap(state->z[state->a], state->z[n1]);
        swap(state->x[state->a], state->x[n2]);
      
        // Update the global Carry on Array Indices
        state->a += state->b + (n1^n2);
        state->b += 1;
      
        // Second Swap sequentially cycle over every Array Element
        swap(state->z[state->b], state->z[n1]);
        swap(state->x[state->b], state->x[n2]);
      
        // Calculate the internal State Selector Value
        y = (state->z[n1] ^ state->x[n2]);
        
        // Never reveal internal State Values directly
        *out++ = *in++ ^ (state->z[state->x[y]] ^ (n1+n2));
      }
    }
    Why i cnt decode string?
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2011
    Posts
    51
    Rep Power
    56
    Originally Posted by KAPAKYM
    What im doing wrong?

    Why i cnt decode string?
    Regarding our modifiation

    1) you need to pass the keyword as HEX values not as a character string like

    Code:
    ./zx8_ps $(echo -en 'the keyword' | md5)
    
     - or -
     
    ./zx8_ps  83131d7765a40e2d62130c85ddaa57fb

    2) you need to perform the KSA before decrypting the ciphertext because otherwise the internal state has moved on. You need to "reset" it with the proper values from the keyword in order to get the same internal state as for the encryption.

    Hope that helps.

    Cheers,
    Karl-Uwe

    Code:
    /* 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
    */
    
    /*
    ------------------------------------------------------------------
     zx8 (ps) Test vectors
    ------------------------------------------------------------------
     Key:        Password 
     Key (Hex):  50617373776F7264
     Keystream:  8A1A89B3221AC4AB9AAB   
     Plaintext:  Plaintext
     Ciphertext: DA76E8DA4C6EA1D3EEA1
    --------------------------------------------------------------------
     Key:        SecretKey  
     Key (Hex):  5365637265744B6579
     Keystream:  983283BFE117A0B211E5B433FD0799DCBB43           
     Plaintext:  Secure my Secrets   
     Ciphertext: CB57E0CA937280DF68C5E7569E75FCA8C849
    --------------------------------------------------------------------
     Key:        HQQMG005
     Key (Hex):  4851514D47303035
     Keystream:  9094D05D6D1F67EAE75C6A6FD59D35
     Plaintext:  Attack at dawn
     Ciphertext: D1E0A43C0E74478B937C0E0EA2F33F
    -------------------------------------------------------------------
     Key:        HQQMG007
     Key (Hex):  4851514D47303037
     Keystream:  295C7428FC2C329C627ADD05043F76AC
     Plaintext:  Victory is near
     Ciphertext: 7F35175C935E4BBC0B09FD6B615E04A6
    -------------------------------------------------------------------
     Example:
     echo "Secure my Secrets" | ./zx8_stdio 5365637265744B6579 > ciphertext.out
     cat ciphertext.out  | ./zx8_stdio 5365637265744B6579
    -------------------------------------------------------------------
    */
    
    
    #include <stdlib.h>
    #include <stdio.h> 
    #include <stdint.h>
    #include <string.h>
    
    //-----------------------------------------
    // 
    // Swap Values
    //
    // http://rosettacode.org/wiki/Generic_swap#Works_with:_gcc
    //
    #define swap(X,Y)  do { __typeof__ (X) _T = X; X = Y; Y = _T; } while(0)
    
    
    //-----------------------------------------
    //
    // Global Varaiable Definition
    // 
    typedef struct {
      unsigned char z[256];
      unsigned char x[256];
      unsigned char a, b;
    } zx8_CTX;
    
    
    // Function prototypes
    void zx8_KSA(zx8_CTX *state, size_t keybytes, unsigned char *key);
    void zx8_PRGA(zx8_CTX *state, size_t n, unsigned char *in, unsigned char *out);
    
    
    
    //-----------------------------------------
    // 
    // rm -f zx8_stdio && gcc -O3 -std=c99 zx8_stdio.c -o zx8_stdio
    // 
    //-----------------------------------------
    //
    // ./zx8_stdio $(echo -en 'egN99T8eK6peC2UC' | md5) < Plainfile > CipherFile
    // 
    // ./zx8_stdio 7d0ef66789aca2cfa6c76db7560554 <Plainfile >CipherFile
    //
    // cat CipherFile | ./zx8_stdio 7d0ef66789aca2cfa6c76db7560554 > Plainfile
    //
    
    
    //-----------------------------------------
    //
    
    
    //-----------------------------------------
    // Main 
    //
    int main(int argc, char *argv[]) 
    { 
    
    
      //-----------------------------------------
      //
      // Read the Encryption Keyword
      //
      unsigned char KeyWord[256]; int KeyLen;
      // only char here
      char KeyHash[512]; char hex[3]; 
      int i;
    
      // Make sure the arrays get initialised properly
      // and wipe out anything which might be there
      for (i=0; i<256; i++) KeyWord[i] = 0; KeyWord[256] = '\0';
      for (i=0; i<512; i++) KeyHash[i] = 0; KeyHash[512] = '\0';
      hex[0]=0; hex[1]=0; hex[2]='\0';
    
      // Rebuild KeyWord[] from KeyHash
      strcpy(KeyHash, argv[1]);
      KeyLen = strlen(KeyHash);
      KeyHash[KeyLen] = '\0';
    
      KeyLen = KeyLen/2;
      for (i=0; i<KeyLen; i++) {
        strncpy(hex, KeyHash +(i*2), 2);
        KeyWord[i] = strtol(hex, NULL, 16);
      }
    
      // Debug
      fprintf(stderr,"\n\n");
      fprintf(stderr,"Key   = ");
      for (i=0; i<KeyLen; i++) fprintf(stderr,"%02x ", KeyWord[i]);
      fprintf(stderr,"\n\n");
      
      
    
      //-----------------------------------------
      // Initialisation of zx8(ps)
      //
      // perform the Key Schedule
      zx8_CTX ctx;
    //-->  zx8_KSA(&ctx, KeyLen, KeyWord);        <================================= !!!!!!
    
    
      //-----------------------------------------
      //
      // Encrypt/Decrypt fixed String
      //
      const    int  BUF_SIZE = 16384;
      unsigned char inB[BUF_SIZE], outB[BUF_SIZE];
    
    
      // Initialise Plaintext
    
      unsigned char plainIN[20] = "blablabla2blubblub";
      unsigned char plainOUT[20] = "         ";
    
    
      fprintf(stderr,"Initialise Plaintext\n============================================\n");
    
      fprintf(stderr,"plainIN (as String) = ");
      for (i=0; i<strlen(plainIN); i++) fprintf(stderr,"%c",plainIN[i]);
      fprintf(stderr,"\n\n");
      
      fprintf(stderr,"plainIN (in HEX) = ");
      for (i=0; i<strlen(plainIN); i++) fprintf(stderr,"%02x ",plainIN[i]);
      fprintf(stderr,"\n\n");
    
    
      // Encrypt Plaintext
    
      fprintf(stderr,"Encrypt Plaintext\n============================================\n");
    
      zx8_KSA(&ctx, KeyLen, KeyWord);
      
      // Debug
      fprintf(stderr,"KeyWord = ");
      for (i=0; i<32; i++) fprintf(stderr,"%02x ", KeyWord[i]);
      fprintf(stderr,"\n\n");
    
      fprintf(stderr,"State = ");
      for (i=0; i<32; i++) fprintf(stderr,"%02x ", ctx.z[i]);
      fprintf(stderr,"\n\n");
      
      zx8_PRGA(&ctx, strlen(plainIN), plainIN, outB);
      fprintf(stderr,"Ciphertext (always HEX) = ");
      for (i=0; i<strlen(outB); i++) fprintf(stderr,"%02x ",outB[i]);
      fprintf(stderr,"\n\n");
    
    
    
      // Decrypt Ciphertext
    
      fprintf(stderr,"Decrypt Ciphertext\n============================================\n");
    
      zx8_KSA(&ctx, KeyLen, KeyWord);
    
      // Debug
      fprintf(stderr,"KeyWord = ");
      for (i=0; i<32; i++) fprintf(stderr,"%02x ", KeyWord[i]);
      fprintf(stderr,"\n\n");
    
      fprintf(stderr,"State = ");
      for (i=0; i<32; i++) fprintf(stderr,"%02x ", ctx.z[i]);
      fprintf(stderr,"\n\n");
    
      zx8_PRGA(&ctx, strlen(outB), outB, plainOUT);
      fprintf(stderr,"plainOUT (in HEX) = ");
      for (i=0; i<strlen(plainOUT); i++) fprintf(stderr,"%02x ",plainOUT[i]);
      fprintf(stderr,"\n\n");
    
      fprintf(stderr,"plainOUT (as String) = ");
      for (i=0; i<strlen(plainOUT); i++) fprintf(stderr,"%c",plainOUT[i]);
      fprintf(stderr,"\n\n");
    
    
      return 0;   
    } 
    
    
    //-----------------------------------------
    // 
    // Key Schedule Algorithm (ps)
    //
    void zx8_KSA(zx8_CTX *state, size_t keybytes, unsigned char *key)
    {
      int i;
      unsigned char j, bufI[128], bufO[128]; 
    
      // Prefill the Arrays
      for (i=0; i<256; i++) state->z[i] = state->x[i] = i;
       
      state->a = state->b = 0; 
      
      for (i=0; i<256; i++) {
        zx8_PRGA(state, 128, bufI, bufO);
        j += (bufO[127] + state->z[i] + key[(i%keybytes)]);
        swap(state->z[i], state->z[j]);
        
        zx8_PRGA(state, 128, bufI, bufO);
        j += (bufO[127] + state->x[i] + state->z[state->x[j]]);
        swap(state->x[i], state->x[j]);
      } 
    
      // Reset the Array Indices Start Point
      state->a = state->b = 0; 
    }
    
    
    //-----------------------------------------
    //
    // Pseudo Random Generation Algorithm (ps)
    //
    void zx8_PRGA(zx8_CTX *state, size_t len, unsigned char *in, unsigned char *out)
    {
      unsigned char n1, n2, y;
      
      while (len--) {
        // Calculate distant Array Element Indices
        n1 = state->z[state->a] + state->x[state->a];
        n2 = state->z[state->b] + state->x[state->b];
      
        // First Swap randomly selected Array Element
        swap(state->z[state->a], state->z[n1]);
        swap(state->x[state->a], state->x[n2]);
      
        // Update the global Carry on Array Indices
        state->a += state->b + (n1^n2);
        state->b += 1;
      
        // Second Swap sequentially cycle over every Array Element
        swap(state->z[state->b], state->z[n1]);
        swap(state->x[state->b], state->x[n2]);
      
        // Calculate the internal State Selector Value
        y = (state->z[n1] ^ state->x[n2]);
        
        // Never reveal internal State Values directly
        *out++ = *in++ ^ (state->z[state->x[y]] ^ (n1+n2));
      }
    }
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    2
    Rep Power
    0
    Code:
    ./test 2b246544dbcce012019c57b4b9728ecc1ca544dbcce012019c57b4b9728ecc1caa17ed
    Plain: blablabla2blubblub
    Decoded: ��P���^�O���s
    And now whats wrong? Its your code from previous post(i delete only debug)
    Code:
    int main(int argc, char *argv[]) 
    { 
      unsigned char KeyWord[256]; int KeyLen;
      // only char here
      char KeyHash[512]; char hex[3]; 
      int i;
    
      for (i=0; i<256; i++) KeyWord[i] = 0; KeyWord[256] = '\0';
      for (i=0; i<512; i++) KeyHash[i] = 0; KeyHash[512] = '\0';
      hex[0]=0; hex[1]=0; hex[2]='\0';
    
      // Rebuild KeyWord[] from KeyHash
      strcpy(KeyHash, argv[1]);
      KeyLen = strlen(KeyHash);
      KeyHash[KeyLen] = '\0';
    
      KeyLen = KeyLen/2;
      for (i=0; i<KeyLen; i++) {
        strncpy(hex, KeyHash +(i*2), 2);
        KeyWord[i] = strtol(hex, NULL, 16);
      }
    
      zx8_CTX ctx;
    
      const    int  BUF_SIZE = 16384;
      unsigned char inB[BUF_SIZE], outB[BUF_SIZE];
      unsigned char plainIN[20] = "blablabla2blubblub";
      unsigned char plainOUT[20] = "         ";
    
      
      printf("Plain: %s\n", plainIN);
    
      zx8_KSA(&ctx, KeyLen, KeyWord);
      zx8_PRGA(&ctx, strlen(plainIN), plainIN, outB);
    
    
      zx8_KSA(&ctx, KeyLen, KeyWord);
      zx8_PRGA(&ctx, strlen(outB), outB, plainOUT);
    
    printf("Decoded: %s\n", plainOUT);
    
    
      return 0;   
    }
    Try code without
    Code:
    fprintf(stderr, "some ****");
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2011
    Posts
    51
    Rep Power
    56
    Just try it this way

    Code:
      zx8_KSA(&ctx, KeyLen, KeyWord);
      zx8_PRGA(&ctx, strlen(plainIN), plainIN, outB);
      printf("Plain: %s\n", plainIN);
    
    
      zx8_KSA(&ctx, KeyLen, KeyWord);
      zx8_PRGA(&ctx, strlen(outB), outB, plainOUT);
      printf("Decoded: %s\n", plainOUT);

IMN logo majestic logo threadwatch logo seochat tools logo