template <> int svpcvp(Options &o, ZZ_mat<mpz_t> &b, const vector<Z_NR<mpz_t>> &target) { const char *format = o.output_format ? o.output_format : "s"; IntVect sol_coord; // In the LLL-reduced basis IntVect sol_coord_2; // In the initial basis IntVect solution; IntMatrix u; bool with_coord = strchr(format, 'c') != NULL; bool with_coord_std = strchr(format, 's') != NULL; int flags = SVP_DEFAULT | (o.verbose ? SVP_VERBOSE : 0); int flagsLLL = LLL_DEFAULT | (o.verbose ? LLL_VERBOSE : 0); int status; if (!o.no_lll) { if (with_coord) { status = lll_reduction(b, u, LLL_DEF_DELTA, LLL_DEF_ETA, LM_WRAPPER, FT_DEFAULT, 0, flagsLLL); } else { status = lll_reduction(b, LLL_DEF_DELTA, LLL_DEF_ETA, LM_WRAPPER, FT_DEFAULT, 0, flagsLLL); } if (status != RED_SUCCESS) { cerr << "LLL reduction failed: " << get_red_status_str(status) << endl; return status; } } if (target.empty()) status = shortest_vector(b, sol_coord, SVPM_PROVED, flags); else status = closest_vector(b, target, sol_coord, flags); if (status != RED_SUCCESS) { cerr << "Failure: " << get_red_status_str(status) << endl; return status; } if (with_coord) { if (o.no_lll) sol_coord_2 = sol_coord; else vector_matrix_product(sol_coord_2, sol_coord, u); } if (with_coord_std) { vector_matrix_product(solution, sol_coord, b); } for (int i = 0; format[i]; i++) { switch (format[i]) { case 'c': cout << sol_coord_2 << endl; break; case 's': cout << solution << endl; break; case 't': cout << status << endl; break; case ' ': cout << endl; break; } } return status; }
template<class Z> Obj dofplll(Obj gapmat, Obj lllargs, Obj svpargs) { if (!IS_PLIST(gapmat)) return INTOBJ_INT(-1); Int numrows = LEN_PLIST(gapmat), numcols = -1; for (int i = 1; i <= numrows; i++) { Obj row = ELM_PLIST(gapmat,i); if (numcols == -1) numcols = LEN_PLIST(row); if (numcols != LEN_PLIST(row)) return INTOBJ_INT(-1); } if (numcols <= 0) return INTOBJ_INT(-1); ZZ_mat<Z> mat(numrows, numcols); for (int i = 1; i <= numrows; i++) for (int j = 1; j <= numcols; j++) SET_INTOBJ(mat[i-1][j-1], ELM_PLIST(ELM_PLIST(gapmat,i),j)); if (lllargs != Fail) { double delta = 0.99; double eta = 0.51; LLLMethod method = LM_WRAPPER; FloatType floatType = FT_DEFAULT; int precision = 0; int flags = LLL_DEFAULT; if (lllargs != True) { if (!IS_PLIST(lllargs) || LEN_PLIST(lllargs) != 6) return INTOBJ_INT(-20); Obj v = ELM_PLIST(lllargs,1); if (IS_MACFLOAT(v)) delta = VAL_MACFLOAT(v); else if (v != Fail) return INTOBJ_INT(-21); v = ELM_PLIST(lllargs,2); if (IS_MACFLOAT(v)) eta = VAL_MACFLOAT(v); else if (v != Fail) return INTOBJ_INT(-22); v = ELM_PLIST(lllargs,3); if (v == INTOBJ_INT(0)) method = LM_WRAPPER; else if (v == INTOBJ_INT(1)) method = LM_PROVED; else if (v == INTOBJ_INT(2)) method = LM_HEURISTIC; else if (v == INTOBJ_INT(3)) method = LM_FAST; else if (v != Fail) return INTOBJ_INT(-23); v = ELM_PLIST(lllargs,4); if (v == INTOBJ_INT(0)) floatType = FT_DEFAULT; else if (v == INTOBJ_INT(1)) floatType = FT_DOUBLE; else if (v == INTOBJ_INT(2)) floatType = FT_DPE; else if (v == INTOBJ_INT(3)) floatType = FT_MPFR; else if (v != Fail) return INTOBJ_INT(-24); v = ELM_PLIST(lllargs,5); if (IS_INTOBJ(v)) precision = INT_INTOBJ(v); else if (v != Fail) return INTOBJ_INT(-25); v = ELM_PLIST(lllargs,6); if (IS_INTOBJ(v)) flags = INT_INTOBJ(v); else if (v != Fail) return INTOBJ_INT(-26); } int result = lll_reduction(mat, delta, eta, method, floatType, precision, flags); if (result != RED_SUCCESS) return INTOBJ_INT(10*result+1); } if (svpargs != Fail) { SVPMethod method = SVPM_PROVED; int flags = SVP_DEFAULT; // __asm__ ("int3"); if (svpargs != True) { if (!IS_PLIST(svpargs) || LEN_PLIST(svpargs) != 2) return INTOBJ_INT(-30); Obj v = ELM_PLIST(svpargs,1); if (v == INTOBJ_INT(0)) method = SVPM_PROVED; else if (v == INTOBJ_INT(1)) method = SVPM_FAST; else if (v != Fail) return INTOBJ_INT(-31); v = ELM_PLIST(svpargs,2); if (IS_INTOBJ(v)) flags = INT_INTOBJ(v); else if (v != Fail) return INTOBJ_INT(-32); } vector<Integer> sol(numrows); IntMatrix svpmat(numrows,numcols); for (int i = 0; i < numrows; i++) for (int j = 0; j < numcols; j++) SET_Z(svpmat[i][j],mat[i][j]); int result = shortest_vector(svpmat, sol, method, flags); if (result != RED_SUCCESS) return INTOBJ_INT(10*result+2); Obj gapvec; if (lllargs == Fail) { // return coordinates of shortest vector in mat gapvec = NEW_PLIST(T_PLIST,numrows); SET_LEN_PLIST(gapvec,numrows); for (int i = 1; i <= numrows; i++) { Obj v = GET_INTOBJ(sol[i-1]); SET_ELM_PLIST(gapvec,i,v); } } else { // return shortest vector gapvec = NEW_PLIST(T_PLIST,numcols); SET_LEN_PLIST(gapvec,numcols); for (int i = 1; i <= numcols; i++) { Integer s; s = 0; for (int j = 0; j < numrows; j++) s.addmul(sol[j],svpmat[j][i-1]); Obj v = GET_INTOBJ(s); SET_ELM_PLIST(gapvec,i,v); } } return gapvec; } gapmat = NEW_PLIST(T_PLIST,numrows); SET_LEN_PLIST(gapmat,numrows); for (int i = 1; i <= numrows; i++) { Obj gaprow = NEW_PLIST(T_PLIST,numcols); SET_LEN_PLIST(gaprow,numcols); SET_ELM_PLIST(gapmat,i,gaprow); for (int j = 1; j <= numcols; j++) { Obj v = GET_INTOBJ(mat[i-1][j-1]); SET_ELM_PLIST(gaprow,j,v); } } return gapmat; }