/// <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!"); } }
/// <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!"); } }
/// <summary> /// Calculates the multiplicative inverse of <c>this</c> using the modified almost inverse algorithm and returns the result in a new GF2nPolynomialElement /// </summary> /// /// <returns>Returns <c>this</c>^(-1)</returns> public GF2nPolynomialElement InvertMAIA() { if (IsZero()) { throw new ArithmeticException(); } GF2Polynomial b = new GF2Polynomial(mDegree, "ONE"); GF2Polynomial c = new GF2Polynomial(mDegree); GF2Polynomial u = GetGF2Polynomial(); GF2Polynomial v = mField.FieldPolynomial; GF2Polynomial h; while (true) { while (!u.TestBit(0)) { // x|u (x divides u) u.ShiftRightThis(); // u = u / x if (!b.TestBit(0)) { b.ShiftRightThis(); } else { b.AddToThis(mField.FieldPolynomial); b.ShiftRightThis(); } } if (u.IsOne()) { return(new GF2nPolynomialElement((GF2nPolynomialField)mField, b)); } u.ReduceN(); v.ReduceN(); if (u.Length < v.Length) { h = u; u = v; v = h; h = b; b = c; c = h; } u.AddToThis(v); b.AddToThis(c); } }
/// <summary> /// Creates a new GF2nField of degree <c>i</c> and uses the given <c>G</c> as field polynomial. /// <para>The <c>G</c> is checked whether it is irreducible. This can take some time if <c>Degree</c> is huge!</para> /// </summary> /// /// <param name="Degree">The degree of the GF2nField</param> /// <param name="G">The field polynomial to use</param> public GF2nPolynomialField(int Degree, GF2Polynomial G) { if (Degree < 3) { throw new ArgumentException("degree must be at least 3"); } if (G.Length != Degree + 1) { throw new Exception(); } if (!G.IsIrreducible()) { throw new Exception(); } DegreeN = Degree; // fieldPolynomial = new Bitstring(polynomial); FieldPoly = G; ComputeSquaringMatrix(); int k = 2; // check if the polynomial is a trinomial or pentanomial for (int j = 1; j < FieldPoly.Length - 1; j++) { if (FieldPoly.TestBit(j)) { k++; if (k == 3) { _tc = j; } if (k <= 5) { _pc[k - 3] = j; } } } if (k == 3) { _isTrinomial = true; } if (k == 5) { _isPentanomial = true; } Fields = new ArrayList(); Matrices = new ArrayList(); }
/// <summary> /// Creates a new GF2nField of degree <c>i</c> and uses the given <c>G</c> as field polynomial. /// <para>The <c>G</c> is checked whether it is irreducible. This can take some time if <c>Degree</c> is huge!</para> /// </summary> /// /// <param name="Degree">The degree of the GF2nField</param> /// <param name="G">The field polynomial to use</param> public GF2nPolynomialField(int Degree, GF2Polynomial G) { if (Degree < 3) throw new ArgumentException("degree must be at least 3"); if (G.Length != Degree + 1) throw new Exception(); if (!G.IsIrreducible()) throw new Exception(); DegreeN = Degree; // fieldPolynomial = new Bitstring(polynomial); FieldPoly = G; ComputeSquaringMatrix(); int k = 2; // check if the polynomial is a trinomial or pentanomial for (int j = 1; j < FieldPoly.Length - 1; j++) { if (FieldPoly.TestBit(j)) { k++; if (k == 3) _tc = j; if (k <= 5) _pc[k - 3] = j; } } if (k == 3) _isTrinomial = true; if (k == 5) _isPentanomial = true; Fields = new ArrayList(); Matrices = new ArrayList(); }
/// <summary> /// Calculates the multiplicative inverse of <c>this</c> using the modified almost inverse algorithm and returns the result in a new GF2nPolynomialElement /// </summary> /// /// <returns>Returns <c>this</c>^(-1)</returns> public GF2nPolynomialElement InvertMAIA() { if (IsZero()) { throw new ArithmeticException(); } GF2Polynomial b = new GF2Polynomial(mDegree, "ONE"); GF2Polynomial c = new GF2Polynomial(mDegree); GF2Polynomial u = GetGF2Polynomial(); GF2Polynomial v = mField.FieldPolynomial; GF2Polynomial h; while (true) { while (!u.TestBit(0)) { // x|u (x divides u) u.ShiftRightThis(); // u = u / x if (!b.TestBit(0)) { b.ShiftRightThis(); } else { b.AddToThis(mField.FieldPolynomial); b.ShiftRightThis(); } } if (u.IsOne()) return new GF2nPolynomialElement((GF2nPolynomialField)mField, b); u.ReduceN(); v.ReduceN(); if (u.Length < v.Length) { h = u; u = v; v = h; h = b; b = c; c = h; } u.AddToThis(v); b.AddToThis(c); } }
/// <summary> /// Checks whether the indexed bit of the bit representation is set /// </summary> /// /// <param name="Index">The index of the bit to test</param> /// /// <returns>Returns <c>true</c> if the indexed bit is set</returns> public override bool TestBit(int Index) { return(polynomial.TestBit(Index)); }