2

For example the 33-term polynomial $x^{32} + c_{31} x^{31} + \ldots + c_1 x + c_0$, where the coefficients are 16-bit finite field numbers. For the cases I'm considering, the 33-term polynomial will have 16 quadratic factors of the form $x^2 + a x + b$, again where the coefficients are 16 bit finite field numbers. Currently I'm doing a somewhat optimized brute force over the nearly $2^{32}$ (4 billion) possible combinations of $a$ and $b$ ($a$ is $\geq 1$).

This can be used for finding a "compatible" (isomorphic) composite mapping of $\operatorname{GF}(2^{32})$ with primitive element $α(x) = x (\operatorname{hex} 2)$ to a quadratic of $\operatorname{GF}((2^{16})^2)$ with primitive element $β(x) = x (\operatorname{hex} 10000).$

Let $f(x)$ be the defining primitive polynomial for $\operatorname{GF}(2^{32}).$ If the 1 bit coefficients of $f(x)$ are treated as elements in $\operatorname{GF}(2^{16}),$ there will be 16 primitive quadratic factors of $f(x).$ Any of those 16 quadratic factors can be used for the mapping meeting the isomorphic requirements that $\operatorname{map}(a + b) = \operatorname{map}(a) + \operatorname{map}(b)$ and $\operatorname{map}(a b) = \operatorname{map}(a) \operatorname{map}(b).$

For $\operatorname{GF}(2^{32})$ to $\operatorname{GF}((2^{16})^2),$ even though a brute force search is nearly 4 billion cases, it can be done in a few minutes on a typical PC. I'm wondering if there is some faster way so that a case like mapping from $\operatorname{GF}(2^{64})$ to $\operatorname{GF}((2^{32})^2)$ could be searched for in a similar way.

With carryless multiply instructions like pclmulqdq on X86 or parallel table look up instructions like pshufb on X86, it may be a pointless mapping (primarily used to calculate $1/x$).


Example for $\operatorname{GF}(2^{16}),$ primitive polynomial $x^{16} + x^{12} + x^3 + x + 1.$ The coefficients of $f(x)$ are $0$ and $1,$ but are elements of $\operatorname{GF}(2^{16})$

f(x) = x^32 + x^22 + x^2 + x + 1

There are 16 quadratic factors, values shown in hex:

x^2 + 04c4 x + 118d
x^2 + 09ad x + 1cec
x^2 + 0e38 x + 1cb7
x^2 + 16b6 x + 1dbc
x^2 + 173b x + 0cf9
x^2 + 1c89 x + 1cf0
x^2 + 40ab x + 4be1
x^2 + 524f x + 0a76
x^2 + 5e62 x + 0716
x^2 + 5eec x + 0a37
x^2 + b67f x + 4188
x^2 + be6f x + fbf0
x^2 + e079 x + 17d4
x^2 + effe x + ed71
x^2 + f62b x + 07d5
x^2 + fd83 x + 17dd

An alternative for mapping from $\operatorname{GF}(2^{32})$ to $\operatorname{GF}((2^{16})^2)$ is to pre-select a primitive polynomial for $\operatorname{GF}((2^{16})^2)$, such as $x^2 + x + 2000_{16}$, then do a brute force search for any primitive element α(x) of $\operatorname{GF}(2^{32})$ based on polynomial $f(x) = x^{32} + x^{22} + x^2 + x + 1$, that will result in an isomorphic mapping. Turns out for that there are 32 instance of α(x) (out of 2^31 possible α(x)), but the search is much slower.

