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

📄 anubis.c

📁 开源的目录加密软件
💻 C
📖 第 1 页 / 共 5 页
字号:
 /**    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 LTC_CLEAN_STACKstatic int _anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)#elseint  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 LTC_CLEAN_STACKint  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  @return CRYPT_OK if successful*/int 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);   return CRYPT_OK;}/**  Decrypts a block of text with Anubis  @param ct The input ciphertext (16 bytes)  @param pt The output plaintext (16 bytes)  @param skey The key as scheduled   @return CRYPT_OK if successful*/int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey){   LTC_ARGCHK(pt   != NULL);   LTC_ARGCHK(ct   != NULL);   LTC_ARGCHK(skey != NULL);   anubis_crypt(ct, pt, skey->anubis.roundKeyDec, skey->anubis.R);   return CRYPT_OK;}/**  Performs a self-test of the Anubis block cipher  @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled*/int anubis_test(void){#if !defined(LTC_TEST)  return CRYPT_NOP;#else  static const struct test {     int keylen;     unsigned char pt[16], ct[16], key[40];  } tests[] = {#ifndef ANUBIS_TWEAK  /**** ORIGINAL ANUBIS ****/  /* 128 bit keys */{

⌨️ 快捷键说明

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