Dado n
(o número de jogadores), t
(o valor limite) e s
(o segredo), são apresentados os n
segredos gerados pelo algoritmo de Compartilhamento Secreto de Shamir .
O Algoritmo
Para os propósitos deste desafio, os cálculos serão feitos em GF (251) (o campo finito de tamanho 251
, também conhecido como número inteiro mod 251 ). Normalmente, o campo seria escolhido de tal forma que seu tamanho seja um primo muito maior que n
. Para simplificar o desafio, o tamanho do campo será constante. 251
foi escolhido porque é o maior número primo representável por um número inteiro não assinado de 8 bits.
- Gere
t-1
números inteiros aleatórios no intervalo (inclusive)[0, 250]
. Rotular essas um 1 por meio de um t-1 . - Construa um
t-1
polinômio de th grau usandos
como valor constante e os números inteiros aleatórios da etapa 1 como os coeficientes das potências dex
: f (x) = s + x * a 1 + x 2 * a 2 + ... + x t- 1 * a t-1 . - Saída
(f(z) mod 251)
para cada umz
na faixa (inclusive)[1, n]
.
Implementação de referência
#!/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)
Verificação
O seguinte snippet de pilha pode ser usado para verificar as saídas:
Regras
s
será um número inteiro não negativo menor que251
en
et
números inteiros positivos menores que251
e maiores que1
. Além disso, você tem a garantia de que as entradas são válidas (significadot <= n
).- A entrada e a saída podem estar em qualquer formato razoável, inequívoco e consistente.
- Números aleatórios devem ser amostrados a partir de uma distribuição uniforme - cada valor possível deve ter igual probabilidade de ser escolhido.
z
ef(z)
? Se eu imprimir uma matriz def(z)
s em ordem,z
está implícito no índice.[[1, 5], [2, 2], [3, 9], [4, 14]]
não contém mais informações que[5, 2, 9, 14]
.