"""Arithmetic operations on Galois Field 2**8."""
def _ffmul(a, b):
"""Basic multiplication."""
r=0
while a!=0:
if (a&1)!=0: r^=b
t=b&0x80
b=(b<<1)&255
if t!=0: b^=0x1b
a>>=1
return r
g=3 # generator
E=[None]*256 # exponentials
L=[None]*256 # logarithms
acc=1
for i in range(256):
E[i]=acc
L[acc]=i
acc=_ffmul(acc, g)
L[1]=0
inv=[E[255-L[i]] if i!=0 else None for i in range(256)] # multiplicative inverse
def ffmul(a, b):
"""Fast multiplication. Basic multiplication is expensive. a*b==g**(log(a)+log(b))"""
if a==0 or b==0: return 0
t=L[a]+L[b]
if t>255: t-=255
return E[t]
def evaluate(coefs,x):
"""Evaluate polynomial's value at x.
:param coefs: [a0, a1, ...]."""
res=0
xK=1
for a in coefs:
res^=ffmul(a,xK)
xK=ffmul(xK,x)
return res
def getConstantCoef(*points):
"""Compute constant polynomial coefficient given the points."""
k=len(points)
res=0
for i in range(k):
(x,y)=points[i]
prod=1
for j in range(k):
if i==j: continue
(xj,yj)=points[j]
prod=ffmul(prod, (ffmul(xj,inv[xj^x])))
res^=ffmul(y,prod)
return res