text: 
  
  /* This is an independent implementation of the encryption algorithm:   */
  
  /*                                                                      */
  
  /*         DEAL by Richard Outerbridge and Lars Knudsen                 */
  
  /*                                                                      */
  
  /* which is a candidate algorithm in the Advanced Encryption Standard   */
  
  /* programme of the US National Institute of Standards and Technology.  */
  
  /*                                                                      */
  
  /* Copyright in this implementation is held by Dr B R Gladman but I     */
  
  /* hereby give permission for its free direct or derivative use subject */
  
  /* to acknowledgment of its origin and compliance with any conditions   */
  
  /* that the originators of the algorithm place on its exploitation.     */
  
  /*                                                                      */
  
  /* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999     */
  
  
  
  /* Timing Data for DEAL (deal.c)
  
  
  
  With unmodified DES
  
  
  
  128 bit key:
  
  Key Setup:    8635 cycles
  
  Encrypt:      2682 cycles =     9.5 mbits/sec
  
  Decrypt:      2670 cycles =     9.6 mbits/sec
  
  Mean:         2676 cycles =     9.6 mbits/sec
  
  
  
  192 bit key:
  
  Key Setup:    8651 cycles
  
  Encrypt:      2677 cycles =     9.6 mbits/sec
  
  Decrypt:      2669 cycles =     9.6 mbits/sec
  
  Mean:         2673 cycles =     9.6 mbits/sec
  
  
  
  256 bit key:
  
  Key Setup:   11522 cycles
  
  Encrypt:      3541 cycles =     7.2 mbits/sec
  
  Decrypt:      3535 cycles =     7.2 mbits/sec
  
  Mean:         3538 cycles =     7.2 mbits/sec
  
  
  
  With modified DES
  
  
  
  128 bit key:
  
  Key Setup:    8635 cycles
  
  Encrypt:      2339 cycles =    10.9 mbits/sec
  
  Decrypt:      2365 cycles =    10.8 mbits/sec
  
  Mean:         2352 cycles =    10.9 mbits/sec
  
  
  
  192 bit key:
  
  Key Setup:    8653 cycles
  
  Encrypt:      2358 cycles =    10.9 mbits/sec
  
  Decrypt:      2363 cycles =    10.8 mbits/sec
  
  Mean:         2361 cycles =    10.8 mbits/sec
  
  
  
  256 bit key:
  
  Key Setup:   11698 cycles
  
  Encrypt:      3115 cycles =     8.2 mbits/sec
  
  Decrypt:      3088 cycles =     8.3 mbits/sec
  
  Mean:         3102 cycles =     8.3 mbits/sec
  
  
  
  */
  
  
  
  #define MODIFIED_DES
  
  
  
  #include "../std_defs.h"
  
  #include "../des/des.h"
  
  
  
  #ifdef  MODIFIED_DES
  
    void des_ecm(const void *i_blk, void *o_blk, void *key);
  
  #else
  
  #  define   des_ecm des_ec
  
  #endif
  
  
  
  static char *alg_name[] = { "deal", "deal.c", "deal" };
  
  
  
  char **cipher_name()
  
  {
  
      return alg_name;
  
  }
  
  
  
  u4byte  ks_key[2] = { 0x67452301, 0xefcdab89 };
  
  
  
  u4byte  ks_ks[32];  /* storage for the local key schedule   */
  
  u4byte  ks_init = 0;
  
  
  
  u4byte  k_len;      /* copy of key_length                   */ 
  
  u4byte  l_key[256]; /* storage for key schedule             */
  
  
  
  /* initialise the key schedule from the user supplied key   */
  
  
  
  u4byte *set_key(const u4byte key_blk[], const u4byte key_len)
  
  {   u4byte  lk[2];
  
  
  
      if(!ks_init)
  
      {
  
          des_ky(ks_key, ks_ks); ks_init = 1;
  
      }
  
  
  
      k_len = (key_len + 63) / 64;
  
  
  
      switch(k_len)
  
      {
  
          case 2:
  
              lk[0] = key_blk[0]; 
  
              lk[1] = key_blk[1]; 
  
              des_ec(lk, lk, ks_ks); 
  
              des_ky(lk, l_key);
  
  
  
              lk[0] ^= key_blk[2]; 
  
              lk[1] ^= key_blk[3];
  
              des_ec(lk, lk, ks_ks); 
  
              des_ky(lk, l_key + 32);
  
                
  
              lk[0] ^= key_blk[0] ^ 0x00000080;  
  
              lk[1] ^= key_blk[1];
  
              des_ec(lk, lk, ks_ks); 
  
              des_ky(lk, l_key + 64);
  
                
  
              lk[0] ^= key_blk[2] ^ 0x00000040;  
  
              lk[1] ^= key_blk[3];
  
              des_ec(lk, lk, ks_ks); 
  
              des_ky(lk, l_key + 96);
  
                
  
              lk[0] ^= key_blk[0] ^ 0x00000020;  
  
              lk[1] ^= key_blk[1];
  
              des_ec(lk, lk, ks_ks); 
  
              des_ky(lk, l_key + 128);
  
                
  
              lk[0] ^= key_blk[2] ^ 0x00000010;  
  
              lk[1] ^= key_blk[3];
  
              des_ec(lk, lk, ks_ks); 
  
              des_ky(lk, l_key + 160);
  
              break;
  
          case 3:
  
              lk[0] = key_blk[0]; 
  
              lk[1] = key_blk[1]; 
  
              des_ec(lk, lk, ks_ks); 
  
              des_ky(lk, l_key);
  
  
  
              lk[0] ^= key_blk[2]; 
  
              lk[1] ^= key_blk[3];
  
              des_ec(lk, lk, ks_ks); des_ky(lk, l_key + 32);
  
                
  
              lk[0] ^= key_blk[4];  
  
              lk[1] ^= key_blk[5];
  
              des_ec(lk, lk, ks_ks); des_ky(lk, l_key + 64);
  
                
  
              lk[0] ^= key_blk[0] ^ 0x00000080;  
  
              lk[1] ^= key_blk[1];
  
              des_ec(lk, lk, ks_ks); des_ky(lk, l_key + 96);
  
                
  
              lk[0] ^= key_blk[2] ^ 0x00000040;  
  
              lk[1] ^= key_blk[3];
  
              des_ec(lk, lk, ks_ks); des_ky(lk, l_key + 128);
  
                
  
              lk[0] ^= key_blk[4] ^ 0x00000020;  
  
              lk[1] ^= key_blk[5];
  
              des_ec(lk, lk, ks_ks); des_ky(lk, l_key + 160);
  
              break;
  
          case 4:
  
              lk[0] = key_blk[0]; 
  
              lk[1] = key_blk[1]; 
  
              des_ec(lk, lk, ks_ks); des_ky(lk, l_key);
  
  
  
              lk[0] ^= key_blk[2]; 
  
              lk[1] ^= key_blk[3];
  
              des_ec(lk, lk, ks_ks); des_ky(lk, l_key + 32);
  
                
  
              lk[0] ^= key_blk[4];  
  
              lk[1] ^= key_blk[5];
  
              des_ec(lk, lk, ks_ks); des_ky(lk, l_key + 64);
  
                
  
              lk[0] ^= key_blk[6];  
  
              lk[1] ^= key_blk[7];
  
              des_ec(lk, lk, ks_ks); des_ky(lk, l_key + 96);
  
                
  
              lk[0] ^= key_blk[0] ^ 0x00000080;  
  
              lk[1] ^= key_blk[1];
  
              des_ec(lk, lk, ks_ks); des_ky(lk, l_key + 128);
  
                
  
              lk[0] ^= key_blk[2] ^ 0x00000040;  
  
              lk[1] ^= key_blk[3];
  
              des_ec(lk, lk, ks_ks); des_ky(lk, l_key + 160);
  
              lk[0] ^= key_blk[4] ^ 0x00000020;  
  
              lk[1] ^= key_blk[5];
  
              des_ec(lk, lk, ks_ks); des_ky(lk, l_key + 192);
  
                
  
              lk[0] ^= key_blk[6] ^ 0x00000010;  
  
              lk[1] ^= key_blk[7];
  
              des_ec(lk, lk, ks_ks); des_ky(lk, l_key + 224);
  
              break;
  
      }   
  
      return l_key;
  
  };
  
  
  
  /* encrypt a block of text  */
  
  
  
  void encrypt(const u4byte in_blk[4], u4byte out_blk[4])
  
  {   u4byte  a[2], b[2], c[2], tt;
  
  
  
      a[0] = in_blk[0]; a[1] = in_blk[1];
  
      b[0] = in_blk[2]; b[1] = in_blk[3];
  
      
  
  #ifdef  MODIFIED_DES
  
      ip(a[1], a[0]); ip(b[1], b[0]);
  
  #endif
  
  
  
      des_ecm(a, c, l_key +   0); b[0] ^= c[0]; b[1] ^= c[1];
  
      des_ecm(b, c, l_key +  32); a[0] ^= c[0]; a[1] ^= c[1];
  
  
  
      des_ecm(a, c, l_key +  64); b[0] ^= c[0]; b[1] ^= c[1];
  
      des_ecm(b, c, l_key +  96); a[0] ^= c[0]; a[1] ^= c[1];
  
  
  
      des_ecm(a, c, l_key + 128); b[0] ^= c[0]; b[1] ^= c[1];
  
      des_ecm(b, c, l_key + 160); a[0] ^= c[0]; a[1] ^= c[1];
  
  
  
      if(k_len == 4)
  
      {
  
          des_ecm(a, c, l_key + 192); b[0] ^= c[0]; b[1] ^= c[1];
  
          des_ecm(b, c, l_key + 224); a[0] ^= c[0]; a[1] ^= c[1];
  
  
  
      }
  
  
  
  #ifdef  MODIFIED_DES
  
      fp(a[1], a[0]); fp(b[1], b[0]);
  
  #endif
  
  
  
      out_blk[0] = a[0]; out_blk[1] = a[1];
  
      out_blk[2] = b[0]; out_blk[3] = b[1];
  
  };
  
  
  
  /* decrypt a block of text  */
  
  
  
  void decrypt(const u4byte in_blk[4], u4byte out_blk[4])
  
  {   u4byte  a[2], b[2], c[2], tt;
  
  
  
      a[0] = in_blk[0]; a[1] = in_blk[1];
  
      b[0] = in_blk[2]; b[1] = in_blk[3];
  
  
  
  #ifdef  MODIFIED_DES
  
      ip(a[1], a[0]); ip(b[1], b[0]);
  
  #endif
  
       
  
      if(k_len == 4)
  
      {
  
          des_ecm(b, c, l_key + 224); a[0] ^= c[0]; a[1] ^= c[1];
  
          des_ecm(a, c, l_key + 192); b[0] ^= c[0]; b[1] ^= c[1];
  
      }
  
  
  
      des_ecm(b, c, l_key + 160); a[0] ^= c[0]; a[1] ^= c[1];
  
      des_ecm(a, c, l_key + 128); b[0] ^= c[0]; b[1] ^= c[1];
  
  
  
      des_ecm(b, c, l_key +  96); a[0] ^= c[0]; a[1] ^= c[1];
  
      des_ecm(a, c, l_key +  64); b[0] ^= c[0]; b[1] ^= c[1];
  
  
  
      des_ecm(b, c, l_key +  32); a[0] ^= c[0]; a[1] ^= c[1];
  
      des_ecm(a, c, l_key +   0); b[0] ^= c[0]; b[1] ^= c[1];
  
  
  
  #ifdef  MODIFIED_DES
  
      fp(a[1], a[0]); fp(b[1], b[0]);
  
  #endif
  
  
  
      out_blk[0] = a[0]; out_blk[1] = a[1];
  
      out_blk[2] = b[0]; out_blk[3] = b[1];
  
  };
  
  