Addictive and Subtractive Properties of Shamir Secret Sharing (Shamir秘密共享的半同态加密的性质(加性和减性))

The Example 1 to show its addictive property

import random
from math import ceil
from decimal import Decimal

FIELD_SIZE = 10**5


def reconstruct_secret(shares):
	"""
	Combines individual shares (points on graph)
	using Lagranges interpolation.

	`shares` is a list of points (x, y) belonging to a
	polynomial with a constant of our key.
	"""
	sums = 0
	prod_arr = []

	for j, share_j in enumerate(shares):
		xj, yj = share_j
		prod = Decimal(1)

		for i, share_i in enumerate(shares):
			xi, _ = share_i
			if i != j:
				prod *= Decimal(Decimal(xi)/(xi-xj))

		prod *= yj
		sums += Decimal(prod)

	return int(round(Decimal(sums), 0))


def polynom(x, coefficients):
	"""
	This generates a single point on the graph of given polynomial
	in `x`. The polynomial is given by the list of `coefficients`.
	"""
	point = 0
	# Loop through reversed list, so that indices from enumerate match the
	# actual coefficient indices
	for coefficient_index, coefficient_value in enumerate(coefficients[::-1]):
		point += x ** coefficient_index * coefficient_value
	return point


def coeff(t, secret):
	"""
	Randomly generate a list of coefficients for a polynomial with
	degree of `t` - 1, whose constant is `secret`.

	For example with a 3rd degree coefficient like this:
		3x^3 + 4x^2 + 18x + 554

		554 is the secret, and the polynomial degree + 1 is
		how many points are needed to recover this secret.
		(in this case it's 4 points).
	"""
	coeff = [random.randrange(0, FIELD_SIZE) for _ in range(t - 1)]
	coeff.append(secret)
	return coeff


def generate_shares(n, m, secret):
	"""
	Split given `secret` into `n` shares with minimum threshold
	of `m` shares to recover this `secret`, using SSS algorithm.
	"""
	coefficients = coeff(m, secret)
	shares = []

	for i in range(1, n+1):
		x = i
		shares.append((x, polynom(x, coefficients)))

	return shares


# Driver code
if __name__ == '__main__':

	# (3,5) sharing scheme
  t, n = 2, 5
  secret_1 = 1234
  secret_2 = 1233
  print(f'Original Secret_1: {secret_1}')
  print(f'Original Secret_2: {secret_2}')

	# Phase I: Generation of shares
  shares_1 = generate_shares(n, t, secret_1)
  shares_2 = generate_shares(n, t, secret_2)
  print(f'Shares_1: {", ".join(str(share) for share in shares_1)}')
  print(f'Shares_2: {", ".join(str(share) for share in shares_2)}')
  diff_shares = []
  diff_shares.append((1, shares_1[0][1]+shares_2[0][1]))
  diff_shares.append((2, shares_1[1][1]+shares_2[1][1]))
  print(diff_shares)
  print(f'Reconstructed secret: {reconstruct_secret(diff_shares)}')

The reults

Original Secret_1: 1234
Original Secret_2: 1233
Shares_1: (1, 3256), (2, 5278), (3, 7300), (4, 9322), (5, 11344)
Shares_2: (1, 95205), (2, 189177), (3, 283149), (4, 377121), (5, 471093)
[(1, 98461), (2, 194455)]
Reconstructed secret: 2467

The Example 2 to show its subtractive property

import random
from math import ceil
from decimal import Decimal

FIELD_SIZE = 10**5


def reconstruct_secret(shares):
	"""
	Combines individual shares (points on graph)
	using Lagranges interpolation.

	`shares` is a list of points (x, y) belonging to a
	polynomial with a constant of our key.
	"""
	sums = 0
	prod_arr = []

	for j, share_j in enumerate(shares):
		xj, yj = share_j
		prod = Decimal(1)

		for i, share_i in enumerate(shares):
			xi, _ = share_i
			if i != j:
				prod *= Decimal(Decimal(xi)/(xi-xj))

		prod *= yj
		sums += Decimal(prod)

	return int(round(Decimal(sums), 0))


def polynom(x, coefficients):
	"""
	This generates a single point on the graph of given polynomial
	in `x`. The polynomial is given by the list of `coefficients`.
	"""
	point = 0
	# Loop through reversed list, so that indices from enumerate match the
	# actual coefficient indices
	for coefficient_index, coefficient_value in enumerate(coefficients[::-1]):
		point += x ** coefficient_index * coefficient_value
	return point


def coeff(t, secret):
	"""
	Randomly generate a list of coefficients for a polynomial with
	degree of `t` - 1, whose constant is `secret`.

	For example with a 3rd degree coefficient like this:
		3x^3 + 4x^2 + 18x + 554

		554 is the secret, and the polynomial degree + 1 is
		how many points are needed to recover this secret.
		(in this case it's 4 points).
	"""
	coeff = [random.randrange(0, FIELD_SIZE) for _ in range(t - 1)]
	coeff.append(secret)
	return coeff


