/// <summary> /// Compute a random root of the given GF2Polynomial /// </summary> /// /// <param name="G">The polynomial</param> /// /// <returns>Returns a random root of <c>G</c></returns> public override GF2nElement RandomRoot(GF2Polynomial G) { // We are in B1!!! GF2nPolynomial c; GF2nPolynomial ut; GF2nElement u; GF2nPolynomial h; int hDegree; // 1. Set g(t) <- f(t) GF2nPolynomial g = new GF2nPolynomial(G, this); int gDegree = g.Degree; int i; // 2. while deg(g) > 1 while (gDegree > 1) { do { // 2.1 choose random u (element of) GF(2^m) u = new GF2nPolynomialElement(this, new Random()); ut = new GF2nPolynomial(2, GF2nPolynomialElement.Zero(this)); // 2.2 Set c(t) <- ut ut.Set(1, u); c = new GF2nPolynomial(ut); // 2.3 For i from 1 to m-1 do for (i = 1; i <= DegreeN - 1; i++) { // 2.3.1 c(t) <- (c(t)^2 + ut) mod g(t) c = c.MultiplyAndReduce(c, g); c = c.Add(ut); } // 2.4 set h(t) <- GCD(c(t), g(t)) h = c.Gcd(g); // 2.5 if h(t) is constant or deg(g) = deg(h) then go to // step 2.1 hDegree = h.Degree; gDegree = g.Degree; }while ((hDegree == 0) || (hDegree == gDegree)); // 2.6 If 2deg(h) > deg(g) then set g(t) <- g(t)/h(t) ... if ((hDegree << 1) > gDegree) { g = g.Quotient(h); } else { g = new GF2nPolynomial(h); // ... else g(t) <- h(t) } gDegree = g.Degree; } // 3. Output g(0) return(g.At(0)); }
/// <summary> /// Divides <c>this</c> by <c>b</c> and stores the result in a new PolynomialGF2n[2], quotient in result[0] and remainder in result[1] /// </summary> /// /// <param name="B">The divisor</param> /// /// <returns>Retuens the quotient and remainder of <c>this</c> / <c>b</c></returns> public GF2nPolynomial[] Divide(GF2nPolynomial B) { GF2nPolynomial[] result = new GF2nPolynomial[2]; GF2nPolynomial a = new GF2nPolynomial(this); a.Shrink(); GF2nPolynomial shift; GF2nElement factor; int bDegree = B.Degree; GF2nElement inv = (GF2nElement)B._coeff[bDegree].Invert(); if (a.Degree < bDegree) { result[0] = new GF2nPolynomial(this); result[0].AssignZeroToElements(); result[0].Shrink(); result[1] = new GF2nPolynomial(this); result[1].Shrink(); return(result); } result[0] = new GF2nPolynomial(this); result[0].AssignZeroToElements(); int i = a.Degree - bDegree; while (i >= 0) { factor = (GF2nElement)a._coeff[a.Degree].Multiply(inv); shift = B.ScalarMultiply(factor); shift.ShiftThisLeft(i); a = a.Add(shift); a.Shrink(); result[0]._coeff[i] = (GF2nElement)factor.Clone(); i = a.Degree - bDegree; } result[1] = a; result[0].Shrink(); return(result); }
/// <summary> /// Compute a random root of the given GF2Polynomial /// </summary> /// /// <param name="G">The polynomial</param> /// /// <returns>Returns a random root of <c>G</c></returns> public override GF2nElement RandomRoot(GF2Polynomial G) { // We are in B1!!! GF2nPolynomial c; GF2nPolynomial ut; GF2nElement u; GF2nPolynomial h; int hDegree; // 1. Set g(t) <- f(t) GF2nPolynomial g = new GF2nPolynomial(G, this); int gDegree = g.Degree; int i; // 2. while deg(g) > 1 while (gDegree > 1) { do { // 2.1 choose random u (element of) GF(2^m) u = new GF2nPolynomialElement(this, new Random()); ut = new GF2nPolynomial(2, GF2nPolynomialElement.Zero(this)); // 2.2 Set c(t) <- ut ut.Set(1, u); c = new GF2nPolynomial(ut); // 2.3 For i from 1 to m-1 do for (i = 1; i <= DegreeN - 1; i++) { // 2.3.1 c(t) <- (c(t)^2 + ut) mod g(t) c = c.MultiplyAndReduce(c, g); c = c.Add(ut); } // 2.4 set h(t) <- GCD(c(t), g(t)) h = c.Gcd(g); // 2.5 if h(t) is constant or deg(g) = deg(h) then go to // step 2.1 hDegree = h.Degree; gDegree = g.Degree; } while ((hDegree == 0) || (hDegree == gDegree)); // 2.6 If 2deg(h) > deg(g) then set g(t) <- g(t)/h(t) ... if ((hDegree << 1) > gDegree) g = g.Quotient(h); else g = new GF2nPolynomial(h); // ... else g(t) <- h(t) gDegree = g.Degree; } // 3. Output g(0) return g.At(0); }
/// <summary> /// Divides <c>this</c> by <c>b</c> and stores the result in a new PolynomialGF2n[2], quotient in result[0] and remainder in result[1] /// </summary> /// /// <param name="B">The divisor</param> /// /// <returns>Retuens the quotient and remainder of <c>this</c> / <c>b</c></returns> public GF2nPolynomial[] Divide(GF2nPolynomial B) { GF2nPolynomial[] result = new GF2nPolynomial[2]; GF2nPolynomial a = new GF2nPolynomial(this); a.Shrink(); GF2nPolynomial shift; GF2nElement factor; int bDegree = B.Degree; GF2nElement inv = (GF2nElement)B._coeff[bDegree].Invert(); if (a.Degree < bDegree) { result[0] = new GF2nPolynomial(this); result[0].AssignZeroToElements(); result[0].Shrink(); result[1] = new GF2nPolynomial(this); result[1].Shrink(); return result; } result[0] = new GF2nPolynomial(this); result[0].AssignZeroToElements(); int i = a.Degree - bDegree; while (i >= 0) { factor = (GF2nElement)a._coeff[a.Degree].Multiply(inv); shift = B.ScalarMultiply(factor); shift.ShiftThisLeft(i); a = a.Add(shift); a.Shrink(); result[0]._coeff[i] = (GF2nElement)factor.Clone(); i = a.Degree - bDegree; } result[1] = a; result[0].Shrink(); return result; }