शमीर की गुप्त साझेदारी


17

यह देखते हुए n(खिलाड़ियों की संख्या), t(थ्रेशोल्ड वैल्यू), और s(सीक्रेट), शमीर के सीक्रेट शेयर एल्गोरिथ्मn द्वारा उत्पन्न रहस्यों को आउटपुट करता है ।

एल्गोरिथ्म

इस चुनौती के प्रयोजनों के लिए, गणना GF (251) (आकार के परिमित क्षेत्र 251, अन्यथा पूर्णांक मॉड 251 के रूप में जाना जाता है ) में की जाएगी। आमतौर पर, फ़ील्ड को इस तरह चुना जाएगा कि उसका आकार एक अभाज्य से अधिक हो n। चुनौती को सरल बनाने के लिए, क्षेत्र का आकार स्थिर रहेगा। 251चुना गया है क्योंकि यह 8-बिट अहस्ताक्षरित पूर्णांक द्वारा सबसे बड़ा अभाज्य अभाज्य है।

  1. उत्पन्न t-1(सम्मिलित) रेंज में यादृच्छिक पूर्णांकों [0, 250]। इन लेबल करें एक 1 के माध्यम से एक टी 1
  2. लगातार मूल्य और चरण 1 से यादृच्छिक पूर्णांकों के रूप में t-1उपयोग कर एक वें डिग्री बहुपद का निर्माण करें : sशक्तियों की गुणांक के रूप में x: f (x) = s + x * a 1 + x 2 * a 2 + ... + x t- 1 * एक टी -1
  3. (सम्मिलित) श्रेणी में (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)।
  • इनपुट और आउटपुट किसी भी उचित, स्पष्ट और सुसंगत प्रारूप में हो सकते हैं।
  • यादृच्छिक संख्या को एक समान वितरण से नमूना किया जाना है - प्रत्येक संभावित मूल्य में चुने जाने की समान संभावना होनी चाहिए।

1
क्या हमें आउटपुट z और f(z) ? यदि मैं f(z)क्रम में एस की एक सरणी प्रिंट करता हूं , zतो सूचकांक द्वारा निहित है। [[1, 5], [2, 2], [3, 9], [4, 14]]से अधिक जानकारी नहीं है [5, 2, 9, 14]
orlp


@orlp फेयर पॉइंट।
Mego

कोई टेस्टकेस?
लीक नन

4
@LeakyNun चूंकि यह प्रश्न यादृच्छिक रूप से टैग किया गया है , मुझे लगता है कि सत्यापन स्निपेट परीक्षण मामलों की तुलना में बहुत अधिक मूल्यवान है जो प्रत्येक रन के लिए अलग-अलग होंगे।
FryAmTheEggman

जवाबों:


13

जेली , 15 बाइट्स

251©xX€⁵0¦ḅЀ%®

कमांड लाइन तर्क के रूप में टी , एन , और एस की अपेक्षा करता है। इसे ऑनलाइन आज़माएं!

यह काम किस प्रकार करता है

251©xX€⁵0¦ḅЀ%®  Main link. Left argument: t. Right argument: n Third argument: s

251©             Yield 251 and copy it to the register.
    x            Repeat [251] t times.
     X€          Random choice each; pseudo-randomly choose t integers from
                 [1, ..., 251]. Since 251 = 0 (mod 251), this is equivalent to
                 choosing them from [0, ..., 250].
       ⁵0¦       Replace the last generated integer (index 0) with s (⁵).
          ḅЀ    Interpret the resulting array as a base-k number, for each k in
                 [1, ..., n], and convert to integer.
              ®  Yield 251 from the register.
             %   Take the generated integers modulo 251.

3
अंतिम पूर्णांक को बदलना बहुत ही सुंदर है :)
लिन

8

गणितज्ञ, ५ ९ ५६ बाइट्स

