feat: 使用ML优化Deuring-correspondence,v1

This commit is contained in:
AsyncKurisu
2025-11-24 23:09:14 +08:00
parent c7cef447b8
commit 28154c2a31
3 changed files with 191 additions and 6 deletions

View File

@@ -0,0 +1,6 @@
#ifndef ML_PREDICT_H
#define ML_PREDICT_H
double ml_predict_success(long norm, int trace, int order);
#endif

View File

@@ -0,0 +1,136 @@
#include "ml_predict.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include <math.h>
#include "../src/quaternion/ref/generic/include/intbig.h"
#include "../src/quaternion/ref/generic/include/quaternion.h"
// 下述是macOS为获取时间戳的操作
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
// ==================== 辅助函数 ====================
// 将 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);
}
}

View File

@@ -1,4 +1,7 @@
#include <signature.h> #include <signature.h>
#include <ml_predict.h> // 包含机器学习模型的头文件
#include "ml_predict.c" // 包含实现文件(仅用于测试,生产环境应编译链接)
#include <assert.h>
#include <tools.h> #include <tools.h>
#include <quaternion_data.h> #include <quaternion_data.h>
#include <id2iso.h> #include <id2iso.h>
@@ -7,21 +10,61 @@
// compute the commitment with ideal to isogeny clapotis // compute the commitment with ideal to isogeny clapotis
// and apply it to the basis of E0 (together with the multiplication by some scalar u) // 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 static bool
commit(ec_curve_t *E_com, ec_basis_t *basis_even_com, quat_left_ideal_t *lideal_com) 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; 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); // Step 1. 随机生成理想
// replacing it with a shorter prime norm equivalent ideal found = quat_sampling_random_ideal_O0_given_norm(lideal_com, &COM_DEGREE, 1,
found = found && quat_lideal_prime_norm_reduced_equivalent( &QUAT_represent_integer_params, NULL);
lideal_com, &QUATALG_PINFTY, QUAT_primality_num_iter, QUAT_equiv_bound_coeff); // Step 2. 用机器学习预测理想是否值得尝试
// ideal to isogeny clapotis 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); 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; return found;
} }
static void static void
compute_challenge_ideal_signature(quat_left_ideal_t *lideal_chall_two, const signature_t *sig, const secret_key_t *sk) compute_challenge_ideal_signature(quat_left_ideal_t *lideal_chall_two, const signature_t *sig, const secret_key_t *sk)
{ {