शमीर के गुप्त साझा पुनर्निर्माण को लागू करें


11

शमीर की गुप्त साझा योजना , इसे फिर से संगठित करने के लिए आवश्यक कई भागों में विभाजित करके एक गुप्त को बचाने का एक सरल तरीका है।

आपका कार्य प्रधान द्वारा परिभाषित परिमित क्षेत्र पर शमीर के गुप्त साझा पुनर्निर्माण को लागू करना है 1928049029। यदि आपको इस बारे में कोई संदेह है कि इसका क्या अर्थ है, तो बस विकिपीडिया (नीचे अधिक संसाधन) में परिमित क्षेत्र और परिमित क्षेत्र अंकगणित पूछें या देखें ।

इनपुट

स्टड का उपयोग करके इनपुट किया जाता है। पहले एक पूर्णांक आता है k, फिर k रेखाएँ अनुसरण करती हैं। इनमें से प्रत्येक पंक्ति में पूर्णांक की एक जोड़ी होती है x yजो एक गुप्त का प्रतिनिधित्व करती है। f(x) = yमूल बहुपद में दूसरे शब्दों में जिसका उपयोग रहस्यों के निर्माण के लिए किया गया था।

दिए गए रहस्यों की संख्या हमेशा संबंधित रहस्य के निर्माण के लिए पर्याप्त है।

उत्पादन

पुन: निर्मित राज़ को रोकने के लिए आउटपुट।

उदाहरण

इनपुट:

5         
1 564797566
2 804114535
4 1354242660
6 1818201132
7 503769263

आउटपुट:

1234

इनपुट:

7
1 819016192
2 1888749673
3 1737609270
4 365594983
5 1628804870
6 1671140873
7 492602992

आउटपुट:

456457856

साधन

विकिपीडिया लेख

कागज़

परिमित क्षेत्र स्रोत: विकिपीडिया

परिमित क्षेत्र अंकगणित स्रोत: विकिपीडिया

लैग्रेंज बहुपद स्रोत: विकिपीडिया

परिमित क्षेत्र अंकगणित पर अध्याय

जवाबों:


4

बैश, 271 वर्ण

आर () {
[$ {1/0 /}] && {r $ (($ 2% $ 1)) $ 1; (t = u, u = v- $ 2 / $ 1 * u, v = t)};};
}
पढ़ना
((एन = +१९२८०४९०२९, एन = 0))
जबकि x [$ n] y [$ n] पढ़ा जाता है
कर ((एन ++))
किया हुआ
के लिए ((मैं n =; z = (z + एल)% N, मैं -;)) करना
के लिए ((जे = n, एल = y [i]; j -;)) करना
((यू = 0, वी = 1, डी = एक्स [जे] -x [i], एम = एन + घ))
आर एमएन
[$ {d / 0 /}] && ((l = l * x [j]% N * (u + N) N
किया हुआ
किया हुआ
इको $ z

नए मामलों को अधिकांश मामलों में अर्धविराम से बदला जा सकता है, लेकिन मुझे नहीं लगता कि कोई अनावश्यक व्हाट्सएप है।

(मुझे आज से पहले महसूस नहीं हुआ था कि बैश के पूर्णांक 64-बिट - बहुत उपयोगी हैं)।

बैर के लिए पुनरावर्ती जीसीडी (वैश्विक राज्य का शोषण), पुनरावृत्तियों की तुलना में अधिक कॉम्पैक्ट प्रतीत होता है। यह ज्यादातर सीधा है; दिलचस्प चाल है [ ${d/0/} ]&&fooजो प्रभावी रूप से हैif [ $d -ne 0 ];then foo;fi


अच्छा! मैंने कभी भी इस समस्या का जवाब नहीं दिया। +1
जुआन

@ जुआन, मैंने इसे पर्ल में करना शुरू कर दिया, और इसे फ्लोट के बजाय पूर्णांक विभाजन करने के लिए मजबूर करने के साथ तंग आ गया। और मैं वैसे भी बेहतर तरीके से बैश जानता हूं, इसलिए इसमें दीवार के खिलाफ सिर की कम धड़कन शामिल है।
पीटर टेलर

3

ऑक्टेव में 199 वर्ण:

m=@(x)mod(x,1928049029);[d,l]=scanf('%d');c=d(1);e=repmat(int64(d(2:2:l)),1,c);[_,b]=gcd(e-e',1928049029*ones(c));b=eye(c)+m(e.*b);x=b(1,:);for i=2:c;x=m(x.*b(i,:));end;disp(m(sum(m(x'.*d(3:2:l)))))

3

गोल्फस्क्रिप्ट, 114 112 111 110 109 65 (86) चार्ट

