blowfish-example.c

来自「嵌入环境下Blowfish加密算法的实现」· C语言 代码 · 共 525 行 · 第 1/2 页

C
525
字号
      0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L,
      0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
      0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL,
      0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L,
      0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L,
      0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL,
      0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
      0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL,
      0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L,
      0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL,
      0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L,
      0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
      0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
      0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
      0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
      0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L  }
};


unsigned long F(BLOWFISH_CTX *ctx, unsigned long x) {
  unsigned short a, b, c, d;
  unsigned long  y;

  d = x & 0x00FF;
  x >>= 8;
  c = x & 0x00FF;
  x >>= 8;
  b = x & 0x00FF;
  x >>= 8;
  a = x & 0x00FF;
  y = ctx->S[0][a] + ctx->S[1][b];
  y = y ^ ctx->S[2][c];
  y = y + ctx->S[3][d];

  return y;
}


void Blowfish_Encrypt(BLOWFISH_CTX *ctx, 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 ^ ctx->P[i];
    Xr = F(ctx, Xl) ^ Xr;
    temp = Xl;
    Xl = Xr;
    Xr = temp;
  }

  temp = Xl;
  Xl = Xr;
  Xr = temp;
  Xr = Xr ^ ctx->P[N];
  Xl = Xl ^ ctx->P[N + 1];
  *xl = Xl;
  *xr = Xr;
}

void Blowfish_Decrypt(BLOWFISH_CTX *ctx, 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 ^ ctx->P[i];
    Xr = F(ctx, Xl) ^ Xr;
    temp = Xl;
    Xl = Xr;
    Xr = temp;
  }

  temp = Xl;
  Xl = Xr;
  Xr = temp;

  Xr = Xr ^ ctx->P[1];
  Xl = Xl ^ ctx->P[0];

  *xl = Xl;
  *xr = Xr;
}


void Blowfish_Init(BLOWFISH_CTX *ctx, unsigned char *key, int keyLen) {
  int i, j, k;
  unsigned long data, datal, datar;

  for (i = 0; i < 4; i++) {
    for (j = 0; j < 256; j++)
      ctx->S[i][j] = ORIG_S[i][j];
  }

  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 >= keyLen)
        j = 0;
    }
    ctx->P[i] = ORIG_P[i] ^ data;
  }

  datal = 0x00000000;
  datar = 0x00000000;

  for (i = 0; i < N + 2; i += 2) {
    Blowfish_Encrypt(ctx, &datal, &datar);
    ctx->P[i] = datal;
    ctx->P[i + 1] = datar;
  }

  for (i = 0; i < 4; ++i) {
    for (j = 0; j < 256; j += 2) {
      Blowfish_Encrypt(ctx, &datal, &datar);
      ctx->S[i][j] = datal;
      ctx->S[i][j + 1] = datar;
    }
  }
}


int Blowfish_Test(BLOWFISH_CTX *ctx) {
  unsigned long L = 1, R = 2;

  Blowfish_Init (ctx, (unsigned char*)"TESTKEY", 7);
  Blowfish_Encrypt(ctx, &L, &R);
  if (L != 0xDF333FD2L || R != 0x30A71BB4L)
    return (-1);
  Blowfish_Decrypt(ctx, &L, &R);
  if (L != 1 || R != 2)
    return (-1);
  return (0);
}


#include <stdio.h>
#include <string.h>

int main (void) {
  BLOWFISH_CTX ctx;
  int n;

  /* must be less than 56 bytes */
  char *key = "a random number string would be a better key";
  int keylen = strlen(key);

  unsigned char *plaintext_string = "this is our message";
  int plaintext_len = strlen(plaintext_string);

  unsigned char ciphertext_buffer[256];
  unsigned char *ciphertext_string = &ciphertext_buffer[0];
  int ciphertext_len = 0;

  unsigned long message_left;
  unsigned long message_right;
  int block_len;


#if 1
  /* sanity test, encrypts a known message */
  n = Blowfish_Test(&ctx);
  printf("Blowfish_Test returned: %d.%s\n", n, n ? "  Abort." : "");
  if (n) return n;
#endif

  Blowfish_Init(&ctx, key, keylen);

  printf("Plaintext message string is: %s\n", plaintext_string);

  /* encrypt the plaintext message string */
  printf("Encrypted message string is: ");

  while(plaintext_len) {
    message_left = message_right = 0UL;

    /* crack the message string into a 64-bit block (ok, really two
       32-bit blocks); pad with zeros if necessary */
    for (block_len = 0; block_len < 4; block_len++) {
      message_left = message_left << 8;
      if (plaintext_len) {
	message_left += *plaintext_string++;
	plaintext_len--;
      }
      else message_left += 0;
    }
    for (block_len = 0; block_len < 4; block_len++) {
      message_right = message_right << 8;
      if (plaintext_len) {
	message_right += *plaintext_string++;
	plaintext_len--;
      }
      else message_right += 0;
    }

    /* encrypt and print the results */
    Blowfish_Encrypt(&ctx, &message_left, &message_right);
    printf("%lx%lx", message_left, message_right);

    /* save the results for decryption below */
    *ciphertext_string++ = (unsigned char)(message_left >> 24);
    *ciphertext_string++ = (unsigned char)(message_left >> 16);
    *ciphertext_string++ = (unsigned char)(message_left >> 8);
    *ciphertext_string++ = (unsigned char)message_left;
    *ciphertext_string++ = (unsigned char)(message_right >> 24);
    *ciphertext_string++ = (unsigned char)(message_right >> 16);
    *ciphertext_string++ = (unsigned char)(message_right >> 8);
    *ciphertext_string++ = (unsigned char)message_right;
    ciphertext_len += 8;
  }

  printf("\n");

  /* reverse the process */
  printf("Decrypted message string is: ");

  ciphertext_string = &ciphertext_buffer[0];
  while(ciphertext_len) {
      message_left = message_right = 0UL;

      for (block_len = 0; block_len < 4; block_len++) {
	message_left = message_left << 8;
	message_left += *ciphertext_string++;
	if (ciphertext_len)
	  ciphertext_len--;
      }
      for (block_len = 0; block_len < 4; block_len++) {
	message_right = message_right << 8;
	message_right += *ciphertext_string++;
	if (ciphertext_len)
	  ciphertext_len--;
      }

      Blowfish_Decrypt(&ctx, &message_left, &message_right);

      /* if the plaintext message string was padded, you will see
	 (by design) extra zeros here */
      printf("%c%c%c%c%c%c%c%c", (int)(message_left >> 24), (int)(message_left >> 16),
	     (int)(message_left >> 8), (int)(message_left),
	     (int)(message_right >> 24), (int)(message_right >> 16),
	     (int)(message_right >> 8), (int)(message_right));
    }
  
  printf("\n");
  
  return 0;
}



⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?