Guest User

An Idea Variant

a guest
Jan 28th, 2015
347
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdint.h>
  2. #include <stdlib.h>
  3. #include <inttypes.h>
  4. #include <stdio.h>
  5.  
  6. typedef struct andIdea128_key_schedule
  7. {
  8.     uint8_t num_rounds;
  9.     uint16_t *subkeys;
  10. } anIdea128_key_schedule;
  11.  
  12. static inline uint16_t mult(uint16_t a, uint16_t b)
  13. {
  14.     return (uint16_t)(((uint32_t)a+1)*((uint32_t)b+1)%65537 - 1);
  15. }
  16.  
  17. static inline void anIdea128_round(uint16_t block[4], const uint16_t key[4])
  18. {
  19.     block[0] = mult(block[0], key[0]);
  20.     block[1] ^= key[1];
  21.     block[2] ^= key[2];
  22.     block[3] = mult(block[3], key[3]);
  23.  
  24.     block[1] = mult(block[0], block[1]);
  25.     block[2] = mult(block[3], block[2]);
  26.  
  27.     block[2] += block[1];
  28.     block[1] += block[2];
  29.     block[0] ^= block[2];
  30.     block[3] ^= block[1];
  31. }
  32.  
  33. anIdea128_key_schedule anIdea128_init(const uint16_t *key, size_t key_length,
  34.         uint8_t num_rounds)
  35. {
  36.     uint16_t i;
  37.     uint16_t pi[4] = {0x243F, 0x6A88, 0x85A3, 0x08D3};
  38.     uint16_t num_subkeys = num_rounds*4+16;
  39.     uint16_t temp_length = num_subkeys+7;
  40.     uint16_t *temp_subkeys;
  41.     anIdea128_key_schedule sched;
  42.    
  43.     if (key_length % 4 != 0 || num_rounds < 1)
  44.         return (anIdea128_key_schedule) {0, NULL};
  45.  
  46.     temp_subkeys = (uint16_t *)malloc(sizeof(uint16_t)*temp_length);
  47.     sched.subkeys = (uint16_t *)malloc(sizeof(uint16_t)*num_subkeys);
  48.     sched.num_rounds = num_rounds;
  49.  
  50.     for (i=0; i<temp_length; i++)
  51.     {
  52.         temp_subkeys[i] = i;
  53.     }
  54.  
  55.     for (i=0; i<key_length; i+=4)
  56.     {
  57.         anIdea128_round(temp_subkeys, key+i);
  58.     }
  59.    
  60.     for (i=1; i<(temp_length-3); i++)
  61.     {
  62.         temp_subkeys[i+3] ^= temp_subkeys[i-1];
  63.         temp_subkeys[i]   ^= key[i*4%key_length];
  64.         temp_subkeys[i+1] ^= key[i*4%key_length+1];
  65.         temp_subkeys[i+2] ^= key[i*4%key_length+2];
  66.         temp_subkeys[i+3] ^= key[i*4%key_length+3];
  67.  
  68.         anIdea128_round(temp_subkeys+i, pi);
  69.     }
  70.  
  71.     for (i=4; i<(temp_length-3); i++)
  72.     {
  73.         sched.subkeys[i-4] = temp_subkeys[i];
  74.     }
  75.     free(temp_subkeys);
  76.  
  77.     return sched;
  78. }
  79.  
  80. void anIdea128_dest(anIdea128_key_schedule *sched)
  81. {
  82.     free(sched->subkeys);
  83.     sched->subkeys = NULL;
  84.     sched->num_rounds = 0;
  85. }
  86.  
  87. void anIdea128_encrypt(uint16_t block[8], anIdea128_key_schedule sched)
  88. {
  89.     int16_t i;
  90.     uint16_t temp[4];
  91.  
  92.     for (i=0; i<8; i++)
  93.     {
  94.         block[i] ^= sched.subkeys[i];
  95.     }
  96.  
  97.     for (i=0; i<sched.num_rounds; i++)
  98.     {
  99.         temp[0] = block[i*4%8];
  100.         temp[1] = block[i*4%8+1];
  101.         temp[2] = block[i*4%8+2];
  102.         temp[3] = block[i*4%8+3];
  103.  
  104.         anIdea128_round(temp, sched.subkeys+(i+2)*4);
  105.  
  106.         block[(i+1)*4%8]   ^= temp[0];
  107.         block[(i+1)*4%8+1] ^= temp[1];
  108.         block[(i+1)*4%8+2] ^= temp[2];
  109.         block[(i+1)*4%8+3] ^= temp[3];
  110.     }
  111.  
  112.     for (i=0; i<8; i++)
  113.     {
  114.         block[i] ^= sched.subkeys[(sched.num_rounds+2)*4+i];
  115.     }
  116. }
  117. void anIdea128_decrypt(uint16_t block[8], anIdea128_key_schedule sched)
  118. {
  119.     int16_t i;
  120.     uint16_t temp[4];
  121.  
  122.     for (i=0; i<8; i++)
  123.     {
  124.         block[i] ^= sched.subkeys[(sched.num_rounds+2)*4+i];
  125.     }
  126.  
  127.     for (i=sched.num_rounds-1; i>=0; i--)
  128.     {
  129.         temp[0] = block[i*4%8];
  130.         temp[1] = block[i*4%8+1];
  131.         temp[2] = block[i*4%8+2];
  132.         temp[3] = block[i*4%8+3];
  133.  
  134.         anIdea128_round(temp, sched.subkeys+(i+2)*4);
  135.  
  136.         block[(i+1)*4%8]   ^= temp[0];
  137.         block[(i+1)*4%8+1] ^= temp[1];
  138.         block[(i+1)*4%8+2] ^= temp[2];
  139.         block[(i+1)*4%8+3] ^= temp[3];
  140.     }
  141.  
  142.     for (i=0; i<8; i++)
  143.     {
  144.         block[i] ^= sched.subkeys[i];
  145.     }
  146. }
  147.  
  148. int main()
  149. {
  150.     int i;
  151.     uint16_t block[8] = {0};
  152.     uint16_t key[16] = {0};
  153.  
  154.     anIdea128_key_schedule sched = anIdea128_init(key, sizeof(key)/sizeof(uint16_t), 16);
  155.  
  156.     for (i=0; i<sched.num_rounds*4+16; i++)
  157.         printf("%04"PRIx16"\n", sched.subkeys[i]);
  158.  
  159.     anIdea128_encrypt(block, sched);
  160.  
  161.     for (i=0; i<8; i++)
  162.     {
  163.         printf("%04"PRIx16, block[i]);
  164.     }
  165.     anIdea128_decrypt(block, sched);
  166.     printf("\n");
  167.     for (i=0; i<8; i++)
  168.     {
  169.         printf("%04"PRIx16, block[i]);
  170.     }
  171.     printf("\n");
  172.  
  173.  
  174.     anIdea128_dest(&sched);
  175.  
  176.     return 1;
  177. }
RAW Paste Data