Cipher

void Cipher(uint8_t *state, const uint32_t *roundKey, int mode)
{
  // ENCRYPT 모드
  if (mode == ENCRYPT) {
    uint8_t round = 0;
    // 본격적인 round에 들어가기 전, AddRoundKey를 1회 수행
    AddRoundKey(state, roundKey, round);
    round++;
    // round를 9번 반복
    for (int i = 1; i < Nr; i++) {
      SubBytes(state, ENCRYPT);
      ShiftRows(state, ENCRYPT);
      MixColumns(state, ENCRYPT);
      AddRoundKey(state, roundKey, round);
      round ++;
    }
    // Finial round에서는 MixColumn을 제외하고 수행
    SubBytes(state, ENCRYPT);
    ShiftRows(state, ENCRYPT);
    AddRoundKey(state, roundKey, round);
  }
  // DECRYPT 모드
  else {
    // 암호화의 역으로 수행을 함
    uint8_t round = 10;
    // 본격적인 round에 들어가기 전, AddRoundKey를 1회 수행
    AddRoundKey(state, roundKey, round);
    round--;
    // round를 9번 반복
    for (int i = Nr-1; i > 0; i--) {
      ShiftRows(state, DECRYPT);
      SubBytes(state, DECRYPT);
      AddRoundKey(state, roundKey, round);
      MixColumns(state, DECRYPT);
      round --;
    }
    // Finial round에서는 MixColumn을 제외하고 수행
    ShiftRows(state, DECRYPT);
    SubBytes(state, DECRYPT);
    AddRoundKey(state, roundKey, round);
  }
}

暗号化モード中、Add Round Key を1 回遂行した後、繰り返し文に従ってround を繰り返す。

繰り返し文内での関数の実行順序は、SubBytes、ShiftRows、MixColumns、AddRoundKeyの順である。

計9回を繰り返した後、最後の10番目のラウンドにはMixColumnを除いた残りを遂行する。

復号モード中、Addround Key を1 回遂行した後、繰り返し文に従ってround を下げながら繰り返す。

繰り返し文内での関数の実行順序はShiftRows、SubBytes、AddRoundKey、MixColumnsの順である。

同じように計9回を繰り返した後、最後の10番目のラウンドでMixColumnを除いた残りを実行する。

Add Round Key を除いた SubBytes、Shift Rows、Mix Columns 関数にはmode を入力してもらい、復号時には暗号化の逆過程で実行されるようにした。

SubBytes

static void SubBytes(uint8_t *state, int mode) {
  uint8_t i;
  // 암호화 모드이면 sbox에서 값을 찾아 대체
  if (mode == ENCRYPT) {
    for (i = 0; i < 16; i++)
    {
      state[i] = sbox[state[i]];
    }   
  }
  // 복호화 모드이면 isbox에서 값을 찾아 대체
  else {
    for (i = 0; i < 16; i++)
    {
      state[i] = isbox[state[i]];
    }
  }
}

SubBytes 関数は、現在state にある値を暗号化時にはsbox を、復号時にはisbox を参照してsubstitute するものである。 これは各byte別に適用されなければならず、繰り返し文によって順番に値を代替した。

ShiftRows

static void ShiftRows(uint8_t *state, int mode) {
  uint8_t temp;
  // 암호화 모드이면
  if (mode == ENCRYPT) {
    // 2번째 row 값들을 왼쪽으로 하나씩 옮김
    temp = state[1];
    state[1] = state[5];
    state[5] = state[9];
    state[9] = state[13];
    state[13] = temp;

    // 3번째 row 값들을 왼쪽으로 두개씩 옮김
    temp = state[2];
    state[2] = state[10];
    state[10] = temp;
    temp = state[6];
    state[6] = state[14];
    state[14] = temp;

    // 4번째 row 값들을 왼쪽으로 세개씩 옮김
    temp = state[3];
    state[3] = state[15];
    state[15] = state[11];
    state[11] = state[7];
    state[7] = temp;
  }
  // 복호화 모드이면
  else {
    // 2번째 row 값들을 오른쪽으로 하나씩 옮김
    temp = state[1];
    state[1] = state[13];
    state[13] = state[9];
    state[9] = state[5];
    state[5] = temp;

    // 3번째 row 값들을 오른쪽으로 두개씩 옮김(ENCRYPT때와 동일함)
    temp = state[2];
    state[2] = state[10];
    state[10] = temp;
    temp = state[6];
    state[6] = state[14];
    state[14] = temp;

    // 4번째 row 값들을 오른쪽으로 세개씩 옮김
    temp = state[3];
    state[3] = state[7];
    state[7] = state[11];
    state[11] = state[15];
    state[15] = temp;
  }
}

ShiftRows 関数は値の順序を混ぜる役割をする。

暗号化の際、最初のrowはそのままにし、2番目のrowは左に1マスずつ、3番目のrowは左に2マスずつ、4番目のrowは左に3マスずつ(=右に1マス)移したものである。

tempという変数を置いて値を直接変えてくれた。

復号時には暗号化で行っていた方式と逆とした。