Учитывая n
(количество игроков), t
(пороговое значение) и s
(секрет), выведите n
секреты, сгенерированные алгоритмом Shamir's Secret Sharing .
Алгоритм
Для целей этой задачи вычисления будут выполняться в GF (251) (конечное поле размера 251
, также известное как mod 251 целых чисел ). Обычно поле выбирается таким образом, чтобы его размер был больше простого числа n
. Чтобы упростить задачу, размер поля будет постоянным. 251
был выбран, потому что это наибольшее простое число, представимое 8-битным целым числом без знака.
- Генерация
t-1
случайных целых чисел в (включительно) диапазоне[0, 250]
. Добавьте эти с 1 через в Т-1 . - Построить
t-1
полином i-й степени, используяs
в качестве значения константы и случайные целые числа из шага 1 в качестве коэффициентов степенейx
: f (x) = s + x * a 1 + x 2 * a 2 + ... + x t- 1 * Т-1 . - Выход
(f(z) mod 251)
для каждогоz
в (включительно) диапазоне[1, n]
.
Реализация эталона
#!/usr/bin/env python
from __future__ import print_function
import random
import sys
# Shamir's Secret Sharing algorithm
# Input is taken on the command line, in the format "python shamir.py n t s"
n, t, s = [int(x) for x in sys.argv[1:4]]
if t > n:
print("Error: t must be less than or equal to n")
exit()
if n not in range(2, 251):
print("Error: n must be a positive integer less than 251")
exit()
if t not in range(2, 251):
print("Error: t must be a positive integer less than 251")
exit()
if s not in range(251):
print("Error: s must be a non-negative integer less than 251")
exit()
p = 251
a = [random.randrange(0, 251) for x in range(t-1)]
def f(x):
return s + sum(c*x**(i+1) for i,c in enumerate(a))
# Outputting the polynomial is for explanatory purposes only, and should not be included
# in the output for the challenge
print("f(x) = {0} + {1}".format(s, ' + '.join('{0}*x^{1}'.format(c, i+1) for i,c in enumerate(a))))
for z in range(1, n+1):
print(f(z) % p)
верификация
Следующий фрагмент стека может быть использован для проверки выходных данных:
правила
s
будет неотрицательным целым числом меньше чем251
,n
иt
будет положительным целым числом меньше251
и больше чем1
. Кроме того, вы гарантированно, что входные данные являются действительными (то естьt <= n
).- Ввод и вывод могут быть в любом разумном, однозначном и согласованном формате.
- Случайные числа должны выбираться из равномерного распределения - каждое возможное значение должно иметь равную вероятность выбора.
z
иf(z)
? Если я печатаю массивf(z)
s по порядку,z
подразумевается индекс.[[1, 5], [2, 2], [3, 9], [4, 14]]
не содержит больше информации, чем[5, 2, 9, 14]
.