Changeset - c6815615a077
[Not reviewed]
default
0 1 0
Laman - 4 years ago 2020-12-18 12:07:10

gfmul caching
1 file changed with 2 insertions and 1 deletions:
0 comments (0 inline, 0 general)
src/shamira/gf256.py
Show inline comments
 
# GNU GPLv3, see LICENSE
 

	
 
"""Arithmetic operations on Galois Field 2**8. See https://en.wikipedia.org/wiki/Finite_field_arithmetic"""
 

	
 
from functools import reduce
 
from functools import reduce, cache
 
import operator
 

	
 

	
 
def _gfmul(a, b):
 
	"""Basic multiplication. Russian peasant algorithm."""
 
	res = 0
 
	while a and b:
 
		if b&1: res ^= a
 
		if a&0x80: a = 0xff&(a<<1)^0x1b
 
		else: a <<= 1
 
		b >>= 1
 
	return res
 

	
 

	
 
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 = _gfmul(acc, g)
 
L[1] = 0
 
INV = [E[255-L[i]] if i!=0 else None for i in range(256)]  # multiplicative inverse
 

	
 

	
 
@cache
 
def gfmul(a, b):
 
	"""Fast multiplication. Basic multiplication is expensive. a*b==g**(log(a)+log(b))"""
 
	assert 0<=a<=255, 0<=b<=255
 
	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: [an, ..., a1, a0]."""
 
	res = 0
 

	
 
	for a in coefs:  # Horner's rule
 
		res = gfmul(res, x)
 
		res ^= a
 

	
 
	return res
 

	
 

	
 
def get_constant_coef(weights, y_coords):
 
	"""Compute constant polynomial coefficient given the points.
 

	
 
	See https://en.wikipedia.org/wiki/Shamir's_Secret_Sharing#Computationally_Efficient_Approach"""
 
	return reduce(
 
		operator.xor,
 
		map(lambda ab: gfmul(*ab), zip(weights, y_coords))
 
	)
 

	
 

	
 
def compute_weights(x_coords):
 
	assert x_coords
 

	
 
	res = [
 
			reduce(
 
				gfmul,
 
				(gfmul(xj, INV[xj^xi]) for xj in x_coords if xi!=xj),
 
				1
 
			) for xi in x_coords
 
	]
 

	
 
	return res
0 comments (0 inline, 0 general)