#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define N 4
#define MAX_ROUNDS 40
#define MAX_VAL 5
// F函数 - 模拟非线性变换
int F(int x) {
if (x == 0) return 0;
if (x == 1) return 2;
if (x == 2) return 2;
if (x == 3) return 4;
if (x == 4) return 4;
return -1;
}
// 自定义XOR操作 - 基于查找表
int XOR(int a, int b) {
int table[5][5] = {
{0,1,2,3,4},
{1,0,3,2,4},
{2,3,4,4,4},
{3,2,4,4,4},
{4,4,4,4,4}
};
return table[a][b];
}
typedef struct {
char expr[256];
int valid;
} FuncExpr;
FuncExpr forward_expr[4];
FuncExpr backward_expr[4];
// 解析单行表达式
void parse_line(char* line, char prefix, int index) {
char* equals = strchr(line, '=');
if (!equals) return;
// 跳过等号和空格
char* expr_start = equals + 1;
while (*expr_start == ' ') expr_start++;
// 复制表达式部分
if (prefix == 'Y') {
strncpy(forward_expr[index].expr, expr_start, 255);
forward_expr[index].valid = 1;
} else {
strncpy(backward_expr[index].expr, expr_start, 255);
backward_expr[index].valid = 1;
}
}
// 解析表达式并计算单点值
int eval_expr(char* expr, int state[N], int is_forward, int* used_f) {
char temp[256];
strcpy(temp, expr);
char* token = strtok(temp, "^");
int result = 0;
while (token != NULL) {
while (isspace(*token)) token++;
int value = 0;
int is_function = 0;
char* func_start = strstr(token, "F(");
if (func_start != NULL) {
is_function = 1;
token = func_start + 2;
*used_f = 1;
}
if (token[0] == 'X' || token[0] == 'Y') {
int idx = token[1] - '0';
if (idx < 0 || idx >= N) return -1;
if (token[0] == 'X') {
value = state[idx];
} else { // 'Y'
if (!is_forward) {
value = state[idx];
} else {
return -1;
}
}
}
if (is_function) {
value = F(value);
}
result = XOR(result, value);
token = strtok(NULL, "^");
}
return result;
}
// 正向轮函数R
void R(int state[N], int new_state[N]) {
for (int i = 0; i < 4; i++) {
int used_f = 0;
new_state[i] = eval_expr(forward_expr[i].expr, state, 1, &used_f);
if (new_state[i] < 0 || new_state[i] > 4) {
new_state[i] = 0;
}
}
}
// 反向轮函数R_inv
void R_inv(int state[N], int new_state[N]) {
for (int i = 0; i < 4; i++) {
int used_f = 0;
new_state[i] = eval_expr(backward_expr[i].expr, state, 0, &used_f);
if (new_state[i] < 0 || new_state[i] > 4) {
new_state[i] = 0;
}
}
}
// 检查两个差分是否矛盾
int is_contradictory(int a, int b) {
if (a == 0 && b == 1) return 1;
if (a == 0 && b == 2) return 1;
if (a == 1 && b == 3) return 1;
if (b == 0 && a == 1) return 1;
if (b == 0 && a == 2) return 1;
if (b == 1 && a == 3) return 1;
return 0;
}
// 检查输出是否为全零(0000)
int is_all_zero(int y0, int y1, int y2, int y3) {
return (y0 == 0 && y1 == 0 && y2 == 0 && y3 == 0);
}
// 打印不可能差分路径表格
void print_paths(int enc_path[MAX_ROUNDS + 1][N], int dec_path[MAX_ROUNDS + 1][N],
int total_rounds, int conflict_round,
int initial_x[4], int final_y[4]) {
// 打印路径信息
printf("\n找到的不可能差分路径: (%d,%d,%d,%d) -> (%d,%d,%d,%d)\n",
initial_x[3], initial_x[2], initial_x[1], initial_x[0],
final_y[3], final_y[2], final_y[1], final_y[0]);
// 打印表头
printf("\n===== 不可能差分路径详情 =====\n");
printf("加密方向递推表 解密方向递推表\n");
printf("轮数 X3 X2 X1 X0 轮数 Y3 Y2 Y1 Y0\n");
printf("----------------------------------------------------\n");
// 打印每一轮的状态
for (int i = 0; i <= total_rounds; i++) {
// 打印加密方向
printf("%d", i);
if (i == conflict_round) printf("*"); // 标记矛盾轮
else printf(" ");
for (int j = 3; j >= 0; j--) {
printf(" %d", enc_path[i][j]);
}
// 打印解密方向
printf(" %d", i);
if (i == conflict_round) printf("*");
else printf(" ");
for (int j = 3; j >= 0; j--) {
printf(" %d", dec_path[i][j]);
}
printf("\n");
}
printf("----------------------------------------------------\n");
printf("* 表示出现矛盾的轮次\n");
}
int main() {
printf("请粘贴整个密码结构(8行):\n");
printf("格式示例:\n");
printf("Y0=F(X0)^X1\n");
printf("Y1=F(X0)^X1^X2\n");
printf("Y2=F(X0)^X1^X2^X3\n");
printf("Y3=X0\n");
printf("X0=Y3\n");
printf("X1=Y0^F(Y3)\n");
printf("X2=Y1^Y0\n");
printf("X3=Y2^Y1\n\n");
char lines[8][256];
// 读取8行输入
for (int i = 0; i < 8; i++) {
if (fgets(lines[i], sizeof(lines[i]), stdin) == NULL) {
printf("输入错误\n");
return 1;
}
// 去除换行符
lines[i][strcspn(lines[i], "\n")] = 0;
}
// 解析正向轮函数(Y0-Y3)
for (int i = 0; i < 4; i++) {
parse_line(lines[i], 'Y', i);
}
// 解析反向轮函数(X0-X3)
for (int i = 4; i < 8; i++) {
parse_line(lines[i], 'X', i - 4);
}
int max_impossible_rounds = 0;
int enc_path[MAX_ROUNDS + 1][N];
int dec_path[MAX_ROUNDS + 1][N];
int best_conflict_round = -1;
int best_initial_x[4];
int best_final_y[4];
for (int total_rounds = 1; total_rounds < MAX_ROUNDS; total_rounds++) {
int found_impossible = 0;
int current_conflict_round = -1;
int current_initial_x[4];
int current_final_y[4];
for (int x = 1; x < (1 << N); x++) {
int current_enc[MAX_ROUNDS + 1][N];
for (int i = 0; i < N; i++) {
current_enc[0][i] = (x >> i) & 1;
current_initial_x[i] = current_enc[0][i];
}
for (int i = 1; i <= total_rounds; i++) {
R(current_enc[i - 1], current_enc[i]);
}
for (int y0 = 0; y0 < 2; y0++) {
for (int y1 = 0; y1 < 2; y1++) {
for (int y2 = 0; y2 < 2; y2++) {
for (int y3 = 0; y3 < 2; y3++) {
if (is_all_zero(y0, y1, y2, y3)) {
continue;
}
int current_dec[MAX_ROUNDS + 1][N];
current_dec[total_rounds][0] = y0;
current_dec[total_rounds][1] = y1;
current_dec[total_rounds][2] = y2;
current_dec[total_rounds][3] = y3;
current_final_y[0] = y0;
current_final_y[1] = y1;
current_final_y[2] = y2;
current_final_y[3] = y3;
for (int i = total_rounds - 1; i >= 0; i--) {
R_inv(current_dec[i + 1], current_dec[i]);
}
for (int round = 0; round <= total_rounds; round++) {
for (int j = 0; j < N; j++) {
if (is_contradictory(current_enc[round][j], current_dec[round][j])) {
memcpy(enc_path, current_enc, sizeof(int) * (MAX_ROUNDS + 1) * N);
memcpy(dec_path, current_dec, sizeof(int) * (MAX_ROUNDS + 1) * N);
current_conflict_round = round;
found_impossible = 1;
break;
}
}
if (found_impossible) break;
}
if (found_impossible) break;
}
if (found_impossible) break;
}
if (found_impossible) break;
}
if (found_impossible) break;
}
if (found_impossible) break;
}
if (found_impossible) {
max_impossible_rounds = total_rounds;
best_conflict_round = current_conflict_round;
memcpy(best_initial_x, current_initial_x, sizeof(current_initial_x));
memcpy(best_final_y, current_final_y, sizeof(current_final_y));
} else {
printf("最长不可能差分轮数为: %d\n", total_rounds - 1);
if (total_rounds - 1 > 0) {
printf("最后找到的不可能差分路径如下:");
print_paths(enc_path, dec_path, max_impossible_rounds, best_conflict_round,
best_initial_x, best_final_y);
}
return 0;
}
}
printf("\n最长不可能差分轮数为: %d\n", MAX_ROUNDS - 1);
printf("最后找到的不可能差分路径如下:");
print_paths(enc_path, dec_path, max_impossible_rounds, best_conflict_round,
best_initial_x, best_final_y);
return 0;
}
接下来修改一下输入的参数格式,改成所有等式的等号左边都只有Y,等号右边都只有X,统一格式,
比如原来是:
Y0=F(X0)^X1
Y1=F(X0)^X1^X2
Y2=F(X0)^X1^X2^X3
Y3=X0
X0=Y3
X1=Y0^F(Y3)
X2=Y1^Y0
X3=Y2^Y1
现在修改成:
Y0=F(X0)^X1
Y1=F(X0)^X1^X2
Y2=F(X0)^X1^X2^X3
Y3=X0
Y0=X3
Y1=X0^F(X3)
Y2=X1^X0
Y3=X2^X1
程序能够正常识别前4行为加密函数,后4行为解密函数,并正常进行分析,得出不可能差分结果,修改时尽可能小改程序