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

📄 dc3.c

📁 应用密码学手册-英文版,学习密码学和网络安全的好资料。
💻 C
📖 第 1 页 / 共 2 页
字号:
      b5 = (Bj >> 1) & 1;
      b6 = Bj & 1;
      row = 2 * b1 + b6;
      col = 8 * b2 + 4 * b3 + 2 * b4 + b5;
      t[j] = S[j][row][col];
    }
    tpp = (t[0] << 28) | (t[1] << 24)
        | (t[2] << 20) | (t[3] << 16)
        | (t[4] << 12) | (t[5] <<  8)
        | (t[6] <<  4) | t[7];
    Tpp[0] = tpp;
    Tpp[1] = 0;
    for (j = 1; j <= 32; j++)
      set_bit(j, get_bit(P[j - 1], Tpp), Tppp);
    R1[0] = L0[0] ^ Tppp[0];
    L0[0] = L1[0];
    R0[0] = R1[0];
    L1[1] = R1[1] = 0;
  }
  for (i = 1; i <= 32; i++) {
    set_bit(i, get_bit(i, L1), c);
    j = 32 + i;
    set_bit(j, get_bit(i, R1), c);
  }
}

void calculate_EEC(char *IP, long *Cp, long *L0p,
                   long *R0, long *R0p, long *R3p,
                   long *e, long *es)
{
  char i;
  long T[2];

  DES_E(R0, e);
  DES_E(R0p, es);
  T[0] = R3p[0] ^ L0p[0];
  for (i = 1; i <= 32; i++)
    set_bit(i, get_bit(IP[i - 1], T), Cp);
  printf("E  = %8x %8x\n", e[0], e[1]);
  printf("E* = %8x %8x\n", es[0], es[1]);
  printf("C' = %8x\n", Cp[0]);
}

void calculate_INj(int j, int Bjp, int Cjp,
                   int *INj, int *Nj)
{
  int b, b1, b2, b3, b4, b5, b6, col, row;
  int Bj, Sj, Sjp;

  *Nj = 0;
  for (Bj = 0; Bj < 64; Bj++) {
    b = Bj;
    b1 =  b >> 5;
    b2 = (b >> 4) & 1;
    b3 = (b >> 3) & 1;
    b4 = (b >> 2) & 1;
    b5 = (b >> 1) & 1;
    b6 =  b & 1;
    row = 2 * b1 + b6;
    col = 8 * b2 + 4 * b3 + 2 * b4 + b5;
    Sj = S[j][row][col];
    b = Bj ^ Bjp;
    b1 =  b >> 5;
    b2 = (b >> 4) & 1;
    b3 = (b >> 3) & 1;
    b4 = (b >> 2) & 1;
    b5 = (b >> 1) & 1;
    b6 =  b & 1;
    row = 2 * b1 + b6;
    col = 8 * b2 + 4 * b3 + 2 * b4 + b5;
    Sjp = S[j][row][col];
    Sj ^= Sjp;
    if (Sj == Cjp) {
      INj[*Nj] = Bj;
      *Nj = *Nj + 1;
    }
  }
}

void calculate_testj(int j, int Cjp, int Ej, int Ejs,
                     int *testj, int *size)
{
  int INj[64], Nj, i;

  calculate_INj(j, Ej ^ Ejs, Cjp, INj, &Nj);
  *size = Nj;
  for (i = 0; i < Nj; i++) testj[i] = INj[i] ^ Ej;
}

