Ausgehend von n
(der Anzahl der Spieler), t
(dem Schwellenwert) und s
(dem Geheimnis) werden die n
Geheimnisse ausgegeben, die durch Shamirs Secret-Sharing-Algorithmus generiert wurden .
Der Algorithmus
Für die Zwecke dieser Herausforderung werden die Berechnungen in GF (251) (dem endlichen Feld der Größe 251
, auch bekannt als Ganzzahlen mod 251 ) durchgeführt. Normalerweise würde das Feld so gewählt, dass seine Größe eine Primzahl ist, die viel größer ist als n
. Um die Herausforderung zu vereinfachen, ist die Feldgröße konstant. 251
wurde gewählt, weil es die größte durch eine 8-Bit-Ganzzahl ohne Vorzeichen darstellbare Primzahl ist.
- Generieren Sie
t-1
zufällige Ganzzahlen im Bereich (einschließlich)[0, 250]
. Beschriften Sie diese ein 1 durch einen t-1 . - Konstruiere ein
t-1
Polynom des Grades mits
dem konstanten Wert und den Zufallszahlen aus Schritt 1 als Koeffizienten der Potenzen vonx
: f (x) = s + x * a 1 + x 2 * a 2 + ... + x t- 1 * a t-1 . - Ausgabe
(f(z) mod 251)
jeweilsz
im (inklusive) Bereich[1, n]
.
Referenzimplementierung
#!/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)
Nachprüfung
Das folgende Stack-Snippet kann zum Überprüfen von Ausgaben verwendet werden:
Regeln
s
wird weniger eine nicht negative ganze Zahl ist als251
undn
undt
wird positive ganze Zahlen kleiner als251
und größer als1
. Darüber hinaus ist gewährleistet, dass die Eingaben gültig sind (Bedeutungt <= n
).- Die Ein- und Ausgabe kann in jedem vernünftigen, eindeutigen und konsistenten Format erfolgen.
- Zufallszahlen sind aus einer Gleichverteilung abzutasten - jeder mögliche Wert sollte die gleiche Wahrscheinlichkeit haben, gewählt zu werden.
z
undf(z)
? Wenn ich ein Array vonf(z)
s in der richtigen Reihenfolgez
drucke , wird dies durch den Index impliziert.[[1, 5], [2, 2], [3, 9], [4, 14]]
enthält nicht mehr Informationen als[5, 2, 9, 14]
.