Define the finite field GF(9)

Haskell, 118 112 107 bytes

Here I use the numbers \$n= 0,1,2,\ldots,8\$ to represent the field elements. Internally these are converted to a list \$[a,b]\$ that represents a polynomial \$aX+b\$, (using \$a = \lfloor n/3 \rfloor\$ and \$b = n \mod 3 \$, or \$n=3a+b\$), and we then proceed using the usual arithmetic using these polynomials in \$(\mathbb Z / 3\mathbb Z)[X]/(X^2+1)\$. In this case we have

$$(aX+b) + (cX+d) = (a+c)X + (b+d)$$

and similarly

$$\begin{align*} (aX+b) \cdot (cX+d) &= acX^2+(ad+bc)X + bd \\ & \equiv ac(-1) +(ad+bc)X + bd \mod X^2+1\\ & \equiv (ad+bc)X+(bd-ac) \end{align*}$$

Thanks for -6 bytes @WheatWizard!

i x=[div x 3,x]                --conert integer to polynomial/list representation
j[a,b]=mod(a*3+mod b 3)9       --inverse of i
s=(.i).(j.).zipWith(+).i       --"sum"
m[a,b][c,d]=j[a*d+b*c,b*d-a*c] --core function of "product"
p=(.i).m.i                     --"product"

Try it online!


05AB1E, 24 17 16 bytes

Uses 0, 1, 2, 10, 11, 12, 20, 21, 22 as the 9 field elements.

Addition, 5 bytes:

OS3%J

Try it online! or print the entire table.

O             # sum of the inputs
 S            # split to a list of digits
  3%          # mod 3 each digit
    J         # join

Multiplication, 11 bytes:

PƵÈ%98%S3%J

Try it online! or print the entire table.

P             # product of the inputs
 ƵÈ%          # mod 300
    98%       # mod 98
       S3%J   # split, mod 3 each digit, join

Retina 0.8.2, 53 + 111 = 164 23 + 61 = 84 bytes

Edit: Saved 80 bytes by switching to @Grimmy's I/O format. However, the provided links include a footer which converts the output back to 0-8 format and formats the results into a square.

Addition (53 23 bytes):

\d+
$*
M`1
3$
0
T`34`_1

Try it online! Link includes test suite. Explanation:

\d+
$*

Convert both arguments to unary.

M`1

Take the sum and convert to decimal.

3$
0
T`34`_1

Modulo the last digit by 3, and modulo by 30.

Multiplication (111 61 bytes):

\d+
$*
1(?=1*;(1*))|.
$1
1{300}|1{98}|1{30}

M`1
T`3-8`012012

Try it online! Link includes test suite. Explanation:

\d+
$*

Convert to unary.

1(?=1*;(1*))|.
$1

Take the product.

1{300}|1{98}|1{30}

Modulo by 300, 98 and 30.

M`1

Convert to decimal.

T`3-8`012012

Modulo the last digit by 3.