Elements of finite fields of characteristic 2 - Finite Rings

Skip to content
Back to top
View this page
Edit this page

# Elements of finite fields of characteristic 2

This implementation uses NTL’s GF2E class to perform the arithmetic and is the standard implementation for `GF(2^n)` for `n >= 16`.

AUTHORS:

- Martin Albrecht <malb@informatik.uni-bremen.de> (2007-10)

class sage.rings.finite_rings.element_ntl_gf2e.Cache_ntl_gf2e

  Bases: `Cache_base`

  This class stores information for an NTL finite field in a Cython class so that elements can access it quickly.

  It’s modeled on `NativeIntStruct`, but includes many functions that were previously included in the parent (see Issue #12062).

  degree()

    If the field has cardinality \(2^n\) this method returns \(n\).

    EXAMPLES:

    Sage

        sage: k.<a> = GF(2^64)
        sage: k._cache.degree()
        64

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(2)**Integer(64), names=('a',)); (a,) = k._first_ngens(1)
        >>> k._cache.degree()
        64

  fetch_int(number)

    Given an integer less than \(p^n\) with base \(2\) representation \(a_0 + a_1 \cdot 2 + \cdots + a_k 2^k\), this returns \(a_0 + a_1 x + \cdots + a_k x^k\), where \(x\) is the generator of this finite field.

    INPUT:

    - `number` – integer; of size less than the cardinality

    EXAMPLES:

    Sage

        sage: k.<a> = GF(2^48)
        sage: k._cache.fetch_int(2^33 + 2 + 1)
        a^33 + a + 1

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(2)**Integer(48), names=('a',)); (a,) = k._first_ngens(1)
        >>> k._cache.fetch_int(Integer(2)**Integer(33) + Integer(2) + Integer(1))
        a^33 + a + 1

  import_data(e)

    EXAMPLES:

    Sage

        sage: k.<a> = GF(2^17)
        sage: V = k.vector_space(map=False)
        sage: v = [1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0]
        sage: k._cache.import_data(v)
        a^13 + a^8 + a^5 + 1
        sage: k._cache.import_data(V(v))
        a^13 + a^8 + a^5 + 1

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(2)**Integer(17), names=('a',)); (a,) = k._first_ngens(1)
        >>> V = k.vector_space(map=False)
        >>> v = [Integer(1),Integer(0),Integer(0),Integer(0),Integer(0),Integer(1),Integer(0),Integer(0),Integer(1),Integer(0),Integer(0),Integer(0),Integer(0),Integer(1),Integer(0),Integer(0),Integer(0)]
        >>> k._cache.import_data(v)
        a^13 + a^8 + a^5 + 1
        >>> k._cache.import_data(V(v))
        a^13 + a^8 + a^5 + 1

  order()

    Return the cardinality of the field.

    EXAMPLES:

    Sage

        sage: k.<a> = GF(2^64)
        sage: k._cache.order()
        18446744073709551616

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(2)**Integer(64), names=('a',)); (a,) = k._first_ngens(1)
        >>> k._cache.order()
        18446744073709551616

  polynomial()

    Return the list of 0s and 1s giving the defining polynomial of the field.

    EXAMPLES:

    Sage

        sage: k.<a> = GF(2^20,modulus='minimal_weight')
        sage: k._cache.polynomial()
        [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(2)**Integer(20),modulus='minimal_weight', names=('a',)); (a,) = k._first_ngens(1)
        >>> k._cache.polynomial()
        [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]

