diff --git a/.cmake/arm_optimization.cmake b/.cmake/arm_optimization.cmake index 6d77034..9ae8704 100644 --- a/.cmake/arm_optimization.cmake +++ b/.cmake/arm_optimization.cmake @@ -23,39 +23,51 @@ if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64" OR ${CMAKE_SYSTEM_PROCESSOR} MAT add_compile_options(-march=armv8-a+crypto) add_compile_definitions(HAVE_ARM64_CRYPTO) endif() + + # CPU特定优化 + # 根据实际部署平台选择合适的CPU型号 + add_compile_options(-mtune=cortex-a76) # 默认使用cortex-a76 + + # 更多ARM64优化选项 + add_compile_options( + -moutline-atomics # 内联原子操作 + -mstrict-align # 严格对齐优化 + ) + else() # ARM32架构 add_compile_options(-march=armv7-a -mfpu=neon) endif() # 通用ARM优化选项 - # 启用循环展开和其他优化 - add_compile_options(-O3 -funroll-loops) + add_compile_options( + -O3 # 最高级别优化 + -funroll-loops # 循环展开 + -fomit-frame-pointer # 省略帧指针 + -frename-registers # 重命名寄存器 + -fipa-pta # 点对点分析 + -floop-optimize # 循环优化 + -fprefetch-loop-arrays # 预取循环数组 + -funroll-all-loops # 展开所有循环 + -fpeel-loops # 循环剥离 + ) + + # 浮点运算优化 + add_compile_options( + -ffast-math # 快速数学运算 + -ffp-contract=fast # 快速浮点收缩 + -funsafe-math-optimizations # 不安全的数学优化 + -ftree-vectorize # 树向量化 + ) # 启用链接时优化(LTO) include(CheckIPOSupported) check_ipo_supported(RESULT result) if(result) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) - # 检查编译器是否支持 thin LTO - include(CheckCCompilerFlag) - # check_c_compiler_flag("-flto=thin" HAS_THIN_LTO) - # if(HAS_THIN_LTO) - # add_compile_options(-flto=thin) - # else() - # # 回退到普通 LTO - # add_compile_options(-flto) - # endif() add_compile_options(-flto=auto) endif() - # 启用快速数学运算(可能影响精度) - # add_compile_options(-ffast-math) - - # 针对特定CPU的优化 - # 可以根据目标设备替换为具体的CPU型号,如"cortex-a72"等 - add_compile_options(-mtune=cortex-a76) - message(STATUS "ARM optimizations enabled for ${CMAKE_SYSTEM_PROCESSOR}") # 添加NEON支持的定义 diff --git a/.cmake/target.cmake b/.cmake/target.cmake index 75d0cde..2018968 100644 --- a/.cmake/target.cmake +++ b/.cmake/target.cmake @@ -51,6 +51,11 @@ else() message("Warning: system architecture not detected, defaulting to 64 bit") endif() +# 修改默认GF_RADIX为64 +if (NOT DEFINED GF_RADIX) + set(GF_RADIX 64) +endif() + if (NOT GF_RADIX STREQUAL "AUTO") if (NOT((GF_RADIX EQUAL 64) OR (GF_RADIX EQUAL 32))) message(FATAL_ERROR "Currently supported options for GF_RADIX: 32 or 64. Aborting") @@ -97,4 +102,4 @@ if (NOT DEFINED SQISIGN_TEST_REPS) set(SQISIGN_TEST_REPS 10) endif() -add_compile_definitions(SQISIGN_TEST_REPS=${SQISIGN_TEST_REPS}) +add_compile_definitions(SQISIGN_TEST_REPS=${SQISIGN_TEST_REPS}) \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 0466923..05527c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,9 +13,21 @@ option(ENABLE_STRICT "Build with strict compile options." ON) option(ENABLE_TESTS "Enable compilation of tests." ON) option(ENABLE_CT_TESTING "Enable compilation for constant time testing." OFF) option(ENABLE_SIGN "Build with sign functionality" ON) +option(ENABLE_OPENMP "Enable OpenMP for parallel computation" OFF) set(GMP_LIBRARY "SYSTEM" CACHE STRING "Which version of GMP to use: SYSTEM, BUILD or MINI") set(GF_RADIX "AUTO" CACHE STRING "Set the radix for the gf module (currently supported values: 32 or 64), or AUTO.") +if(ENABLE_OPENMP) + find_package(OpenMP REQUIRED) + if(OpenMP_C_FOUND) + add_compile_definitions(HAVE_OPENMP) + # 将OpenMP标志添加到全局编译选项,供后续目标使用 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${OpenMP_SHARED_LINKER_FLAGS}") + endif() +endif() + if (NOT DEFINED SQISIGN_BUILD_TYPE) SET(SQISIGN_BUILD_TYPE "ref") endif() diff --git a/src/common/arm64crypto/randombytes_ctrdrbg.c b/src/common/arm64crypto/randombytes_ctrdrbg.c index 5bc3d06..fd00658 100644 --- a/src/common/arm64crypto/randombytes_ctrdrbg.c +++ b/src/common/arm64crypto/randombytes_ctrdrbg.c @@ -29,36 +29,40 @@ __attribute__((hot)) static void AES256_key_schedule(uint8_t subkeys[15][16], const uint8_t *key) { - subkeys_t *sk = (subkeys_t *)subkeys; - uint8_t rcon = 1; - uint32_t s; - int i, j; + uint8x16_t rcon = vdupq_n_u8(0x01); + // uint8x16_t rcon_step = vdupq_n_u8(0x1b); - memcpy(&subkeys[0][0], key, 32 * sizeof(uint8_t)); + // 一次性复制前两轮密钥 + memcpy(&subkeys[0][0], key, 32); - for (i = 2; i < 14; i += 2) { - s = AES_sbox_x4(sk->u32[i - 1][3]); - sk->u32[i][0] = ROTR32(s, 8) ^ rcon ^ sk->u32[i - 2][0]; + uint8x16_t prev_key = vld1q_u8(&subkeys[0][0]); + uint8x16_t prev_prev_key = vld1q_u8(&subkeys[1][0]); - for (j = 1; j < 4; j++) { - sk->u32[i][j] = sk->u32[i][j - 1] ^ sk->u32[i - 2][j]; - } + for (int i = 2; i < 15; i++) { + // 提取最后一列并进行S-box变换 + uint8x16_t last_col = vextq_u8(prev_key, vdupq_n_u8(0), 12); + last_col = vaeseq_u8(last_col, vdupq_n_u8(0)); - s = AES_sbox_x4(sk->u32[i][3]); - sk->u32[i + 1][0] = s ^ sk->u32[i - 1][0]; + // RotWord + last_col = vextq_u8(last_col, last_col, 3); - for (j = 1; j < 4; j++) { - sk->u32[i + 1][j] = sk->u32[i + 1][j - 1] ^ sk->u32[i - 1][j]; - } + // XOR with rcon + uint8x16_t new_key_first = veorq_u8(veorq_u8(last_col, rcon), prev_prev_key); - rcon = (rcon << 1) ^ ((rcon >> 7) * 0x11b); - } + // 生成新密钥的剩余部分 + uint8x16_t new_key = vextq_u8(prev_prev_key, new_key_first, 12); - s = AES_sbox_x4(sk->u32[13][3]); - sk->u32[14][0] = ROTR32(s, 8) ^ rcon ^ sk->u32[12][0]; + // 保存新密钥 + vst1q_u8(&subkeys[i][0], new_key); - for (j = 1; j < 4; j++) { - sk->u32[14][j] = sk->u32[14][j - 1] ^ sk->u32[12][j]; + // 更新rcon + uint8_t rcon_val = vgetq_lane_u8(rcon, 0); + rcon_val = (rcon_val << 1) ^ ((rcon_val >> 7) * 0x1b); + rcon = vdupq_n_u8(rcon_val); + + // 更新前两个密钥 + prev_prev_key = prev_key; + prev_key = new_key; } } @@ -198,7 +202,7 @@ randombytes_init_arm64crypto(unsigned char *entropy_input, unsigned char *person DRBG_ctx.reseed_counter = 1; } -#define WAYS 4 +#define WAYS 8 int randombytes_arm64crypto(unsigned char *x, unsigned long long xlen) @@ -223,7 +227,10 @@ randombytes_arm64crypto(unsigned char *x, unsigned long long xlen) Vle[j] = Vle[j - 1] + 1; V[j] = Vle[j]; bswap128(&V[j]); - vV.val[j] = vld1q_u8((uint8_t *)&V[j]); + // 分批加载到向量寄存器中 + if (j % 4 == 0 || j == WAYS - 1) { + vV = vld1q_u8_x4((uint8_t *)&V[j-3]); + } } int entered_fast_path = (xlen >= WAYS * 16) ? 1 : 0; @@ -232,25 +239,55 @@ randombytes_arm64crypto(unsigned char *x, unsigned long long xlen) // 添加预取指令 __builtin_prefetch(&x[64], 1, 3); for (int j = 0; j < WAYS; j++) { - Vle[j] += 4; + Vle[j] += 8; // 增加步长以减少循环次数 } - for (int j = 0; j < WAYS; j++) { - vV.val[j] = vaeseq_u8(vV.val[j], vsubkeys[0]); - vV.val[j] = vaesmcq_u8(vV.val[j]); - } + // 展开循环以减少分支预测失败 + for (int j = 0; j < WAYS; j += 4) { + uint8x16_t state0 = vaeseq_u8(vV.val[0], vsubkeys[0]); + uint8x16_t state1 = vaeseq_u8(vV.val[1], vsubkeys[0]); + uint8x16_t state2 = vaeseq_u8(vV.val[2], vsubkeys[0]); + uint8x16_t state3 = vaeseq_u8(vV.val[3], vsubkeys[0]); + + state0 = vaesmcq_u8(state0); + state1 = vaesmcq_u8(state1); + state2 = vaesmcq_u8(state2); + state3 = vaesmcq_u8(state3); - for (int i = 1; i < 13; i++) { - for (int j = 0; j < WAYS; j++) { - vV.val[j] = vaeseq_u8(vV.val[j], vsubkeys[i]); - vV.val[j] = vaesmcq_u8(vV.val[j]); + for (int i = 1; i < 13; i++) { + state0 = vaeseq_u8(state0, vsubkeys[i]); + state1 = vaeseq_u8(state1, vsubkeys[i]); + state2 = vaeseq_u8(state2, vsubkeys[i]); + state3 = vaeseq_u8(state3, vsubkeys[i]); + + state0 = vaesmcq_u8(state0); + state1 = vaesmcq_u8(state1); + state2 = vaesmcq_u8(state2); + state3 = vaesmcq_u8(state3); } - } - for (int j = 0; j < WAYS; j++) { - vV.val[j] = vaeseq_u8(vV.val[j], vsubkeys[13]); - vV.val[j] = veorq_u8(vV.val[j], vsubkeys[14]); - vst1q_u8(x + j * 16, vV.val[j]); + state0 = vaeseq_u8(state0, vsubkeys[13]); + state1 = vaeseq_u8(state1, vsubkeys[13]); + state2 = vaeseq_u8(state2, vsubkeys[13]); + state3 = vaeseq_u8(state3, vsubkeys[13]); + + state0 = veorq_u8(state0, vsubkeys[14]); + state1 = veorq_u8(state1, vsubkeys[14]); + state2 = veorq_u8(state2, vsubkeys[14]); + state3 = veorq_u8(state3, vsubkeys[14]); + + vst1q_u8(x + 0 * 16, state0); + vst1q_u8(x + 1 * 16, state1); + vst1q_u8(x + 2 * 16, state2); + vst1q_u8(x + 3 * 16, state3); + + // 更新向量寄存器 + if (j + 4 < WAYS) { + vV.val[0] = vld1q_u8((uint8_t *)&V[j+4]); + vV.val[1] = vld1q_u8((uint8_t *)&V[j+5]); + vV.val[2] = vld1q_u8((uint8_t *)&V[j+6]); + vV.val[3] = vld1q_u8((uint8_t *)&V[j+7]); + } } for (int j = 0; j < WAYS; j++) { @@ -265,8 +302,8 @@ randombytes_arm64crypto(unsigned char *x, unsigned long long xlen) } if (entered_fast_path && xlen == 0) { - asm volatile("" : "+r,m"(Vle[3]) : : "memory"); - V[0] = Vle[3] - 4; + asm volatile("" : "+r,m"(Vle[7]) : : "memory"); + V[0] = Vle[7] - 8; bswap128(&V[0]); } diff --git a/src/quaternion/ref/generic/lll/lll_tests.c b/src/quaternion/ref/generic/lll/lll_tests.c index 0a0c773..780584c 100644 --- a/src/quaternion/ref/generic/lll/lll_tests.c +++ b/src/quaternion/ref/generic/lll/lll_tests.c @@ -655,13 +655,48 @@ quat_test_lll_lideal_lideal_mul_reduced() ibz_mat_4x4_mul(&(gram_test), &(gram_test), &(prod.lattice.basis)); ibz_mat_4x4_transpose(&(gram_test), &(gram_test)); ibz_mat_4x4_mul(&(gram_test), &(gram_test), &(prod.lattice.basis)); - for (int i = 0; i < 4; i++) { - ibz_vec_4_set(&vec, (i == 0), (i == 1), (i == 2), (i == 3)); - quat_qf_eval(&norm, &gram, &vec); - quat_qf_eval(&test_norm, &gram_test, &vec); - ibz_mul(&norm, &(prod.norm), &norm); - res = res || !(ibz_cmp(&norm, &test_norm) == 0); - } + + // ARM优化: 循环展开以减少分支预测失败的可能性 + // 原始循环: + // for (int i = 0; i < 4; i++) { + // ibz_vec_4_set(&vec, (i == 0), (i == 1), (i == 2), (i == 3)); + // quat_qf_eval(&norm, &gram, &vec); + // quat_qf_eval(&test_norm, &gram_test, &vec); + // ibz_mul(&norm, &(prod.norm), &norm); + // res = res || !(ibz_cmp(&norm, &test_norm) == 0); + // } + + // 展开后的循环 - 减少循环开销,更适合ARM处理器流水线 + ibz_vec_4_set(&vec, 1, 0, 0, 0); + quat_qf_eval(&norm, &gram, &vec); + quat_qf_eval(&test_norm, &gram_test, &vec); + ibz_mul(&norm, &(prod.norm), &norm); + res = res || !(ibz_cmp(&norm, &test_norm) == 0); + + ibz_vec_4_set(&vec, 0, 1, 0, 0); + quat_qf_eval(&norm, &gram, &vec); + quat_qf_eval(&test_norm, &gram_test, &vec); + ibz_mul(&norm, &(prod.norm), &norm); + res = res || !(ibz_cmp(&norm, &test_norm) == 0); + + ibz_vec_4_set(&vec, 0, 0, 1, 0); + quat_qf_eval(&norm, &gram, &vec); + quat_qf_eval(&test_norm, &gram_test, &vec); + ibz_mul(&norm, &(prod.norm), &norm); + res = res || !(ibz_cmp(&norm, &test_norm) == 0); + + ibz_vec_4_set(&vec, 0, 0, 0, 1); + quat_qf_eval(&norm, &gram, &vec); + quat_qf_eval(&test_norm, &gram_test, &vec); + ibz_mul(&norm, &(prod.norm), &norm); + res = res || !(ibz_cmp(&norm, &test_norm) == 0); + + // 使用NEON优化大整数运算(如果可用) +#ifdef HAVE_NEON + // 在支持NEON的ARM64平台上并行处理多个规范评估 + // 这里可以进一步优化,但需要重构底层的大整数运算库 +#endif + quat_lattice_hnf(&(prod.lattice)); res = res || !quat_lideal_equals(&i1, &lideal1, &alg); diff --git a/src/signature/ref/lvlx/keygen.c b/src/signature/ref/lvlx/keygen.c index c1c206c..cad5634 100644 --- a/src/signature/ref/lvlx/keygen.c +++ b/src/signature/ref/lvlx/keygen.c @@ -3,6 +3,9 @@ #include #include #include +#ifdef _OPENMP +#include +#endif void secret_key_init(secret_key_t *sk) @@ -27,7 +30,59 @@ protocols_keygen(public_key_t *pk, secret_key_t *sk) // iterating until a solution has been found while (!found) { + // 尝试并行生成多个理想,提高找到解决方案的概率 +#ifdef _OPENMP + int num_threads = omp_get_max_threads(); + if (num_threads > 1) { + int local_found = 0; +#pragma omp parallel shared(found, local_found) num_threads(num_threads) + { + if (!local_found) { + secret_key_t local_sk; + secret_key_init(&local_sk); + + int thread_found = quat_sampling_random_ideal_O0_given_norm( + &local_sk.secret_ideal, &SEC_DEGREE, 1, &QUAT_represent_integer_params, NULL); + // replacing the secret key ideal by a shorter equivalent one for efficiency + thread_found = thread_found && quat_lideal_prime_norm_reduced_equivalent( + &local_sk.secret_ideal, &QUATALG_PINFTY, QUAT_primality_num_iter, QUAT_equiv_bound_coeff); + + // ideal to isogeny clapotis + ec_basis_t local_B_0_two; + thread_found = thread_found && dim2id2iso_arbitrary_isogeny_evaluation(&local_B_0_two, &local_sk.curve, &local_sk.secret_ideal); + + if (thread_found) { +#pragma omp critical + { + if (!local_found) { + local_found = 1; + found = 1; + // Copy local results to global variables + quat_left_ideal_copy(&sk->secret_ideal, &local_sk.secret_ideal); + ec_curve_copy(&sk->curve, &local_sk.curve); + // Copy basis + ec_point_copy(&B_0_two.P, &local_B_0_two.P); + ec_point_copy(&B_0_two.Q, &local_B_0_two.Q); + ec_point_copy(&B_0_two.PmQ, &local_B_0_two.PmQ); + } + } + } + secret_key_finalize(&local_sk); + } + } + } else { + found = quat_sampling_random_ideal_O0_given_norm( + &sk->secret_ideal, &SEC_DEGREE, 1, &QUAT_represent_integer_params, NULL); + + // replacing the secret key ideal by a shorter equivalent one for efficiency + found = found && quat_lideal_prime_norm_reduced_equivalent( + &sk->secret_ideal, &QUATALG_PINFTY, QUAT_primality_num_iter, QUAT_equiv_bound_coeff); + + // ideal to isogeny clapotis + found = found && dim2id2iso_arbitrary_isogeny_evaluation(&B_0_two, &sk->curve, &sk->secret_ideal); + } +#else found = quat_sampling_random_ideal_O0_given_norm( &sk->secret_ideal, &SEC_DEGREE, 1, &QUAT_represent_integer_params, NULL); @@ -36,8 +91,8 @@ protocols_keygen(public_key_t *pk, secret_key_t *sk) &sk->secret_ideal, &QUATALG_PINFTY, QUAT_primality_num_iter, QUAT_equiv_bound_coeff); // ideal to isogeny clapotis - found = found && dim2id2iso_arbitrary_isogeny_evaluation(&B_0_two, &sk->curve, &sk->secret_ideal); +#endif } // Assert the isogeny was found and images have the correct order @@ -61,4 +116,4 @@ protocols_keygen(public_key_t *pk, secret_key_t *sk) assert(fp2_is_one(&pk->curve.C) == 0xFFFFFFFF); return found; -} +} \ No newline at end of file diff --git a/src/signature/ref/lvlx/ml_predict.c b/src/signature/ref/lvlx/ml_predict.c index 195b5aa..6d0af71 100644 --- a/src/signature/ref/lvlx/ml_predict.c +++ b/src/signature/ref/lvlx/ml_predict.c @@ -78,47 +78,47 @@ double ml_predict_success(long norm_val, int trace_val, int kernel_order) { // 日志函数:记录一次理想尝试 // 记录到 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 = "./dataset"; - struct stat st = {0}; +// void ml_log_ideal_attempt(int attempt, +// const quat_left_ideal_t *lideal_com, +// int kernel_order, +// int success_flag) +// { +// const char *dir_path = "./dataset"; +// struct stat st = {0}; - if (stat(dir_path, &st) == -1) { - mkdir(dir_path, 0755); - } +// 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); +// // 使用固定文件名,避免频繁创建文件 +// 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; - } +// // 使用追加模式,避免覆盖 +// 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"); - } +// // 如果是第一次写入,添加表头 +// 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); +// // 提取特征和记录 +// 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); +// 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); +// fprintf(logfile, "%s,%d,%ld,%d,%d,%.3f,%d\n", +// time_str, attempt, norm_val, trace_val, kernel_order, prob, success_flag); - fclose(logfile); -} \ No newline at end of file +// fclose(logfile); +// } \ No newline at end of file diff --git a/src/signature/ref/lvlx/sign.c b/src/signature/ref/lvlx/sign.c index d7728da..019c887 100644 --- a/src/signature/ref/lvlx/sign.c +++ b/src/signature/ref/lvlx/sign.c @@ -7,6 +7,14 @@ #include #include #include +#include +#ifdef _OPENMP +#include +#endif + +// 添加函数声明 +static bool execute_commit_serial(ec_curve_t *E_com, ec_basis_t *basis_even_com, + quat_left_ideal_t *lideal_com, int *attempt_counter, int kernel_order); // compute the commitment with ideal to isogeny clapotis // and apply it to the basis of E0 (together with the multiplication by some scalar u) @@ -36,6 +44,76 @@ commit(ec_curve_t *E_com, ec_basis_t *basis_even_com, quat_left_ideal_t *lideal_ bool found = false; int kernel_order = 2; + // 使用并行计算来加速随机理想采样 +#ifdef _OPENMP + int num_threads = omp_get_max_threads(); + if (num_threads > 1) { +#pragma omp parallel for reduction(|:found) num_threads(num_threads) + for (int i = 0; i < num_threads && !found; i++) { + // 为每个线程创建独立的临时变量 + quat_left_ideal_t local_ideal; + quat_left_ideal_init(&local_ideal); + + // 添加线程特定的随机性 + random_state_t local_rand; + random_init(&local_rand); + random_add_entropy(&local_rand, (unsigned char*)&i, sizeof(i)); + + // 尝试采样理想 + bool local_found = quat_sampling_random_ideal_O0_given_norm( + &local_ideal, &COM_DEGREE, 1, &QUAT_represent_integer_params, &local_rand); + + if (local_found) { + // 用机器学习预测理想是否值得尝试 + long norm_val = mpz_get_si(local_ideal.norm); + int trace_val = quat_ideal_trace(&local_ideal); + double prob = ml_predict_success(norm_val, trace_val, kernel_order); + + if (prob >= 0.3) { // 概率足够高才继续 + // 尝试优化等价理想 + local_found = local_found && + quat_lideal_prime_norm_reduced_equivalent(&local_ideal, &QUATALG_PINFTY, + QUAT_primality_num_iter, QUAT_equiv_bound_coeff); + + if (local_found) { +#pragma omp critical + { + if (!found) { + // 复制成功的结果到输出参数 + quat_left_ideal_copy(lideal_com, &local_ideal); + found = true; + } + } + } + } + } + + quat_left_ideal_finalize(&local_ideal); + random_finalize(&local_rand); + } + + // 如果并行搜索成功,则执行同源映射评估 + if (found) { + found = dim2id2iso_arbitrary_isogeny_evaluation(basis_even_com, E_com, lideal_com); + } + } else { + // 单线程情况 - 原有逻辑 + found = execute_commit_serial(E_com, basis_even_com, lideal_com, &attempt_counter, kernel_order); + } +#else + // 没有OpenMP的情况 - 原有逻辑 + found = execute_commit_serial(E_com, basis_even_com, lideal_com, &attempt_counter, kernel_order); +#endif + + return found; +} + +// 辅助函数:串行提交逻辑 +static bool execute_commit_serial(ec_curve_t *E_com, ec_basis_t *basis_even_com, + quat_left_ideal_t *lideal_com, int *attempt_counter, int kernel_order) +{ + bool found = false; + // Step 1. 随机生成理想 found = quat_sampling_random_ideal_O0_given_norm(lideal_com, &COM_DEGREE, 1, &QUAT_represent_integer_params, NULL); @@ -46,7 +124,7 @@ commit(ec_curve_t *E_com, ec_basis_t *basis_even_com, quat_left_ideal_t *lideal_ if (prob < 0.3) { // 概率太低,跳过以节省计算 - ml_log_ideal_attempt(attempt_counter++, lideal_com, kernel_order, 0); + ml_log_ideal_attempt((*attempt_counter)++, lideal_com, kernel_order, 0); return false; } @@ -59,7 +137,7 @@ commit(ec_curve_t *E_com, ec_basis_t *basis_even_com, quat_left_ideal_t *lideal_ 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); + ml_log_ideal_attempt((*attempt_counter)++, lideal_com, kernel_order, found ? 1 : 0); return found; }