Mod[Power~Array~{#2,#-1}.RandomInteger[250,#-1]+#3,251]&

आदेश t , n और s में तीन तर्क देता है । N पंक्तियों और t -1 कॉलम के साथ 2d-array बनाता है। प्रत्येक पंक्ति वेक्टर j , जिसे 1 थ्रू n से क्रमांकित किया गया है , में j thru j t -1 की शक्तियाँ समाहित हैं । फिर 0 से 250 की सीमा में यादृच्छिक पूर्णांक गुणांक का एक वेक्टर t -1 मानों के साथ बनाया जाता है । यही कारण है कि मैट्रिक्स गुणा 2 डी सरणी के साथ है, और फिर रहा है तत्व के लिहाज से और मॉड्यूल 251 लिया में से प्रत्येक में बहुपद का मान प्राप्त करने के लिए जोड़ा जाता है n अंक।


1
बस के साथ एक 79-बाइट उत्तर पोस्ट करने के बारे में था, के साथ अच्छी चाल Sum!
15 मई को लीजियनममाल 978

1
मुझे एक अलग दृष्टिकोण मिला है, लेकिन यह वर्तमान में दो बाइट्स लंबा है। शायद आपके पास एक विचार है कि इसे कैसे छोटा किया जाए:Mod[x#+#2&~Fold~RandomInteger[250,#2-1]x+#3/.x->Range@#,251]&
मार्टिन एंडर



3

जावास्क्रिप्ट, 181 बाइट्स

(n,t,s)=>{r=Array(t-1).fill(0).map($=>{return Math.random()*251});f=(x=>{p = 0;r.map((k,c)=>p+=k*Math.pow(x, c));return s+p});_=Array(t-1).fill(0);_.map((l,i)=>_[i]=f(i));return _;}

Ungolfed:

(n, t, s) => {
    r = Array(t - 1).fill(0).map($ =>{return Math.random() * 251});
    f = (x => {
        p = 0;
        r.map((k, c) => p += k * Math.pow(x, c));
        return s + p
    });
    _ = Array(t - 1).fill(0);
    _.map((l, i) => _[i] = f(i));
    return _;
}

मुझे नहीं पता कि इसे ठीक से कैसे जांचना है, लेकिन मुझे पता है कि जेएस को एक नए सरणी में मैप करने के लिए एक दर्द था क्योंकि स्पष्ट रूप .mapसे अपरिभाषित मूल्यों को छोड़ देता है। अगर किसी को सुधार करने के लिए कोई रास्ता दिखता है, या खामियां हैं, तो मुझे बताने में संकोच न करें।


123 बाइट्स:(n,t,s,A=f=>Array(t-1).fill(0).map(f),r=A($=>Math.random()*251))=> A((l,i,_,p=0)=>(r.map((k,c)=>p+=k*Math.pow(i,c)),s+p))
डेंड्रोबियम

आप उपयोग नहीं कर रहे हैं n, जो गलत लगता है। आपका कोड भी 1-आधारित अनुक्रमण मान रहा है। [...Array()]से थोड़ा छोटा है fiil()। इसके अलावा, अंतिम दो पंक्तियों को घटाया जा सकता हैreturn _.map(f);
नील

3

सी #, 138 134 बाइट्स

(n,t,s)=>new int[n+1].Select((_,x)=>(s+new int[t-1].Select(k=>new Random(e).Next(251)).Select((c,i)=>c*Math.Pow(x+1,i+1)).Sum())%251);

C # लंबो जहां इनपुट्स हैं intऔर आउटपुट ए है IEnumerable<double>। आप .netFiddle पर मेरे कोड की कोशिश कर सकते हैं ।

मैं अपने एल्गोरिथ्म की वैधता के बारे में 100% निश्चित नहीं हूं, कृपया टिप्पणी करें कि क्या मैंने कुछ गलत समझा है।

@ बग्घी की चाल से 4 बाइट बच गईं ।


3

MATL , 20 19 बाइट्स

251tliq3$Yrihi:ZQw\

इनपुट आदेश है t, s, n

इसे ऑनलाइन आज़माएं!

व्याख्या

251t    % Push 251 twice
l       % Push 1
iq      % Take input t. Subtract 1
3$Yr    % Generate t-1 random integers in [1 2 ... 251]
ih      % Take input s. Concatenate with the random integers
i:      % Take input n. Generate range [1 2 ... n]
ZQ      % Evvaluate polynomial at those values
w       % Swap to move copy og 251 to the top of the stack
\       % Modulo. Implicitly display


1

जावास्क्रिप्ट (ईएस 6), 116 बाइट्स

(n,t,s)=>[...Array(n)].map((_,i)=>++i&&t.reduce((r,a)=>r*i+a)%251,t=[...Array(t)].map(_=>--t?Math.random()*251|0:s))

मुझे लगता है कि यह उन दुर्लभ मामलों में से एक है जहां reduceधड़कता है map


1

NumPy के साथ पायथन 3 , 103 बाइट्स

from numpy import*
lambda n,t,s:[poly1d(append(random.randint(0,251,t-1),s))(i+1)%251for i in range(n)]

मैं ईमानदारी से कह सकता हूं कि मैंने कोड गोल्फ के लिए कभी भी NumPy का उपयोग करने की उम्मीद नहीं की ...

एक अनाम फ़ंक्शन जो तर्क के माध्यम से इनपुट लेता है और एक सूची देता है।

यह काम किस प्रकार करता है

from numpy import*         Import everything in the NumPy library
lambda n,t,s...            Function with input number of players n, threshold value t and
                           secret s
random.randint(0,251,t-1)  Generate a NumPy array R of t-1 random integers in [0,250]
append(...,s)              Append s to R
poly1d(...)                Generate a polynomial p of order t-1 with coefficients R and
                           constant term s
...for i in range(n)       For all integers i in [0,n-1]...
...(i+1)                   ...evaluate p(i+1), so for all integers in [1,n]...
...%251                    ...and take modulo 251
...:[...]                  return as list

Ideone पर इसे आज़माएं


1

जे , 32 30 बाइट्स

251|(1+i.@{.)p.~{:0}251?@#~1&{

मूल्यों के साथ एक सूची ले जाता है n , टी , और रों

@ डेनिस के समाधान से इंडेक्स 0 आइडिया के स्थान पर 2 बाइट्स का उपयोग करके सहेजा गया ।

व्याख्या

251|(1+i.@{.)p.~{:0}251?@#~1&{  Input: [n t s]
                           1&{  Select at index 1 (t)
                    251  #~     Create that many copies of 251
                       ?@       Generate that many random integers in [0, 251)
                {:              Get the tail of the input (s)
                  0}            Replace the value at index 0 of the random integer list
                                with s to make a coefficient list of the polynomial
          {.                    Get the head of the input (n)
       i.@                      Make the range [0, n-1]
     1+                         Add 1 to each to get [1, n]
             p.~                Evaluate the polynomial at each value [1, n]
251|                            Take each value mod 251 and return

0

जावा 8, 224 बाइट्स:

(n,t,s)->{int[]W=new int[t-1];for(int i=0;i<t-1;i++){W[i]=new java.util.Random().nextInt(251);};long[]O=new long[n];for(int i=1;i<=n;i++){long T=0;for(int h=1;h<t;h++){T+=W[h-1]*Math.pow(i,h);}O[i-1]=((T+s)%251);}return O;};

एक जावा 8 लंबोदर अभिव्यक्ति। एक अल्पविराम से अलग पूर्णांक सरणी को आउटपुट करता है, और पूरी तरह से तब तक काम करता है जब तक आउटपुट सरणी में मान जावा की सीमा से परे नहीं पहुंचता है long, या 64-बिट हस्ताक्षरित पूर्णांक, डेटा प्रकार, जिस पर -200सरणी में आउटपुट होता है।

यह ऑनलाइन की कोशिश करो! (Ideone)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.