/// <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> /// 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> /// Decides whether the given object <c>other</c> is the same as this field /// </summary> /// /// <param name="Obj">The object for comparison</param> /// /// <returns>Returns <c>(this == other)</c></returns> public override bool Equals(Object Obj) { if (Obj == null || !(Obj is GF2nField)) { return(false); } GF2nField otherField = (GF2nField)Obj; if (otherField.DegreeN != DegreeN) { return(false); } if (!FieldPoly.Equals(otherField.FieldPoly)) { return(false); } if ((this is GF2nPolynomialField) && !(otherField is GF2nPolynomialField)) { return(false); } if ((this is GF2nONBField) && !(otherField is GF2nONBField)) { return(false); } return(true); }
/// <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> /// Computes the change-of-basis matrix for basis conversion according to 1363. /// The result is stored in the lists fields and matrices. /// </summary> /// /// <param name="B1">The GF2nField to convert to</param> public override void ComputeCOBMatrix(GF2nField B1) { // we are in B0 here! if (DegreeN != B1.Degree) { throw new ArgumentException("GF2nField.computeCOBMatrix: B1 has a different degree and thus cannot be coverted to!"); } int i, j; GF2nElement[] gamma; GF2nElement u; GF2Polynomial[] COBMatrix = new GF2Polynomial[DegreeN]; for (i = 0; i < DegreeN; i++) { COBMatrix[i] = new GF2Polynomial(DegreeN); } // find Random Root do { // u is in representation according to B1 u = B1.RandomRoot(FieldPoly); }while (u.IsZero()); gamma = new GF2nPolynomialElement[DegreeN]; // build gamma matrix by squaring gamma[0] = (GF2nElement)u.Clone(); for (i = 1; i < DegreeN; i++) { gamma[i] = gamma[i - 1].Square(); } // convert horizontal gamma matrix by vertical Bitstrings for (i = 0; i < DegreeN; i++) { for (j = 0; j < DegreeN; j++) { if (gamma[i].TestBit(j)) { COBMatrix[DegreeN - j - 1].SetBit(DegreeN - i - 1); } } } Fields.Add(B1); Matrices.Add(COBMatrix); B1.Fields.Add(this); B1.Matrices.Add(InvertMatrix(COBMatrix)); }
/// <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> /// 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> /// Computes the change-of-basis matrix for basis conversion according to 1363. /// The result is stored in the lists fields and matrices. /// </summary> /// /// <param name="B1">The GF2nField to convert to</param> public override void ComputeCOBMatrix(GF2nField B1) { // we are in B0 here! if (DegreeN != B1.Degree) { throw new ArgumentException("GF2nPolynomialField.computeCOBMatrix: B1 has a different degree and thus cannot be coverted to!"); } if (B1 is GF2nONBField) { // speedup (calculation is done in PolynomialElements instead of ONB) B1.ComputeCOBMatrix(this); return; } int i, j; GF2nElement[] gamma; GF2nElement u; GF2Polynomial[] COBMatrix = new GF2Polynomial[DegreeN]; for (i = 0; i < DegreeN; i++) { COBMatrix[i] = new GF2Polynomial(DegreeN); } // find Random Root do { // u is in representation according to B1 u = B1.RandomRoot(FieldPoly); }while (u.IsZero()); // build gamma matrix by multiplying by u if (u is GF2nONBElement) { gamma = new GF2nONBElement[DegreeN]; gamma[DegreeN - 1] = GF2nONBElement.One((GF2nONBField)B1); } else { gamma = new GF2nPolynomialElement[DegreeN]; gamma[DegreeN - 1] = GF2nPolynomialElement.One((GF2nPolynomialField)B1); } gamma[DegreeN - 2] = u; for (i = DegreeN - 3; i >= 0; i--) { gamma[i] = (GF2nElement)gamma[i + 1].Multiply(u); } if (B1 is GF2nONBField) { // convert horizontal gamma matrix by vertical Bitstrings for (i = 0; i < DegreeN; i++) { for (j = 0; j < DegreeN; j++) { // TODO remember: ONB treats its Bits in reverse order !!! if (gamma[i].TestBit(DegreeN - j - 1)) { COBMatrix[DegreeN - j - 1].SetBit(DegreeN - i - 1); } } } } else { // convert horizontal gamma matrix by vertical Bitstrings for (i = 0; i < DegreeN; i++) { for (j = 0; j < DegreeN; j++) { if (gamma[i].TestBit(j)) { COBMatrix[DegreeN - j - 1].SetBit(DegreeN - i - 1); } } } } // store field and matrix for further use Fields.Add(B1); Matrices.Add(COBMatrix); // store field and inverse matrix for further use in B1 B1.Fields.Add(this); B1.Matrices.Add(InvertMatrix(COBMatrix)); }
/// <summary> /// Computes the change-of-basis matrix for basis conversion according to 1363. /// The result is stored in the lists fields and matrices. /// </summary> /// /// <param name="B1">The GF2nField to convert to</param> public override void ComputeCOBMatrix(GF2nField B1) { // we are in B0 here! if (DegreeN != B1.Degree) throw new ArgumentException("GF2nPolynomialField.computeCOBMatrix: B1 has a different degree and thus cannot be coverted to!"); if (B1 is GF2nONBField) { // speedup (calculation is done in PolynomialElements instead of ONB) B1.ComputeCOBMatrix(this); return; } int i, j; GF2nElement[] gamma; GF2nElement u; GF2Polynomial[] COBMatrix = new GF2Polynomial[DegreeN]; for (i = 0; i < DegreeN; i++) COBMatrix[i] = new GF2Polynomial(DegreeN); // find Random Root do { // u is in representation according to B1 u = B1.RandomRoot(FieldPoly); } while (u.IsZero()); // build gamma matrix by multiplying by u if (u is GF2nONBElement) { gamma = new GF2nONBElement[DegreeN]; gamma[DegreeN - 1] = GF2nONBElement.One((GF2nONBField)B1); } else { gamma = new GF2nPolynomialElement[DegreeN]; gamma[DegreeN - 1] = GF2nPolynomialElement.One((GF2nPolynomialField)B1); } gamma[DegreeN - 2] = u; for (i = DegreeN - 3; i >= 0; i--) gamma[i] = (GF2nElement)gamma[i + 1].Multiply(u); if (B1 is GF2nONBField) { // convert horizontal gamma matrix by vertical Bitstrings for (i = 0; i < DegreeN; i++) { for (j = 0; j < DegreeN; j++) { // TODO remember: ONB treats its Bits in reverse order !!! if (gamma[i].TestBit(DegreeN - j - 1)) COBMatrix[DegreeN - j - 1].SetBit(DegreeN - i - 1); } } } else { // convert horizontal gamma matrix by vertical Bitstrings for (i = 0; i < DegreeN; i++) { for (j = 0; j < DegreeN; j++) { if (gamma[i].TestBit(j)) COBMatrix[DegreeN - j - 1].SetBit(DegreeN - i - 1); } } } // store field and matrix for further use Fields.Add(B1); Matrices.Add(COBMatrix); // store field and inverse matrix for further use in B1 B1.Fields.Add(this); B1.Matrices.Add(InvertMatrix(COBMatrix)); }
/// <summary> /// Computes the change-of-basis matrix for basis conversion according to 1363. /// <para>The result is stored in the lists fields and matrices.</para> /// </summary> /// /// <param name="B1">The GF2nField to convert to</param> public abstract void ComputeCOBMatrix(GF2nField B1);
/// <summary> /// Computes the change-of-basis matrix for basis conversion according to 1363. /// The result is stored in the lists fields and matrices. /// </summary> /// /// <param name="B1">The GF2nField to convert to</param> public override void ComputeCOBMatrix(GF2nField B1) { // we are in B0 here! if (DegreeN != B1.Degree) throw new ArgumentException("GF2nField.computeCOBMatrix: B1 has a different degree and thus cannot be coverted to!"); int i, j; GF2nElement[] gamma; GF2nElement u; GF2Polynomial[] COBMatrix = new GF2Polynomial[DegreeN]; for (i = 0; i < DegreeN; i++) COBMatrix[i] = new GF2Polynomial(DegreeN); // find Random Root do { // u is in representation according to B1 u = B1.RandomRoot(FieldPoly); } while (u.IsZero()); gamma = new GF2nPolynomialElement[DegreeN]; // build gamma matrix by squaring gamma[0] = (GF2nElement)u.Clone(); for (i = 1; i < DegreeN; i++) gamma[i] = gamma[i - 1].Square(); // convert horizontal gamma matrix by vertical Bitstrings for (i = 0; i < DegreeN; i++) { for (j = 0; j < DegreeN; j++) { if (gamma[i].TestBit(j)) COBMatrix[DegreeN - j - 1].SetBit(DegreeN - i - 1); } } Fields.Add(B1); Matrices.Add(COBMatrix); B1.Fields.Add(this); B1.Matrices.Add(InvertMatrix(COBMatrix)); }
/// <summary> /// Performs a basis transformation of this element to the given GF2nField <c>basis</c> /// </summary> /// /// <param name="Basis">The GF2nField representation to transform this element to</param> /// /// <returns>Returns this element in the representation of <c>basis</c></returns> public GF2nElement Convert(GF2nField Basis) { return(mField.Convert(this, Basis)); }
/// <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!"); } }