class sage.rings.finite_rings.element_ntl_gf2e.FiniteField_ntl_gf2eElement

  Bases: `FinitePolyExtElement`

  An element of an NTL:GF2E finite field.

  charpoly(var='x')

    Return the characteristic polynomial of `self` as a polynomial in var over the prime subfield.

    INPUT:

    - `var` – string (default: `'x'`)

    OUTPUT: polynomial

    EXAMPLES:

    Sage

        sage: k.<a> = GF(2^8, implementation="ntl")
        sage: b = a^3 + a
        sage: b.minpoly()
        x^4 + x^3 + x^2 + x + 1
        sage: b.charpoly()
        x^8 + x^6 + x^4 + x^2 + 1
        sage: b.charpoly().factor()
        (x^4 + x^3 + x^2 + x + 1)^2
        sage: b.charpoly('Z')
        Z^8 + Z^6 + Z^4 + Z^2 + 1

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(2)**Integer(8), implementation="ntl", names=('a',)); (a,) = k._first_ngens(1)
        >>> b = a**Integer(3) + a
        >>> b.minpoly()
        x^4 + x^3 + x^2 + x + 1
        >>> b.charpoly()
        x^8 + x^6 + x^4 + x^2 + 1
        >>> b.charpoly().factor()
        (x^4 + x^3 + x^2 + x + 1)^2
        >>> b.charpoly('Z')
        Z^8 + Z^6 + Z^4 + Z^2 + 1

  is_one()

    Return `True` if `self == k(1)`.

    Equivalent to `self != k(0)`.

    EXAMPLES:

    Sage

        sage: k.<a> = GF(2^20)
        sage: a.is_one() # indirect doctest
        False
        sage: k(1).is_one()
        True

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(2)**Integer(20), names=('a',)); (a,) = k._first_ngens(1)
        >>> a.is_one() # indirect doctest
        False
        >>> k(Integer(1)).is_one()
        True

  is_square()

    Return `True` as every element in \(\GF{2^n}\) is a square.

    EXAMPLES:

    Sage

        sage: k.<a> = GF(2^18)
        sage: e = k.random_element()
        sage: e.parent() is k
        True
        sage: e.is_square()
        True
        sage: e.sqrt()^2 == e
        True

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(2)**Integer(18), names=('a',)); (a,) = k._first_ngens(1)
        >>> e = k.random_element()
        >>> e.parent() is k
        True
        >>> e.is_square()
        True
        >>> e.sqrt()**Integer(2) == e
        True

  is_unit()

    Return `True` if `self` is nonzero, so it is a unit as an element of the finite field.

    EXAMPLES:

    Sage

        sage: k.<a> = GF(2^17)
        sage: a.is_unit()
        True
        sage: k(0).is_unit()
        False

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(2)**Integer(17), names=('a',)); (a,) = k._first_ngens(1)
        >>> a.is_unit()
        True
        >>> k(Integer(0)).is_unit()
        False

  log(base, order=None, check=False)

    Compute an integer \(x\) such that \(b^x = a\), where \(a\) is `self` and \(b\) is `base`.

    INPUT:

    - `base` – finite field element

    - `order` – integer (optional), the order of the base

    - `check` – boolean (default: `False`): If set, test whether the given `order` is correct.

    OUTPUT:

    Integer \(x\) such that \(a^x = b\), if it exists. Raises a `ValueError` exception if no such \(x\) exists.

    ALGORITHM: pari:fflog

    EXAMPLES:

    Sage

        sage: F = FiniteField(2^10, 'a')
        sage: g = F.gen()
        sage: b = g; a = g^37
        sage: a.log(b)
        37
        sage: b^37; a
        a^8 + a^7 + a^4 + a + 1
        a^8 + a^7 + a^4 + a + 1

    Python

        >>> from sage.all import *
        >>> F = FiniteField(Integer(2)**Integer(10), 'a')
        >>> g = F.gen()
        >>> b = g; a = g**Integer(37)
        >>> a.log(b)
        37
        >>> b**Integer(37); a
        a^8 + a^7 + a^4 + a + 1
        a^8 + a^7 + a^4 + a + 1

    Big instances used to take a very long time before Issue #32842:

    Sage

        sage: g = GF(2^61).gen()
        sage: g.log(g^7)
        1976436865040309101

    [Python]

        >>> from sage.all import *
        >>> g = GF(Integer(2)**Integer(61)).gen()
        >>> g.log(g**Integer(7))
        1976436865040309101

    AUTHORS:

    - David Joyner and William Stein (2005-11)

    - Lorenz Panny (2021-11): use PARI’s pari:fflog instead of `sage.groups.generic.discrete_log()`

  minpoly(var='x')

    Return the minimal polynomial of `self`, which is the smallest degree polynomial \(f \in \GF{2}[x]\) such that `f(self) == 0`.

    INPUT:

    - `var` – string (default: `'x'`)

    OUTPUT: polynomial

    EXAMPLES:

    Sage

        sage: K.<a> = GF(2^100)
        sage: f = a.minpoly(); f
        x^100 + x^57 + x^56 + x^55 + x^52 + x^48 + x^47 + x^46 + x^45 + x^44 + x^43 + x^41 + x^37 + x^36 + x^35 + x^34 + x^31 + x^30 + x^27 + x^25 + x^24 + x^22 + x^20 + x^19 + x^16 + x^15 + x^11 + x^9 + x^8 + x^6 + x^5 + x^3 + 1
        sage: f(a)
        0
        sage: g = K.random_element()
        sage: g.minpoly()(g)
        0

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(2)**Integer(100), names=('a',)); (a,) = K._first_ngens(1)
        >>> f = a.minpoly(); f
        x^100 + x^57 + x^56 + x^55 + x^52 + x^48 + x^47 + x^46 + x^45 + x^44 + x^43 + x^41 + x^37 + x^36 + x^35 + x^34 + x^31 + x^30 + x^27 + x^25 + x^24 + x^22 + x^20 + x^19 + x^16 + x^15 + x^11 + x^9 + x^8 + x^6 + x^5 + x^3 + 1
        >>> f(a)
        0
        >>> g = K.random_element()
        >>> g.minpoly()(g)
        0

  polynomial(name=None)

    Return `self` viewed as a polynomial over `self.parent().prime_subfield()`.

    INPUT:

    - `name` – (optional) variable name

    EXAMPLES:

    Sage

        sage: k.<a> = GF(2^17)
        sage: e = a^15 + a^13 + a^11 + a^10 + a^9 + a^8 + a^7 + a^6 + a^4 + a + 1
        sage: e.polynomial()
        a^15 + a^13 + a^11 + a^10 + a^9 + a^8 + a^7 + a^6 + a^4 + a + 1

        sage: from sage.rings.polynomial.polynomial_element import Polynomial
        sage: isinstance(e.polynomial(), Polynomial)
        True

        sage: e.polynomial('x')
        x^15 + x^13 + x^11 + x^10 + x^9 + x^8 + x^7 + x^6 + x^4 + x + 1

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(2)**Integer(17), names=('a',)); (a,) = k._first_ngens(1)
        >>> e = a**Integer(15) + a**Integer(13) + a**Integer(11) + a**Integer(10) + a**Integer(9) + a**Integer(8) + a**Integer(7) + a**Integer(6) + a**Integer(4) + a + Integer(1)
        >>> e.polynomial()
        a^15 + a^13 + a^11 + a^10 + a^9 + a^8 + a^7 + a^6 + a^4 + a + 1

        >>> from sage.rings.polynomial.polynomial_element import Polynomial
        >>> isinstance(e.polynomial(), Polynomial)
        True

        >>> e.polynomial('x')
        x^15 + x^13 + x^11 + x^10 + x^9 + x^8 + x^7 + x^6 + x^4 + x + 1

  sqrt(all=False, extend=False)

    Return a square root of this finite field element in its parent.

    EXAMPLES:

    Sage

        sage: k.<a> = GF(2^20)
        sage: a.is_square()
        True
        sage: a.sqrt()
        a^19 + a^15 + a^14 + a^12 + a^9 + a^7 + a^4 + a^3 + a + 1
        sage: a.sqrt()^2 == a
        True

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(2)**Integer(20), names=('a',)); (a,) = k._first_ngens(1)
        >>> a.is_square()
        True
        >>> a.sqrt()
        a^19 + a^15 + a^14 + a^12 + a^9 + a^7 + a^4 + a^3 + a + 1
        >>> a.sqrt()**Integer(2) == a
        True

    This failed before Issue #4899:

    Sage

        sage: GF(2^16,'a')(1).sqrt()
        1

    [Python]

        >>> from sage.all import *
        >>> GF(Integer(2)**Integer(16),'a')(Integer(1)).sqrt()
        1

  trace()

    Return the trace of `self`.

    EXAMPLES:

    Sage

        sage: K.<a> = GF(2^25)
        sage: a.trace()
        0
        sage: a.charpoly()
        x^25 + x^8 + x^6 + x^2 + 1
        sage: parent(a.trace())
        Finite Field of size 2

        sage: b = a+1
        sage: b.trace()
        1
        sage: b.charpoly()[1]
        1

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(2)**Integer(25), names=('a',)); (a,) = K._first_ngens(1)
        >>> a.trace()
        0
        >>> a.charpoly()
        x^25 + x^8 + x^6 + x^2 + 1
        >>> parent(a.trace())
        Finite Field of size 2

        >>> b = a+Integer(1)
        >>> b.trace()
        1
        >>> b.charpoly()[Integer(1)]
        1

  weight()

    Return the number of nonzero coefficients in the polynomial representation of `self`.

    EXAMPLES:

    Sage

        sage: K.<a> = GF(2^21)
        sage: a.weight()
        1
        sage: (a^5+a^2+1).weight()
        3
        sage: b = 1/(a+1); b
        a^20 + a^19 + a^18 + a^17 + a^16 + a^15 + a^14 + a^13 + a^12 + a^11 + a^10 + a^9 + a^8 + a^7 + a^6 + a^4 + a^3 + a^2
        sage: b.weight()
        18

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(2)**Integer(21), names=('a',)); (a,) = K._first_ngens(1)
        >>> a.weight()
        1
        >>> (a**Integer(5)+a**Integer(2)+Integer(1)).weight()
        3
        >>> b = Integer(1)/(a+Integer(1)); b
        a^20 + a^19 + a^18 + a^17 + a^16 + a^15 + a^14 + a^13 + a^12 + a^11 + a^10 + a^9 + a^8 + a^7 + a^6 + a^4 + a^3 + a^2
        >>> b.weight()
        18

sage.rings.finite_rings.element_ntl_gf2e.unpickleFiniteField_ntl_gf2eElement(parent, elem)

  EXAMPLES:

  Sage

      sage: k.<a> = GF(2^20)
      sage: e = k.random_element()
      sage: f = loads(dumps(e)) # indirect doctest
      sage: e == f
      True

  Python

      >>> from sage.all import *
      >>> k = GF(Integer(2)**Integer(20), names=('a',)); (a,) = k._first_ngens(1)
      >>> e = k.random_element()
      >>> f = loads(dumps(e)) # indirect doctest
      >>> e == f
      True