/// <summary> /// Shifts left <c>this</c> by <c>N</c> and stores the result in <c>this</c> PolynomialGF2n /// </summary> /// /// <param name="N">The amount the amount to shift the coefficients</param> public void ShiftThisLeft(int N) { if (N > 0) { int i; int oldSize = _size; GF2nField f = _coeff[0].GetField(); Enlarge(_size + N); for (i = oldSize - 1; i >= 0; i--) { _coeff[i + N] = _coeff[i]; } if (_coeff[0] is GF2nPolynomialElement) { for (i = N - 1; i >= 0; i--) { _coeff[i] = GF2nPolynomialElement.Zero((GF2nPolynomialField)f); } } else if (_coeff[0] is GF2nONBElement) { for (i = N - 1; i >= 0; i--) { _coeff[i] = GF2nONBElement.Zero((GF2nONBField)f); } } } }
/// <summary> /// Enlarges the size of this PolynomialGF2n to <c>k</c> + 1 /// </summary> /// /// <param name="K">The new maximum degree</param> public void Enlarge(int K) { if (K <= _size) { return; } int i; GF2nElement[] res = new GF2nElement[K]; Array.Copy(_coeff, 0, res, 0, _size); GF2nField f = _coeff[0].GetField(); if (_coeff[0] is GF2nPolynomialElement) { for (i = _size; i < K; i++) { res[i] = GF2nPolynomialElement.Zero((GF2nPolynomialField)f); } } else if (_coeff[0] is GF2nONBElement) { for (i = _size; i < K; i++) { res[i] = GF2nONBElement.Zero((GF2nONBField)f); } } _size = K; _coeff = res; }
/// <summary> /// Computes a random root of the given polynomial /// </summary> /// /// <param name="P">A polynomial</param> /// /// <returns>A random root of the polynomial</returns> public override GF2nElement RandomRoot(GF2Polynomial P) { // We are in B1!!! GF2nPolynomial c; GF2nPolynomial ut; GF2nElement u; GF2nPolynomial h; int hDegree; // 1. Set g(t) <- f(t) GF2nPolynomial g = new GF2nPolynomial(P, 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 GF2nONBElement(this, m_secRand); ut = new GF2nPolynomial(2, GF2nONBElement.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 // ... else g(t) <- h(t) { g = new GF2nPolynomial(h); } gDegree = g.Degree; } // 3. Output g(0) return(g.At(0)); }
/// <summary> /// Creates a new PolynomialGF2n from the given Bitstring <c>G</c> over the GF2nField <c>B1</c> /// </summary> /// /// <param name="G">The Bitstring to use</param> /// <param name="B1">The field</param> public GF2nPolynomial(GF2Polynomial G, GF2nField B1) { _size = B1.Degree + 1; _coeff = new GF2nElement[_size]; int i; if (B1 is GF2nONBField) { for (i = 0; i < _size; i++) { if (G.TestBit(i)) { _coeff[i] = GF2nONBElement.One((GF2nONBField)B1); } else { _coeff[i] = GF2nONBElement.Zero((GF2nONBField)B1); } } } else if (B1 is GF2nPolynomialField) { for (i = 0; i < _size; i++) { if (G.TestBit(i)) { _coeff[i] = GF2nPolynomialElement.One((GF2nPolynomialField)B1); } else { _coeff[i] = GF2nPolynomialElement.Zero((GF2nPolynomialField)B1); } } } else { throw new ArgumentException("GF2nPolynomial: PolynomialGF2n(Bitstring, GF2nField): B1 must be an instance of GF2nONBField or GF2nPolynomialField!"); } }