21 #ifndef __GSDECODER_IMPL_H__
22 #define __GSDECODER_IMPL_H__
34 #include <NTL/vec_ZZ_p.h>
35 #include <NTL/ZZ_pXFactoring.h>
36 #include <NTL/GF2EXFactoring.h>
37 #include <NTL/mat_ZZ_p.h>
38 #include <NTL/mat_GF2E.h>
40 #include "subset_iter.h"
41 #include "percyresult.h"
68 struct RSDecoder_ZZ_p::DT {
69 typedef vec_ZZ_pX vec_FX;
70 typedef vec_pair_ZZ_pX_long vec_pair_FX_long;
74 struct RSDecoder_GF2E::DT {
75 typedef vec_GF2EX vec_FX;
76 typedef vec_pair_GF2EX_long vec_pair_FX_long;
83 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
85 const vec_F &values,
const vec_F &indices,
86 const vector<unsigned short> &I,
const vector<unsigned short> &G,
87 unsigned short &numagree,
unsigned short &numdisagree,
88 vector<unsigned short> &vecagree, FX &phi)
90 numagree = numdisagree = 0;
94 vec_F I_indices, I_values;
95 I_indices.SetLength(t+1);
96 I_values.SetLength(t+1);
97 vector<unsigned short>::const_iterator Iiter;
99 for (Iiter = I.begin(); Iiter != I.end(); ++i, ++Iiter) {
100 I_indices[i] = indices[*Iiter];
101 I_values[i] = values[*Iiter];
103 interpolate(phi, I_indices, I_values);
107 vector<unsigned short>::const_iterator Giter;
108 for (Giter = G.begin(); Giter != G.end(); ++Giter) {
110 eval(phival, phi, indices[*Giter]);
111 if (phival == values[*Giter]) {
113 vecagree.push_back(*Giter);
120 extern uint64_t hasseop;
130 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
132 unsigned int r,
unsigned int s,
133 F alpha, F beta, Ccache_t &Ccache)
138 for (
int j = ydeg; j >= (int)s; --j) {
139 const FX &gj = coeff(g,j);
145 for (
int i = xdeg; i >= (int) r; --i) {
147 resx += C(Ccache, i,r) * coeff(gj, i);
153 res += C(Ccache, j,s) * resx;
160 extern uint64_t kotter_usec;
169 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
171 unsigned int v,
unsigned int t,
172 const vector<unsigned short> &goodservers,
173 const vec_F &indices,
const vec_F &shares)
175 struct timeval st, et;
176 gettimeofday(&st, NULL);
178 unsigned int n = goodservers.size();
181 unsigned int m = 1 + (
unsigned int)(floor( v*n / (t*t-v*n)));
182 unsigned int L = (m*t - 1)/v;
184 if (getenv(
"PIRC_L")) {
185 L = atoi(getenv(
"PIRC_L"));
187 if (getenv(
"PIRC_m")) {
188 m = atoi(getenv(
"PIRC_m"));
191 std::cerr <<
"Constructing (1," << v <<
")-degree " << L*v <<
" polynomial...\n";
192 std::cerr <<
"Estimated work: " << n * m * (m+1) / 2 * (L+1) <<
"\n";
193 std::cerr <<
"L = " << L <<
"\n";
194 std::cerr <<
"m = " << m <<
"\n";
195 std::cerr <<
"Min matches: " << t <<
"\n";
196 std::cerr <<
"Max degree: " << v <<
"\n";
198 double Km = v * n * (m+1);
200 Km = floor(sqrt(Km));
201 std::cerr <<
"Km ~= " << Km <<
"\n";
202 unsigned int C = n * m * (m+1) / 2;
204 cerr << (K*(K+v)+(K%v)*(v-(K%v)))/(2*v) <<
" " << C <<
"\n";
205 if ( ((K*(K+v)+(K%v)*(v-(K%v)))/(2*v)) > C ) {
206 std::cerr <<
"Km: " << (K-1)/m + 1 <<
"\n";
213 typedef pair<FXY, unsigned int> polydeg;
214 polydeg * g =
new polydeg[L+1];
215 for (
unsigned int j = 0; j <= L; ++j) {
216 SetCoeff(g[j].first, j);
222 F * Delta =
new F[L+1];
223 for (
unsigned int i = 0; i < n; ++i) {
224 F alpha = indices[goodservers[i]];
225 F beta = shares[goodservers[i]];
226 for (
unsigned int r = 0; r < m; ++r) {
227 for (
unsigned int s = 0; s < m - r; ++s) {
229 unsigned int seendeg = 0, jstar = 0;
230 for (
unsigned int j = 0; j <= L; ++j) {
231 Delta[j] = evalhasse(g[j].first, r, s, alpha, beta,
237 seendeg = g[j].second;
243 for (
unsigned int j = 0; j <= L; ++j) {
244 if (Delta[j] != 0 && g[j].second <= seendeg) {
245 seendeg = g[j].second;
249 F Deltajstar = Delta[jstar];
250 FXY f = g[jstar].first;
253 for (
unsigned int j = 0; j <= L; ++j) {
258 g[j].first = Deltajstar * g[j].first -
263 SetCoeff(xminusalpha, 1, 1);
264 SetCoeff(xminusalpha, 0, -alpha);
266 g[j].first = Deltajstar * xminusalpha * f;
280 unsigned int minweight = g[0].second;
281 unsigned int minindex = 0;
282 for (
unsigned int i=1; i<=L; ++i) {
283 if (g[i].second <= minweight) {
284 minweight = g[i].second;
289 gettimeofday(&et, NULL);
290 kotter_usec = ((uint64_t)(et.tv_sec - st.tv_sec))*1000000
291 + (et.tv_usec - st.tv_usec);
295 return g[minindex].first;
305 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
307 unsigned int ell,
unsigned int h,
308 const vector<unsigned short> &goodservers,
309 const vec_F &indices,
const vec_F &shares)
312 std::cerr <<
"STARTING COHN-HENINGER...\n";
315 unsigned int n = goodservers.size();
316 unsigned int m = ((h - ell) * n) / (h * h - ell * n) + 1;
317 unsigned int k = (h * m) / n;
318 unsigned int t = m - k;
324 for (i = 0; i < n; ++i) {
326 SetCoeff(newTerm, 0, -(indices[goodservers[i]]));
327 SetCoeff(newTerm, 1);
332 for (i = 0; i < n; ++i) {
334 SetCoeff(zPoly, 0, 1);
335 for (j = 0; j < n; ++j) {
340 SetCoeff(newTerm, 0, -(indices[goodservers[j]]));
341 SetCoeff(newTerm, 1);
343 zPoly /= (indices[goodservers[i]] - indices[goodservers[j]]);
345 constCoeff += (zPoly * shares[goodservers[i]]);
349 SetCoeff(f, 0, -constCoeff);
352 std::cerr <<
"ell = " << ell << std::endl;
353 std::cerr <<
"h = " << h << std::endl;
354 std::cerr <<
"n = " << n << std::endl;
355 std::cerr <<
"m = " << m << std::endl;
356 std::cerr <<
"k = " << k << std::endl;
357 std::cerr <<
"t = " << t << std::endl;
358 std::cerr <<
"goodservers =";
359 for (i = 0; i < n; ++i) {
360 std::cerr <<
" " << goodservers[i];
362 std::cerr << std::endl;
363 std::cerr <<
"indices =";
364 for (i = 0; i < n; ++i) {
365 std::cerr <<
" " << indices[goodservers[i]];
367 std::cerr << std::endl;
368 std::cerr <<
"shares =";
369 for (i = 0; i < n; ++i) {
370 std::cerr <<
" " << shares[goodservers[i]];
372 std::cerr << std::endl;
373 std::cerr <<
"p(z) = " << p << std::endl;
374 std::cerr <<
"f(x) = " << f << std::endl;
380 SetCoeff(z_toell, ell);
382 SetCoeff(z_toell_x, 1, z_toell);
383 FXY f_of_z_toell_x = f;
384 SetCoeff(f_of_z_toell_x, 1, z_toell);
386 vector<FXY> powers_of_f;
388 SetCoeff(one2, 0, 1);
389 powers_of_f.push_back(one2);
390 powers_of_f.push_back(f_of_z_toell_x);
391 for (i = 2; i <= k; ++i) {
392 powers_of_f.push_back(powers_of_f.back() * f_of_z_toell_x);
395 vector<FX> powers_of_p;
397 SetCoeff(one1, 0, 1);
398 powers_of_p.push_back(one1);
399 powers_of_p.push_back(p);
400 for (i = 2; i <= k; ++i) {
401 powers_of_p.push_back(powers_of_p.back() * p);
404 for (i = 0; i <= k; ++i) {
405 FXY basis_poly = powers_of_f[i] * powers_of_p[k - i];
406 basis.push_back(basis_poly);
409 char *opt_ch_env = getenv(
"PIRC_OPT_CH");
410 if (opt_ch_env && atoi(opt_ch_env)) {
413 FXY last_poly = basis[k] * z_toell_x;
414 basis.push_back(last_poly);
418 FXY current_basis_poly = powers_of_f[k];
419 for (j = 1; j < t; ++j) {
420 current_basis_poly *= z_toell_x;
421 basis.push_back(current_basis_poly);
425 vector<vector<FX> > lattice;
426 for (i = 0; i < m; ++i) {
428 for (j = 0; j < m; ++j) {
429 row.push_back(coeff(basis[i], j));
431 lattice.push_back(row);
437 std::cerr <<
"ELEMENT DEGREES:\n";
438 for (i = 0; i < m; ++i) {
440 for (j = 0; j < m; ++j) {
441 std::cerr << deg(lattice[i][j]) <<
"\t";
443 std::cerr << std::endl;
447 vector<vector<FX> > aux (m, vector<FX>());
448 vector<vector<FX> > reducedLattice = reduce_lattice_MS(lattice, aux, k*h);
451 for (i = 0; i < m; ++i) {
453 for (j = 0; j < m; ++j) {
454 FX c = reducedLattice[i][j];
455 if (deg(c) >= maxdeg) {
459 if (minindex < 0 || maxdeg < mindeg) {
466 for (i = 0; i < m; ++i) {
467 SetCoeff(Q, i, reducedLattice[minindex][i]);
471 std::cerr <<
"Q = [" << std::endl;
472 for (i = 0; i < m; ++i) {
474 std::cerr <<
" " << c <<
" (degree " << deg(c) + 1 <<
")"
477 std::cerr <<
" ]" << std::endl;
481 for (i = 0; i < m; ++i) {
482 SetCoeff(new_Q, i, RightShift(coeff(Q, i), i*ell));
486 std::cerr <<
"new_Q = [" << std::endl;
487 for (i = 0; i < m; ++i) {
488 FX c = coeff(new_Q, i);
489 std::cerr <<
" " << c <<
" (degree " << deg(c) + 1 <<
")"
492 std::cerr <<
" ]" << std::endl;
505 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
509 vector<vector<FX> >& aux,
510 const int reduceTo,
const unsigned int reduceNumber)
514 map<unsigned int, bool> small_rows;
532 unsigned int m = lattice.size();
534 bool use_aux = aux.size() == m && aux[0].size() > 0;
537 PivotInfo * pivots =
new PivotInfo[m];
539 for (
unsigned int row = 0; row < m; ++row) {
540 unsigned int workrow = row;
542 unsigned int pIndex = 0;
543 unsigned int degree = deg(lattice[workrow][0]) + 1;
544 for (
unsigned int i = 0; i < m; ++i) {
545 if ((
unsigned int)(deg(lattice[workrow][i]) + 1) >= degree) {
547 degree = deg(lattice[workrow][i]) + 1;
550 F lc = LeadCoeff(lattice[workrow][pIndex]);
553 if (reduceTo >= 0 && degree <= (
unsigned int)reduceTo) {
554 small_rows[workrow] =
true;
556 if (small_rows.size() >= reduceNumber) {
562 std::cerr <<
"Element Degrees:" << std::endl;
563 for (
unsigned int i = 0; i < m; ++i) {
565 for (
unsigned int j = 0; j < m; ++j) {
566 std::cerr << deg(lattice[i][j]) + 1 <<
"\t";
568 std::cerr << std::endl;
570 std::cerr <<
"Pivot Info:" << std::endl;
571 for (
unsigned int i = 0; i < m; ++i) {
572 std::cerr <<
"pivot[" << i <<
"]:\tused = " << pivots[i].used
573 <<
"\trow = " << pivots[i].row <<
"\tdegree = "
574 << pivots[i].degree <<
"\tlc = " << pivots[i].lc << std::endl;
576 std::cerr <<
"workrow = " << workrow << std::endl;
577 std::cerr <<
"pIndex = " << pIndex << std::endl;
578 std::cerr <<
"degree = " << degree << std::endl;
579 std::cerr <<
"lc = " << lc << std::endl;
582 while (pivots[pIndex].used) {
583 if (degree < pivots[pIndex].degree) {
585 unsigned int tmp_workrow = workrow;
586 unsigned int tmp_degree = degree;
588 workrow = pivots[pIndex].row;
589 degree = pivots[pIndex].degree;
590 lc = pivots[pIndex].lc;
591 pivots[pIndex].row = tmp_workrow;
592 pivots[pIndex].degree = tmp_degree;
593 pivots[pIndex].lc = tmp_lc;
597 FX transConst (degree - pivots[pIndex].degree, lc / pivots[pIndex].lc);
598 for (
unsigned int i = 0; i < m; ++i) {
599 lattice[workrow][i] -= lattice[pivots[pIndex].row][i] * transConst;
602 for (
unsigned int i = 0; i < aux[0].size(); ++i) {
603 aux[workrow][i] -= aux[pivots[pIndex].row][i] * transConst;
609 degree = deg(lattice[workrow][0]) + 1;
610 for (
unsigned int i = 1; i < m; ++i) {
611 if ((
unsigned int)(deg(lattice[workrow][i]) + 1) >= degree) {
613 degree = deg(lattice[workrow][i]) + 1;
616 lc = LeadCoeff(lattice[workrow][pIndex]);
619 if (reduceTo >= 0 && degree <= (
unsigned int)reduceTo) {
620 small_rows[workrow] =
true;
622 if (small_rows.size() >= reduceNumber) {
628 std::cerr <<
"Element Degrees:" << std::endl;
629 for (
unsigned int i = 0; i < m; ++i) {
631 for (
unsigned int j = 0; j < m; ++j) {
632 std::cerr << deg(lattice[i][j]) + 1 <<
"\t";
634 std::cerr << std::endl;
636 std::cerr <<
"Pivot Info:" << std::endl;
637 for (
unsigned int i = 0; i < m; ++i) {
638 std::cerr <<
"pivot[" << i <<
"]:\tused = " << pivots[i].used
639 <<
"\trow = " << pivots[i].row <<
"\tdegree = "
640 << pivots[i].degree <<
"\tlc = " << pivots[i].lc << std::endl;
642 std::cerr <<
"workrow = " << workrow << std::endl;
643 std::cerr <<
"pIndex = " << pIndex << std::endl;
644 std::cerr <<
"degree = " << degree << std::endl;
645 std::cerr <<
"lc = " << lc << std::endl;
649 pivots[pIndex].used =
true;
650 pivots[pIndex].row = workrow;
651 pivots[pIndex].degree = degree;
652 pivots[pIndex].lc = lc;
656 std::cerr <<
"Element Degrees:" << std::endl;
657 for (
unsigned int i = 0; i < m; ++i) {
659 for (
unsigned int j = 0; j < m; ++j) {
660 std::cerr << deg(lattice[i][j]) + 1 <<
"\t";
662 std::cerr << std::endl;
664 std::cerr <<
"Pivot Info:" << std::endl;
665 for (
unsigned int i = 0; i < m; ++i) {
666 std::cerr <<
"pivot[" << i <<
"]:\tused = " << pivots[i].used
667 <<
"\trow = " << pivots[i].row <<
"\tdegree = "
668 << pivots[i].degree <<
"\tlc = " << pivots[i].lc << std::endl;
680 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
682 unsigned int t,
const vector<unsigned short> &goodservers,
683 const vec_F &indices,
const vec_F &shares, TestType testType)
690 P = interpolate_kotter(k, t, goodservers, indices, shares);
693 P = interpolate_cohn_heninger(k, t, goodservers, indices, shares);
696 std::cerr <<
"ERROR: Invalid test method for findpolys().\n";
697 return vector<RecoveryPoly<FX> >();
702 for(
int j=0;j<=deg(P);++j) {
704 for(
int i=0; i<=deg(x); ++i) {
710 std::cerr <<
"Finding roots of resulting polynomial...\n";
717 vector<FX> roots = findroots(P, k);
722 vector< RecoveryPoly<FX> > polys;
723 unsigned int numroots = roots.size();
724 for (
unsigned int i=0; i<numroots; ++i) {
725 if (deg(roots[i]) > (
long)k)
continue;
726 vector<unsigned short>::const_iterator gooditer;
727 vector<unsigned short> vecagree;
728 unsigned short numagree = 0;
729 for (gooditer = goodservers.begin(); gooditer != goodservers.end();
732 eval(phival, roots[i], indices[*gooditer]);
733 if (phival == shares[*gooditer]) {
735 vecagree.push_back(*gooditer);
757 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
759 int k_signed,
unsigned int t,
760 const vector<unsigned short> &goodservers,
761 const vec_F &indices,
const vec_F &shares)
766 return vector<RecoveryPoly<FX> >();
770 if (k_signed == -1) {
772 vector<unsigned short>::const_iterator gooditer;
773 vector<unsigned short> vecagree;
774 unsigned short numagree = 0;
775 for (gooditer = goodservers.begin(); gooditer != goodservers.end();
777 if (F::zero() == shares[*gooditer]) {
779 vecagree.push_back(*gooditer);
783 return vector< RecoveryPoly<FX> >(1,
RecoveryPoly<FX>(vecagree, FX::zero()));
785 return vector< RecoveryPoly<FX> >();
792 unsigned int k = (
unsigned int)k_signed;
793 vector<RecoveryPoly<FX> > polys;
795 unsigned int numcombs = 0;
801 while(!iter.atend()) {
806 unsigned short numagree, numdisagree;
807 vector<unsigned short> vecagree;
815 test_interpolate(k, shares, indices, *iter, goodservers,
816 numagree, numdisagree, vecagree, phi);
822 typename vector<RecoveryPoly<FX> >::iterator polysiter;
823 bool matched =
false;
824 for (polysiter = polys.begin(); polysiter != polys.end();
826 if (polysiter->phi == phi) {
836 if (t > k + numdisagree) {
854 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
856 unsigned int ell,
unsigned int h,
857 const vector<unsigned short> &goodservers,
858 const vec_F &indices,
const vec_F &shares)
860 unsigned int n = goodservers.size();
861 unsigned int numcols = n + n - h - h + ell + 2;
862 mat_F M(INIT_SIZE, n, numcols);
864 for (
unsigned int i = 0; i < n; ++i) {
865 F multiplier = indices[goodservers[i]];
867 for (
unsigned int j = 1; j <= n - h + ell; ++j) {
868 M[i][j] = M[i][j-1] * multiplier;
870 M[i][n-h+ell+1] = -(shares[goodservers[i]]);
871 for (
unsigned int j = n - h + ell + 2; j < numcols; ++j) {
872 M[i][j] = M[i][j-1] * multiplier;
877 std::cerr <<
"n = " << n << std::endl;
878 std::cerr <<
"ell = " << ell << std::endl;
879 std::cerr <<
"h = " << h << std::endl;
880 std::cerr <<
"indices =";
881 for (
unsigned int i = 0; i < n; ++i) {
882 std::cerr <<
" " << indices[goodservers[i]];
884 std::cerr << std::endl;
885 std::cerr <<
"shares =";
886 for (
unsigned int i = 0; i < n; ++i) {
887 std::cerr <<
" " << shares[goodservers[i]];
889 std::cerr << std::endl;
890 std::cerr <<
"numcols = " << numcols << std::endl;
891 std::cerr <<
"M = " << M << std::endl;
894 unsigned int rank = gauss(M);
897 std::cerr <<
"rank = " << rank << std::endl;
898 std::cerr <<
"reduced M = " << M << std::endl;
901 if (rank == numcols) {
903 std::cerr <<
"FAIL: y_i*E(x_i)=Q)x_i) has no solution" << std::endl;
905 return vector<RecoveryPoly<FX> >();
909 for (findex = 0; findex < n; ++findex) {
910 if (IsZero(M[findex][findex])) {
916 std::cerr <<
"findex = " << findex << std::endl;
919 vec_F coeffs(INIT_SIZE, numcols);
921 for (
unsigned int i = findex; i > 0; ) {
924 for (
unsigned int j = i + 1; j <= findex; ++j) {
925 c -= M[i][j] * coeffs[j];
932 std::cerr <<
"coeffs:" << std::endl;
933 for (
unsigned int i = 0; i < numcols; ++i) {
934 std::cerr <<
"\t" << i <<
"\t" << coeffs[i] << std::endl;
939 for (
unsigned int i = 0; i <= n - h + ell; ++i) {
940 SetCoeff(Q, i, coeffs[i]);
942 for (
unsigned int i = 0; i <= n - h; ++i) {
943 SetCoeff(E, i, coeffs[n - h + ell + 1 + i]);
947 std::cerr <<
"Q = " << Q << std::endl;
948 std::cerr <<
"E = " << E << std::endl;
951 for (
unsigned int i = 0; i < n; ++i) {
952 if (shares[goodservers[i]] * eval(E, indices[goodservers[i]]) != eval(Q, indices[goodservers[i]])) {
953 std::cerr <<
"ERROR: check failed for i = " << i << std::endl;
959 if (!divide(result, Q, E)) {
961 std::cerr <<
"FAIL: Q % E != 0" << std::endl;
963 return vector<RecoveryPoly<FX> >();
966 if (deg(result) > 0 && ((
unsigned int)deg(result)) > ell) {
968 std::cerr <<
"FAIL: deg(result) > " << ell << std::endl;
970 return vector<RecoveryPoly<FX> >();
974 std::cerr <<
"result = " << result << std::endl;
979 vector< RecoveryPoly<FX> > polys;
980 vector<unsigned short>::const_iterator gooditer;
981 vector<unsigned short> vecagree;
982 unsigned short numagree = 0;
983 for (gooditer = goodservers.begin(); gooditer != goodservers.end();
986 eval(phival, result, indices[*gooditer]);
987 if (phival == shares[*gooditer]) {
989 vecagree.push_back(*gooditer);
992 if (numagree >= h && 2*numagree > n+ell) {
1057 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
1059 vector<vector<FX> >& A, vector<FX>& b,
unsigned int modulus) {
1062 unsigned int n = A.size();
1064 std::cerr <<
"FAIL: invalid_linsys: A is empty\n";
1065 return vector<FX>();
1067 unsigned int m = A[0].size();
1068 if (b.size() != n) {
1069 std::cerr <<
"FAIL: invalid_linsys: Size of b does not match dimensions of A\n";
1070 return vector<FX>();
1073 std::vector<unsigned int> freeCols;
1075 for (
unsigned int i = 0; i < n && h < m; ++i) {
1076 while (IsZero(A[i][h])) {
1080 for (j = i+1; j < n; ++j) {
1081 if (!IsZero(A[j][h])) {
1083 vector<FX> tmp_row = A[i];
1095 freeCols.push_back(h);
1099 goto done_upper_triangular;
1105 for (
unsigned int j = i+1; j < n; ++j) {
1106 if (!IsZero(A[j][h])) {
1109 FX gcd = GCD(A[i][h], A[j][h]);
1110 FX mult1 = A[i][h] / gcd;
1111 FX mult2 = A[j][h] / gcd;
1113 for (
unsigned int k = h; k < m; ++k) {
1114 A[j][k] = MulTrunc(A[j][k], mult1, modulus)
1115 - MulTrunc(A[i][k], mult2, modulus);
1117 b[j] = MulTrunc(b[j], mult1, modulus)
1118 - MulTrunc(b[i], mult2, modulus);
1120 for (
unsigned int k = h; k < m; ++k) {
1121 A[j][k] = (A[j][k] * mult1) - (A[i][k] * mult2);
1123 b[j] = (b[j] * mult1) - (b[i] * mult2);
1130 done_upper_triangular:
1146 unsigned int rank = n - freeCols.size();
1147 for (
unsigned int i = rank; i < n; ++i) {
1148 if (!IsZero(b[i])) {
1149 std::cerr <<
"FAIL: no_solution: inconsistent matrix\n";
1150 return vector<FX>();
1155 vector<FX> solution (m, FX::zero());
1156 unsigned int sub = freeCols.size();
1157 for (
unsigned int i = m; i > 0;) {
1159 if (sub > 0 && freeCols[sub-1] == i) {
1162 solution[i] = b[i-sub];
1163 for (
unsigned int j = i+1; j < m; ++j) {
1164 solution[i] -= A[i-sub][j] * solution[j];
1166 solution[i] = solution[i] / A[i-sub][i];
1178 #ifdef INCLUDE_GENERAL_MULTI
1179 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
1181 unsigned int ell,
unsigned int h, map<unsigned int, FX> partial,
1182 const vector<vector<FX> >& rows, vector<unsigned int> row_order,
1183 const vector<vector<unsigned int> >& order_of_expts)
1192 unsigned int dim = order_of_expts.size();
1194 #ifdef VERBOSE_CH_MULTI
1195 std::cerr <<
"FAIL: order_of_expts is empty\n";
1197 return vector<map<unsigned int, FX> >();
1199 unsigned int m = order_of_expts[0].size();
1202 if (partial.size() == m) {
1204 for (
unsigned int i = 0; i < row_order.size(); ++i) {
1205 vector<FX> row = rows[row_order[i]];
1207 for (
unsigned int j = 0; j < dim; ++j) {
1208 if (IsZero(row[j])) {
1211 FX current = row[j];
1212 vector<unsigned int> expts = order_of_expts[j];
1213 for (
unsigned int p = 0; p < m; ++p) {
1214 current *= power(partial[p], expts[p]);
1219 if (!IsZero(cterm)) {
1220 return vector<map<unsigned int, FX> >();
1223 return vector<map<unsigned int, FX> >(1, partial);
1227 for (
unsigned int i = 0; i < row_order.size(); ++i) {
1229 vector<FX> row = rows[row_order[i]];
1232 unsigned int tosolve_var = 0;
1233 bool has_tosolve_var =
false;
1234 bool too_many_vars =
false;
1235 for (
unsigned int j = 0; j < dim; ++j) {
1237 if (IsZero(row[j])) {
1240 vector<unsigned int> expts = order_of_expts[j];
1242 for (
unsigned int p = 0; p < m; ++p) {
1244 if (expts[p] == 0) {
1247 typename map<unsigned int, FX>::iterator partialIter = partial.find(p);
1248 if (partialIter == partial.end()) {
1250 if (has_tosolve_var && tosolve_var != p) {
1251 too_many_vars =
true;
1254 has_tosolve_var =
true;
1257 coeff *= power(partialIter->second, expts[p]);
1260 if (too_many_vars) {
1263 if (has_tosolve_var) {
1264 tosolve +=
FXY(expts[tosolve_var], coeff);
1266 tosolve +=
FXY(0, coeff);
1270 has_tosolve_var =
false;
1276 if (too_many_vars) {
1282 row_order.erase(row_order.begin() + i);
1283 if (!has_tosolve_var) {
1285 if (!IsZero(tosolve)) {
1286 return vector<map<unsigned int, FX> >();
1292 vector<FX> roots = findroots(tosolve, ell);
1300 vector<map<unsigned int, FX> > result;
1301 for (
unsigned int j = 0; j < roots.size(); ++j) {
1302 partial[tosolve_var] = roots[j];
1303 vector<map<unsigned int, FX> > root_result =
1304 solve_partial_solution(ell, h, partial, rows, row_order, order_of_expts);
1305 result.insert(result.end(), root_result.begin(), root_result.end());
1309 if (partial.size() > 0) {
1310 return vector<map<unsigned int, FX> >(1, partial);
1312 return vector<map<unsigned int, FX> >();
1315 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
1317 unsigned int ell,
unsigned int h,
unsigned int m,
unsigned int& t,
1319 const vector<unsigned short> &goodservers,
1320 const vec_F &indices,
const vector<vec_F> &shares) {
1322 #ifdef VERBOSE_CH_MULTI
1323 std::cerr <<
"Starting Cohn-Heninger Multi-Polynomial algorithm...\n";
1326 unsigned int n = goodservers.size();
1327 unsigned int dim = 1;
1328 for (
unsigned int i = 0; i < (m<t?m:t); ++i) {
1333 #ifdef VERBOSE_CH_MULTI
1334 std::cerr <<
"n = " << n <<
"\n";
1335 std::cerr <<
"ell = " << ell <<
"\n";
1336 std::cerr <<
"h = " << h <<
"\n";
1337 std::cerr <<
"m = " << m <<
"\n";
1338 std::cerr <<
"t = " << t <<
"\n";
1339 std::cerr <<
"k = " << k <<
"\n";
1340 std::cerr <<
"dim = " << dim <<
"\n";
1344 std::stringstream tsout;
1345 tsout << n <<
"," << ell <<
"," << h <<
",";
1351 for (
unsigned int i = 0; i < n; ++i) {
1353 SetCoeff(newTerm, 0, -(indices[goodservers[i]]));
1354 SetCoeff(newTerm, 1);
1358 #ifdef VERBOSE_CH_MULTI
1359 std::cerr <<
"N(z) = " << N <<
" (" << deg(N) <<
")\n";
1364 vec_F goodIndices(INIT_SIZE, n);
1365 for (
unsigned int j = 0; j < n; ++j) {
1366 goodIndices[j] = indices[goodservers[j]];
1368 for (
unsigned int i = 0; i < m; ++i) {
1369 vec_F goodShares(INIT_SIZE, n);
1370 for (
unsigned int j = 0; j < n; ++j) {
1371 goodShares[j] = shares[i][goodservers[j]];
1374 interpolate(L_i, goodIndices, goodShares);
1378 #ifdef VERBOSE_CH_MULTI
1379 for (
unsigned int i = 0; i < m; ++i) {
1380 std::cerr <<
"L[" << i <<
"](z) = " << L[i] <<
" (" << deg(L[i]) <<
")\n";
1384 vector<FX> powers_of_N;
1385 powers_of_N.push_back(FX(0, 1));
1386 for (
unsigned int i = 1; i <= k; ++i) {
1387 powers_of_N.push_back(powers_of_N[i-1] * N);
1390 #ifdef VERBOSE_CH_MULTI
1391 for (
unsigned int i = 0; i <= k; ++i) {
1392 std::cerr <<
"powers_of_N[" << i <<
"](z) = " << powers_of_N[i] <<
")\n";
1397 vector<vector<FX> > lattice(m+1, vector<FX>(m+1));
1400 for (
unsigned int i = 0; i < m; ++i) {
1401 lattice[i+1][0] = -(L[i]);
1402 lattice[i+1][i+1] = z_toell;
1405 #ifdef VERBOSE_CH_MULTI
1406 std::cerr <<
"lattice =\n";
1407 for (
unsigned int i = 0; i <= m; ++i) {
1408 for (
unsigned int j = 0; j <= m; ++j) {
1409 std::cerr <<
"\t" << i <<
"," << j <<
":\t" << lattice[i][j] <<
"\n";
1414 vector<vector<FX> > aux (m+1, vector<FX>());
1417 struct timeval st, et;
1418 gettimeofday(&st, NULL);
1421 vector<vector<FX> > reducedLattice = reduce_lattice_MS(lattice, aux);
1424 gettimeofday(&et, NULL);
1425 unsigned long long elapsedus = ((
unsigned long long)(et.tv_sec -
1426 st.tv_sec)) * 1000000 + (et.tv_usec - st.tv_usec);
1427 tsout <<
"lattice reduction," << elapsedus <<
",";
1430 #ifdef VERBOSE_CH_MULTI
1431 std::cerr <<
"reducedLattice =\n";
1432 for (
unsigned int i = 0; i < m+1; ++i) {
1433 for (
unsigned int j = 0; j < m+1; ++j) {
1434 std::cerr <<
"\t" << i <<
"," << j <<
":\t" << reducedLattice[i][j] <<
"\n";
1437 std::cerr <<
"reducedLattice degrees:\n";
1438 for (
unsigned int i = 0; i < m+1; ++i) {
1440 for (
unsigned int j = 0; j < m+1; ++j) {
1441 std::cerr << deg(reducedLattice[i][j]) <<
"\t";
1447 vector<unsigned int> smallRows;
1448 for (
unsigned int i = 0; i < m+1; ++i) {
1450 for (
unsigned int j = 0; j < m+1; ++j) {
1451 if (deg(reducedLattice[i][j]) > maxdeg) {
1452 maxdeg = deg(reducedLattice[i][j]);
1456 if (maxdeg < (
int)(h)) {
1457 smallRows.push_back(i);
1461 #ifdef VERBOSE_CH_MULTI
1462 std::cerr <<
"smallRows =";
1463 vector<unsigned int>::iterator sriter;
1464 for (sriter = smallRows.begin(); sriter != smallRows.end(); ++sriter) {
1465 std::cerr <<
" " << *sriter;
1470 if (smallRows.size() < m) {
1473 if (t == 1 && k == 1) {
1474 #ifdef VERBOSE_CH_MULTI
1475 std::cerr <<
"FAIL: explicit t=k=1 failed\n";
1477 return vector<RecoveryPolyMulti<FX> >();
1480 #ifdef VERBOSE_CH_MULTI
1481 std::cerr <<
"Not enough small vectors with t=k=1. Trying larger values...\n";
1484 vector<vector<vector<FX> > > coeff_by_expts;
1485 for (
unsigned int i = 0; i < m; ++i) {
1486 vector<vector<FX> > coeffs_for_var;
1487 coeffs_for_var.push_back(vector<FX>(1, FX(0, 1)));
1488 for (
unsigned int j = 1; j <= t; ++j) {
1489 vector<FX> current_j;
1490 for (
unsigned int p = 0; p <= j; ++p) {
1493 current = coeffs_for_var[j-1][p] * (-(L[i]));
1494 }
else if (p == j) {
1497 current = coeffs_for_var[j-1][p] * (-(L[i]));
1498 current += coeffs_for_var[j-1][p-1];
1500 current_j.push_back(current);
1502 coeffs_for_var.push_back(current_j);
1504 coeff_by_expts.push_back(coeffs_for_var);
1507 #ifdef VERBOSE_CH_MULTI
1508 std::cerr <<
"coeff_by_expts =\n";
1509 for (
unsigned int i = 0; i < m; ++i) {
1510 for (
unsigned int j = 0; j <= t; ++j) {
1511 for (
unsigned int p = 0; p <= j; ++p) {
1512 std::cerr <<
"\t" << i <<
"," << j <<
"," << p <<
"\t" << coeff_by_expts[i][j][p] <<
"\n";
1518 vector<vector<unsigned int> > order_of_expts;
1519 order_of_expts.push_back(vector<unsigned int>(m, 0));
1520 vector<vector<vector<unsigned int> > > prev_t;
1521 for (
unsigned int i = 0; i < m; ++i) {
1522 vector<unsigned int> current (m, 0);
1524 prev_t.push_back(vector<vector<unsigned int> >(1, current));
1525 order_of_expts.push_back(current);
1527 for (
unsigned i = 2; i <= t; ++i) {
1528 vector<vector<vector<unsigned int> > > curr_t;
1529 for (
unsigned int j = 0; j < m; ++j) {
1530 vector<vector<unsigned int> > current_j;
1531 for (
unsigned int p = j; p < m; ++p) {
1532 vector<vector<unsigned int> >::iterator iter;
1533 for (iter = prev_t[p].begin(); iter != prev_t[p].end(); ++iter) {
1534 vector<unsigned int> current = *iter;
1536 current_j.push_back(current);
1537 order_of_expts.push_back(current);
1540 curr_t.push_back(current_j);
1545 vector<unsigned int> exptSum;
1546 for (
unsigned int i = 0; i < dim; ++i) {
1547 unsigned int current = 0;
1548 vector<unsigned int> expts = order_of_expts[i];
1549 for (
unsigned int p = 0; p < m; ++p) {
1550 current += expts[p];
1552 exptSum.push_back(current);
1555 #ifdef VERBOSE_CH_MULTI
1556 std::cerr <<
"order_of_expts, exptSum =\n";
1557 for (
unsigned int i = 0; i < dim; ++i) {
1559 for (
unsigned int j = 0; j < m; ++j) {
1560 std::cerr << order_of_expts[i][j] <<
" ";
1562 std::cerr <<
", " << exptSum[i] <<
"\n";
1566 vector<vector<FX> > lattice2;
1567 for (
unsigned int i = 0; i < dim; ++i) {
1568 vector<unsigned int> rowExpts = order_of_expts[i];
1570 for (
unsigned j = 0; j < dim; ++j) {
1571 vector<unsigned int> termExpts = order_of_expts[j];
1572 bool nonZero =
true;
1573 for (
unsigned int p = 0; p < m; ++p) {
1574 if (termExpts[p] > rowExpts[p]) {
1580 row.push_back(FX());
1583 FX termCoeff = FX(0, 1);
1584 for (
unsigned int p = 0; p < m; ++p) {
1585 termCoeff *= coeff_by_expts[p][rowExpts[p]][termExpts[p]];
1587 termCoeff *= power(z_toell, exptSum[j]);
1588 if (exptSum[i] < k) {
1589 termCoeff *= powers_of_N[k - exptSum[i]];
1591 row.push_back(termCoeff);
1593 lattice2.push_back(row);
1596 #ifdef VERBOSE_CH_MULTI
1597 std::cerr <<
"lattice2 =\n";
1598 for (
unsigned int i = 0; i < dim; ++i) {
1599 for (
unsigned int j = 0; j < dim; ++j) {
1600 std::cerr <<
"\t" << i <<
"," << j <<
"\t" << lattice2[i][j] <<
"\n";
1603 std::cerr <<
"lattice2 non-zero elements:\n";
1604 for (
unsigned int i = 0; i < dim; ++i) {
1606 for (
unsigned int j = 0; j < dim; ++j) {
1607 std::cerr << (IsZero(lattice2[i][j]) ?
" " :
"X");
1614 vector<vector<FX> > aux (dim, vector<FX>());
1616 vector<vector<FX> > reducedLattice2WSpoon = reduce_lattice_MS(lattice2, aux);
1618 #ifdef VERBOSE_CH_MULTI
1619 std::cerr <<
"reducedLattice2WSpoon =\n";
1620 for (
unsigned int i = 0; i < dim; ++i) {
1621 for (
unsigned int j = 0; j < dim; ++j) {
1622 std::cerr <<
"\t" << i <<
"," << j <<
":\t" << reducedLattice2WSpoon[i][j] <<
"\n";
1626 std::cerr <<
"reducedLattice2WSpoon degrees:\n";
1627 for (
unsigned int i = 0; i < dim; ++i) {
1629 for (
unsigned int j = 0; j < dim; ++j) {
1630 std::cerr << deg(reducedLattice2WSpoon[i][j]) <<
"\t";
1637 vector<vector<FX> > reducedLattice2;
1638 for (
unsigned int i = 0; i < dim; ++i) {
1640 for (
unsigned int j = 0; j < dim; ++j) {
1650 row.push_back(reducedLattice2WSpoon[i][j] / power(z_toell, exptSum[j]));
1652 reducedLattice2.push_back(row);
1655 #ifdef VERBOSE_CH_MULTI
1656 std::cerr <<
"reducedLattice2 =\n";
1657 for (
unsigned int i = 0; i < dim; ++i) {
1658 for (
unsigned int j = 0; j < dim; ++j) {
1659 std::cerr <<
"\t" << i <<
"," << j <<
":\t" << reducedLattice2[i][j] <<
"\n";
1663 std::cerr <<
"reducedLattice2 degrees:\n";
1664 for (
unsigned int i = 0; i < dim; ++i) {
1666 for (
unsigned int j = 0; j < dim; ++j) {
1667 std::cerr << deg(reducedLattice2[i][j]) <<
"\t";
1673 map<int, unsigned int> reducedDegrees;
1674 vector<unsigned int> smallRows;
1675 for (
unsigned int i = 0; i < dim; ++i) {
1677 for (
unsigned int j = 0; j < dim; ++j) {
1678 if (deg(reducedLattice2[i][j]) > maxdeg) {
1679 maxdeg = deg(reducedLattice2[i][j]);
1682 if (maxdeg < (
int)(k*h)) {
1683 smallRows.push_back(i);
1685 map<int, unsigned int>::iterator it = reducedDegrees.find(maxdeg);
1686 if (it != reducedDegrees.end()) {
1687 reducedDegrees[maxdeg] += 1;
1689 reducedDegrees[maxdeg] = 1;
1699 std::cerr <<
"reducedLattice2 max degrees:";
1700 for (map<int, unsigned int>::iterator it = reducedDegrees.begin();
1701 it != reducedDegrees.end(); ++it) {
1702 for (
unsigned int j = 0; j < it->second; ++j) {
1703 std::cerr <<
" " << it->first;
1708 #ifdef VERBOSE_CH_MULTI
1709 std::cerr <<
"smallRows =";
1710 vector<unsigned int>::iterator sriter;
1711 for (sriter = smallRows.begin(); sriter != smallRows.end(); ++sriter) {
1712 std::cerr <<
" " << *sriter;
1714 std::cerr <<
" (" << smallRows.size() <<
")\n";
1717 if (smallRows.size() < m) {
1718 std::cerr <<
"FAIL: few_small_vectors: Not enough small vectors\n";
1719 return vector<RecoveryPolyMulti<FX> >();
1722 std::stringstream tosage;
1723 for (vector<unsigned int>::iterator iter = smallRows.begin();
1724 iter != smallRows.end();
1726 tosage <<
"{" << reducedLattice2[*iter][0];
1727 for (
unsigned int j = 1; j < dim; ++j) {
1728 tosage <<
"," << reducedLattice2[*iter][j];
1733 const std::string tosageFile =
"/tmp/tosage.txt";
1734 const std::string fromsageFile =
"/tmp/fromsage.txt";
1735 std::ofstream tosageStream(tosageFile.c_str());
1736 tosageStream << tosage.str();
1737 tosageStream.close();
1739 std::stringstream cmd;
1740 cmd <<
"sage solveGroebnerBasis.sage " << m <<
" " << t;
1744 #elif defined USE_GF24
1746 #elif defined USE_W8
1748 #elif defined USE_W32
1753 cmd <<
" < " << tosageFile <<
" > " << fromsageFile;
1755 if (system(cmd.str().c_str()) != 0) {
1756 #ifdef VERBOSE_CH_MULTI
1757 std::cerr <<
"FAIL: sage failed\n";
1759 return vector<RecoveryPolyMulti<FX> >();
1762 vector<vector<FX> > fromsage;
1764 std::ifstream fromsageStream(fromsageFile.c_str());
1765 fromsageStream >> rows;
1766 for (
unsigned int i = 0; i < rows; ++i) {
1768 for (
unsigned int j = 0; j < dim; ++j) {
1770 fromsageStream >> current;
1771 row.push_back(current);
1773 fromsage.push_back(row);
1775 fromsageStream.close();
1777 #ifdef VERBOSE_CH_MULTI
1778 std::cerr <<
"rows = " << rows <<
"\n";
1779 std::cerr <<
"fromsage =\n";
1780 for (
unsigned int i = 0; i < rows; ++i) {
1781 for (
unsigned int j = 0; j < dim; ++j) {
1782 std::cerr <<
"\t" << i <<
"," << j <<
"\t" << fromsage[i][j] <<
"\n";
1788 vector<map<unsigned int, bool> > hasVars(rows);
1789 for (
unsigned int i = 0; i < dim; ++i) {
1790 vector<unsigned int> expts = order_of_expts[i];
1791 for (
unsigned int j = 0; j < rows; ++j) {
1792 if (fromsage[j][i] != 0) {
1793 for (
unsigned int p = 0; p < m; ++p) {
1794 if (expts[p] != 0) {
1795 hasVars[j][p] =
true;
1802 #ifdef VERBOSE_CH_MULTI
1803 std::cerr <<
"hasVars =\n";
1804 for (
unsigned int i = 0; i < rows; ++i) {
1805 std::cerr <<
"\tRow " << i <<
"\t";
1806 typename map<unsigned int, bool>::iterator varIter;
1807 for (varIter = hasVars[i].begin(); varIter != hasVars[i].end(); ++varIter) {
1808 std::cerr << varIter->first <<
" ";
1815 vector<unsigned int> row_order;
1816 for (
unsigned int i = 0; i <= m; ++i) {
1817 for (
unsigned int j = 0; j < rows; ++j) {
1818 if (hasVars[j].size() == i) {
1819 row_order.push_back(j);
1824 #ifdef VERBOSE_CH_MULTI
1825 std::cerr <<
"row_order =";
1826 for (
unsigned int i = 0; i < rows; ++i) {
1827 std::cerr <<
" " << row_order[i];
1833 vector<map<unsigned int, FX> > solutions =
1834 solve_partial_solution(ell, h, map<unsigned int, FX>(), fromsage, row_order, order_of_expts);
1836 if (solutions.size() == 0) {
1837 #ifdef VERBOSE_CH_MULTI
1838 std::cerr <<
"FAIL: no solutions found\n";
1840 return vector<RecoveryPolyMulti<FX> >();
1843 #ifdef VERBOSE_CH_MULTI
1844 std::cerr <<
"solutions =\n";
1845 for (
unsigned int i = 0; i < solutions.size(); ++i) {
1846 for (
unsigned int j = 0; j < m; ++j) {
1847 std::cerr <<
"\tx" << j <<
"\t";
1848 typename map<unsigned int, FX>::iterator it = solutions[i].find(j);
1849 if (it != solutions[i].end()) {
1850 std::cerr << solutions[i][j] <<
" [ ";
1851 for (
unsigned int p = 0; p < n; ++p) {
1853 eval(phival, solutions[i][j], indices[goodservers[p]]);
1854 if (phival == shares[j][goodservers[p]]) {
1855 std::cerr << p <<
" ";
1867 vector<RecoveryPolyMulti<FX> > polys;
1868 for (
unsigned int j = 0; j < solutions.size(); ++j) {
1871 map<unsigned int, FX> solution = solutions[j];
1874 if (solution.size() != m) {
1878 vector<unsigned short>::iterator gooditer;
1879 vector<unsigned short> vecagree = goodservers;
1880 vector<FX> vecsolution;
1881 for (
unsigned int i = 0; i < m; ++i) {
1882 for (gooditer = vecagree.begin(); gooditer != vecagree.end(); ) {
1884 eval(phival, solution[i], indices[*gooditer]);
1885 if (phival == shares[i][*gooditer]) {
1888 gooditer = vecagree.erase(gooditer);
1891 vecsolution.push_back(solution[i]);
1893 if (vecagree.size() >= h) {
1899 #ifdef VERBOSE_CH_MULTI
1900 std::cerr <<
"polys = \n";
1901 for (
unsigned int i = 0; i < polys.size(); ++i) {
1902 for (
unsigned int j = 0; j < m; ++j) {
1903 std::cerr <<
"\t" << j <<
"\t" << polys[i].phis[j] <<
"\n";
1913 vector<vector<FX> > A;
1915 vector<unsigned int>::iterator smallIter = smallRows.begin();
1916 for (
unsigned int i = 0; smallIter != smallRows.end() && i < m; ++smallIter, ++i) {
1918 for (
unsigned int j = 1; j <= m; ++j) {
1919 currRow.push_back(RightShift(reducedLattice[*smallIter][j], ell));
1921 A.push_back(currRow);
1922 b.push_back(-(reducedLattice[*smallIter][0]));
1925 #ifdef VERBOSE_CH_MULTI
1926 std::cerr <<
"A =\n";
1927 for (
unsigned int i = 0; i < m; ++i) {
1928 for (
unsigned int j = 0; j < m; ++j) {
1929 std::cerr <<
"\t" << i <<
"," << j <<
":\t" << A[i][j] <<
"\n";
1932 std::cerr <<
"b =\n";
1933 for (
unsigned int i = 0; i < m; ++i) {
1934 std::cerr <<
"\t" << i <<
":\t" << b[i] <<
"\n";
1939 gettimeofday(&st, NULL);
1943 vector<FX> solution = solve_linsys_FX(A, b);
1946 gettimeofday(&et, NULL);
1947 unsigned long long elapsedus = ((
unsigned long long)(et.tv_sec -
1948 st.tv_sec)) * 1000000 + (et.tv_usec - st.tv_usec);
1949 tsout <<
"solving linear system," << elapsedus <<
",";
1952 if (solution.size() == 0) {
1953 return vector<RecoveryPolyMulti<FX> >();
1956 #ifdef VERBOSE_CH_MULTI
1957 std::cerr <<
"solution =\n";
1958 for (
unsigned int i = 0; i < m; ++i) {
1959 std::cerr <<
"\t" << i <<
":\t" << solution[i] <<
"\n";
1965 vector< RecoveryPolyMulti<FX> > polys;
1966 vector<unsigned short>::iterator gooditer;
1967 vector<unsigned short> vecagree = goodservers;
1968 for (
unsigned int i = 0; i < m; ++i) {
1969 for (gooditer = vecagree.begin(); gooditer != vecagree.end(); ) {
1971 eval(phival, solution[i], indices[*gooditer]);
1972 if (phival == shares[i][*gooditer]) {
1975 gooditer = vecagree.erase(gooditer);
1979 if (vecagree.size() >= h) {
1988 #ifdef VERBOSE_CH_MULTI
1989 std::cerr <<
"polys = \n";
1990 for (
unsigned int i = 0; i < polys.size(); ++i) {
1991 for (
unsigned int j = 0; j < m; ++j) {
1992 std::cerr <<
"\t" << j <<
"\t" << polys[i].phis[j] <<
"\n";
2001 char * testOutfile = getenv(
"TIME_PARTS_OUTFILE");
2003 std::ofstream timefile;
2004 timefile.open (testOutfile, ios::app);
2005 timefile << tsout.str();
2008 std::cerr <<
"Time Parts: " << tsout.str();
2017 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
2019 unsigned int ell,
unsigned int h,
unsigned int m,
2020 const vector<unsigned short> &goodservers,
2021 const vec_F &indices,
const vector<vec_F> &shares) {
2023 #ifdef VERBOSE_CH_TK1
2024 std::cerr <<
"Starting Cohn-Heninger Linear Multi-Polynomial algorithm...\n";
2028 unsigned int n = goodservers.size();
2030 #ifdef VERBOSE_CH_TK1
2031 std::cerr <<
"n = " << n <<
"\n";
2032 std::cerr <<
"ell = " << ell <<
"\n";
2033 std::cerr <<
"h = " << h <<
"\n";
2034 std::cerr <<
"m = " << m <<
"\n";
2038 std::stringstream tsout;
2039 tsout << n <<
"," << ell <<
"," << h <<
",";
2045 for (
unsigned int i = 0; i < n; ++i) {
2047 SetCoeff(newTerm, 0, -(indices[goodservers[i]]));
2048 SetCoeff(newTerm, 1);
2052 #ifdef VERBOSE_CH_TK1
2053 std::cerr <<
"N(z) = " << N <<
" (" << deg(N) <<
")\n";
2058 vec_F goodIndices(INIT_SIZE, n);
2059 for (
unsigned int j = 0; j < n; ++j) {
2060 goodIndices[j] = indices[goodservers[j]];
2062 for (
unsigned int i = 0; i < m; ++i) {
2063 vec_F goodShares(INIT_SIZE, n);
2064 for (
unsigned int j = 0; j < n; ++j) {
2065 goodShares[j] = shares[i][goodservers[j]];
2068 interpolate(L_i, goodIndices, goodShares);
2072 #ifdef VERBOSE_CH_TK1
2073 for (
unsigned int i = 0; i < m; ++i) {
2074 std::cerr <<
"L[" << i <<
"](z) = " << L[i] <<
" (" << deg(L[i]) <<
")\n";
2079 vector<vector<FX> > lattice(m+1, vector<FX>(m+1));
2082 for (
unsigned int i = 0; i < m; ++i) {
2083 lattice[i+1][0] = -(L[i]);
2084 lattice[i+1][i+1] = z_toell;
2087 #ifdef VERBOSE_CH_TK1
2088 std::cerr <<
"lattice =\n";
2089 for (
unsigned int i = 0; i <= m; ++i) {
2090 for (
unsigned int j = 0; j <= m; ++j) {
2091 std::cerr <<
"\t" << i <<
"," << j <<
":\t" << lattice[i][j] <<
"\n";
2096 vector<vector<FX> > aux (m+1, vector<FX>());
2099 struct timeval st, et;
2100 gettimeofday(&st, NULL);
2103 vector<vector<FX> > reducedLattice = reduce_lattice_MS(lattice, aux);
2106 gettimeofday(&et, NULL);
2107 unsigned long long elapsedus = ((
unsigned long long)(et.tv_sec -
2108 st.tv_sec)) * 1000000 + (et.tv_usec - st.tv_usec);
2109 tsout <<
"lattice reduction," << elapsedus <<
",";
2112 #ifdef VERBOSE_CH_TK1
2113 std::cerr <<
"reducedLattice =\n";
2114 for (
unsigned int i = 0; i < m+1; ++i) {
2115 for (
unsigned int j = 0; j < m+1; ++j) {
2116 std::cerr <<
"\t" << i <<
"," << j <<
":\t" << reducedLattice[i][j] <<
"\n";
2119 std::cerr <<
"reducedLattice degrees:\n";
2120 for (
unsigned int i = 0; i < m+1; ++i) {
2122 for (
unsigned int j = 0; j < m+1; ++j) {
2123 std::cerr << deg(reducedLattice[i][j]) <<
"\t";
2129 vector<unsigned int> smallRows;
2130 for (
unsigned int i = 0; i < m+1; ++i) {
2132 for (
unsigned int j = 0; j < m+1; ++j) {
2133 if (deg(reducedLattice[i][j]) > maxdeg) {
2134 maxdeg = deg(reducedLattice[i][j]);
2138 if (maxdeg < (
int)(h)) {
2139 smallRows.push_back(i);
2143 #ifdef VERBOSE_CH_TK1
2144 std::cerr <<
"smallRows =";
2145 vector<unsigned int>::iterator sriter;
2146 for (sriter = smallRows.begin(); sriter != smallRows.end(); ++sriter) {
2147 std::cerr <<
" " << *sriter;
2152 if (smallRows.size() < m) {
2153 #ifdef VERBOSE_CH_TK1
2154 std::cerr <<
"FAIL: Not enough small rows\n";
2156 return vector<RecoveryPolyMulti<FX> >();
2159 vector<vector<FX> > A;
2161 vector<unsigned int>::iterator smallIter = smallRows.begin();
2162 for (
unsigned int i = 0; smallIter != smallRows.end() && i < m; ++smallIter, ++i) {
2164 for (
unsigned int j = 1; j <= m; ++j) {
2165 currRow.push_back(RightShift(reducedLattice[*smallIter][j], ell));
2167 A.push_back(currRow);
2168 b.push_back(-(reducedLattice[*smallIter][0]));
2171 #ifdef VERBOSE_CH_TK1
2172 std::cerr <<
"A =\n";
2173 for (
unsigned int i = 0; i < m; ++i) {
2174 for (
unsigned int j = 0; j < m; ++j) {
2175 std::cerr <<
"\t" << i <<
"," << j <<
":\t" << A[i][j] <<
"\n";
2178 std::cerr <<
"b =\n";
2179 for (
unsigned int i = 0; i < m; ++i) {
2180 std::cerr <<
"\t" << i <<
":\t" << b[i] <<
"\n";
2185 gettimeofday(&st, NULL);
2189 vector<FX> solution = solve_linsys_FX(A, b);
2192 gettimeofday(&et, NULL);
2193 unsigned long long elapsedus = ((
unsigned long long)(et.tv_sec -
2194 st.tv_sec)) * 1000000 + (et.tv_usec - st.tv_usec);
2195 tsout <<
"solving linear system," << elapsedus <<
",";
2198 if (solution.size() == 0) {
2199 #ifdef VERBOSE_CH_TK1
2200 std::cerr <<
"FAIL: solve_linsys_FX failed\n";
2202 return vector<RecoveryPolyMulti<FX> >();
2205 #ifdef VERBOSE_CH_TK1
2206 std::cerr <<
"solution =\n";
2207 for (
unsigned int i = 0; i < m; ++i) {
2208 std::cerr <<
"\t" << i <<
":\t" << solution[i] <<
"\n";
2214 vector< RecoveryPolyMulti<FX> > polys;
2215 vector<unsigned short>::iterator gooditer;
2216 vector<unsigned short> vecagree = goodservers;
2217 for (
unsigned int i = 0; i < m; ++i) {
2218 for (gooditer = vecagree.begin(); gooditer != vecagree.end(); ) {
2220 eval(phival, solution[i], indices[*gooditer]);
2221 if (phival == shares[i][*gooditer]) {
2224 gooditer = vecagree.erase(gooditer);
2228 if (vecagree.size() >= h) {
2233 #ifdef VERBOSE_CH_TK1
2234 std::cerr <<
"polys = \n";
2235 for (
unsigned int i = 0; i < polys.size(); ++i) {
2236 for (
unsigned int j = 0; j < m; ++j) {
2237 std::cerr <<
"\t" << j <<
"\t" << polys[i].phis[j] <<
"\n";
2246 char * testOutfile = getenv(
"TIME_PARTS_OUTFILE");
2248 std::ofstream timefile;
2249 timefile.open (testOutfile, ios::app);
2250 timefile << tsout.str();
2253 std::cerr <<
"Time Parts: " << tsout.str();
2292 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
2295 bool operator() (
const FX& a,
const FX& b)
const {
2303 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
2305 unsigned int ell,
unsigned int h,
2306 const vector<unsigned short> &goodservers,
2307 const vec_F &indices,
const vec_F &shares,
2308 const DPType dptype,
unsigned int gord)
2310 unsigned int n = goodservers.size();
2313 vector<unsigned short> assume_servers, sub_goodservers;
2316 std::cerr <<
"\tindices = ";
2317 for (
unsigned int i = 0; i < n; ++i) {
2318 std::cerr << indices[goodservers[i]] <<
" ";
2321 std::cerr <<
"\tshares = ";
2322 for (
unsigned int i = 0; i < n; ++i) {
2323 std::cerr << shares[goodservers[i]] <<
" ";
2327 if (dptype == ASSUME_CORRECT) {
2329 std::cerr <<
"ASSUME CORRECT: g = " << gord <<
"\n";
2331 assume_servers.insert(assume_servers.begin(), goodservers.begin(), goodservers.begin() + n - h + gord);
2333 while( ! subIter.atend() ) {
2335 std::cerr <<
"\t*subIter = ";
2336 for (
unsigned int i = 0; i < gord; ++i) {
2337 std::cerr << (*subIter)[i] <<
" ";
2341 vector<unsigned short>::const_iterator siIter = (*subIter).begin();
2342 vector<unsigned short>::const_iterator gsIter = goodservers.begin();
2343 for (; gsIter != goodservers.end(); ++gsIter) {
2344 if (siIter != (*subIter).end() && *gsIter == *siIter) {
2347 sub_goodservers.push_back(*gsIter);
2351 std::cerr <<
"\tsub_goodservers = ";
2352 for (
unsigned int i = 0; i < n - gord; ++i) {
2353 std::cerr << sub_goodservers[i] <<
" ";
2359 unsigned short numagree, numdisagree;
2360 vector<unsigned short> vecagree;
2361 test_interpolate(gord - 1, shares, indices, *subIter, goodservers, numagree, numdisagree, vecagree, L);
2362 for (
unsigned int i = 0; i < gord; ++i) {
2363 FX mult(0, -(indices[(*subIter)[i]]));
2364 SetCoeff(mult, 1, 1);
2369 std::cerr <<
"\tL(z) = " << L <<
"\n";
2370 std::cerr <<
"\tB(z) = " << B <<
"\n";
2374 new_shares.SetLength(shares.length());
2375 for (
unsigned int i = 0; i < sub_goodservers.size(); ++i) {
2376 new_shares[sub_goodservers[i]] = (shares[sub_goodservers[i]] - eval(L, indices[sub_goodservers[i]])) / eval(B, indices[sub_goodservers[i]]);
2380 std::cerr <<
"\tnew_shares =";
2381 for (
int i = 0; i < new_shares.length(); ++i) {
2382 std::cerr <<
" " << new_shares[i];
2387 TestType testType = BEST;
2388 vector<RecoveryPoly<FX> > sub_polys = findpolys(ell - gord, h - gord, sub_goodservers, indices, new_shares, testType);
2391 std::cerr <<
"\tsub_polys =\n";
2392 for (
unsigned int j = 0; j < sub_polys.size(); ++j) {
2393 std::cerr <<
"\t\t" << sub_polys[j].phi <<
", { ";
2394 for (
unsigned int i = 0; i < sub_polys[j].G.size(); ++i) {
2395 std::cerr << sub_polys[j].G[i] <<
" ";
2399 std::cerr <<
"\tpolys +=\n";
2401 typename vector<RecoveryPoly<FX> >::iterator rpIter;
2402 for (rpIter = sub_polys.begin(); rpIter != sub_polys.end(); ++rpIter) {
2403 soln_map[rpIter->phi * B + L].insert(rpIter->G.begin(), rpIter->G.end());
2406 sub_goodservers.clear();
2410 }
else if (dptype == ASSUME_WRONG) {
2412 std::cerr <<
"ASSUME WRONG: g = " << gord <<
"\n";
2414 assume_servers.insert(assume_servers.begin(), goodservers.begin(), goodservers.begin() + h + gord);
2416 while( ! subIter.atend() ) {
2418 std::cerr <<
"\t*subIter = ";
2419 for (
unsigned int i = 0; i < gord; ++i) {
2420 std::cerr << (*subIter)[i] <<
" ";
2424 vector<unsigned short>::const_iterator siIter = (*subIter).begin();
2425 vector<unsigned short>::const_iterator gsIter = goodservers.begin();
2426 for (; gsIter != goodservers.end(); ++gsIter) {
2427 if (siIter != (*subIter).end() && *gsIter == *siIter) {
2430 sub_goodservers.push_back(*gsIter);
2434 std::cerr <<
"\tsub_goodservers = ";
2435 for (
unsigned int i = 0; i < n - gord; ++i) {
2436 std::cerr << sub_goodservers[i] <<
" ";
2441 TestType testType = BEST;
2442 vector<RecoveryPoly<FX> > sub_polys = findpolys(ell, h, sub_goodservers, indices, shares, testType);
2445 std::cerr <<
"\tsub_polys =\n";
2446 for (
unsigned int j = 0; j < sub_polys.size(); ++j) {
2447 std::cerr <<
"\t\t" << sub_polys[j].phi <<
", { ";
2448 for (
unsigned int i = 0; i < sub_polys[j].G.size(); ++i) {
2449 std::cerr << sub_polys[j].G[i] <<
" ";
2453 std::cerr <<
"\tpolys +=\n";
2455 typename vector<RecoveryPoly<FX> >::iterator rpIter;
2456 for (rpIter = sub_polys.begin(); rpIter != sub_polys.end(); ++rpIter) {
2457 soln_map[rpIter->phi].insert(rpIter->G.begin(), rpIter->G.end());
2460 sub_goodservers.clear();
2464 }
else if (dptype == ASSUME_SHARES) {
2466 std::cerr <<
"ASSUME SHARES: d = " << gord <<
"\n";
2468 assume_servers.insert(assume_servers.begin(), goodservers.begin(), goodservers.begin() + gord);
2469 sub_goodservers.insert(sub_goodservers.begin(), goodservers.begin() + gord, goodservers.end());
2471 for (
unsigned int r = 0; r <= gord && r <= ell + 1; ++r) {
2473 while( ! subIter.atend() ) {
2475 std::cerr <<
"\t*subIter = ";
2476 for (
unsigned int i = 0; i < r; ++i) {
2477 std::cerr << (*subIter)[i] <<
" ";
2484 unsigned short numagree, numdisagree;
2485 vector<unsigned short> vecagree;
2486 test_interpolate(r - 1, shares, indices, *subIter, goodservers, numagree, numdisagree, vecagree, L);
2487 for (
unsigned int i = 0; i < r; ++i) {
2488 FX mult(0, -(indices[(*subIter)[i]]));
2489 SetCoeff(mult, 1, 1);
2497 std::cerr <<
"\tL(z) = " << L <<
"\n";
2498 std::cerr <<
"\tB(z) = " << B <<
"\n";
2502 new_shares.SetLength(shares.length());
2503 for (
unsigned int i = 0; i < sub_goodservers.size(); ++i) {
2504 new_shares[sub_goodservers[i]] = (shares[sub_goodservers[i]] - eval(L, indices[sub_goodservers[i]])) / eval(B, indices[sub_goodservers[i]]);
2508 std::cerr <<
"\tnew_shares =";
2509 for (
int i = 0; i < new_shares.length(); ++i) {
2510 std::cerr <<
" " << new_shares[i];
2515 TestType testType = BEST;
2516 vector<RecoveryPoly<FX> > sub_polys = findpolys(ell - r, h - r, sub_goodservers, indices, new_shares, testType);
2519 std::cerr <<
"\tsub_polys =\n";
2520 for (
unsigned int j = 0; j < sub_polys.size(); ++j) {
2521 std::cerr <<
"\t\t" << sub_polys[j].phi <<
", { ";
2522 for (
unsigned int i = 0; i < sub_polys[j].G.size(); ++i) {
2523 std::cerr << sub_polys[j].G[i] <<
" ";
2527 std::cerr <<
"\tpolys +=\n";
2529 typename vector<RecoveryPoly<FX> >::iterator rpIter;
2530 for (rpIter = sub_polys.begin(); rpIter != sub_polys.end(); ++rpIter) {
2531 soln_map[rpIter->phi * B + L].insert(rpIter->G.begin(), rpIter->G.end());
2537 sub_goodservers.clear();
2541 std::cerr <<
"FAIL: Invalid DPType\n";
2543 return vector<RecoveryPoly<FX> >();
2546 vector<RecoveryPoly<FX> > polys;
2548 for (soln_iter = soln_map.begin(); soln_iter != soln_map.end(); ++soln_iter) {
2549 vector<unsigned short> new_G (soln_iter->second.begin(), soln_iter->second.end());
2556 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
2558 unsigned int n,
int ell,
2559 unsigned int h,
const vector<unsigned short> &goodservers,
2560 const vec_F &indices,
const vec_F &shares, TestType &testType, DPType &dpType,
2617 portfolioChoice(n, ell, h, testType, dpType, gord);
2619 #ifdef VERBOSE_FINDPOLYS
2620 std::cerr <<
"The best algoritm is:\n";
2621 std::cerr <<
" testType = " << testTypeStrings[testType] <<
"\n";
2622 std::cerr <<
" dpType = " << DPTypeStrings[dpType] <<
"\n";
2623 std::cerr <<
" gord = " << gord <<
"\n";
2626 DPType usedDPType = dpType;
2627 vector<RecoveryPoly<FX> > polys = findpolys(ell, h, goodservers, indices, shares, testType, usedDPType, gord);
2633 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
2635 unsigned int t,
const vector<unsigned short> &goodservers,
2636 const vec_F &indices,
const vec_F &shares, TestType &testType, DPType &dpType,
int &gord)
2638 unsigned int n = goodservers.size();
2641 std::cerr <<
"RUNNING findpolys WITH (" << testTypeStrings[testType] <<
", " << n <<
", " << k <<
", " << t <<
")\n";
2644 vector<RecoveryPoly<FX> > polys;
2647 polys = findpolys_best(n, k, t, goodservers, indices, shares, testType, dpType, gord);
2650 polys = findpolys_brute(k, t, goodservers, indices, shares);
2654 polys = findpolys_gs(k, t, goodservers, indices, shares, testType);
2657 polys = findpolys_bw(k, t, goodservers, indices, shares);
2660 polys = findpolys_dp(k, t, goodservers, indices, shares, dpType, gord);
2664 #ifdef VERBOSE_FINDPOLYS
2665 std::cerr <<
"FAIL: Invalid single poly test type\n";
2667 return vector<RecoveryPoly<FX> >();
2673 #ifdef VERBOSE_FINDPOLYS
2674 std::cerr <<
"FAIL: Not a valid test type\n";
2676 return vector<RecoveryPoly<FX> >();
2684 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
2686 unsigned int t,
const vector<unsigned short> &goodservers,
2687 const vec_F &indices,
const vector<vec_F> &shares, TestType testType)
2689 unsigned int n = goodservers.size();
2690 unsigned int m = shares.size();
2692 vector<RecoveryPolyMulti<FX> > multipolys;
2693 vector<RecoveryPoly<FX> > polys;
2701 #ifdef VERBOSE_FINDPOLYS
2702 std::cerr <<
"FAIL: Invalid multi poly test type\n";
2704 return vector<RecoveryPolyMulti<FX> >();
2708 #ifdef VERBOSE_FINDPOLYS
2709 std::cerr <<
"FAIL: The test type CH_MULTI is not implemented\n";
2711 return vector<RecoveryPolyMulti<FX> >();
2715 multipolys = findpolys_ch_tk1(k, t, m, goodservers, indices, shares);
2722 #ifdef VERBOSE_FINDPOLYS
2723 std::cerr <<
"Invalid test type!\n";
2725 return vector<RecoveryPolyMulti<FX> >();
2733 template <
class F,
class vec_F,
class FX>
2735 dbsize_t word_number, vector<
RecoveryPoly<FX> > polys,
const vec_F &interp_indices)
2737 typename vector<RecoveryPoly<FX> >::iterator poly_iter;
2738 if (results.empty()) {
2739 for (poly_iter = polys.begin(); poly_iter != polys.end(); ++poly_iter) {
2740 if (poly_iter->G.size() >= h) {
2741 vector<map<dbsize_t, F> > new_recovered_vec;
2743 if (interp_indices.length() != 0){
2744 for (
int i=0; i<interp_indices.length(); i++) {
2745 map<dbsize_t, F> new_recovered;
2746 eval(wz, poly_iter->phi, interp_indices[i]);
2747 new_recovered[word_number] = wz;
2748 new_recovered_vec.push_back(new_recovered);
2751 map<dbsize_t, F> new_recovered;
2752 eval(wz, poly_iter->phi, F::zero());
2753 new_recovered[word_number] = wz;
2754 new_recovered_vec.push_back(new_recovered);
2763 if (results.size() > 0 && results[0].recovered.size() > 0 &&
2764 results[0].recovered[0].find(word_number) != results[0].recovered[0].end()) {
2765 #ifdef VERBOSE_RECOVER
2766 std::cerr <<
"This one is already done!\n";
2771 ssize_t result_size = results.size();
2772 ssize_t num_interp_indices = interp_indices.length();
2773 for (ssize_t idx=0; idx < result_size; ++idx) {
2774 vector<nservers_t> orig_G = results[idx].G;
2778 results[idx].recovered.resize(num_interp_indices > 0 ?
2779 num_interp_indices : 1);
2782 for (poly_iter = polys.begin(); poly_iter != polys.end(); ++poly_iter) {
2783 vector<nservers_t> intersection = intersect(poly_iter->G, orig_G);
2784 if (intersection.size() >= h) {
2787 results[idx].G = intersection;
2788 if (num_interp_indices != 0) {
2789 for (
int sub_query = 0; sub_query < num_interp_indices; sub_query++) {
2790 eval(wz, poly_iter->phi, interp_indices[sub_query]);
2791 results[idx].recovered[sub_query][word_number] = wz;
2794 eval(wz, poly_iter->phi, F::zero());
2795 results[idx].recovered[0][word_number] = wz;
2800 results[idx].recovered));
2801 if (num_interp_indices != 0) {
2802 for (
int sub_query = 0; sub_query < num_interp_indices; sub_query++) {
2803 eval(wz, poly_iter->phi, interp_indices[sub_query]);
2804 results[results.size()-1].recovered[sub_query][word_number] = wz;
2807 eval(wz, poly_iter->phi, F::zero());
2808 results[results.size()-1].recovered[0][word_number] = wz;
2814 results.erase(results.begin()+idx);
2822 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
2824 nservers_t t, nservers_t h,
const vector<nservers_t> &goodservers,
2825 const vector<vector<vec_F> > &values,
const vec_F &server_indices,
2827 vector<std::set<dbsize_t> > &decoded,
2828 const vector<vec_F> &vecs_interp_indices,
const nqueries_t multi_only)
2830 #ifdef VERBOSE_RECOVER
2834 nservers_t k = goodservers.size();
2835 nservers_t maxdeg = t;
2838 map<nqueries_t, std::set<dbsize_t> > undecoded;
2840 nqueries_t num_queries = values.size();
2841 for (nqueries_t q = 0; q < num_queries; ++q) {
2842 undecoded[q] = std::set<dbsize_t>();
2843 dbsize_t num_words = values[q].size();
2844 nqueries_t qbs = vecs_interp_indices[q].length();
2848 if (maxdeg < t + qbs - 1) {
2849 maxdeg = t + qbs - 1;
2851 for (dbsize_t i = 0; i < num_words; ++i) {
2852 #ifdef VERBOSE_RECOVER
2853 std::cerr <<
"Decoding (" << q <<
", " << i <<
"):\n";
2854 std::cerr <<
" (k, t, h) = (" << k <<
", " << t <<
", " << h <<
2856 std::cerr <<
" vii[q] = " << vecs_interp_indices[q] <<
"\n";
2857 std::cerr <<
" qbs = " << qbs <<
"\n";
2859 if (decoded[q].find(i) != decoded[q].end()) {
2860 #ifdef VERBOSE_RECOVER
2861 std::cerr <<
" Already decoded.\n";
2866 if (q >= multi_only) {
2868 bool easy_result = EasyRecover(bytes_per_word, t+qbs-1, h, results[q], i,
2869 values[q][i], server_indices, vecs_interp_indices[q]);
2871 #ifdef VERBOSE_RECOVER
2872 std::cerr <<
" EASY: PASS\n";
2874 decoded[q].insert(i);
2877 #ifdef VERBOSE_RECOVER
2878 std::cerr <<
" EASY: FAIL\n";
2883 vector<RecoveryPoly<FX> > bw_result = findpolys(t+qbs-1, h, goodservers, server_indices, values[q][i], ttype);
2884 if (bw_result.size() > 0) {
2885 #ifdef VERBOSE_RECOVER
2886 std::cerr <<
" BW: PASS\n";
2888 addResult<F,vec_F,FX>(results[q], h, i, bw_result, vecs_interp_indices[q]);
2889 decoded[q].insert(i);
2892 #ifdef VERBOSE_RECOVER
2893 std::cerr <<
" BW: FAIL\n";
2900 if (h > sqrt(k*(t+qbs-1)) || h == t+qbs) {
2901 vector<RecoveryPoly<FX> > best_result = findpolys(t+qbs-1, h, goodservers, server_indices, values[q][i], ttype);
2902 if (best_result.size() > 0) {
2903 #ifdef VERBOSE_RECOVER
2904 std::cerr <<
" BEST: PASS (#results: " << best_result.size() <<
")\n";
2905 for (
size_t iw=0;iw<best_result.size(); ++iw) {
2906 std::cerr <<
" " << best_result[iw].phi <<
"\n";
2909 addResult<F,vec_F,FX>(results[q], h, i, best_result, vecs_interp_indices[q]);
2910 decoded[q].insert(i);
2913 #ifdef VERBOSE_RECOVER
2914 std::cerr <<
" BEST: FAIL\n";
2920 #ifdef VERBOSE_RECOVER
2921 std::cerr <<
" Saving for multi...\n";
2923 undecoded[q].insert(i);
2925 if (undecoded[q].empty()) {
2926 #ifdef VERBOSE_RECOVER
2927 std::cerr <<
"Query " << q <<
" is done\n";
2934 if (undecoded.empty()) {
2935 #ifdef VERBOSE_RECOVER
2936 std::cerr <<
"All queries are done\n";
2942 double queries_needed = (double)(k - h) / (double)(h - maxdeg - 1);
2943 #ifdef VERBOSE_RECOVER
2944 std::cerr <<
"queries_needed = " << queries_needed <<
"\n";
2948 vector<nqueries_t> ud_queries;
2949 vector<typename std::set<dbsize_t>::iterator> ud_iters;
2950 map<nqueries_t, std::set<dbsize_t> >::iterator ud_iter;
2951 for (ud_iter = undecoded.begin(); ud_iter != undecoded.end(); ++ud_iter) {
2952 ud_queries.push_back(ud_iter->first);
2953 ud_iters.push_back(ud_iter->second.begin());
2955 while (ud_queries.size() >= queries_needed) {
2956 vector<vec_F> multi_values;
2957 for (nqueries_t i = 0; i < ud_queries.size(); ++i) {
2959 nqueries_t q = ud_queries[i];
2960 dbsize_t w = *(ud_iters[i]);
2961 multi_values.push_back(values[q][w]);
2964 vector<RecoveryPolyMulti<FX> > multi_result = findpolys_multi(maxdeg, h, goodservers, server_indices, multi_values, ttype);
2966 if (multi_result.size() == 0) {
2967 #ifdef VERBOSE_RECOVER
2968 std::cerr <<
" TK1: FAIL\n";
2970 for (nqueries_t i = 0; i < ud_queries.size(); ++i) {
2974 #ifdef VERBOSE_RECOVER
2975 std::cerr <<
" TK1: PASS\n";
2978 for (nqueries_t i = 0; i < ud_queries.size(); ++i) {
2980 nqueries_t q = ud_queries[i];
2981 dbsize_t w = *(ud_iters[i]);
2983 vector<RecoveryPoly<FX> > ith_result;
2984 typename vector<RecoveryPolyMulti<FX> >::iterator iter;
2985 for (iter = multi_result.begin(); iter != multi_result.end();
2989 addResult<F,vec_F,FX>(results[q], h, w, ith_result, vecs_interp_indices[q]);
2990 decoded[q].insert(w);
2991 undecoded[q].erase(w);
2995 for (nqueries_t i = 0; i < ud_queries.size(); ++i) {
2997 nqueries_t q = ud_queries[i];
2998 if (ud_iters[i] == undecoded[q].end()) {
3000 #ifdef VERBOSE_RECOVER
3001 if (undecoded[q].empty()) {
3003 std::cerr <<
"Query " << q <<
" is done\n";
3005 std::cerr <<
"Query " << q <<
" was not fully decoded\n";
3008 ud_queries.erase(ud_queries.begin() + i);
3009 ud_iters.erase(ud_iters.begin() + i);
3016 if (undecoded.empty()) {
3017 #ifdef VERBOSE_RECOVER
3018 std::cerr <<
"All queries are done\n";
3022 #ifdef VERBOSE_RECOVER
3023 std::cerr <<
"NOT all queries were decoded\n";
3031 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
3042 cout <<
"\nVertex " << u <<
": pi[" << u <<
"] = " << pi[u] <<
3043 ", deg[" << u <<
"] = " << Deg[u] <<
", Coeff[" << u <<
3044 "] = " << Coeff[u] <<
"\n";
3045 cout <<
"Q[" << u <<
"] = " << Q[u] <<
"\n";
3048 if ( IsZero(Q[u]) || IsZero(Q[u].rep[0])) {
3052 while (Deg[u] >= 0) {
3053 SetCoeff(fux, Deg[u], Coeff[u]);
3057 cout <<
"Outputting " << fux <<
"\n";
3060 }
else if (degreebound < 0 || Deg[u] < degreebound) {
3063 int degqu = deg(Q[u]);
3064 for (
int d = 0; d <= degqu; ++d) {
3065 SetCoeff(Qu0y, d, coeff(Q[u].rep[d], 0));
3069 cout <<
"Q[" << u <<
"](0,y) = " << Qu0y <<
"\n";
3073 findroots_FX<F,vec_F,FX,
3074 typename DT::vec_FX,
typename DT::vec_pair_FX_long>(Qu0y);
3076 cout <<
"Rootlist = " << rootlist <<
"\n";
3078 int numroots = rootlist.length();
3079 for (
int r=0; r<numroots; ++r) {
3086 Deg.push_back(Deg[u]+1);
3087 Coeff.push_back(rootlist[r]);
3089 Q.push_back(mapit(Q[u], rootlist[r]));
3090 dfs(res, v, pi, Deg, Coeff, Q, t, degreebound);
3098 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
3100 const FXY &P,
int degreebound)
3110 std::cerr <<
"Now in findroots(" << P <<
", " << degreebound <<
")\n";
3113 FXY P0 = backShiftX(P, minX(P));
3116 Coeff.push_back(F::zero());
3120 if (degreebound < 0) {
3121 degreebound = degX(P0);
3123 dfs(res, u, pi, Deg, Coeff, Q, t, degreebound);
3135 template<
class F,
class vec_F,
class FX,
class FXY,
class mat_F>
3139 vector<FX> result = rr_findroots(P, degreebound);
Definition: subset_iter.h:37
Definition: rsdecoder_impl.h:2293
Reed-Solomon Decoder.
Definition: rsdecoder.h:161
A struct containing a reconstructed polynomial over the field F.
Definition: rsdecoder.h:57
Contains the results (so far) of decoding words.
Definition: rsdecoder.h:87
bool Recover(dbsize_t bytes_per_word, nservers_t t, nservers_t h, const vector< nservers_t > &goodservers, const vector< vector< vec_F > > &values, const vec_F &server_indices, vector< vector< DecoderResult< F > > > &results, vector< std::set< dbsize_t > > &decoded, const vector< vec_F > &vec_interp_indices, const nqueries_t multi_only=0)
The main method to do the Reed-Solomon Decoding.
Definition: rsdecoder_impl.h:2823
static void test_interpolate(unsigned short t, const vec_F &values, const vec_F &indices, const vector< unsigned short > &I, const vector< unsigned short > &G, unsigned short &numagree, unsigned short &numdisagree, vector< unsigned short > &vecagree, FX &phi)
Interpolate some points I and check how many points G agree with the result.
Definition: rsdecoder_impl.h:84
A struct containing a multiple reconstructed polynomials over the field F.
Definition: rsdecoder.h:72