Extremely large fields¶
Arbitrarily-large \(\mathrm{GF}(2^m)\), \(\mathrm{GF}(p)\), \(\mathrm{GF}(p^m)\) fields are supported.
Because field elements can’t be represented with numpy.int64
, we use dtype=object
in the numpy
arrays. This enables
use of native python int
, which doesn’t overflow. It comes at a performance cost though. There are no JIT-compiled
arithmetic ufuncs. All the arithmetic is done in pure python. All the same array operations, broadcasting, ufunc methods,
etc are supported.
Large GF(p) fields¶
In [1]: prime = 36893488147419103183
In [2]: galois.is_prime(prime)
Out[2]: True
In [3]: GF = galois.GF(prime)
In [4]: print(GF)
<class 'numpy.ndarray over GF(36893488147419103183)'>
In [5]: a = GF.Random(10); a
Out[5]:
GF([32022262295980937295, 17777994672429940414, 26603063961600424036,
26010196159902292800, 36035743165771900556, 3907689977334808998,
33471928405882959984, 13780615723314654872, 2189855045530062196,
33965356244979682636], order=36893488147419103183)
In [6]: b = GF.Random(10); b
Out[6]:
GF([12097744675074532915, 2688024972966347050, 30899788886335902044,
27194036301618848530, 15007360874943183182, 34133296948191062966,
2238083592850156507, 5531835876766243380, 3088646357533113261,
21042866188846212124], order=36893488147419103183)
In [7]: a + b
Out[7]:
GF([7226518823636367027, 20466019645396287464, 20609364700517222897,
16310744314102038147, 14149615893295980555, 1147498778106768781,
35710011998733116491, 19312451600080898252, 5278501403063175457,
18114734286406791577], order=36893488147419103183)
Large GF(2^m) fields¶
In [8]: GF = galois.GF(2**100)
In [9]: print(GF)
<class 'numpy.ndarray over GF(2^100)'>
In [10]: a = GF([2**8, 2**21, 2**35, 2**98]); a
Out[10]:
GF([256, 2097152, 34359738368, 316912650057057350374175801344],
order=2^100)
In [11]: b = GF([2**91, 2**40, 2**40, 2**2]); b
Out[11]:
GF([2475880078570760549798248448, 1099511627776, 1099511627776, 4],
order=2^100)
In [12]: a + b
Out[12]:
GF([2475880078570760549798248704, 1099513724928, 1133871366144,
316912650057057350374175801348], order=2^100)
# Display elements as polynomials
In [13]: GF.display("poly")
Out[13]: <galois._field._meta_class.DisplayContext at 0x7f01c63ff390>
In [14]: a
Out[14]: GF([α^8, α^21, α^35, α^98], order=2^100)
In [15]: b
Out[15]: GF([α^91, α^40, α^40, α^2], order=2^100)
In [16]: a + b
Out[16]: GF([α^91 + α^8, α^40 + α^21, α^40 + α^35, α^98 + α^2], order=2^100)
In [17]: a * b
Out[17]:
GF([α^99, α^61, α^75,
α^57 + α^56 + α^55 + α^52 + α^48 + α^47 + α^46 + α^45 + α^44 + α^43 + α^41 + α^37 + α^36 + α^35 + α^34 + α^31 + α^30 + α^27 + α^25 + α^24 + α^22 + α^20 + α^19 + α^16 + α^15 + α^11 + α^9 + α^8 + α^6 + α^5 + α^3 + 1],
order=2^100)
# Reset the display mode
In [18]: GF.display()
Out[18]: <galois._field._meta_class.DisplayContext at 0x7f01c63ffe48>