rcgldr
  • 764
  • https://en.wikipedia.org/wiki/Berlekamp%27s_algorithm ? – Angina Seng Jul 12 '20 at 09:23
  • @AnginaSeng - I'm looking at that and also factoring .... For the first algorithm, note that f '(x) = 1. I need to try to understand the other algorithms, but it seems that the math will end multiplying or xor'ing 0 and 1, and I don't see how it will produce non-zero values other than 1. I included an example factorization in my answer, using an optimized brute force search. – rcgldr Jul 13 '20 at 14:09
  • You can do better than brute force using a factorization algorithm. –  Jul 13 '20 at 15:12
  • http://flintlib.org/features.html implements Berlekamp, Cantor-Zassenhaus, Kaltofen-Shoup algorithms –  Jul 13 '20 at 15:13
  • 1
    I have seen several questions about representing $GF(2^{2^n})$ as a quadratic extension of $GF(2^{2^{n-1}})$. Ever since reading this question I have been under the impression that the interest comes from the need to implement the arithmetic of a larger field on a very limited piece of hardware. What I have been wondering about is the following. Are you then really stuck with a fixed way of defining the big field? – Jyrki Lahtonen Jul 14 '20 at 06:44
  • 1
    (cont'd) We have a simple recursive method of constructing this particular tower of fields 1,2. Is there a technical reason why that way cannot be used in this app? I may be wrong, but I think that would make the extension $n-1\to n$ trivial. These fields are so large that using a discrete logarithm table is surely out of the question, so why insist that we use a primitive polynomial to define the field? – Jyrki Lahtonen Jul 14 '20 at 06:47
  • @JyrkiLahtonen - this is mostly an academic question. In many cases for larger fields, there is no attempt to define what the larger field is or how it could be mapped to the composite (aka reduced or sub-mapped) field. The math is performed only in the composite field knowing that it will be isomorphic to any field with the same number of elements, even though GF(2^k) and how to map to/from GF((2^m)^n) is unknown. – rcgldr Jul 14 '20 at 07:20
  • 1
    @JyrkiLahtonen - getting back on point, I was hoping there was some relatively fast algorithm to factor polynomials with large field coefficients, but I'm getting the impression that there isn't one. On a side note, as for transition between field representations, I have yet to see any article that explains how the mapping matrix is derived, so I created an explanation for a specific AES mapping in mapping example pdf . – rcgldr Jul 14 '20 at 07:45
  • Sounds great! Something went wrong with my attempt to access the GitHub doc, but I will retry and hopefully refer future askers to it. Undoubtedly you know that if $\alpha$ is a zero of that degree $32$ polynomial, then those 16 factors over $GF(2^{16})$ are $$(x-\alpha^{2^i})(x-\alpha^{2^{16+i}})$$ with $i$ ranging from $0$ to $15$. Writing those factors using an unrelated construction of $GF(2^{16})$ is what makes this a bit taxing. If I get to choose my way of constructing the smaller field, then it becomes easier, I think. – Jyrki Lahtonen Jul 14 '20 at 08:35
  • @JyrkiLahtonen - I've had intermittent issues with github, so I have a backup link: composite field mapping pdf . – rcgldr Jul 14 '20 at 08:41
  • Hmm. I'm no longer sure. Say, if $\alpha$ is known to be primitive, then $\beta=\alpha^{1+2^{16}}$ is a primitive element of the smaller field, and we could use that. But writing the trace $\alpha+\alpha^{2^{16}}$ may not be as straight forward as I though. I will think about this one, and hope to come back to it later. Anyway, the task of matching a given construction of the 32-bit field with an unrelated construction of the 16-bit field feels more taxing. – Jyrki Lahtonen Jul 14 '20 at 08:42

1 Answers1

1

Once you have found one quadratic factor you can find the others (assuming they are all Galois conjugates) by applying the Frobenius Automorphism:

from sage.rings.finite_rings.hom_finite_field import FiniteFieldHomomorphism_generic

K.<T> = GF(2^16)

R.<x> = PolynomialRing(K)

p = x^32 + x^22 + x^2 + x + 1

factor(p)

f = x^2 + (T^12 + T^10 + T^9 + T^6 + T^4 + 1)*x + T^15 + T^12 + T^10 + T^5 + T^4 + T + 1

Frob = K.frobenius_endomorphism(); Frob

Frobenius endomorphism T |--> T^2 on Finite Field in T of size 2^16

Frob(T^12 + T^10 + T^9 + T^6 + T^4 + 1)

T^13 + T^12 + T^11 + T^10 + T^9 + T^6 + T^5 + T^2 + 1

Frob(T^15 + T^12 + T^10 + T^5 + T^4 + T + 1)

T^14 + T^13 + T^11 + T^9 + T^8 + T^7 + T^6 + T^3 + T


$T^{12} + T^{10} + T^9 + T^6 + T^4 + 1$

Represents $1011001010001 = 0x1651$

Jyrki Lahtonen
  • 140,891
  • the T's are representing the coefficients like 04c4, added an example –  Jul 13 '20 at 18:45
  • 1
    That is what I thought but x^2 + 1651 x + 9433 is not one of the factors of f(x) in my question. – rcgldr Jul 13 '20 at 19:03
  • 1
    For larger fields, such as finding any of the 32 quadratic roots for f(x) = x^64 + ... + 1 with coefficients in GF(2^32) involves ~ 2^64) possible combinations. – rcgldr Jul 13 '20 at 19:17
  • 1
    This is definitely the way to find the other factors after you have located one. Basically taking advantage of the fact that the coefficients of the big polynomial are in the prime field. If the results don't match, may be this SAGE-snipper defined the 16-bit field differently? – Jyrki Lahtonen Jul 14 '20 at 06:26
  • 1
    The GF(2^16) polynomial is x^16 + x^12 + x^3 + x + 1. f(x) = x^32 + x^22 + x^2 + x + 1. On my system, a brute force search finds about 2 of the 16 factors per minute, on a friends system, it finds about 4 of the 16 factors per minute. The issue is with larger fields, such as GF(2^64) to GF(2^32). I'm wondering how the math for large fields, like GF(2^256) or GF(2^512) are implemented. – rcgldr Jul 14 '20 at 17:34
  • @rcgldr try an efficient factorization algorithm rather than brute force –  Jul 14 '20 at 19:41
  • @rain1 - The ones I've found so far require a brute force search for the first factor. For GF(2^64), that's 2^64 possible combinations of coefficients of the first factor, making it infeasible. I'll keep searching for better algorithms for large fields.. – rcgldr Jul 15 '20 at 20:42