Skip to content

Commit fbd3503

Browse files
wNaf Edwards twisted torsion 16 stage 2 OK
1 parent ee6b0ba commit fbd3503

File tree

1 file changed

+68
-18
lines changed

1 file changed

+68
-18
lines changed

src/modes/RunEcmTwistedEdwards.cpp

Lines changed: 68 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,13 @@ int App::runECMMarinTwistedEdwards()
767767
// (options.torsion16 ? string("16") : string("8"));
768768
bool built = false;
769769

770+
// In-memory checkpoint of the last known good state for fast recovery on errors
771+
std::vector<char> last_good_state;
772+
bool have_last_good_state = false;
773+
uint32_t last_good_iter = 0;
774+
uint32_t current_iter_for_invariant = 0;
775+
const size_t ctx_ckpt_size = eng->get_checkpoint_size();
776+
770777
auto force_on_curve = [&](mpz_class& aE_ref,
771778
mpz_class& dE_ref,
772779
const mpz_class& X,
@@ -873,15 +880,24 @@ int App::runECMMarinTwistedEdwards()
873880
auto lhs = addm(mulm(aE, sqrm(Xv)), sqrm(Yv));
874881
auto rhs = addm(sqrm(Zv), mulm(dE, sqrm(Tv)));
875882
auto rel = subm(lhs, rhs);
876-
if (rel != 0){std::cout << "[ECM] invariant FAIL (a="
877-
<< aE << ")\n";
878-
return false;
879-
}
880-
else{
881-
std::cout << "[ECM] check invariant OK (a="
882-
<< aE << ")\n";
883-
return true;
884-
}
883+
if (rel != 0){
884+
std::cout << "[ECM] invariant FAIL (a="
885+
<< aE << ")\n";
886+
return false;
887+
}
888+
else{
889+
std::cout << "[ECM] check invariant OK (a="
890+
<< aE << ")\n";
891+
// Save an in-memory checkpoint of this good state
892+
if (ctx_ckpt_size > 0) {
893+
last_good_state.resize(ctx_ckpt_size);
894+
if (eng->get_checkpoint(last_good_state)) {
895+
have_last_good_state = true;
896+
last_good_iter = current_iter_for_invariant;
897+
}
898+
}
899+
return true;
900+
}
885901
};
886902

887903
torsion_last = torsion_used;
@@ -1328,7 +1344,20 @@ int App::runECMMarinTwistedEdwards()
13281344

13291345

13301346
bool resumed = (rr == 0 && start_i > 0);
1331-
if (!resumed) { saved_et = 0.0; nb_ck = 0; }
1347+
if (!resumed) {
1348+
saved_et = 0.0;
1349+
nb_ck = 0;
1350+
} else {
1351+
// Treat the resumed state as a valid last-good checkpoint
1352+
if (ctx_ckpt_size > 0) {
1353+
last_good_state.resize(ctx_ckpt_size);
1354+
if (eng->get_checkpoint(last_good_state)) {
1355+
have_last_good_state = true;
1356+
last_good_iter = start_i;
1357+
current_iter_for_invariant = start_i;
1358+
}
1359+
}
1360+
}
13321361

13331362
auto t0 = high_resolution_clock::now();
13341363
auto last_save = t0;
@@ -1395,6 +1424,10 @@ int App::runECMMarinTwistedEdwards()
13951424
}
13961425
}
13971426
bool errordone = false;
1427+
bool fatal_error = false;
1428+
if(resume_stage2){
1429+
start_i = total_steps;
1430+
}
13981431
for (uint32_t i = start_i; i < total_steps; ++i) {
13991432
if (core::algo::interrupted) {
14001433
double elapsed = duration<double>(high_resolution_clock::now() - t0).count() + saved_et;
@@ -1440,14 +1473,32 @@ int App::runECMMarinTwistedEdwards()
14401473
}
14411474
}
14421475
auto now = high_resolution_clock::now();
1443-
if (duration_cast<seconds>(now - last_check).count() >= options.ecm_check_interval) {
1476+
if (duration_cast<seconds>(now - last_check).count() >= options.ecm_check_interval || i+1 == total_steps) {
14441477

14451478
std::cout<<"\n[ECM] Error check ...."<<std::endl;
1479+
// remember which iteration this invariant corresponds to
1480+
current_iter_for_invariant = i + 1;
14461481
if(check_invariant()){
14471482
std::cout<<"[ECM] Error check Done ! ...."<<std::endl;
14481483
}
14491484
else{
14501485
std::cout<<"[ECM] Error detected!!!!!!!! ...."<<std::endl;
1486+
if (have_last_good_state) {
1487+
std::cout << "[ECM] Restoring last known good state at iteration "
1488+
<< last_good_iter << " and retrying from there." << std::endl;
1489+
if (eng->set_checkpoint(last_good_state)) {
1490+
// rewind loop to last_good_iter so it will be processed again
1491+
i = (last_good_iter > 0) ? (last_good_iter - 1) : 0;
1492+
last_check = now;
1493+
last_save = now;
1494+
continue;
1495+
} else {
1496+
std::cout << "[ECM] Failed to restore last good state, aborting curve." << std::endl;
1497+
}
1498+
} else {
1499+
std::cout << "[ECM] No saved good state available, aborting curve." << std::endl;
1500+
}
1501+
fatal_error = true;
14511502
break;
14521503
}
14531504
/*std::cout<<"[ECM] Check if factored ...."<<std::endl;
@@ -1487,6 +1538,12 @@ int App::runECMMarinTwistedEdwards()
14871538
mpz_clear(zXpos); mpz_clear(zYpos); mpz_clear(zTpos);
14881539
mpz_clear(zXneg); mpz_clear(zYneg); mpz_clear(zTneg);
14891540

1541+
if (fatal_error) {
1542+
std::cout << "[ECM] Curve " << (c+1) << " aborted after unrecoverable error, skipping.\n";
1543+
delete eng;
1544+
continue;
1545+
}
1546+
14901547
mpz_class Zacc = compute_X_with_dots(eng, (engine::Reg)5, N);
14911548
mpz_class g = gcd_with_dots(Zacc, N);
14921549
if (g == N) {
@@ -1538,13 +1595,6 @@ int App::runECMMarinTwistedEdwards()
15381595
continue;
15391596
}*/
15401597
if (B2 > B1) {
1541-
if(check_invariant()){
1542-
std::cout<<"[ECM] Error check Done and OK! ...."<<std::endl;
1543-
}
1544-
else{
1545-
std::cout<<"[ECM] Error detected!!!!!!!! ...."<<std::endl;
1546-
continue;
1547-
}
15481598
mpz_class M(1);
15491599
for (uint64_t q : primesS2_v) mpz_mul_ui(M.get_mpz_t(), M.get_mpz_t(), q);
15501600
uint32_t stage2_bits = (uint32_t)mpz_sizeinbase(M.get_mpz_t(), 2);

0 commit comments

Comments
 (0)