zoukankan      html  css  js  c++  java
  • IDEA算法c语言实现

    原文:http://blog.csdn.net/sdccyong/article/details/6289410

    1. /* IDEA.h */  
    2. #ifndef IDEA_H  
    3. #define IDEA_H  
    4.   
    5. /* define return status */  
    6. #define IDEA_SUCCESS        0  
    7. #define IDEA_ERROR          1  
    8.   
    9. /* define data length */  
    10. #define IDEA_KEY_LEN        128  
    11. #define IDEA_BLOCK_SIZE     64  
    12. #define IDEA_SUB_BLOCK_SIZE 16  
    13.   
    14. /* define global variable */  
    15. #define IDEA_ADD_MODULAR    65536  
    16. #define IDEA_MP_MODULAR     65537  
    17.   
    18. /* define operation mode */  
    19. #define ECB 0  
    20. #define CBC 1  
    21. #define CFB 2  
    22. #define OFB 3  
    23.   
    24. /* define data type */  
    25. //typedef bool            bit_t, status_t;  
    26. typedef unsigned char   byte_t, uint8_t;  
    27. typedef unsigned short  word_t, uint16_t;  
    28. typedef unsigned int    dword_t, uint32_t, status_t;  
    29. typedef unsigned long long uint64_t;  
    30.   
    31. /* declare fuction */  
    32. status_t idea_encrypt(uint64_t plaintext, uint16_t key[8], uint64_t *ciphertext);  
    33. status_t idea_decrypt(uint64_t ciphertext, uint16_t key[8], uint64_t *plaintext);  
    34. status_t idea_round(uint16_t X[4], uint16_t Z[6], uint16_t out[4]);  
    35. status_t MA(uint16_t ma_in[2], uint16_t sub_key[2],uint16_t ma_out[2]);  
    36. status_t subkey_generation(uint16_t key[8], uint16_t sub_key[52]);  
    37. status_t subdkey_generation(uint16_t key[8], uint16_t sub_dkey[52]);  
    38. status_t extended_eucild(uint16_t d, uint32_t k, uint32_t *result);  
    39.   
    40. #endif  

    [c-sharp] view plaincopy
    1. /* IDEA(International Data Encryption Algorithm), refer to http://www.quadibloc.com/crypto/co040302.htm 
    2.  * IDEA.c, an IDEA encryption and decryption program. 
    3.  * Author shenyang 
    4.  * Mar. 4th, 2011 
    5.  * TODO: Fault analysis on IDEA, defence of fault analysis on IDEA. 
    6.  */  
    7.  
    8. #ifndef IDEA_H  
    9. #include "IDEA.h"  
    10. #endif  
    11.  
    12. #include <string.h>  
    13. #include <stdio.h>  
    14.   
    15. /* define operation */  
    16. static uint16_t add_mod(uint16_t a, uint16_t b);  
    17. static uint16_t mp_mod(uint16_t a,uint16_t b);  
    18. static uint16_t XOR(uint16_t a, uint16_t b);  
    19. static status_t left_shift(uint16_t key[8], int num);  
    20. static void swap(uint16_t *a, uint16_t *b);  
    21.   
    22. /* addition and mod 65536 */  
    23. static uint16_t add_mod(uint16_t a, uint16_t b)  
    24. {  
    25.     uint32_t tmp = a+b;  
    26.     uint16_t ret = tmp % IDEA_ADD_MODULAR;  
    27.     return ret;  
    28. }  
    29.   
    30. /* multiply and mod 65537 */  
    31. static uint16_t mp_mod(uint16_t a,uint16_t b)  
    32. {  
    33.     /* Note: In IDEA, for purposes of multiplication, a 16 bit word containing all zeroes is considered to represent the number 65,536; 
    34.      * other numbers are represented in conventional unsigned notation, and multiplication is modulo the prime number 65,537 
    35.      */  
    36.     uint64_t tmp, tmp_a, tmp_b; //if both a and b are 2^16, the result will be 2^32 which will exceed a 32-bit int  
    37.     tmp_a = a==0 ? (1<<16) : a;  
    38.     tmp_b = b==0 ? (1<<16) : b;  
    39.     tmp = (tmp_a * tmp_b) % IDEA_MP_MODULAR;  
    40.     return (uint16_t)(tmp);  
    41. }  
    42.   
    43. /* XOR */  
    44. static uint16_t XOR(uint16_t a, uint16_t b)  
    45. {  
    46.     return a^b;  
    47. }  
    48.   
    49. static void swap(uint16_t *a, uint16_t *b)  
    50. {  
    51.     uint16_t c = 0;  
    52.     c = *a;  
    53.     *a = *b;  
    54.     *b = c;  
    55. }  
    56.   
    57. /* IDEA encryption */  
    58. status_t idea_encrypt(uint64_t plaintext, uint16_t key[8], uint64_t *ciphertext)  
    59. {  
    60.     uint16_t X[4], sub_key[52], out[4];  
    61.     status_t st;  
    62.     int i, j;  
    63.       
    64.     /* cut 64-bit plaintext into 4 16-bit sub blocks */  
    65.     for(i = 0; i < 4; i++)  
    66.         X[i] = (plaintext >> (48-i*16)) & 0xffff;  
    67.       
    68.     /* generate sub keys */  
    69.     st = subkey_generation(key, sub_key);  
    70.       
    71.     for(i = 0; i < 8; i++)  
    72.     {  
    73.         idea_round(X, &(sub_key[i*6]), out);  
    74.         for(j = 0; j < 4; j++)  
    75.             X[j] = out[j];  
    76.     }  
    77.       
    78.     /* round 9, do output transform */  
    79.     //Note that the swap of B and C is not performed after round 8. So we swap them again.  
    80.     swap(&(out[1]), &(out[2]));  
    81.     out[0] = mp_mod(out[0], sub_key[48]);  
    82.     out[1] = add_mod(out[1], sub_key[49]);  
    83.     out[2] = add_mod(out[2], sub_key[50]);  
    84.     out[3] = mp_mod(out[3], sub_key[51]);  
    85.     *ciphertext = out[0];  
    86.     for(i = 1; i <= 3; i++)  
    87.         *ciphertext = ((*ciphertext)<<16)|out[i];  
    88.       
    89.     return st;  
    90. }  
    91.   
    92. /* IDEA decryption */  
    93. status_t idea_decrypt(uint64_t ciphertext, uint16_t key[8], uint64_t *plaintext)  
    94. {  
    95.     status_t st;  
    96.     uint16_t X[4], sub_dkey[52], out[4];  
    97.     int i, j;  
    98.       
    99.     for(i = 0; i < 4; i++)  
    100.         X[i] = (ciphertext >> (48-i*16)) & 0xffff;  
    101.       
    102.     /* generate sub keys for decryption*/  
    103.     st = subdkey_generation(key, sub_dkey);  
    104.     if(st != IDEA_SUCCESS)  
    105.         return st;  
    106.       
    107.     for(i = 0; i < 8; i++)  
    108.     {  
    109.         idea_round(X, &(sub_dkey[i*6]), out);  
    110.         for(j = 0; j < 4; j++)  
    111.             X[j] = out[j];  
    112.     }  
    113.       
    114.     out[0] = mp_mod(out[0], sub_dkey[48]);  
    115.     out[1] = add_mod(out[1], sub_dkey[49]);  
    116.     out[2] = add_mod(out[2], sub_dkey[50]);  
    117.     out[3] = mp_mod(out[3], sub_dkey[51]);  
    118.     swap(&(out[1]), &(out[2]));     //Note that the unswap in decryption is called after transform, that is different from the encryption.  
    119.       
    120.     *plaintext = out[0];  
    121.     for(i = 1; i <= 3; i++)  
    122.         *plaintext = ((*plaintext)<<16) | out[i];  
    123.           
    124.     return st;  
    125. }  
    126.   
    127. status_t idea_round(uint16_t X[4], uint16_t Z[6], uint16_t out[4])  
    128. {  
    129.     status_t st;  
    130.     uint16_t tmp[4], ma_in[2], ma_out[2];  
    131.     tmp[0] = mp_mod(X[0], Z[0]);    //step 1. multiply X1 by 1st sub key  
    132.     tmp[1] = add_mod(X[1], Z[1]);   //step 2. add X2 to 2nd sub key  
    133.     tmp[2] = add_mod(X[2], Z[2]);   //step 3. add X3 to 3rd sub key  
    134.     tmp[3] = mp_mod(X[3], Z[3]);    //step 4. multiply X4 by 4th sub key  
    135.       
    136.     ma_in[0] = XOR(tmp[0], tmp[2]); //step 5. XOR results in step 1 and step 3  
    137.     ma_in[1] = XOR(tmp[1], tmp[3]); //step 6. XOR results in step 2 and step 4  
    138.       
    139.     st = MA(ma_in, &Z[4], ma_out);  //step 7. MA diffusion  
    140.       
    141.     /* step 8. generate the output*/  
    142.     out[0] = XOR(tmp[0], ma_out[1]);  
    143.     out[1] = XOR(tmp[1], ma_out[0]);  
    144.     out[2] = XOR(tmp[2], ma_out[1]);  
    145.     out[3] = XOR(tmp[3], ma_out[0]);  
    146.     swap(&(out[1]), &(out[2]));  
    147.       
    148.     return st;  
    149. }  
    150.   
    151. /* MA diffusion */  
    152. status_t MA(uint16_t ma_in[2], uint16_t sub_key[2],uint16_t ma_out[2])  
    153. {  
    154.     uint16_t tmp[2];  
    155.       
    156.     tmp[0] = mp_mod(ma_in[0], sub_key[0]);  
    157.     tmp[1] = add_mod(ma_in[1], tmp[0]);  
    158.     ma_out[1] = mp_mod(tmp[1], sub_key[1]);  
    159.     ma_out[0] = add_mod(tmp[0], ma_out[1]);  
    160.       
    161.     return IDEA_SUCCESS;  
    162. }  
    163.   
    164. /* sub keys generation */  
    165. status_t subkey_generation(uint16_t key[8], uint16_t sub_key[52])  
    166. {  
    167.     int i, j;  
    168.     uint16_t tmp_key[8];  
    169.     for(i = 0; i < 8; i++)  
    170.         tmp_key[i] = key[i];  
    171.     for(i = 0; i < 6; i++)  
    172.     {  
    173.         for(j = 0; j < 8; j++)  
    174.             sub_key[i*8+j] = tmp_key[j];  
    175.         left_shift(tmp_key, 25);  
    176.     }  
    177.     for(i = 0; i < 4; i++)  
    178.         sub_key[48+i] = tmp_key[i];  
    179.     return IDEA_SUCCESS;  
    180. }  
    181.   
    182. /* sub dkeys generation 
    183.  *  
    184.  *The decryption key schedule is: 
    185.  * 
    186.  *The first four subkeys for decryption are: 
    187.  * 
    188.  *KD(1) = 1/K(49) 
    189.  *KD(2) =  -K(50) 
    190.  *KD(3) =  -K(51) 
    191.  *KD(4) = 1/K(52) 
    192.  * 
    193.  *and they do not quite follow the same pattern as the remaining subkeys which follow. 
    194.  * 
    195.  *The following is repeated eight times, adding 6 to every decryption key's index and subtracting 6 from every encryption key's index: 
    196.  * 
    197.  *KD(5)  =   K(47) 
    198.  *KD(6)  =   K(48) 
    199.  * 
    200.  *KD(7)  = 1/K(43) 
    201.  *KD(8)  =  -K(45) 
    202.  *KD(9)  =  -K(44) 
    203.  *KD(10) = 1/K(46) 
    204.  *  
    205.  */  
    206. status_t subdkey_generation(uint16_t key[8], uint16_t sub_dkey[52])  
    207. {  
    208.     status_t st;  
    209.     int i;  
    210.     uint16_t sub_key[52];  
    211.     uint32_t tmp;  
    212.       
    213.     st = subkey_generation(key, sub_key);  
    214.       
    215.     st = extended_eucild(sub_key[48], IDEA_MP_MODULAR, &tmp);  
    216.     if(st != IDEA_SUCCESS)  
    217.     {  
    218.         printf("subdkey_generation error!/n");  
    219.         return st;  
    220.     }  
    221.     sub_dkey[0] = tmp == 65536 ? 0 : (uint16_t)tmp;  
    222.     sub_dkey[1] = (IDEA_ADD_MODULAR - sub_key[49]) % IDEA_ADD_MODULAR;  
    223.     sub_dkey[2] = (IDEA_ADD_MODULAR - sub_key[50]) % IDEA_ADD_MODULAR;  
    224.     st = extended_eucild(sub_key[51], IDEA_MP_MODULAR, &tmp);  
    225.     if(st != IDEA_SUCCESS)  
    226.     {  
    227.         printf("subdkey_generation error!/n");  
    228.         return st;  
    229.     }  
    230.     sub_dkey[3] = tmp == 65536 ? 0 : (uint16_t)tmp;  
    231.       
    232.     for(i = 0; i < 8; i++)   //This is awful?!...May be I should make a table.  
    233.     {  
    234.         sub_dkey[4+i*6] = sub_key[52-(i+1)*6];  
    235.         sub_dkey[4+i*6+1] = sub_key[52-(i+1)*6+1];  
    236.         st = extended_eucild(sub_key[52-(i+1)*6-4], IDEA_MP_MODULAR, &tmp);  
    237.         if(st != IDEA_SUCCESS)  
    238.         {  
    239.             printf("subdkey_generation error!/n");  
    240.             return st;  
    241.         }  
    242.         sub_dkey[4+i*6+2] = tmp == 65536 ? 0 : (uint16_t)tmp;  
    243.         sub_dkey[4+i*6+3] = (IDEA_ADD_MODULAR - sub_key[52-(i+1)*6-2]) % IDEA_ADD_MODULAR;  
    244.         sub_dkey[4+i*6+4] = (IDEA_ADD_MODULAR - sub_key[52-(i+1)*6-3]) % IDEA_ADD_MODULAR;  
    245.         st = extended_eucild(sub_key[52-(i+1)*6-1], IDEA_MP_MODULAR, &tmp);  
    246.         if(st != IDEA_SUCCESS)  
    247.         {  
    248.             printf("subdkey_generation error!/n");  
    249.             return st;  
    250.         }  
    251.         sub_dkey[4+i*6+5] = tmp == 65536 ? 0 : (uint16_t)tmp;  
    252.     }  
    253.     return IDEA_SUCCESS;  
    254. }  
    255.   
    256. /* left shift */  
    257. static status_t left_shift(uint16_t key[8], int num)  
    258. {  
    259.     uint16_t copy_key[8];  
    260.     int i;  
    261.     for(i = 0; i < 8; i++)  
    262.         copy_key[i] = key[i];  
    263.     for(i = 0; i < 8; i++)  
    264.         key[i] = (copy_key[(i+num/16)%8]<<(num%16)) | (copy_key[(i+num/16+1)%8]>>(16-num%16));  
    265.     return IDEA_SUCCESS;  
    266. }  
    267.   
    268. /* Extended Eucild Algorithm to caculate d^-1 mod k*/  
    269. status_t extended_eucild(uint16_t d, uint32_t k, uint32_t *result)  
    270. {  
    271.     int x[4], y[4], t[4], q;  
    272.     int i;  
    273.     x[1] = x[2] = 0;  
    274.     x[3] = k;  
    275.     y[1] = 0, y[2] = 1;  
    276.     y[3] = d == 0 ? (1<<16) : d;  
    277.       
    278.     while(y[3] > 1)  
    279.     {  
    280.         q = x[3] / y[3];  
    281.         for(i = 1; i <= 3; i++)  
    282.             t[i] = x[i] - q*y[i];  
    283.         for(i = 1; i <= 3; i++)  
    284.             x[i] = y[i];  
    285.         for(i = 1; i <= 3; i++)  
    286.             y[i] = t[i];  
    287.     }  
    288.     if(y[3] == 1)  
    289.     {  
    290.         if(y[2] < 0)  
    291.             y[2] += k;  
    292.         *result = y[2];  
    293.         return IDEA_SUCCESS;  
    294.     }  
    295.     else  
    296.         return IDEA_ERROR;  
    297. }  

    [c-sharp] view plaincopy
    1. /* a simple test program of IDEA encryption and decryption.  
    2.  * Author shenyang 
    3.  * */  
    4. #include <stdio.h>  
    5. #include <string.h>  
    6. #include "IDEA.h"  
    7.   
    8. void usage()  
    9. {  
    10.     printf("Usage: IDEA [-e(encrypt)|-d(decrypt)]/n");  
    11. }  
    12.   
    13. void encrypt()  
    14. {  
    15.     uint16_t key[8];  
    16.     uint64_t plaintext[1024], ciphertext[1024];  
    17.     char str[1024];  
    18.     int block_cnt = 0, i = 0, len;  
    19.     printf("/ninput plaintext(in hex):");  
    20.     scanf("%s", str);  
    21.     len = strlen(str);  
    22.     for(; len%16 != 0; len++)//fill the text with '0' such that it can be cut into 64-bit blocks.  
    23.         str[len] = '0';  
    24.     str[len] = '/0';  
    25.       
    26.     while(sscanf(str+block_cnt*16, "%016llx", &(plaintext[block_cnt]))!=EOF)//4x16=64  
    27.         block_cnt++;  
    28.       
    29.     /*while(sscanf(str+block_cnt*4, "%04hx", &(tmp[block_cnt]))!=EOF) 
    30.         block_cnt++; 
    31.     for(i = 0; i*4 < block_cnt; i++) 
    32.     { 
    33.         plaintext[i] = tmp[i*4]; 
    34.         for(j = 1; j < 4; j++) 
    35.             plaintext[i] = (plaintext[i]<<16)|tmp[i*4+j]; 
    36.     } 
    37.     block_cnt /= 4;*/  
    38.       
    39.     printf("/ninput 128-bit secret key(in hex):");  
    40.     scanf("%s", str);  
    41.     len = strlen(str);  
    42.     if(len > 32)  
    43.     {  
    44.         printf("/nsecret key too long");  
    45.         return ;  
    46.     }  
    47.     for(; len < 32; len++)  
    48.         str[len] = '0';  
    49.     str[len] = '/0';  
    50.       
    51.     for(i = 0; i < 8; i++)  
    52.         sscanf(str+i*4, "%04hx", &key[i]);  
    53.   
    54.     printf("/nciphertext = ");  
    55.     for(i = 0; i < block_cnt; i++)  
    56.     {  
    57.         idea_encrypt(plaintext[i], key, &(ciphertext[i]));  
    58.         printf("%016llx", ciphertext[i]);  
    59.     }  
    60.     printf("/n");  
    61. }  
    62.   
    63. void decrypt()  
    64. {  
    65.     uint16_t key[8];  
    66.     uint64_t plaintext[1024], ciphertext[1024];  
    67.     char str[1024];  
    68.     int block_cnt = 0, i = 0, len;  
    69.     printf("/ninput ciphertext(in hex):");  
    70.     scanf("%s", str);  
    71.     len = strlen(str);  
    72.     for(; len%16 != 0; len++)  
    73.         str[len] = '0';  
    74.     str[len] = '/0';  
    75.       
    76.     while(sscanf(str+block_cnt*16, "%016llx", &(ciphertext[block_cnt]))!=EOF)  
    77.         block_cnt++;  
    78.     /*while(sscanf(str+block_cnt*4, "%04hx", &(tmp[block_cnt]))!=EOF) 
    79.         block_cnt++; 
    80.     for(i = 0; i*4 < block_cnt; i++) 
    81.     { 
    82.         ciphertext[i] = tmp[i*4]; 
    83.         for(j = 1; j < 4; j++) 
    84.             ciphertext[i] = (ciphertext[i]<<16)|tmp[i*4+j]; 
    85.     } 
    86.     block_cnt /= 4;*/  
    87.       
    88.     printf("/ninput 128-bit secret key(in hex):");  
    89.     scanf("%s", str);  
    90.     len = strlen(str);  
    91.     if(len > 32)  
    92.     {  
    93.         printf("/nsecret key too long");  
    94.         return ;  
    95.     }  
    96.     for(; len < 32; len++)  
    97.         str[len] = '0';  
    98.     str[len] = '/0';  
    99.       
    100.     for(i = 0; i < 8; i++)  
    101.         sscanf(str+i*4, "%04hx", &key[i]);  
    102.   
    103.     printf("/nplaintext = ");  
    104.     for(i = 0; i < block_cnt; i++)  
    105.     {  
    106.         idea_decrypt(ciphertext[i], key, &(plaintext[i]));  
    107.         printf("%016llx", plaintext[i]);  
    108.     }  
    109.     printf("/n");  
    110. }  
    111.   
    112. int main(int argc, char **argv)  
    113. {  
    114.     if(argc < 2)  
    115.     {  
    116.         usage();  
    117.         return 1;  
    118.     }  
    119.     if(argv[1][0] != '-')  
    120.     {  
    121.         usage();  
    122.         return 1;  
    123.     }  
    124.     switch(argv[1][1])  
    125.     {  
    126.         case 'e':  
    127.         case 'E':   
    128.             encrypt();  
    129.             break;  
    130.         case 'd':  
    131.         case 'D':  
    132.             decrypt();  
    133.             break;  
    134.         default:  
    135.             usage();  
    136.             return 1;  
    137.     }  
    138.     return 0;  
    139. }  

    要注意的是不同环境下读64位整数的方式不同,可能要把%llx改成%I64x.

    阅读(675) | 评论(0) | 转发(1) |
    给主人留下些什么吧!~~
    评论热议
  • 相关阅读:
    UID卡、CUID卡、FUID卡的区别
    高中数学B版 高中数学A版
    Cenots7 服务搭建之搞清用户和组
    Flink 流处理 word count
    Flink Batch File Word Count
    Flink程序运行完yarn 模式后,返回运行standalone模式运行时。经常会出现运行不成功原因分析.
    Kafka消费者 API(自动提交offset)
    kafka 同步发送消息
    kafka 自定义分区
    kafka生产者 API Demo
  • 原文地址:https://www.cnblogs.com/black/p/5171610.html
Copyright © 2011-2022 走看看