यदि आप इस सप्ताह परिणाम प्राप्त करने की परवाह नहीं करते हैं, तो 65 चार्ट पर्याप्त होंगे:

~](;2/0\:X{~\.X{0=}%^\{\.@- 1928049029:P.,\@{@*\%(!}++?**}+/+P%}/

लेकिन अगर आप दक्षता की तलाश कर रहे हैं, तो यह 86 वर्णों से थोड़ा लंबा है:

~](;2/0\:X{~\.X{0=}%^\{\[.0](@-[1928049029:P%P]{.~/{\.(;@@~@*-+\}+2*.1=}do;0=*}+/+P%}/

जितना मैं अपने ब्लॉग पर यहाँ दोहराना चाहता हूँ, उससे कहीं अधिक विवरण में यह विच्छेदित है ।


मुख्य रूप से मेरा काम नहीं है, लेकिन नब्ब से बहुत अधिक घूस देना 47 चार्ट देता है:

n%(!\:A{~A{~;.3$- 1928049029:N((?1or**}/\/+N%}/

नोट: मैंने केवल इस कोड के बारे में तर्क दिया है: इसे चलाने की कोशिश को व्यर्थ किया जाएगा और इसे उपयोग की जाने वाली मेमोरी की समय और मात्रा को देखते हुए।


3

गोल्फस्क्रिप्ट - 52 46 (67)

46 वर्णों में मॉड्यूलर व्युत्क्रम के लिए एक क्रूर बल दृष्टिकोण। बार-बार मनमाने ढंग से सटीक पूर्णांक के साथ ^ (N-2) की गणना करता है।

n%(!\:A{~A{~;.3$-.!+1928049029:N((?**}/\/+N%}/

विस्तारित यूक्लिडियन एल्गोरिथ्म को लागू करने से हमें केवल एक अतिरिक्त 15 अक्षरों का खर्च आता है।

n%(!\:A{~A{~;.3$-:|!1\1928049029:N{@2$|3$/*-\|\:|%.}do;;**}/\/+N%}/

यह कोड मेरे ब्लॉग पोस्ट पर पूरी तरह से विस्तृत है , जिसमें मॉड्यूलर गुणक व्युत्क्रम की गणना के लिए कुछ विकल्प भी शामिल हैं।


1
अच्छा लगा, लेकिन मुझे लगता है कि अभी भी कम से कम दो चार्ट बचाए जाने बाकी हैं। {*N%2<}के {*N%1=}रूप में ब्लॉग के साथ बदलें और आप (;बाद में खाई कर सकते हैं N,। लेकिन फिर प्रदर्शन-अप्रासंगिक प्रविष्टि के लिए आप एक्सफोलिएशन के मॉड्यूलर पक्ष के बारे में परेशान किए बिना फ़र्मेट की छोटी प्रमेय का उपयोग कर सकते हैं - बस अंतिम सुव्यवस्थित के लिए छोड़ दें - इसलिए प्राप्तकर्ता बन जाता है N((?
पीटर टेलर

1
@Peter: {*N%1=}+भाजक शून्य के साथ मामले को याद करेगा, जिसे संभालने के लिए कम से कम 3 वर्ण होंगे। केवल x ^ (N-2) करने पर अच्छी पकड़ हालांकि, हम वास्तव में इसका उपयोग करके 46 वर्ण प्राप्त कर सकते हैं।
नबंवर

2

लुआ 444 चरस

उदाहरण के लिए विकि पृष्ठ पर काम करता है

3
2 1942
4 3402
5 4414

लेकिन किसी तरह इस पृष्ठ पर यहां के उदाहरणों के लिए काम नहीं करता है। अगर किसी को त्रुटि मिल सकती है?

गैर-गोल्फ संस्करण:

-- Reconstruct shamir secret
-- convention, poly = {[0]=a0,a1,...,an}
i=io.read
f=math.fmod
w=1928049029
k=i():match"%d+"
x={} -- Will contain X values
y={} -- Will contain Y values
p={} -- will contain lagrange polynomials

-- Read data
for j=0,k-1 do
    x[j],y[j]=i():match("(%d+) (%d+)")
    print(j,x[j],y[j])
end
-- Multiplication and scaling function
function mul(p,q,s)
    -- multiply polies
    r={} -- poly to be returned
    for k=0,#p do 
        for l=0,#q do
            r[l+k]=r[l+k] or 0 -- if the coeff for degree l+k of x doesn't exist, put 0
            p[k]=p[k] or 0 -- if p hasn't got a coeff for x^k
            q[l]=q[l] or 0 -- idem for q
            r[l+k]=(r[l+k]+s*p[k]*q[l]%w -- calculate increment for coeff for x^(l+k) 
        end
    end
    -- Debugging
    io.write"Multiplied "
    printPoly(p)
    io.write"With       "
    printPoly(q)
    io.write("And scaling factor ",tostring(s),"\n")
    io.write"Yielding   "
    printPoly(r)
    return r
end

function printPoly(p) -- "Pretty" printing of the polynomial
    for k=#p,1,-1 do
        io.write(tostring(p[k] or 0),"x^",tostring(k),"+")
    end
    io.write(p[0])
    io.write"\n"
end
function egcd(a,b)
    if a == 0 then
        return b, 0, 1
    else
        local g, y, x = egcd(b % a, a)
        return g, x - math.floor(b / a) * y, y
    end
end

function inv(a,m)
    a=a>=0 and a or a+m
    local g,x,y = egcd(a,m)
    if g== 1 then
        return x%m
    else
        print(a,"has no inverse mod",m)
    end
end


-- generate lagrange polynomials
for j=0,#x do
    print("j=",j,"*********")
    for m=0,k-1 do
        if m~=j then -- if m==j, continue
            p[j]=p[j]or{[0]=1} -- if this poly doesn't exist, take 1
            p[j]=mul( p[j], {[0]=-x[m],1},inv(x[j]-x[m],w))-- multiply with (x-x_m)/(x_j-x_m)
            io.write"---------------------------------\n"
        end
    end
end
r=0 -- Result for x^0
for k=0,#p do
    print("l_"..k)
    printPoly(p[k]) -- print l_k
    r=r+f(y[k]*p[k][0],w) -- add coeff for x^0 to result
end
print("Secret was",f(r,w)) -- display result

गोल्फ (परिमित क्षेत्र का उपयोग नहीं), 444 वर्ण:

i=io.read f=math.fmod w=1928049029 k=i():match"%d+"x={}y={}p={}for j=0,k-1 do x[j],y[j]=i():match("(%d+) (%d+)")end
function mul(p,q,s)r={}for k=0,#p do for l=0,#q do r[l+k]=r[l+k]or 0 p[k]=p[k]or 0 q[l]=q[l]or 0 r[l+k]=f(r[l+k]+s*p[k]*q[l],w)end end return r end
for j=0,#x do for m=0,k-1 do if m~=j then p[j]=p[j]or{[0]=1}p[j]=mul(p[j],{[0]=-x[m],1},1/(x[j]-x[m]))end end end r=0 for k=0,#p do r=r+f(y[k]*p[k][0],w)end
print(f(r,w))

विकिपीडिया उदाहरण एक परिमित क्षेत्र का उपयोग नहीं करता है, जो वास्तव में एक शर्म की बात है, यह एक बहुत अधिक शिक्षाप्रद होता। यह सबसे अधिक संभावना है कि आपकी त्रुटि का स्रोत है।
आआआआआआआआआआआ आआआआ

2

जावा, 435 407 चार्ट

import java.util.*;public class G{public static void main(String[]args){Scanner s=new Scanner(System.in);int i,k,n=s.nextInt();long N=1928049029L,x[]=new long[n],y[]=new long[n],z=0,l,c;for(i=n;i-->0;){x[i]=s.nextInt();y[i]=s.nextInt();}for(i=n;i-->0;){l=y[i];for(long j:x)if(x[i]!=j){c=1;for(long a=N+j-x[i],b=N,d=0,t;b>0;){t=d;d=c-a/b*d;c=t;t=b;b=a%b;a=t;}l=l*j%N*(c+N)%N;}z+=l;}System.out.println(z%N);}}

Ungolfed:

import java.util.*;
public class G {
    public static void main(String[] args) {
        Scanner s=new Scanner(System.in);
        int i,k,n=s.nextInt();
        long N=1928049029L,x[]=new long[n],y[]=new long[n],z=0,l,c;
        for (i=n; i-->0;) {
            x[i]=s.nextInt();
            y[i]=s.nextInt();
        }
        for (i=n; i-->0;) {
            l=y[i];
            for (long j:x)
                if (x[i]!=j) {
                    // Extended Euclid algorithm - iterative version -
                    // to find the reciprocal of j-x[i] (mod N)
                    c=1;
                    for (long a=N+j-x[i], b=N, d=0, t; b>0;) {
                        t=d; d=c-a/b*d; c=t;
                        t=b; b=a%b; a=t;
                    }
                    l = l*j%N;
                    l = l*(c+N)%N;
                }
                z+=l;
        }
        System.out.println(z%N);
    }
}

2

हास्केल, 183

p=1928049029
a#0=(1,0)
a#b=let(s,t)=b#mod a b in(t,s-div a b*t)
s d=sum[y*product[z*fst((z-x)#p)|[z,_]<-d,z/=x]|[x,y]<-d]
main=interact$show.(`mod`p).s.map(map read.words).tail.lines
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.