/// <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> /// Creates a new PolynomialGF2n of size <c>Degree</c> and elem as coefficients /// </summary> /// /// <param name="Degree">The maximum degree + 1</param> /// <param name="Element">A GF2nElement</param> public GF2nPolynomial(int Degree, GF2nElement Element) { _size = Degree; _coeff = new GF2nElement[_size]; for (int i = 0; i < _size; i++) _coeff[i] = (GF2nElement)Element.Clone(); }
/// <summary> /// Sets the coefficient at <c>Index</c> to <c>Element</c> /// </summary> /// /// <param name="Index">The index</param> /// <param name="E">The GF2nElement to store as coefficient <c>Index</c></param> public void Set(int Index, GF2nElement E) { if (!(E is GF2nPolynomialElement) && !(E is GF2nONBElement)) { throw new ArgumentException("GF2nPolynomial: PolynomialGF2n.Set f must be an instance of either GF2nPolynomialElement or GF2nONBElement!"); } _coeff[Index] = (GF2nElement)E.Clone(); }
/// <summary> /// Creates a new PolynomialGF2n of size <c>Degree</c> and elem as coefficients /// </summary> /// /// <param name="Degree">The maximum degree + 1</param> /// <param name="Element">A GF2nElement</param> public GF2nPolynomial(int Degree, GF2nElement Element) { _size = Degree; _coeff = new GF2nElement[_size]; for (int i = 0; i < _size; i++) { _coeff[i] = (GF2nElement)Element.Clone(); } }
/// <summary> /// Multiplies the scalar <c>E</c> to each coefficient of this PolynomialGF2n and returns the result in a new PolynomialGF2n /// </summary> /// /// <param name="E">The scalar to multiply</param> /// /// <returns>Returns <c>this</c> x <c>E</c></returns> public GF2nPolynomial ScalarMultiply(GF2nElement E) { GF2nPolynomial result = new GF2nPolynomial(Size); for (int i = 0; i < Size; i++) { result._coeff[i] = (GF2nElement)_coeff[i].Multiply(E); } return(result); }
/// <summary> /// Converts the given element in representation according to this field to a new element in /// representation according to B1 using the change-of-basis matrix calculated by computeCOBMatrix. /// </summary> /// /// <param name="Elem">The GF2nElement to convert</param> /// <param name="Basis">The basis to convert <c>Elem</c> to</param> /// /// <returns>Returns <c>Elem</c> converted to a new element representation according to <c>basis</c></returns> public GF2nElement Convert(GF2nElement Elem, GF2nField Basis) { if (Basis == this) return (GF2nElement)Elem.Clone(); if (FieldPoly.Equals(Basis.FieldPoly)) return (GF2nElement)Elem.Clone(); if (DegreeN != Basis.DegreeN) throw new Exception("GF2nField.Convert: B1 has a different degree and thus cannot be coverted to!"); int i; GF2Polynomial[] COBMatrix; i = Fields.IndexOf(Basis); if (i == -1) { ComputeCOBMatrix(Basis); i = Fields.IndexOf(Basis); } COBMatrix = (GF2Polynomial[])Matrices[i]; GF2nElement elemCopy = (GF2nElement)Elem.Clone(); if (elemCopy is GF2nONBElement) ((GF2nONBElement)elemCopy).ReverseOrder(); GF2Polynomial bs = new GF2Polynomial(DegreeN, elemCopy.ToFlexiBigInt()); bs.ExpandN(DegreeN); GF2Polynomial result = new GF2Polynomial(DegreeN); for (i = 0; i < DegreeN; i++) { if (bs.VectorMult(COBMatrix[i])) result.SetBit(DegreeN - 1 - i); } if (Basis is GF2nPolynomialField) { return new GF2nPolynomialElement((GF2nPolynomialField)Basis, result); } else if (Basis is GF2nONBField) { GF2nONBElement res = new GF2nONBElement((GF2nONBField)Basis, result.ToFlexiBigInt()); res.ReverseOrder(); return res; } else { throw new Exception("GF2nField.convert: B1 must be an instance of GF2nPolynomialField or GF2nONBField!"); } }
/// <summary> /// Shrink the size of this PolynomialGF2n /// </summary> public void Shrink() { int i = _size - 1; while (_coeff[i].IsZero() && (i > 0)) { i--; } i++; if (i < _size) { GF2nElement[] res = new GF2nElement[i]; Array.Copy(_coeff, 0, res, 0, i); _coeff = res; _size = i; } }
/// <summary> /// Multiplicatively invert of this element (overwrite <c>this</c>) /// </summary> public void InvertThis() { if (IsZero()) { throw new ArithmeticException(); } int r = 31; // m_Degree kann nur 31 Bits lang sein!!! // Bitlaenge von m_Degree: for (bool found = false; !found && r >= 0; r--) { if (((m_Degree - 1) & _mBitmask[r]) != 0) { found = true; } } r++; GF2nElement m = Zero((GF2nONBField)m_Field); GF2nElement n = new GF2nONBElement(this); int k = 1; for (int i = r - 1; i >= 0; i--) { m = (GF2nElement)n.Clone(); for (int j = 1; j <= k; j++) { m.SquareThis(); } n.MultiplyThisBy(m); k <<= 1; if (((m_Degree - 1) & _mBitmask[i]) != 0) { n.SquareThis(); n.MultiplyThisBy(this); k++; } } n.SquareThis(); }
/// <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> /// Shrink the size of this PolynomialGF2n /// </summary> public void Shrink() { int i = _size - 1; while (_coeff[i].IsZero() && (i > 0)) { i--; } i++; if (i < _size) { GF2nElement[] res = new GF2nElement[i]; Array.Copy(_coeff, 0, res, 0, i); _coeff = res; _size = i; } }
/// <summary> /// Sets the coefficient at <c>Index</c> to <c>Element</c> /// </summary> /// /// <param name="Index">The index</param> /// <param name="E">The GF2nElement to store as coefficient <c>Index</c></param> public void Set(int Index, GF2nElement E) { if (!(E is GF2nPolynomialElement) && !(E is GF2nONBElement)) throw new ArgumentException("GF2nPolynomial: PolynomialGF2n.Set f must be an instance of either GF2nPolynomialElement or GF2nONBElement!"); _coeff[Index] = (GF2nElement)E.Clone(); }
/// <summary> /// Multiplies the scalar <c>E</c> to each coefficient of this PolynomialGF2n and returns the result in a new PolynomialGF2n /// </summary> /// /// <param name="E">The scalar to multiply</param> /// /// <returns>Returns <c>this</c> x <c>E</c></returns> public GF2nPolynomial ScalarMultiply(GF2nElement E) { GF2nPolynomial result = new GF2nPolynomial(Size); for (int i = 0; i < Size; i++) result._coeff[i] = (GF2nElement)_coeff[i].Multiply(E); return result; }
/// <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> /// Converts the given element in representation according to this field to a new element in /// representation according to B1 using the change-of-basis matrix calculated by computeCOBMatrix. /// </summary> /// /// <param name="Elem">The GF2nElement to convert</param> /// <param name="Basis">The basis to convert <c>Elem</c> to</param> /// /// <returns>Returns <c>Elem</c> converted to a new element representation according to <c>basis</c></returns> public GF2nElement Convert(GF2nElement Elem, GF2nField Basis) { if (Basis == this) { return((GF2nElement)Elem.Clone()); } if (FieldPoly.Equals(Basis.FieldPoly)) { return((GF2nElement)Elem.Clone()); } if (DegreeN != Basis.DegreeN) { throw new Exception("GF2nField.Convert: B1 has a different degree and thus cannot be coverted to!"); } int i; GF2Polynomial[] COBMatrix; i = Fields.IndexOf(Basis); if (i == -1) { ComputeCOBMatrix(Basis); i = Fields.IndexOf(Basis); } COBMatrix = (GF2Polynomial[])Matrices[i]; GF2nElement elemCopy = (GF2nElement)Elem.Clone(); if (elemCopy is GF2nONBElement) { ((GF2nONBElement)elemCopy).ReverseOrder(); } GF2Polynomial bs = new GF2Polynomial(DegreeN, elemCopy.ToFlexiBigInt()); bs.ExpandN(DegreeN); GF2Polynomial result = new GF2Polynomial(DegreeN); for (i = 0; i < DegreeN; i++) { if (bs.VectorMult(COBMatrix[i])) { result.SetBit(DegreeN - 1 - i); } } if (Basis is GF2nPolynomialField) { return(new GF2nPolynomialElement((GF2nPolynomialField)Basis, result)); } else if (Basis is GF2nONBField) { GF2nONBElement res = new GF2nONBElement((GF2nONBField)Basis, result.ToFlexiBigInt()); res.ReverseOrder(); return(res); } else { throw new Exception("GF2nField.convert: B1 must be an instance of GF2nPolynomialField or GF2nONBField!"); } }