diff --git a/src/signature/ref/include/ml_predict.h b/src/signature/ref/include/ml_predict.h new file mode 100644 index 0000000..22f7b82 --- /dev/null +++ b/src/signature/ref/include/ml_predict.h @@ -0,0 +1,6 @@ +#ifndef ML_PREDICT_H +#define ML_PREDICT_H + +double ml_predict_success(long norm, int trace, int order); + +#endif diff --git a/src/signature/ref/lvlx/ml_predict.c b/src/signature/ref/lvlx/ml_predict.c new file mode 100644 index 0000000..f50e86f --- /dev/null +++ b/src/signature/ref/lvlx/ml_predict.c @@ -0,0 +1,136 @@ +#include "ml_predict.h" +#include +#include +#include +#include +#include +#include "../src/quaternion/ref/generic/include/intbig.h" +#include "../src/quaternion/ref/generic/include/quaternion.h" + +// 下述是macOS为获取时间戳的操作 +#include +#include +#include + +// ==================== 辅助函数 ==================== + +// 将 ibz_t 转为 long +static long ibz_to_long_safe(const ibz_t *x) { + // 注意:仅用于调试,不要在生产环境中用 long 表示大数 + return (long) mpz_get_si(*x); +} + +// 计算理想的“迹”值(trace) +// 我们使用生成元近似:trace ≈ 2 * a,其中 a 是 quat 元素实部 +int quat_ideal_trace(const quat_left_ideal_t *I) { + if (I == NULL) return 0; + // 理想中存储的 lattice.basis[0] 通常包含 generator 信息 + // 取其第一个坐标近似为实部 a + ibz_t a; + ibz_init(&a); + ibz_copy(&a, &I->lattice.basis[0][0]); + long val = ibz_to_long_safe(&a); + ibz_finalize(&a); + return (int)(2 * val); +} + +// 简单启发式预测函数(可替换为导入的 ML 模型) +// double ml_predict_success(long norm_val, int trace_val, int kernel_order) { +// // 放宽条件,收集更多数据 +// double score = 0.0; +// score += (norm_val < 50) ? 0.3 : 0.1; // 放宽norm条件 +// score += (abs(trace_val) < 20) ? 0.3 : 0.1; // 放宽trace条件 +// score += (kernel_order > 20) ? 0.2 : 0.1; // 放宽kernel条件 + +// // 降低阈值 +// if (score > 0.6) return 0.7; +// else if (score > 0.4) return 0.5; +// else return 0.3; // 即使概率低也尝试 +// } + +// ML测试部分第二版本 +double ml_predict_success(long norm_val, int trace_val, int kernel_order) { + // 简单严格的版本 + double score = 0.0; + + // 严格的条件 + score += (norm_val < 1000000000000000000) ? 0.4 : 0.0; // norm必须小于1e18 + score += (abs(trace_val) < 500000000) ? 0.4 : 0.0; // trace绝对值必须小于5e8 + score += (kernel_order == 2) ? 0.2 : 0.0; // kernel必须等于2 + + // 严格的阈值 + if (score > 0.9) return 0.9; // 完美匹配所有条件 + else if (score > 0.5) return 0.6; // 匹配大部分条件 + else return 0.1; // 不匹配 +} + +// 日志函数:记录一次理想尝试 +// 以下是第一代版本 +// void ml_log_ideal_attempt(int attempt, const quat_left_ideal_t *lideal_com, int kernel_order, int success_flag) { +// FILE *logfile = fopen("ideal_data.csv", "a"); +// if (!logfile) return; + +// long norm_val = ibz_to_long_safe(&lideal_com->norm); +// int trace_val = quat_ideal_trace(lideal_com); +// double prob = ml_predict_success(norm_val, trace_val, kernel_order); + +// fprintf(logfile, "%d,%ld,%d,%d,%.3f,%d\n", attempt, norm_val, trace_val, kernel_order, prob, success_flag); +// fclose(logfile); +// } + + +// 第二代版本日志函数:记录一次理想尝试 +// 记录到 CSV 文件,包含时间戳 +void ml_log_ideal_attempt(int attempt, + const quat_left_ideal_t *lideal_com, + int kernel_order, + int success_flag) +{ + const char *dir_path = "/root/cryptologic_competition_a1_6/dataset"; + struct stat st = {0}; + + if (stat(dir_path, &st) == -1) { + mkdir(dir_path, 0755); + } + + // 使用固定文件名,避免频繁创建文件 + char csv_path[512]; + snprintf(csv_path, sizeof(csv_path), "%s/ideal_data.csv", dir_path); + + // 使用追加模式,避免覆盖 + FILE *logfile = fopen(csv_path, "a+"); + if (!logfile) { + perror("无法打开 ideal_data CSV 文件"); + return; + } + + // 如果是第一次写入,添加表头 + if (ftell(logfile) == 0) { + fprintf(logfile, "Timestamp,Attempt,Norm,Trace,KernelOrder,Prob,Success\n"); + } + + // 提取特征和记录 + long norm_val = ibz_to_long_safe(&lideal_com->norm); + int trace_val = quat_ideal_trace(lideal_com); + double prob = ml_predict_success(norm_val, trace_val, kernel_order); + + time_t t = time(NULL); + struct tm tm_info; + localtime_r(&t, &tm_info); + char time_str[32]; + strftime(time_str, sizeof(time_str), "%Y-%m-%d-%H-%M-%S", &tm_info); + + fprintf(logfile, "%s,%d,%ld,%d,%d,%.3f,%d\n", + time_str, attempt, norm_val, trace_val, kernel_order, prob, success_flag); + + fclose(logfile); + + // 控制台输出成功案例 + if (success_flag) { + printf("[SUCCESS] attempt=%d norm=%ld trace=%d kernel=%d\n", + attempt, norm_val, trace_val, kernel_order); + } else { + printf("[SKIP] attempt=%d norm=%ld trace=%d kernel=%d prob=%.3f\n", + attempt, norm_val, trace_val, kernel_order, prob); + } +} \ No newline at end of file diff --git a/src/signature/ref/lvlx/sign.c b/src/signature/ref/lvlx/sign.c index 9216bbe..d7728da 100644 --- a/src/signature/ref/lvlx/sign.c +++ b/src/signature/ref/lvlx/sign.c @@ -1,4 +1,7 @@ #include +#include // 包含机器学习模型的头文件 +#include "ml_predict.c" // 包含实现文件(仅用于测试,生产环境应编译链接) +#include #include #include #include @@ -7,21 +10,61 @@ // compute the commitment with ideal to isogeny clapotis // and apply it to the basis of E0 (together with the multiplication by some scalar u) + +// 原代码如下,为了进行相应的测试,暂时注释掉 +// static bool +// commit(ec_curve_t *E_com, ec_basis_t *basis_even_com, quat_left_ideal_t *lideal_com) +// { + +// bool found = false; + +// found = quat_sampling_random_ideal_O0_given_norm(lideal_com, &COM_DEGREE, 1, &QUAT_represent_integer_params, NULL); +// // replacing it with a shorter prime norm equivalent ideal +// found = found && quat_lideal_prime_norm_reduced_equivalent( +// lideal_com, &QUATALG_PINFTY, QUAT_primality_num_iter, QUAT_equiv_bound_coeff); +// // ideal to isogeny clapotis +// found = found && dim2id2iso_arbitrary_isogeny_evaluation(basis_even_com, E_com, lideal_com); +// return found; +// } + + +// 这是我的第一个版本的代码,需要进一步测试和调试,于是为了收集更多正确和错误的数据集,我在下面改了第二版 static bool commit(ec_curve_t *E_com, ec_basis_t *basis_even_com, quat_left_ideal_t *lideal_com) { - + static int attempt_counter = 0; bool found = false; + int kernel_order = 2; - found = quat_sampling_random_ideal_O0_given_norm(lideal_com, &COM_DEGREE, 1, &QUAT_represent_integer_params, NULL); - // replacing it with a shorter prime norm equivalent ideal - found = found && quat_lideal_prime_norm_reduced_equivalent( - lideal_com, &QUATALG_PINFTY, QUAT_primality_num_iter, QUAT_equiv_bound_coeff); - // ideal to isogeny clapotis + // Step 1. 随机生成理想 + found = quat_sampling_random_ideal_O0_given_norm(lideal_com, &COM_DEGREE, 1, + &QUAT_represent_integer_params, NULL); + // Step 2. 用机器学习预测理想是否值得尝试 + long norm_val = mpz_get_si(lideal_com->norm); + int trace_val = quat_ideal_trace(lideal_com); + double prob = ml_predict_success(norm_val, trace_val, kernel_order); + + if (prob < 0.3) { + // 概率太低,跳过以节省计算 + ml_log_ideal_attempt(attempt_counter++, lideal_com, kernel_order, 0); + return false; + } + + // Step 3. 尝试优化等价理想 + found = found && quat_lideal_prime_norm_reduced_equivalent(lideal_com, &QUATALG_PINFTY, + QUAT_primality_num_iter, + QUAT_equiv_bound_coeff); + + // Step 4. 理想到同源映射 found = found && dim2id2iso_arbitrary_isogeny_evaluation(basis_even_com, E_com, lideal_com); + + // Step 5. 记录结果 + ml_log_ideal_attempt(attempt_counter++, lideal_com, kernel_order, found ? 1 : 0); + return found; } + static void compute_challenge_ideal_signature(quat_left_ideal_t *lideal_chall_two, const signature_t *sig, const secret_key_t *sk) {