⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 anubis.c

📁 这是由Rinick编写的加解密函数库。最近找了不少关于加解密的C源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U,
    0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU,
    0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU,
    0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU,
    0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU,
    0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU,
    0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU,
    0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU,
    0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU,
};

/**
 * The round constants.
 */
static const ulong32 rc[] = {
   0xa7d3e671U, 0xd0ac4d79U, 0x3ac991fcU, 0x1e4754bdU,
   0x8ca57afbU, 0x63b8ddd4U, 0xe5b3c5beU, 0xa9880ca2U,
   0x39df29daU, 0x2ba8cb4cU, 0x4b22aa24U, 0x4170a6f9U,
   0x5ae2b036U, 0x7de433ffU, 0x6020088bU, 0x5eab7f78U,
   0x7c2c57d2U, 0xdc6d7e0dU, 0x5394c328U,
};

#endif

 /**
    Initialize the Anubis block cipher
    @param key The symmetric key you wish to pass
    @param keylen The key length in bytes
    @param num_rounds The number of rounds desired (0 for default)
    @param skey The key in as scheduled by this function.
    @return CRYPT_OK if successful
 */
#ifdef CLEAN_STACK
static int _anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#else
int  anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#endif
{
   int N, R, i, pos, r;
   ulong32 kappa[MAX_N];
   ulong32 inter[MAX_N];
   ulong32 v, K0, K1, K2, K3;

   LTC_ARGCHK(key  != NULL);
   LTC_ARGCHK(skey != NULL);

   /* Valid sizes (in bytes) are 16, 20, 24, 28, 32, 36, and 40. */
   if ((keylen & 3) || (keylen < 16) || (keylen > 40)) {
      return CRYPT_INVALID_KEYSIZE;
   }
   skey->anubis.keyBits = keylen*8;

   /*
    * determine the N length parameter:
    * (N.B. it is assumed that the key length is valid!)
    */
   N = skey->anubis.keyBits >> 5;

   /*
    * determine number of rounds from key size:
    */
   skey->anubis.R = R = 8 + N;

   if (num_rounds != 0 && num_rounds != skey->anubis.R) {
      return CRYPT_INVALID_ROUNDS;
   }

    /*
    * map cipher key to initial key state (mu):
    */
    for (i = 0, pos = 0; i < N; i++, pos += 4) {
      kappa[i] =
         (key[pos    ] << 24) ^
         (key[pos + 1] << 16) ^
         (key[pos + 2] <<  8) ^
         (key[pos + 3]      );
    }

   /*
    * generate R + 1 round keys:
    */
   for (r = 0; r <= R; r++) {
      /*
       * generate r-th round key K^r:
       */
      K0 = T4[(kappa[N - 1] >> 24)       ];
      K1 = T4[(kappa[N - 1] >> 16) & 0xff];
      K2 = T4[(kappa[N - 1] >>  8) & 0xff];
      K3 = T4[(kappa[N - 1]      ) & 0xff];
      for (i = N - 2; i >= 0; i--) {
         K0 = T4[(kappa[i] >> 24)       ] ^
            (T5[(K0 >> 24)       ] & 0xff000000U) ^
            (T5[(K0 >> 16) & 0xff] & 0x00ff0000U) ^
            (T5[(K0 >>  8) & 0xff] & 0x0000ff00U) ^
            (T5[(K0      ) & 0xff] & 0x000000ffU);
         K1 = T4[(kappa[i] >> 16) & 0xff] ^
            (T5[(K1 >> 24)       ] & 0xff000000U) ^
            (T5[(K1 >> 16) & 0xff] & 0x00ff0000U) ^
            (T5[(K1 >>  8) & 0xff] & 0x0000ff00U) ^
            (T5[(K1      ) & 0xff] & 0x000000ffU);
         K2 = T4[(kappa[i] >>  8) & 0xff] ^
            (T5[(K2 >> 24)       ] & 0xff000000U) ^
            (T5[(K2 >> 16) & 0xff] & 0x00ff0000U) ^
            (T5[(K2 >>  8) & 0xff] & 0x0000ff00U) ^
            (T5[(K2      ) & 0xff] & 0x000000ffU);
         K3 = T4[(kappa[i]      ) & 0xff] ^
            (T5[(K3 >> 24)       ] & 0xff000000U) ^
            (T5[(K3 >> 16) & 0xff] & 0x00ff0000U) ^
            (T5[(K3 >>  8) & 0xff] & 0x0000ff00U) ^
            (T5[(K3      ) & 0xff] & 0x000000ffU);
      }
      /*
      -- this is the code to use with the large U tables:
      K0 = K1 = K2 = K3 = 0;
      for (i = 0; i < N; i++) {
         K0 ^= U[i][(kappa[i] >> 24)       ];
         K1 ^= U[i][(kappa[i] >> 16) & 0xff];
         K2 ^= U[i][(kappa[i] >>  8) & 0xff];
         K3 ^= U[i][(kappa[i]      ) & 0xff];
      }
      */
      skey->anubis.roundKeyEnc[r][0] = K0;
      skey->anubis.roundKeyEnc[r][1] = K1;
      skey->anubis.roundKeyEnc[r][2] = K2;
      skey->anubis.roundKeyEnc[r][3] = K3;

      /*
       * compute kappa^{r+1} from kappa^r:
       */
      if (r == R) {
         break;
      }
      for (i = 0; i < N; i++) {
         int j = i;
         inter[i]  = T0[(kappa[j--] >> 24)       ]; if (j < 0) j = N - 1;
         inter[i] ^= T1[(kappa[j--] >> 16) & 0xff]; if (j < 0) j = N - 1;
         inter[i] ^= T2[(kappa[j--] >>  8) & 0xff]; if (j < 0) j = N - 1;
         inter[i] ^= T3[(kappa[j  ]      ) & 0xff];
      }
      kappa[0] = inter[0] ^ rc[r];
      for (i = 1; i < N; i++) {
         kappa[i] = inter[i];
      }
   }

   /*
    * generate inverse key schedule: K'^0 = K^R, K'^R = K^0, K'^r = theta(K^{R-r}):
    */
   for (i = 0; i < 4; i++) {
      skey->anubis.roundKeyDec[0][i] = skey->anubis.roundKeyEnc[R][i];
      skey->anubis.roundKeyDec[R][i] = skey->anubis.roundKeyEnc[0][i];
   }
   for (r = 1; r < R; r++) {
      for (i = 0; i < 4; i++) {
         v = skey->anubis.roundKeyEnc[R - r][i];
         skey->anubis.roundKeyDec[r][i] =
            T0[T4[(v >> 24)       ] & 0xff] ^
            T1[T4[(v >> 16) & 0xff] & 0xff] ^
            T2[T4[(v >>  8) & 0xff] & 0xff] ^
            T3[T4[(v      ) & 0xff] & 0xff];
      }
   }

   return CRYPT_OK;
}