int main(void)
{
  char IP[32];
  char KS[48] = {51, 27, 10, 36, 25, 58,  9, 33, 43, 50, 60, 18,
                 44, 11,  2,  1, 49, 34, 35, 42, 41,  3, 59, 17,
                 61,  4, 15, 30, 13, 47, 23,  6, 12, 29, 62,  5,
                 37, 28, 14, 39, 54, 63, 21, 53, 20, 38, 31,  7};
  int found, i, i2, i21, i8, j;
  int Cp1, E1, Es1, J[8][64] = {{0}}, size, testj[64];
  long c[6][2] = {{0x03c70306l, 0xd8a09f10l},
                  {0x78560a09l, 0x60e6d4cbl},
                  {0x45fa285bl, 0xe5adc730l},
                  {0x134f7915l, 0xac253457l},
                  {0xd8a31b2fl, 0x28bbc5cfl},
                  {0x0f317ac2l, 0xb23cb944l}};
  long m[6][2] = {{0x748502cdl, 0x38451097l},
                  {0x38747564l, 0x38451097l},
                  {0x48691102l, 0x6acdff31l},
                  {0x375bd31fl, 0x6acdff31l},
                  {0x357418dal, 0x013fec86l},
                  {0x12549847l, 0x013fec86l}};
  long Jj[8], L0p[2], R0[2], R0p[2], R3p[2];
  long Cp[3][2], e[3][2], es[3][2], key[2], kp[2];
  long C[2], D[2], M[2], K[ROUNDS][2], guess[2], sum;
  long guess_bit[64], guess_key_bit[64], key_bit[64];

  for (i = 1; i <= 32; i++) IP[P[i - 1] - 1] = (char) i;
  R0[1] = R0p[1] = L0p[1] = R3p[1] = 0;
  for (i = 0; i < 3; i++) {
    i2 = 2 * i;
    i21 = i2 + 1;
    R0[0]  = c[i2][0];
    R0p[0] = c[i21][0];
    L0p[0] = m[i2][0] ^ m[i21][0];
    R3p[0] = c[i2][1] ^ c[i21][1];
    Cp[i][1] = e[i][1] = es[i][1] = 0;
    calculate_EEC(IP, Cp[i], L0p, R0, R0p, R3p, e[i], es[i]);
  }
  for (i = 0; i < 3; i++) {
    Cp1 = (Cp[i][0] >> 28) & 0xf;
    E1  = ( e[i][0] >> 26) & 0x3f;
    Es1 = (es[i][0] >> 26) & 0x3f;
    calculate_testj(0, Cp1, E1, Es1, testj, &size);
    for (j = 0; j < size; j++) J[0][testj[j]]++;
    Cp1 = (Cp[i][0] >> 24) & 0xf;
    E1  = ( e[i][0] >> 20) & 0x3f;
    Es1 = (es[i][0] >> 20) & 0x3f;
    calculate_testj(1, Cp1, E1, Es1, testj, &size);
    for (j = 0; j < size; j++) J[1][testj[j]]++;
    Cp1 = (Cp[i][0] >> 20) & 0xf;
    E1  = ( e[i][0] >> 14) & 0x3f;
    Es1 = (es[i][0] >> 14) & 0x3f;
    calculate_testj(2, Cp1, E1, Es1, testj, &size);
    for (j = 0; j < size; j++) J[2][testj[j]]++;
    Cp1 = (Cp[i][0] >> 16) & 0xf;
    E1  = ( e[i][0] >>  8) & 0x3f;
    Es1 = (es[i][0] >>  8) & 0x3f;
    calculate_testj(3, Cp1, E1, Es1, testj, &size);
    for (j = 0; j < size; j++) J[3][testj[j]]++;
    Cp1 = (Cp[i][0] >> 12) & 0xf;
    E1  = ( e[i][0] >>  2) & 0x3f;
    Es1 = (es[i][0] >>  2) & 0x3f;
    calculate_testj(4, Cp1, E1, Es1, testj, &size);
    for (j = 0; j < size; j++) J[4][testj[j]]++;
    Cp1 = (Cp[i][0] >> 8) & 0xf;
    E1  = (( e[i][0] & 0x3) << 4) | (( e[i][1] >> 28) & 0xf);
    Es1 = ((es[i][0] & 0x3) << 4) | ((es[i][1] >> 28) & 0xf);
    calculate_testj(5, Cp1, E1, Es1, testj, &size);
    for (j = 0; j < size; j++) J[5][testj[j]]++;
    Cp1 = (Cp[i][0] >> 4) & 0xf;
    E1  = ( e[i][1] >> 22) & 0x3f;
    Es1 = (es[i][1] >> 22) & 0x3f;
    calculate_testj(6, Cp1, E1, Es1, testj, &size);
    for (j = 0; j < size; j++) J[6][testj[j]]++;
    Cp1 = Cp[i][0] & 0xf;
    E1  = ( e[i][1] >> 16) & 0x3f;
    Es1 = (es[i][1] >> 16) & 0x3f;
    calculate_testj(7, Cp1, E1, Es1, testj, &size);
    for (j = 0; j < size; j++) J[7][testj[j]]++;
  }
  for (i = 0; i < 8; i++) {
    for (j = 0; j < 64; j++) {
      printf("%d ", J[i][j]);
      if ((j + 1) % 16 == 0) printf("\n");
    }
    printf("\n");
  }
  for (i = 0; i < 8; i++) {
    found = 0;
    for (j = 0; !found && j < 64; j++) {
      found = J[i][j] == ROUNDS;
      if (found) Jj[i] = j;
    }
  }
  for (i = 0; i < 8; i++) printf("%2x ", Jj[i]);
  printf("\n");
  kp[1] = 0;
  kp[0] = (Jj[0] << 26) | (Jj[1] << 20)
        | (Jj[2] << 14) | (Jj[3] <<  8)
        | (Jj[4] <<  2) | ((Jj[5] >> 4) & 0x3);
  kp[1] = ((Jj[5] & 0xf) << 28)
        | (Jj[6] << 22) | (Jj[7] << 16);
  printf("J = %8lx %8lx\n", kp[0], kp[1]);
  for (i = 0; i < 64; i++) key_bit[i] = 2;
  key_bit[ 7] = key_bit[15] = 3;
  key_bit[23] = key_bit[31] = 3;
  key_bit[39] = key_bit[47] = 3;
  key_bit[55] = key_bit[63] = 3;
  for (i = 1; i <= 48; i++)
    key_bit[KS[i - 1] - 1] = get_bit(i, kp);
  printf("key = ");
  for (i = 1; i <= 64; i++) {
    switch (key_bit[i - 1]) {
      case 0 :
        printf("0");
        break;
      case 1 :
        printf("1");
        break;
      case 2 :
      case 3 :
        printf("?");
        break;
    }
  }
  printf("\n");
  C[0] = c[0][0], C[1] = c[0][1];
  M[0] = m[0][0], M[1] = m[0][1];
  found = 0;
  guess[1] = 0;
  for (guess[0] = 0; !found && guess[0] < 256l; guess[0]++) {
    fprintf(stderr, "\b\b\b%ld", guess[0]);
    for (j = 1; j <= 8; j++)
      guess_bit[j - 1] = get_bit(24 + j, guess);
    j = 0;
    for (i = 0; i < 64; i++) {
      if (key_bit[i] < 2)
        guess_key_bit[i] = key_bit[i];
      else if (key_bit[i] == 2)
        guess_key_bit[i] = guess_bit[j++];
    }
    for (i = 0; i < 8; i++) {
      i8 = 8 * i;
      sum = 0;
      for (j = 0; j < 7; j++) sum += guess_key_bit[i8 + j];
      if (!(sum & 1)) guess_key_bit[i8 + 7] = 1;
      else guess_key_bit[i8 + 7] = 0;
    }
    for (i = 1; i <= 64; i++)
      set_bit(i, guess_key_bit[i - 1], key);
    DES_key_schedule(K, key);
    DES(K, M, D);
    found = C[0] == D[0] && C[1] == D[1];
  }
  fprintf(stderr, "\n");
  printf("key = %8lx %8lx\n", key[0], key[1]);
  return 0;
}

⌨️ 快捷键说明

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