原文:http://blog.csdn.net/sdccyong/article/details/6289410
-
- #ifndef IDEA_H
- #define IDEA_H
-
-
- #define IDEA_SUCCESS 0
- #define IDEA_ERROR 1
-
-
- #define IDEA_KEY_LEN 128
- #define IDEA_BLOCK_SIZE 64
- #define IDEA_SUB_BLOCK_SIZE 16
-
-
- #define IDEA_ADD_MODULAR 65536
- #define IDEA_MP_MODULAR 65537
-
-
- #define ECB 0
- #define CBC 1
- #define CFB 2
- #define OFB 3
-
-
-
- typedef unsigned char byte_t, uint8_t;
- typedef unsigned short word_t, uint16_t;
- typedef unsigned int dword_t, uint32_t, status_t;
- typedef unsigned long long uint64_t;
-
-
- status_t idea_encrypt(uint64_t plaintext, uint16_t key[8], uint64_t *ciphertext);
- status_t idea_decrypt(uint64_t ciphertext, uint16_t key[8], uint64_t *plaintext);
- status_t idea_round(uint16_t X[4], uint16_t Z[6], uint16_t out[4]);
- status_t MA(uint16_t ma_in[2], uint16_t sub_key[2],uint16_t ma_out[2]);
- status_t subkey_generation(uint16_t key[8], uint16_t sub_key[52]);
- status_t subdkey_generation(uint16_t key[8], uint16_t sub_dkey[52]);
- status_t extended_eucild(uint16_t d, uint32_t k, uint32_t *result);
-
- #endif
-
-
-
-
-
-
-
- #ifndef IDEA_H
- #include "IDEA.h"
- #endif
-
- #include
- #include
-
-
- static uint16_t add_mod(uint16_t a, uint16_t b);
- static uint16_t mp_mod(uint16_t a,uint16_t b);
- static uint16_t XOR(uint16_t a, uint16_t b);
- static status_t left_shift(uint16_t key[8], int num);
- static void swap(uint16_t *a, uint16_t *b);
-
-
- static uint16_t add_mod(uint16_t a, uint16_t b)
- {
- uint32_t tmp = a+b;
- uint16_t ret = tmp % IDEA_ADD_MODULAR;
- return ret;
- }
-
-
- static uint16_t mp_mod(uint16_t a,uint16_t b)
- {
-
-
-
- uint64_t tmp, tmp_a, tmp_b;
- tmp_a = a==0 ? (1<<16) : a;
- tmp_b = b==0 ? (1<<16) : b;
- tmp = (tmp_a * tmp_b) % IDEA_MP_MODULAR;
- return (uint16_t)(tmp);
- }
-
-
- static uint16_t XOR(uint16_t a, uint16_t b)
- {
- return a^b;
- }
-
- static void swap(uint16_t *a, uint16_t *b)
- {
- uint16_t c = 0;
- c = *a;
- *a = *b;
- *b = c;
- }
-
-
- status_t idea_encrypt(uint64_t plaintext, uint16_t key[8], uint64_t *ciphertext)
- {
- uint16_t X[4], sub_key[52], out[4];
- status_t st;
- int i, j;
-
-
- for(i = 0; i < 4; i++)
- X[i] = (plaintext >> (48-i*16)) & 0xffff;
-
-
- st = subkey_generation(key, sub_key);
-
- for(i = 0; i < 8; i++)
- {
- idea_round(X, &(sub_key[i*6]), out);
- for(j = 0; j < 4; j++)
- X[j] = out[j];
- }
-
-
-
- swap(&(out[1]), &(out[2]));
- out[0] = mp_mod(out[0], sub_key[48]);
- out[1] = add_mod(out[1], sub_key[49]);
- out[2] = add_mod(out[2], sub_key[50]);
- out[3] = mp_mod(out[3], sub_key[51]);
- *ciphertext = out[0];
- for(i = 1; i <= 3; i++)
- *ciphertext = ((*ciphertext)<<16)|out[i];
-
- return st;
- }
-
-
- status_t idea_decrypt(uint64_t ciphertext, uint16_t key[8], uint64_t *plaintext)
- {
- status_t st;
- uint16_t X[4], sub_dkey[52], out[4];
- int i, j;
-
- for(i = 0; i < 4; i++)
- X[i] = (ciphertext >> (48-i*16)) & 0xffff;
-
-
- st = subdkey_generation(key, sub_dkey);
- if(st != IDEA_SUCCESS)
- return st;
-
- for(i = 0; i < 8; i++)
- {
- idea_round(X, &(sub_dkey[i*6]), out);
- for(j = 0; j < 4; j++)
- X[j] = out[j];
- }
-
- out[0] = mp_mod(out[0], sub_dkey[48]);
- out[1] = add_mod(out[1], sub_dkey[49]);
- out[2] = add_mod(out[2], sub_dkey[50]);
- out[3] = mp_mod(out[3], sub_dkey[51]);
- swap(&(out[1]), &(out[2]));
-
- *plaintext = out[0];
- for(i = 1; i <= 3; i++)
- *plaintext = ((*plaintext)<<16) | out[i];
-
- return st;
- }
-
- status_t idea_round(uint16_t X[4], uint16_t Z[6], uint16_t out[4])
- {
- status_t st;
- uint16_t tmp[4], ma_in[2], ma_out[2];
- tmp[0] = mp_mod(X[0], Z[0]);
- tmp[1] = add_mod(X[1], Z[1]);
- tmp[2] = add_mod(X[2], Z[2]);
- tmp[3] = mp_mod(X[3], Z[3]);
-
- ma_in[0] = XOR(tmp[0], tmp[2]);
- ma_in[1] = XOR(tmp[1], tmp[3]);
-
- st = MA(ma_in, &Z[4], ma_out);
-
-
- out[0] = XOR(tmp[0], ma_out[1]);
- out[1] = XOR(tmp[1], ma_out[0]);
- out[2] = XOR(tmp[2], ma_out[1]);
- out[3] = XOR(tmp[3], ma_out[0]);
- swap(&(out[1]), &(out[2]));
-
- return st;
- }
-
-
- status_t MA(uint16_t ma_in[2], uint16_t sub_key[2],uint16_t ma_out[2])
- {
- uint16_t tmp[2];
-
- tmp[0] = mp_mod(ma_in[0], sub_key[0]);
- tmp[1] = add_mod(ma_in[1], tmp[0]);
- ma_out[1] = mp_mod(tmp[1], sub_key[1]);
- ma_out[0] = add_mod(tmp[0], ma_out[1]);
-
- return IDEA_SUCCESS;
- }
-
-
- status_t subkey_generation(uint16_t key[8], uint16_t sub_key[52])
- {
- int i, j;
- uint16_t tmp_key[8];
- for(i = 0; i < 8; i++)
- tmp_key[i] = key[i];
- for(i = 0; i < 6; i++)
- {
- for(j = 0; j < 8; j++)
- sub_key[i*8+j] = tmp_key[j];
- left_shift(tmp_key, 25);
- }
- for(i = 0; i < 4; i++)
- sub_key[48+i] = tmp_key[i];
- return IDEA_SUCCESS;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- status_t subdkey_generation(uint16_t key[8], uint16_t sub_dkey[52])
- {
- status_t st;
- int i;
- uint16_t sub_key[52];
- uint32_t tmp;
-
- st = subkey_generation(key, sub_key);
-
- st = extended_eucild(sub_key[48], IDEA_MP_MODULAR, &tmp);
- if(st != IDEA_SUCCESS)
- {
- printf("subdkey_generation error!/n");
- return st;
- }
- sub_dkey[0] = tmp == 65536 ? 0 : (uint16_t)tmp;
- sub_dkey[1] = (IDEA_ADD_MODULAR - sub_key[49]) % IDEA_ADD_MODULAR;
- sub_dkey[2] = (IDEA_ADD_MODULAR - sub_key[50]) % IDEA_ADD_MODULAR;
- st = extended_eucild(sub_key[51], IDEA_MP_MODULAR, &tmp);
- if(st != IDEA_SUCCESS)
- {
- printf("subdkey_generation error!/n");
- return st;
- }
- sub_dkey[3] = tmp == 65536 ? 0 : (uint16_t)tmp;
-
- for(i = 0; i < 8; i++)
- {
- sub_dkey[4+i*6] = sub_key[52-(i+1)*6];
- sub_dkey[4+i*6+1] = sub_key[52-(i+1)*6+1];
- st = extended_eucild(sub_key[52-(i+1)*6-4], IDEA_MP_MODULAR, &tmp);
- if(st != IDEA_SUCCESS)
- {
- printf("subdkey_generation error!/n");
- return st;
- }
- sub_dkey[4+i*6+2] = tmp == 65536 ? 0 : (uint16_t)tmp;
- sub_dkey[4+i*6+3] = (IDEA_ADD_MODULAR - sub_key[52-(i+1)*6-2]) % IDEA_ADD_MODULAR;
- sub_dkey[4+i*6+4] = (IDEA_ADD_MODULAR - sub_key[52-(i+1)*6-3]) % IDEA_ADD_MODULAR;
- st = extended_eucild(sub_key[52-(i+1)*6-1], IDEA_MP_MODULAR, &tmp);
- if(st != IDEA_SUCCESS)
- {
- printf("subdkey_generation error!/n");
- return st;
- }
- sub_dkey[4+i*6+5] = tmp == 65536 ? 0 : (uint16_t)tmp;
- }
- return IDEA_SUCCESS;
- }
-
-
- static status_t left_shift(uint16_t key[8], int num)
- {
- uint16_t copy_key[8];
- int i;
- for(i = 0; i < 8; i++)
- copy_key[i] = key[i];
- for(i = 0; i < 8; i++)
- key[i] = (copy_key[(i+num/16)%8]<<(num%16)) | (copy_key[(i+num/16+1)%8]>>(16-num%16));
- return IDEA_SUCCESS;
- }
-
-
- status_t extended_eucild(uint16_t d, uint32_t k, uint32_t *result)
- {
- int x[4], y[4], t[4], q;
- int i;
- x[1] = x[2] = 0;
- x[3] = k;
- y[1] = 0, y[2] = 1;
- y[3] = d == 0 ? (1<<16) : d;
-
- while(y[3] > 1)
- {
- q = x[3] / y[3];
- for(i = 1; i <= 3; i++)
- t[i] = x[i] - q*y[i];
- for(i = 1; i <= 3; i++)
- x[i] = y[i];
- for(i = 1; i <= 3; i++)
- y[i] = t[i];
- }
- if(y[3] == 1)
- {
- if(y[2] < 0)
- y[2] += k;
- *result = y[2];
- return IDEA_SUCCESS;
- }
- else
- return IDEA_ERROR;
- }
-
-
-
- #include
- #include
- #include "IDEA.h"
-
- void usage()
- {
- printf("Usage: IDEA [-e(encrypt)|-d(decrypt)]/n");
- }
-
- void encrypt()
- {
- uint16_t key[8];
- uint64_t plaintext[1024], ciphertext[1024];
- char str[1024];
- int block_cnt = 0, i = 0, len;
- printf("/ninput plaintext(in hex):");
- scanf("%s", str);
- len = strlen(str);
- for(; len%16 != 0; len++)
- str[len] = '0';
- str[len] = '/0';
-
- while(sscanf(str+block_cnt*16, "%016llx", &(plaintext[block_cnt]))!=EOF)
- block_cnt++;
-
-
-
-
-
-
-
-
-
-
-
- printf("/ninput 128-bit secret key(in hex):");
- scanf("%s", str);
- len = strlen(str);
- if(len > 32)
- {
- printf("/nsecret key too long");
- return ;
- }
- for(; len < 32; len++)
- str[len] = '0';
- str[len] = '/0';
-
- for(i = 0; i < 8; i++)
- sscanf(str+i*4, "%04hx", &key[i]);
-
- printf("/nciphertext = ");
- for(i = 0; i < block_cnt; i++)
- {
- idea_encrypt(plaintext[i], key, &(ciphertext[i]));
- printf("%016llx", ciphertext[i]);
- }
- printf("/n");
- }
-
- void decrypt()
- {
- uint16_t key[8];
- uint64_t plaintext[1024], ciphertext[1024];
- char str[1024];
- int block_cnt = 0, i = 0, len;
- printf("/ninput ciphertext(in hex):");
- scanf("%s", str);
- len = strlen(str);
- for(; len%16 != 0; len++)
- str[len] = '0';
- str[len] = '/0';
-
- while(sscanf(str+block_cnt*16, "%016llx", &(ciphertext[block_cnt]))!=EOF)
- block_cnt++;
-
-
-
-
-
-
-
-
-
-
- printf("/ninput 128-bit secret key(in hex):");
- scanf("%s", str);
- len = strlen(str);
- if(len > 32)
- {
- printf("/nsecret key too long");
- return ;
- }
- for(; len < 32; len++)
- str[len] = '0';
- str[len] = '/0';
-
- for(i = 0; i < 8; i++)
- sscanf(str+i*4, "%04hx", &key[i]);
-
- printf("/nplaintext = ");
- for(i = 0; i < block_cnt; i++)
- {
- idea_decrypt(ciphertext[i], key, &(plaintext[i]));
- printf("%016llx", plaintext[i]);
- }
- printf("/n");
- }
-
- int main(int argc, char **argv)
- {
- if(argc < 2)
- {
- usage();
- return 1;
- }
- if(argv[1][0] != '-')
- {
- usage();
- return 1;
- }
- switch(argv[1][1])
- {
- case 'e':
- case 'E':
- encrypt();
- break;
- case 'd':
- case 'D':
- decrypt();
- break;
- default:
- usage();
- return 1;
- }
- return 0;
- }
要注意的是不同环境下读64位整数的方式不同,可能要把%llx改成%I64x.
阅读(2572) | 评论(0) | 转发(1) |