def generate_shares(n, m, secret):
	"""
	Split given `secret` into `n` shares with minimum threshold
	of `m` shares to recover this `secret`, using SSS algorithm.
	"""
	coefficients = coeff(m, secret)
	shares = []

	for i in range(1, n+1):
		x = i
		shares.append((x, polynom(x, coefficients)))

	return shares


# Driver code
if __name__ == '__main__':

	# (3,5) sharing scheme
  t, n = 2, 5
  secret_1 = 1234
  secret_2 = 1233
  print(f'Original Secret_1: {secret_1}')
  print(f'Original Secret_2: {secret_2}')

	# Phase I: Generation of shares
  shares_1 = generate_shares(n, t, secret_1)
  shares_2 = generate_shares(n, t, secret_2)
  print(f'Shares_1: {", ".join(str(share) for share in shares_1)}')
  print(f'Shares_2: {", ".join(str(share) for share in shares_2)}')
  diff_shares = []
  diff_shares.append((1, -shares_1[0][1]+shares_2[0][1]))
  diff_shares.append((2, -shares_1[1][1]+shares_2[1][1]))
  print(diff_shares)
  print(f'Reconstructed secret: {reconstruct_secret(diff_shares)}')

Corresponding Results

Original Secret_1: 1234
Original Secret_2: 1233
Shares_1: (1, 78719), (2, 156204), (3, 233689), (4, 311174), (5, 388659)
Shares_2: (1, 80726), (2, 160219), (3, 239712), (4, 319205), (5, 398698)
[(1, 2007), (2, 4015)]
Reconstructed secret: -1

The example to use larger number to substract the less number

import random
from math import ceil
from decimal import Decimal

FIELD_SIZE = 10**5


def reconstruct_secret(shares):
	"""
	Combines individual shares (points on graph)
	using Lagranges interpolation.

	`shares` is a list of points (x, y) belonging to a
	polynomial with a constant of our key.
	"""
	sums = 0
	prod_arr = []

	for j, share_j in enumerate(shares):
		xj, yj = share_j
		prod = Decimal(1)

		for i, share_i in enumerate(shares):
			xi, _ = share_i
			if i != j:
				prod *= Decimal(Decimal(xi)/(xi-xj))

		prod *= yj
		sums += Decimal(prod)

	return int(round(Decimal(sums), 0))


def polynom(x, coefficients):
	"""
	This generates a single point on the graph of given polynomial
	in `x`. The polynomial is given by the list of `coefficients`.
	"""
	point = 0
	# Loop through reversed list, so that indices from enumerate match the
	# actual coefficient indices
	for coefficient_index, coefficient_value in enumerate(coefficients[::-1]):
		point += x ** coefficient_index * coefficient_value
	return point


def coeff(t, secret):
	"""
	Randomly generate a list of coefficients for a polynomial with
	degree of `t` - 1, whose constant is `secret`.

	For example with a 3rd degree coefficient like this:
		3x^3 + 4x^2 + 18x + 554

		554 is the secret, and the polynomial degree + 1 is
		how many points are needed to recover this secret.
		(in this case it's 4 points).
	"""
	coeff = [random.randrange(0, FIELD_SIZE) for _ in range(t - 1)]
	coeff.append(secret)
	return coeff


def generate_shares(n, m, secret):
	"""
	Split given `secret` into `n` shares with minimum threshold
	of `m` shares to recover this `secret`, using SSS algorithm.
	"""
	coefficients = coeff(m, secret)
	shares = []

	for i in range(1, n+1):
		x = i
		shares.append((x, polynom(x, coefficients)))

	return shares


# Driver code
if __name__ == '__main__':

	# (3,5) sharing scheme
  t, n = 2, 5
  secret_1 = 1234
  secret_2 = 1233
  print(f'Original Secret_1: {secret_1}')
  print(f'Original Secret_2: {secret_2}')

	# Phase I: Generation of shares
  shares_1 = generate_shares(n, t, secret_1)
  shares_2 = generate_shares(n, t, secret_2)
  print(f'Shares_1: {", ".join(str(share) for share in shares_1)}')
  print(f'Shares_2: {", ".join(str(share) for share in shares_2)}')
  diff_shares = []
  diff_shares.append((1, shares_1[0][1]-shares_2[0][1]))
  diff_shares.append((2, shares_1[1][1]-shares_2[1][1]))
  print(diff_shares)
  print(f'Reconstructed secret: {reconstruct_secret(diff_shares)}')

Results

Original Secret_1: 1234
Original Secret_2: 1233
Shares_1: (1, 82486), (2, 163738), (3, 244990), (4, 326242), (5, 407494)
Shares_2: (1, 50272), (2, 99311), (3, 148350), (4, 197389), (5, 246428)
[(1, 32214), (2, 64427)]
Reconstructed secret: 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值