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

📄 dc4.c

📁 应用密码学手册-英文版,学习密码学和网络安全的好资料。
💻 C
📖 第 1 页 / 共 2 页
字号:
      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 *L4,
                   long *L4s, long *R4p,
                   long *e, long *es)
{
  char i;

  DES_E(L4, e);
  DES_E(L4s, es);
  for (i = 1; i <= 32; i++)
    set_bit(i, get_bit(IP[i - 1], R4p), Cp);
  printf("E  = %8lx %8lx\n", e[0], e[1]);
  printf("E* = %8lx %8lx\n", es[0], es[1]);
  printf("C' = %8lx\n", Cp[0]);
}

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

  *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] = {35, 11, 59, 49,  9, 42, 58, 17, 27, 34, 44,  2,
                 57, 60, 51, 50, 33, 18, 19, 26, 25, 52, 43,  1,
                 45, 55, 62, 14, 28, 31,  7, 53, 63, 13, 46, 20,
                 21, 12, 61, 23, 38, 47,  5, 37,  4, 22, 15, 54};
  int Cp1, E1, Es1, J[8][64] = {{0}}, size, testj[64];
  int found, i, i2, i21, i8, j;
  long c[8][2] = {{0xe3321513l, 0x12a18b4fl},
                  {0x87391c27l, 0xe5282161l},
                  {0xb5ddd833l, 0x9d82d1d1l},
                  {0x81f4b92bl, 0xd94b6fd8l},
                  {0x93a4b42fl, 0x62ea59e4l},
                  {0xaba49407l, 0x2bf411e5l},
                  {0xfdeb5262l, 0x75fb9d94l},
                  {0xcc8f72aal, 0xe685fdb1l}};
  long m[8][2] = {{0x18493ac4l, 0x85b8d9a0l},
                  {0x38493ac4l, 0x85b8d9a0l},
                  {0x482765ddl, 0xd7009123l},
                  {0x682765ddl, 0xd7009123l},
                  {0xabcd0987l, 0x33731ff1l},
                  {0x8bcd0987l, 0x33731ff1l},
                  {0x13578642l, 0xaaffedcbl},
                  {0x33578642l, 0xaaffedcbl}};
  long Jj[8], L4[2], L4s[2], R4p[2];
  long Cp[4][2], e[4][2], es[4][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;
  L4[1] = L4s[1] = R4p[1] = 0;
  for (i = 0; i < 4; i++) {
    i2 = 2 * i;
    i21 = i2 + 1;
    L4[0]  = c[i2][0];
    L4s[0] = c[i21][0];
    R4p[0] = c[i2][1] ^ c[i21][1];
    Cp[i][1] = e[i][1] = es[i][1] = 0;
    calculate_EEC(IP, Cp[i], L4, L4s, R4p, e[i], es[i]);
  }
  for (i = 0; i < 4; i++) {
    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 = 1; 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 = 1; i < 8; i++) printf("%2x ", Jj[i]);
  printf("\n");
  kp[0] = kp[1] = 0;
  kp[0] = (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 = 7; 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] < 16384l; guess[0]++) {
    fprintf(stderr, "\b\b\b\b\b%ld", guess[0]);
    for (j = 1; j <= 14; j++)
      guess_bit[j - 1] = get_bit(18 + j, guess);
    j = 0;
    for (i = 1; i <= 64; i++) {
      if (key_bit[i - 1] < 2)
        guess_key_bit[i - 1] = key_bit[i - 1];
      else if (key_bit[i - 1] == 2)
        guess_key_bit[i - 1] = 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]);
  found = 1;
  for (i = 0; found && i < 8; i++) {
    fprintf(stderr, "\b%d", i);
    DES(K, m[i], C);
    found = C[0] == c[i][0] && C[1] == c[i][1];
    if (!found) j = i;
  }
  fprintf(stderr, "\n");
  if (!found) printf("*error*\nin message #%d\n", j);
  return 0;
}

⌨️ 快捷键说明

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