Thread: How to use the Blowfish algo?

  1. #1
    Registered User
    Join Date
    Jul 2008
    Posts
    10

    How to use the Blowfish algo?

    Hello,
    i would include he blowfish algo in a projekt, but i dont know how. Can someone help me and the other reader of this Thread.

    If i have this code:
    main.c
    Code:
    #include <iostream>
    
    using namespace std;
    
    int main() {
        char text[256] = "";
        char dec_text[256] = "";
        char pw[12]   = "";
        cout << "Text:" << endl;
        cin >> text;
        cout << "Password:" << endl;
        cin >> pw;
        // decrypt the text with blowfish and save it in dec_text
        dec_text = blowfisch(text, pw);  // :) ?
        cout << "Verschluesselter Text:" << dec_text << endl;
        return 0;
    }
    The blowfish.cpp algo:
    Code:
    #ifdef little_endian   /* Eg: Intel */
       #include <dos.h>
       #include <graphics.h>
       #include <io.h>
    #endif
    
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #ifdef little_endian   /* Eg: Intel */
       #include <alloc.h>
    #endif
    
    #include <ctype.h>
    
    #ifdef little_endian   /* Eg: Intel */
       #include <dir.h>
       #include <bios.h>
    #endif
    
    #ifdef big_endian
       #include <Types.h>
    #endif
    
    #include "Blowfish.h"
    
    #define N               16
    #define noErr            0
    #define DATAERROR         -1
    #define KEYBYTES         8
    #define subkeyfilename   "Blowfish.dat"
    
    unsigned long P[N + 2];
    unsigned long S[4][256];
    FILE*         SubkeyFile;
    
    short opensubkeyfile(void) /* read only */
    {
       short error;
    
       error = noErr;
    
       if((SubkeyFile = fopen(subkeyfilename,"rb")) == NULL) {
          error = DATAERROR;
       }
     
       return error;
    }
    
    unsigned long F(unsigned long x)
    {
       unsigned short a;
       unsigned short b;
       unsigned short c;
       unsigned short d;
       unsigned long  y;
    
       d = x & 0x00FF;
       x >>= 8;
       c = x & 0x00FF;
       x >>= 8;
       b = x & 0x00FF;
       x >>= 8;
       a = x & 0x00FF;
       //y = ((S[0][a] + S[1][b]) ^ S[2][c]) + S[3][d];
       y = S[0][a] + S[1][b];
       y = y ^ S[2][c];
       y = y + S[3][d];
    
       return y;
    }
    
    void Blowfish_encipher(unsigned long *xl, unsigned long *xr)
    {
       unsigned long  Xl;
       unsigned long  Xr;
       unsigned long  temp;
       short          i;
    
       Xl = *xl;
       Xr = *xr;
    
       for (i = 0; i < N; ++i) {
          Xl = Xl ^ P[i];
          Xr = F(Xl) ^ Xr;
    
          temp = Xl;
          Xl = Xr;
          Xr = temp;
       }
    
       temp = Xl;
       Xl = Xr;
       Xr = temp;
    
       Xr = Xr ^ P[N];
       Xl = Xl ^ P[N + 1];
     
       *xl = Xl;
       *xr = Xr;
    }
    
    void Blowfish_decipher(unsigned long *xl, unsigned long *xr)
    {
       unsigned long  Xl;
       unsigned long  Xr;
       unsigned long  temp;
       short          i;
    
       Xl = *xl;
       Xr = *xr;
    
       for (i = N + 1; i > 1; --i) {
          Xl = Xl ^ P[i];
          Xr = F(Xl) ^ Xr;
    
          /* Exchange Xl and Xr */
          temp = Xl;
          Xl = Xr;
          Xr = temp;
       }
    
       /* Exchange Xl and Xr */
       temp = Xl;
       Xl = Xr;
       Xr = temp;
    
       Xr = Xr ^ P[1];
       Xl = Xl ^ P[0];
    
       *xl = Xl;
       *xr = Xr;
    }
    
    short InitializeBlowfish(char key[], short keybytes)
    {
       short          i;
       short          j;
       short          k;
       short          error;
       short          numread;
       unsigned long  data;
       unsigned long  datal;
       unsigned long  datar;
    
       /* First, open the file containing the array initialization data */
       error = opensubkeyfile();
       if (error == noErr) {
          for (i = 0; i < N + 2; ++i) {
         numread = fread(&data, 4, 1, SubkeyFile);
       #ifdef little_endian      /* Eg: Intel   We want to process things in byte   */
                   /*   order, not as rearranged in a longword          */
         data = ((data & 0xFF000000) >> 24) |
            ((data & 0x00FF0000) >>  8) |
            ((data & 0x0000FF00) <<  8) |
            ((data & 0x000000FF) << 24);
       #endif
    
         if (numread != 1) {
            return DATAERROR;
         } else {
            P[i] = data;
         }
          }
    
          for (i = 0; i < 4; ++i) {
         for (j = 0; j < 256; ++j) {
             numread = fread(&data, 4, 1, SubkeyFile);
    
       #ifdef little_endian      /* Eg: Intel   We want to process things in byte   */
                   /*   order, not as rearranged in a longword          */
            data = ((data & 0xFF000000) >> 24) |
               ((data & 0x00FF0000) >>  8) |
               ((data & 0x0000FF00) <<  8) |
               ((data & 0x000000FF) << 24);
       #endif
    
             if (numread != 1) {
               return DATAERROR;
            } else {
               S[i][j] = data;
            }
         }
          }
    
          fclose(SubkeyFile);
    
          j = 0;
          for (i = 0; i < N + 2; ++i) {
         data = 0x00000000;
         for (k = 0; k < 4; ++k) {
            data = (data << 8) | key[j];
            j = j + 1;
            if (j >= keybytes) {
               j = 0;
            }
         }
         P[i] = P[i] ^ data;
          }
    
        datal = 0x00000000;
          datar = 0x00000000;
    
          for (i = 0; i < N + 2; i += 2) {
         Blowfish_encipher(&datal, &datar);
    
         P[i] = datal;
         P[i + 1] = datar;
          }
    
          for (i = 0; i < 4; ++i) {
         for (j = 0; j < 256; j += 2) {
    
            Blowfish_encipher(&datal, &datar);
       
            S[i][j] = datal;
            S[i][j + 1] = datar;
         }
          }
       } else {
          printf("Unable to open subkey initialization file : %d\n", error);
       }
    
       return error;
    }

    blowfish.h#
    Code:
    #define MAXKEYBYTES 56          /* 448 bits */
    // #define little_endian 1              /* Eg: Intel */
    #define big_endian 1            /* Eg: Motorola */
    
    short opensubkeyfile(void);
    unsigned long F(unsigned long x);
    void Blowfish_encipher(unsigned long *xl, unsigned long *xr);
    void Blowfish_decipher(unsigned long *xl, unsigned long *xr);
    I hope someone can say me how i can use the algo in my programm.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Well, if you have functions called "Blowfish_encipher" and "Blowfish_decipher" I would think you would use those to encipher and decipher, respectively (as opposed to some function "blowfisch" that you didn't bother to write, so far as I can tell).

  3. #3
    Registered User
    Join Date
    Mar 2008
    Posts
    43

  4. #4
    Registered User
    Join Date
    Mar 2008
    Posts
    43
    Quote Originally Posted by mingerso View Post
    Heres an example that would work on strings:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "blowfish.h"
    
    int main(int argc, char * argv[]) 
    {  
        int i;
        int len = strlen(argv[1]);
        unsigned long enc[len];
        char * str = argv[1];
        char denc[len];
        if(argc != 2)
        {
            fprintf(stderr, "Pass one string to encrypt.\n");
            exit(1);
        }    
        
        BLOWFISH_CTX ctx;
        /* you could replace this with a new key of course */
        Blowfish_Init (&ctx, (unsigned char*)"TESTKEY", 7);
        
        printf("Encrypting string(%d): %s\n", len, str);
        
        for(i = 0; i < len; i+=2)
        {
            enc[i] = str[i];
            enc[i+1] = str[i+1];		
            Blowfish_Encrypt(&ctx, &enc[i], &enc[i+1]);
            printf("(%d) ENC_DUMP: %c->0x%08lX, %c->0x%08lX\n", i, str[i], enc[i], str[i+1], enc[i+1]);
        }
        for(i = 0; i < len; i+=2)
        {
            Blowfish_Decrypt(&ctx, &enc[i], &enc[i+1]);
            denc[i] = enc[i];
            denc[i+1] = enc[i+1];
        }
        denc[len] = '\0';
        printf("Decrypted string: %s\n", denc);
        
        return 0;
    }

  5. #5
    Registered User
    Join Date
    Jul 2008
    Posts
    10
    mingerso,
    thank you for the code. How can i use there a password?

  6. #6
    Registered User
    Join Date
    Mar 2008
    Posts
    43
    Quote Originally Posted by Plasm4 View Post
    mingerso,
    thank you for the code. How can i use there a password?
    You would probably want to make some wrapper functions for encrypting and decrypting, but to change the password you have to use this:

    Code:
    Blowfish_Init (&ctx, (unsigned char*)"TESTKEY", 7);

  7. #7
    Registered User
    Join Date
    Jul 2008
    Posts
    10
    the blowfish.cpp
    have all crypts like
    static const unsigned long ORIG_P[16 + 2] = {
    0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
    0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
    0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
    0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
    0x9216D5D9L, 0x8979FB1BL
    };


    isnt it important for blowfish? it isnt in your code, only:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "blowfish.h"
    
    int main(int argc, char * argv[])
    {
        printf("beginn");
        int i;
        char text[];
        int len = strlen(text);
        unsigned long enc[len];
        char * str = text[len];
        char denc[len];
        cin >> text;
       /* if(argc != 2)
        {
            fprintf(stderr, "Pass one string to encrypt.\n");
            exit(1);
        }
    */
        BLOWFISH_CTX ctx;
        // you could replace this with a new key of course
        Blowfish_Init (&ctx, (unsigned char*)"pass", 7);
    
        printf("Encrypting string(%d): %s\n", len, str);
    
        for(i = 0; i < len; i+=2)
        {
            enc[i] = str[i];
            enc[i+1] = str[i+1];
            Blowfish_Encrypt(&ctx, &enc[i], &enc[i+1]);
            printf("(%d) ENC_DUMP: %c->0x%08lX, %c->0x%08lX\n", i, str[i], enc[i], str[i+1], enc[i+1]);
        }
        for(i = 0; i < len; i+=2)
        {
            Blowfish_Decrypt(&ctx, &enc[i], &enc[i+1]);
            denc[i] = enc[i];
            denc[i+1] = enc[i+1];
        }
        denc[len] = '\0';
        printf("Decrypted string: %s\n", denc);
    
        return 0;
    }
    and blowfish.h
    Code:
      
    typedef struct {
      unsigned long P[16 + 2];
      unsigned long S[4][256];
    } BLOWFISH_CTX;
    
    void Blowfish_Init(BLOWFISH_CTX *ctx, unsigned char *key, int keyLen);
    void Blowfish_Encrypt(BLOWFISH_CTX *ctx, unsigned long *xl, unsigned long *xr);
    void Blowfish_Decrypt(BLOWFISH_CTX *ctx, unsigned long *xl, unsigned long *xr);

  8. #8
    Registered User
    Join Date
    Mar 2008
    Posts
    43
    As I linked to before, you need to download the code from here: http://www.schneier.com/code/bfsh-koc.zip
    and you need to use the blowfish.c code when compiling.

    You could always use another code base since it can be done in many ways. Here's a list of open code:
    http://www.schneier.com/blowfish-download.html

    You also had a mistake in your changed code:
    Code:
    Blowfish_Init (&ctx, (unsigned char*)"pass", 7);
    should be
    Code:
    Blowfish_Init (&ctx, (unsigned char*)"pass", 4);
    The last parameter is the length of the password.

  9. #9
    Registered User
    Join Date
    Jul 2008
    Posts
    10
    Ok, i download bfsh-koc.zip

    undefined reference to `WinMain@16'|

    I must write a main funktion.

    Now i use the blowfish.c correct? it didnt worke?
    I past at the end of blowfish.c the errors:
    http://rafb.net/p/wWeCdM97.html


    But where must i put the clear text in?
    Blowfish_Decrypt(&ctx, &L, &R); << ?


    help pls

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Did you read your own file?
    Code:
    COMMENTS ON USING THIS CODE:
     
    Normal usage is as follows:
       [1] Allocate a BLOWFISH_CTX.  (It may be too big for the stack.)
       [2] Call Blowfish_Init with a pointer to your BLOWFISH_CTX, a pointer to
           the key, and the number of bytes in the key.
       [3] To encrypt a 64-bit block, call Blowfish_Encrypt with a pointer to
           BLOWFISH_CTX, a pointer to the 32-bit left half of the plaintext
    	   and a pointer to the 32-bit right half.  The plaintext will be
    	   overwritten with the ciphertext.
       [4] Decryption is the same as encryption except that the plaintext and
           ciphertext are reversed.

  11. #11
    Registered User
    Join Date
    Mar 2008
    Posts
    43
    Quote Originally Posted by Plasm4 View Post
    Ok, i download bfsh-koc.zip

    undefined reference to `WinMain@16'|

    I must write a main funktion.

    Now i use the blowfish.c correct? it didnt worke?
    I past at the end of blowfish.c the errors:
    http://rafb.net/p/wWeCdM97.html


    But where must i put the clear text in?
    Blowfish_Decrypt(&ctx, &L, &R); << ?


    help pls
    You have quite a few issues here and should take the code that was posted earlier as an example to encrypt strings. You don't just pass the whole string but have to do multiple passes to Blowfish_Encrypt() using 64 bits at a time (we're actually utilizing only 16 bits in this example or 2 chars). So if you saved the example as bf_test.c and with your compiler did something along the lines of:

    cc blowfish.c bf_test.c

    then you should get an executable that works.

    blowfish.c does not have main() defined and it sounds like you're trying to compile, assemble and link with just that file (which won't work because you need a _start point).

  12. #12
    Registered User
    Join Date
    Jul 2008
    Posts
    10
    cc blowfish.c bf_test.c
    Aha! this was the mistake.
    But i use windows. I havent got the gcc.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Plasm4 View Post
    cc blowfish.c bf_test.c
    Aha! this was the mistake.
    But i use windows. I havent got the gcc.
    So, if you are using MS compiler, you'd do "cl blowfish.c bf_test.c" or something similar.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. flow control algo
    By Mr.Bit in forum C Programming
    Replies: 4
    Last Post: 04-28-2008, 10:32 AM
  2. Maze generation algo
    By VirtualAce in forum Game Programming
    Replies: 7
    Last Post: 03-01-2006, 05:03 AM
  3. Perfect Number - faster Algo Pls..
    By loko in forum C Programming
    Replies: 18
    Last Post: 08-21-2005, 08:26 AM
  4. Figuring Algo for assignment
    By axon in forum C++ Programming
    Replies: 4
    Last Post: 10-30-2003, 11:03 AM
  5. base conversion algo
    By Unregistered in forum C++ Programming
    Replies: 2
    Last Post: 12-28-2001, 09:28 PM