#ifdef CLEAN_STACK
int  anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
  int err;
  err = _anubis_setup(key, keylen, num_rounds, skey);
  burn_stack(sizeof(int) * 5 + sizeof(ulong32) * (MAX_N + MAX_N + 5));
  return err;
}
#endif
  

static void anubis_crypt(const unsigned char *plaintext, unsigned char *ciphertext,
                         ulong32 roundKey[18 + 1][4], int R) {
   int i, pos, r;
   ulong32 state[4];
   ulong32 inter[4];

    /*
    * map plaintext block to cipher state (mu)
    * and add initial round key (sigma[K^0]):
    */
    for (i = 0, pos = 0; i < 4; i++, pos += 4) {
      state[i] =
         (plaintext[pos    ] << 24) ^
         (plaintext[pos + 1] << 16) ^
         (plaintext[pos + 2] <<  8) ^
         (plaintext[pos + 3]      ) ^
         roundKey[0][i];
    }

    /*
     * R - 1 full rounds:
     */
    for (r = 1; r < R; r++) {
      inter[0] =
         T0[(state[0] >> 24)       ] ^
         T1[(state[1] >> 24)       ] ^
         T2[(state[2] >> 24)       ] ^
         T3[(state[3] >> 24)       ] ^
         roundKey[r][0];
      inter[1] =
         T0[(state[0] >> 16) & 0xff] ^
         T1[(state[1] >> 16) & 0xff] ^
         T2[(state[2] >> 16) & 0xff] ^
         T3[(state[3] >> 16) & 0xff] ^
         roundKey[r][1];
      inter[2] =
         T0[(state[0] >>  8) & 0xff] ^
         T1[(state[1] >>  8) & 0xff] ^
         T2[(state[2] >>  8) & 0xff] ^
         T3[(state[3] >>  8) & 0xff] ^
         roundKey[r][2];
      inter[3] =
         T0[(state[0]      ) & 0xff] ^
         T1[(state[1]      ) & 0xff] ^
         T2[(state[2]      ) & 0xff] ^
         T3[(state[3]      ) & 0xff] ^
         roundKey[r][3];
      state[0] = inter[0];
      state[1] = inter[1];
      state[2] = inter[2];
      state[3] = inter[3];
    }

    /*
    * last round:
    */
   inter[0] =
      (T0[(state[0] >> 24)       ] & 0xff000000U) ^
      (T1[(state[1] >> 24)       ] & 0x00ff0000U) ^
      (T2[(state[2] >> 24)       ] & 0x0000ff00U) ^
      (T3[(state[3] >> 24)       ] & 0x000000ffU) ^
      roundKey[R][0];
   inter[1] =
      (T0[(state[0] >> 16) & 0xff] & 0xff000000U) ^
      (T1[(state[1] >> 16) & 0xff] & 0x00ff0000U) ^
      (T2[(state[2] >> 16) & 0xff] & 0x0000ff00U) ^
      (T3[(state[3] >> 16) & 0xff] & 0x000000ffU) ^
      roundKey[R][1];
   inter[2] =
      (T0[(state[0] >>  8) & 0xff] & 0xff000000U) ^
      (T1[(state[1] >>  8) & 0xff] & 0x00ff0000U) ^
      (T2[(state[2] >>  8) & 0xff] & 0x0000ff00U) ^
      (T3[(state[3] >>  8) & 0xff] & 0x000000ffU) ^
      roundKey[R][2];
   inter[3] =
      (T0[(state[0]      ) & 0xff] & 0xff000000U) ^
      (T1[(state[1]      ) & 0xff] & 0x00ff0000U) ^
      (T2[(state[2]      ) & 0xff] & 0x0000ff00U) ^
      (T3[(state[3]      ) & 0xff] & 0x000000ffU) ^
      roundKey[R][3];

   /*
    * map cipher state to ciphertext block (mu^{-1}):
    */
    for (i = 0, pos = 0; i < 4; i++, pos += 4) {
        ulong32 w = inter[i];
        ciphertext[pos    ] = (unsigned char)(w >> 24);
        ciphertext[pos + 1] = (unsigned char)(w >> 16);
        ciphertext[pos + 2] = (unsigned char)(w >>  8);
        ciphertext[pos + 3] = (unsigned char)(w      );
    }
}

/**
  Encrypts a block of text with Anubis
  @param pt The input plaintext (16 bytes)
  @param ct The output ciphertext (16 bytes)
  @param skey The key as scheduled
*/
void anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
   LTC_ARGCHK(pt   != NULL);
   LTC_ARGCHK(ct   != NULL);
   LTC_ARGCHK(skey != NULL);
   anubis_crypt(pt, ct, skey->anubis.roundKeyEnc, skey->anubis.R);
}

/**
  Decrypts a block of text with Anubis
  @param ct The input ciphertext (16 bytes)

⌨️ 快捷键说明

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