public void FactorizeRR(Polynomial Q, int i, Polynomial f, List <Polynomial> fList) { Q = NormalizeX(Q); #if VERBOSE Console.WriteLine("i: " + i + " - k: " + k); #elif !MUTE Console.Write("."); #endif for (int j = 0; j < Fq.q; j++) { FFE eval = Q.Evaluate(Fq[0], Fq[j]); if (eval == Fq[0]) { #if VERBOSE Console.WriteLine(Q); Console.WriteLine("Q(0," + Fq[j] + ") = " + Q.Evaluate(Fq[0], Fq[j])); #endif Polynomial otherF = f + Fq[j] * (Polynomial.GetX() ^ i); if (i == k - 1) { fList.Add(otherF); } else { Polynomial nextQ = Y_To_XY_Plus_Gamma(Q, Fq[j]); FactorizeRR(nextQ, i + 1, otherF, fList); } } } }
public FFE[] Encode(FFE[] message) { Polynomial f = new Polynomial(message); FFE[] x = new FFE[n]; for (int i = 0; i < n; i++) { x[i] = f.Evaluate(alphas[i], FFE.DEFAULT_FIELD[0]); } return(x); }
protected FiniteField(int p, int n) { this.p = p; this.n = n; this.q = (int)Math.Pow(p, n); this.elements = new FFE[q]; for (int i = 0; i < q; i++) { elements[i] = new FFE(i); } FFE.DEFAULT_FIELD = this; }
public FFE Evaluate(FFE xVal, FFE yVal) { FFE res = FFE.DEFAULT_FIELD[0]; for (int i = 0; i <= GetMaxDegX(); i++) { for (int j = 0; j <= GetMaxDegY(); j++) { res += this.values[i, j] * (xVal ^ i) * (yVal ^ j); } } return(res); }
public FFE[] Decode(double[,] RM) { if (RM == null) { throw new ArgumentNullException("RM cannot be null"); } if (RM.GetLength(0) != n | RM.GetLength(1) != Fq.q) { throw new ArgumentException("RM matrix should have size n x q (" + n + " x " + Fq.q + ")."); } int[,] M = GreedyMAA(RM); int omega = ComputeOmega(Cost(M)); List <Polynomial> polyList = ListDecode(M, omega); if (polyList.Count == 0) { //throw new Exception("Decoding failed"); return(new FFE[n]); } double maxProba = 0; Polynomial best = polyList[0]; foreach (Polynomial poly in polyList) { double proba = 1; for (int i = 0; i < n; i++) { for (int j = 0; j < Fq.q; j++) { if (poly.Evaluate(alphas[i], Fq[0]) == Fq[j]) { proba *= RM[i, j]; } } } if (proba > maxProba) { maxProba = proba; best = poly; } } #if !MUTE Console.WriteLine("\n--== RESULT ==--\n" + best); #endif FFE[] x = new FFE[n]; for (int i = 0; i < n; i++) { x[i] = best.Evaluate(alphas[i], Fq[0]); } return(x); }
public Polynomial Y_To_XY_Plus_Gamma(Polynomial Q, FFE gamma) { Polynomial result = new Polynomial(Q.GetMaxDegX() + Q.GetMaxDegY(), Q.GetMaxDegY()); for (int i = 0; i <= Q.GetMaxDegX(); i++) { for (int j = 0; j <= Q.GetMaxDegY(); j++) { for (int d = 0; d <= j; d++) { result[i + d, d] += Fq[(int)C(d, j) % Fq.p] * Q[i, j] * (gamma ^ (j - d)); } } } return(result); }
FFE[] Decoder.Decode(double[,] RM) { FFE[] y = new FFE[n]; for (int i = 0; i < n; i++) { int maxJ = 0; double max = 0; for (int j = 0; j < Fq.q; j++) { if (RM[i, j] > max) { max = RM[i, j]; maxJ = j; } } y[i] = Fq[maxJ]; } return(this.Decode(y)); }
public static FFE[] GetDefautLocation(FiniteField Fq, int n) { if (n > Fq.q) { throw new ArgumentException("More locations than field elements is not allowed. You must ensure n <= q."); } FFE[] alphas = new FFE[n]; if (n < Fq.q) { for (int i = 0; i < n; i++) { alphas[i] = Fq[i + 1]; } } else // n == q { for (int i = 0; i < n; i++) { alphas[i] = Fq[i]; } } return(alphas); }
private Polynomial[] GetQuotientRemainder(Polynomial dividend, Polynomial divisor) { if (divisor == Fq[0]) { throw new DivideByZeroException(); } if (dividend.GetDegreeX() < divisor.GetDegreeX()) { throw new ArgumentException("The degree of the dividend cannot be less than the degree of the divisor."); } Polynomial remainder = Fq[1] * dividend; // to make a "by value copy" of the dividend Polynomial quotient = new Polynomial(0, 0); Polynomial x = Polynomial.GetX(); int degDiv = divisor.GetDegreeX(); FFE leadingCoeficient = divisor[degDiv, 0]; for (int deg = dividend.GetDegreeX(); deg >= degDiv; deg--) { FFE coef = remainder[deg, 0] / leadingCoeficient; quotient += coef * (x ^ (deg - degDiv)); remainder -= coef * divisor * (x ^ (deg - degDiv)); } return(new Polynomial[] { quotient, remainder }); }
public override string ToString() { String ans = ""; FFE zero = FFE.DEFAULT_FIELD[0]; for (int j = 0; j <= GetMaxDegY(); j++) { for (int i = 0; i <= GetMaxDegX(); i++) { if (this[i, j] != zero) { ans += this[i, j] + (i == 0 ? "" : "x^" + i) + (j == 0 ? "" : "y^" + j) + " + "; } } } if (ans.Length > 0) { return(ans.Substring(0, ans.Length - 2)); } else { return("0"); } }
public Polynomial FindQ(int[,] M, int omega) { int L = omega / (k - 1); Polynomial[] Q = new Polynomial[L + 1]; int[] wdeg = new int[L + 1]; for (int l = 0; l <= L; l++) { Q[l] = new Polynomial(omega, L); Q[l][0, l] = Fq[1]; wdeg[l] = l * (k - 1); } FFE[] lambdas = new FFE[L + 1]; int lowestL; for (int i = 0; i < alphas.Length; i++) { for (int j = 0; j < Fq.q; j++) { if (M[i, j] != 0) { #if VERBOSE Console.WriteLine("i,j: " + alphas[i] + "," + Fq[j]); #endif for (int u = 0; u < M[i, j]; u++) { for (int v = 0; v < M[i, j] - u; v++) { #if !MUTE #if !VERBOSE Console.Write("."); #endif #endif lowestL = -1; for (int l = 0; l <= L; l++) { Polynomial Duv = HasseDerivative(Q[l], u, v); lambdas[l] = Duv.Evaluate(alphas[i], Fq[j]); #if VERBOSE Console.WriteLine("Q[" + l + "](x,y) = " + Q[l] + "\n => D_" + u + "," + v + " = " + Duv + "\n => lambda (" + alphas[i] + "," + Fq[j] + ") = " + lambdas[l]); #endif if (lambdas[l] != Fq[0]) { if (lowestL == -1 || wdeg[l] < wdeg[lowestL]) { lowestL = l; } } } #if VERBOSE Console.WriteLine("\n" + "Lowest l is: " + lowestL + "\n"); #endif if (lowestL != -1) { for (int l = 0; l <= L; l++) { if (lambdas[l] != Fq[0] & l != lowestL) { Q[l] = Q[l] - (lambdas[l] / lambdas[lowestL]) * Q[lowestL]; } } Q[lowestL] = (Polynomial.GetX() - alphas[i]) * Q[lowestL]; wdeg[lowestL] += 1; } } } } } } return(Q[ArgMin(wdeg)]); }
private FFE[] Decode(FFE[] y) { Polynomial[] p_i = new Polynomial[3]; Polynomial[] v_i = new Polynomial[3] { Fq[0], Fq[0], Fq[1] }; Polynomial x = Polynomial.GetX(); // p_1 = prod_j (x - alpha_j) p_i[1] = Fq[1]; for (int i = 0; i < n; i++) { p_i[1] *= (x - alphas[i]); } // p_2 = sum y_i prod (x - alpha_j)/(alpha_i - alpha_j) p_i[2] = Fq[0]; for (int i = 0; i < n; i++) { Polynomial fact = y[i]; for (int j = 0; j < n; j++) { if (j != i) { fact *= Fq[1] / (alphas[i] - alphas[j]) * (x - alphas[j]); } } p_i[2] += fact; } if (p_i[2].GetDegreeX() < k) { FFE[] hatx = new FFE[n]; for (int i = 0; i < n; i++) { hatx[i] = p_i[2].Evaluate(alphas[i], Fq[0]); } return(hatx); } // the Euclidean division begins... Polynomial[] QR; do { p_i[0] = p_i[1]; p_i[1] = p_i[2]; v_i[0] = v_i[1]; v_i[1] = v_i[2]; QR = GetQuotientRemainder(p_i[0], p_i[1]); p_i[2] = QR[1]; v_i[2] = -Fq[1] * QR[0] * v_i[1] + v_i[0]; }while(2 * p_i[2].GetDegreeX() >= n + k); //p_i[2] = f * v[2] + r QR = GetQuotientRemainder(p_i[2], v_i[2]); if (QR[1] == Fq[0]) { // Success FFE[] hatx = new FFE[n]; for (int i = 0; i < n; i++) { hatx[i] = QR[0].Evaluate(alphas[i], Fq[0]); } return(hatx); } else { // Failure return(new FFE[n]); } }
public abstract FFE Add(FFE a, FFE b);
public abstract FFE Substract(FFE a, FFE b);
public int[] AsCoefs(FFE a) { return(AsCoefs(a.value)); }
public abstract FFE Power(FFE a, int exp);
public abstract FFE Opposite(FFE a);
public abstract FFE Divide(FFE a, FFE b);
public abstract FFE Multiply(FFE a, FFE b);