पॉलिनॉमियल्स (Polynomials) का ज़ीरो नॉलेज मल्टीप्लिकेशन
पिछले अध्याय की polynomial commitment स्कीम का उपयोग करके, एक प्रूवर (prover) यह दिखा सकता है कि उसके पास तीन पॉलिनॉमियल्स , , और हैं और यह साबित कर सकता है कि है।
इस एल्गोरिदम के काम करने के लिए, वेरिफायर (verifier) को यह विश्वास होना चाहिए कि पॉलिनॉमियल इवैल्यूएशन (evaluations) सही हैं – लेकिन यह एक ऐसी चीज़ है जिसे हमने पिछले अध्याय में दिखाया था। यहाँ के अधिकांश चरण (steps) केवल उसी polynomial commitment एल्गोरिदम को दोहरा रहे हैं जो हमने पहले किया था।
एक हाई-लेवल पर, प्रूवर , , और के लिए कमिट (commit) करता है और कमिटमेंट्स (commitments) को वेरिफायर के पास भेजता है। फिर, वेरिफायर के लिए एक रैंडम वैल्यू (random value) के रूप में चुनता है और प्रूवर से पर पॉलिनॉमियल्स को इवैल्यूएट करने के लिए कहता है। वेरिफायर तब जाँचता है कि इवैल्यूएशन सही ढंग से किए गए थे या नहीं, और क्या के इवैल्यूएशन को के इवैल्यूएशन से गुणा करने पर वह के इवैल्यूएशन के बराबर है।
उदाहरण के लिए, मान लें कि पहला पॉलिनॉमियल है और दूसरा है। तो होगा। वेरिफायर किसी भी रैंडम वैल्यू को सैंपल कर सकता है, और के गुणनफल (product) का परिणाम होगा। नीचे दिया गया ग्राफ वेरिफायर द्वारा चुनने का एक उदाहरण दिखाता है:

वेरिफायर फिर यह जाँचेगा कि है और प्रूवर के दावे को स्वीकार करेगा।
Schwartz-Zippel lemma यह बताता है कि यदि है, तो किसी रैंडम वैल्यू के लिए होने की प्रोबेबिलिटी (probability) से कम होती है, जहाँ दोनों पॉलिनॉमियल्स की अधिकतम डिग्री (maximum degree) है और finite field का ऑर्डर (order) है। यदि (, से बहुत बहुत छोटा है), तो के दो असमान पॉलिनॉमियल्स का इंटरसेक्शन पॉइंट (intersection point) होने की प्रोबेबिलिटी नगण्य (negligible) है।
विशेष रूप से, मान लीजिए कि प्रूवर झूठ बोल रहा है और है। उस स्थिति में, एक रैंडम के लिए, अत्यंत उच्च प्रोबेबिलिटी के साथ होगा। यदि है, तो और केवल अधिकतम पॉइंट्स पर इंटरसेक्ट करते हैं ( या दोनों में से किसी की अधिकतम डिग्री), और इसकी संभावना बहुत कम है कि वेरिफायर रैंडमली ऐसा चुनेगा जो उन इंटरसेक्शन पॉइंट्स में से एक हो।
स्केल (scale) का अंदाज़ा लगाने के लिए, हमारे मामले में 2 है, लेकिन हमारे इलिप्टिक कर्व्स (elliptic curves) का कर्व ऑर्डर (curve order) (और इसलिए फील्ड का ऑर्डर) लगभग है। इसलिए यदि है, तो होने की प्रोबेबिलिटी है, जो कि लुप्त होने की हद तक छोटी (vanishingly small) है।
अब हम एल्गोरिदम का विस्तार से वर्णन करते हैं, और फिर एक ऑप्टिमाइज़ेशन (optimization) दिखाते हैं।
पॉलिनॉमियल मल्टीप्लिकेशन की नॉलेज साबित करने के स्टेप्स
प्रूवर दो लीनियर (डिग्री 1) पॉलिनॉमियल्स , , और एक क्वाड्रैटिक (डिग्री 2) पॉलिनॉमियल को कमिट करता है, और वेरिफायर को कमिटमेंट्स भेजता है। वेरिफायर एक रैंडम वैल्यू के साथ प्रतिक्रिया देता है, और प्रूवर इवैल्यूएशन के प्रूफ्स के साथ , , और का इवैल्यूएशन करता है। वेरिफायर यह सुनिश्चित करता है कि सभी पॉलिनॉमियल्स का इवैल्यूएशन ठीक से किया गया था और है।
सेटअप (Setup)
प्रूवर और वेरिफायर एक अज्ञात डिस्क्रीट लॉग रिलेशनशिप (discrete log relationship) वाले इलिप्टिक कर्व पॉइंट्स और पर सहमत होते हैं (यानी पॉइंट्स को रैंडमली चुना जाता है)।
प्रूवर , , और के लिए कमिट करता है
प्रूवर तीन पॉलिनॉमियल्स बनाता है:
इसलिए उन्हें प्रत्येक गुणांक (coefficients) के लिए कुल 7 Pedersen commitments उत्पन्न करने की आवश्यकता होगी, जिसके लिए सात ब्लाइंडिंग टर्म्स (blinding terms) की आवश्यकता होगी।
प्रूवर वेरिफायर को भेजता है।
वेरिफायर रैंडम स्केलर जनरेट करता है
… और फील्ड एलिमेंट (field element) प्रूवर को भेजता है।
प्रूवर तीन पॉलिनॉमियल्स का इवैल्यूएशन करता है और तीन प्रूफ्स बनाता है
प्रूवर पॉलिनॉमियल्स में डालता है और जब लागू होता है तो पॉलिनॉमियल कोएफिशिएंट कमिटमेंट्स के ब्लाइंडिंग टर्म्स के योग (sum) की गणना करता है।
प्रूवर मान (values) वेरिफायर को भेजता है। ध्यान दें कि ये सभी फील्ड एलिमेंट्स हैं, न कि इलिप्टिक कर्व पॉइंट्स।
फाइनल वेरिफिकेशन स्टेप
वेरिफायर जाँचता है कि प्रत्येक पॉलिनॉमियल्स का सही ढंग से इवैल्यूएशन किया गया था और का इवैल्यूएशन और के इवैल्यूएशन का गुणनफल (product) है। पहले तीन चेक्स (checks) इस बात के प्रमाण हैं कि कोएफिशिएंट्स के कमिटमेंट के संबंध में पॉलिनॉमियल का सही ढंग से इवैल्यूएशन किया गया था, और अंतिम चेक यह वेरिफाई करता है कि पॉलिनॉमियल्स के आउटपुट में दावा किया गया प्रोडक्ट रिलेशनशिप (product relationship) है।
जब हम टर्म्स (terms) का विस्तार करते हैं, तो हम देखते हैं कि यदि प्रूवर ईमानदार था तो वे संतुलित (balance) हो जाते हैं:
ऑप्टिमाइज़ेशन (Optimization): कम कमिटमेंट्स भेजना
पहले चरण में, प्रूवर 7 इलिप्टिक कर्व पॉइंट्स भेजता है, और अंतिम चरण में, वेरिफायर 4 इक्वालिटीज़ (equalities) की जाँच करता है। हम केवल 5 इलिप्टिक कर्व पॉइंट्स भेजने और 3 इक्वालिटी चेक करने के लिए एल्गोरिदम में सुधार कर सकते हैं।
यह और के कांस्टेंट कोएफिशिएंट्स को एक ही कमिटमेंट में और उन पॉलिनॉमियल्स के लीनियर कोएफिशिएंट्स को एक अलग कमिटमेंट में रखकर किया जाता है। याद दिलाने के लिए, हमने और को इस प्रकार परिभाषित किया था:
इसलिए और कांस्टेंट कोएफिशिएंट्स हैं, और तथा लीनियर कोएफिशिएंट्स हैं।
यह उसी तरह है जैसे हम एक वेक्टर (vector) को कमिट करते हैं। हम एक तरह से कांस्टेंट कोएफिशिएंट्स को एक वेक्टर के रूप में और लीनियर कोएफिशिएंट्स को दूसरे वेक्टर के रूप में कमिट कर रहे हैं।
सेटअप (Setup)
सेटअप के दौरान, अब हमें 3 इलिप्टिक कर्व पॉइंट्स की आवश्यकता है: , , और ।
पॉलिनॉमियल कमिटमेंट (Polynomial commitment)
ध्यान दें कि के कोएफिशिएंट्स पर लागू होते हैं और के कोएफिशिएंट्स पर लागू होते हैं। प्रूवर वेरिफायर को भेजता है, जो के साथ प्रतिक्रिया देता है।
पॉलिनॉमियल इवैल्यूएशन
, , , , और की गणना पहले की तरह की जाती है, लेकिन और के इवैल्यूएशन के प्रूफ्स, जो पहले और थे, उन्हें मिलाकर एक कर दिया गया है: ।
फाइनल वेरिफिकेशन
चेक का विस्तार (expand) इस प्रकार होता है:
बाईं ओर (left-hand-side) कुछ पुनर्व्यवस्था (rearranging) के साथ, हम देख सकते हैं कि इक्वालिटी चेक एक साथ यह जाँचता है कि और दोनों का इवैल्यूएशन सही ढंग से किया गया था।
चेक को देखने के एक और तरीके के रूप में, निम्नलिखित विज़ुअलाइज़ेशन (visualization) पर विचार करें:
स्केलर्स (Scalars) का ज़ीरो नॉलेज मल्टीप्लिकेशन
हमारा यह प्रूफ कि हमने तीसरे पॉलिनॉमियल को प्राप्त करने के लिए दो पॉलिनॉमियल्स को सही ढंग से गुणा किया है, का उपयोग यह साबित करने के लिए किया जा सकता है कि हमने तीसरे को प्राप्त करने के लिए दो स्केलर्स (scalars) को एक साथ गुणा किया है। एल्गोरिदम में किसी बदलाव की आवश्यकता नहीं है, केवल सिमेंटिक्स (semantics) में एक मामूली बदलाव है (हम कमिटमेंट्स की व्याख्या कैसे करते हैं)।
मान लें कि हम यह साबित करना चाहते हैं कि हमने का गुणा (multiplication) किया है।
समस्या का विवरण (Problem statement)
, और के लिए एक कमिटमेंट है, और , के लिए एक कमिटमेंट है जहाँ है। हम यह साबित करना चाहते हैं कि और को दावे के अनुसार कमिट किया गया है बिना , , या को प्रकट किए।
समाधान (Solution)
हाई-लेवल विचार यह है कि स्वेच्छा से (arbitrarily) चुने गए लीनियर टर्म को जोड़कर एक स्केलर को पॉलिनॉमियल में बदला जा सकता है, उदाहरण के लिए , बन जाता है और , बन जाता है। और प्रूवर द्वारा रैंडमली चुने जाते हैं।
जब पॉलिनॉमियल्स और को एक साथ गुणा किया जाता है, तो का गुणा पॉलिनॉमियल मल्टीप्लिकेशन के “अंदर” होता है।
याद करें कि प्रूवर कमिटमेंट्स भेजकर एल्गोरिदम शुरू करता है:
हम बस की “व्याख्या (interpretation)” को पॉलिनॉमियल्स के कांस्टेंट टर्म्स होने के बजाय उन कांस्टेंट्स और में बदल देते हैं जिन्हें हम गुणा कर रहे हैं। हम उस मल्टीप्लिकेशन में के कमिटमेंट के रूप में व्याख्या के बदलाव को दर्शाने के लिए को में बदलते हैं जिसे हम यह साबित करने का प्रयास कर रहे हैं कि हमने सही ढंग से किया है, यानी ।
अभ्यास (Exercise): ऊपर वर्णित एल्गोरिदम को लागू करने के लिए छूटे हुए Python कोड को भरें।
from py_ecc.bn128 import G1, multiply, add, FQ, eq
from py_ecc.bn128 import curve_order as p
import random
def random_element():
return random.randint(0, p)
# these EC points have unknown discrete logs:
G = (FQ(6286155310766333871795042970372566906087502116590250812133967451320632869759), FQ(2167390362195738854837661032213065766665495464946848931705307210578191331138))
H = (FQ(13728162449721098615672844430261112538072166300311022796820929618959450231493), FQ(12153831869428634344429877091952509453770659237731690203490954547715195222919))
B = (FQ(12848606535045587128788889317230751518392478691112375569775390095112330602489), FQ(18818936887558347291494629972517132071247847502517774285883500818572856935411))
# utility function
def addd(A, B, C):
return add(A, add(B, C))
# scalar multiplication example: multiply(G, 42)
# EC addition example: add(multiply(G, 42), multiply(G, 100))
# remember to do all arithmetic modulo p
def commit(a, sL, b, sR, alpha, beta, gamma, tau_1, tau_2):
pass
# return (A, S, V, T1, T2)
def evaluate(f_0, f_1, f_2, u):
return (f_0 + f_1 * u + f_2 * u**2) % p
def prove(blinding_0, blinding_1, blinding_2, u):
# fill this in
# return pi
pass
## step 0: Prover and verifier agree on G and B
## step 1: Prover creates the commitments
a = ...
b = ...
sL = ...
sR = ...
t1 = ...
t2 = ...
### blinding terms
alpha = ...
beta = ...
gamma = ...
tau_1 = ...
tau_2 = ...
A, S, V, T1, T2 = commit(a, sL, b, sR, alpha, beta, gamma, tau_1, tau_2)
## step 2: Verifier picks u
u = ...
## step 3: Prover evaluates l(u), r(u), t(u) and creates evaluation proofs
l_u = evaluate(a, sL, 0, u)
r_u = evaluate(b, sR, 0, u)
t_u = evaluate(a*b, t1, t2, u)
pi_lr = prove(alpha, beta, 0, u)
pi_t = prove(gamma, tau_1, tau_2, u)
## step 4: Verifier accepts or rejects
assert t_u == (l_u * r_u) % p, "tu != lu*ru"
assert eq(add(A, multiply(S, u)), addd(multiply(G, l_u), multiply(H, r_u), multiply(B, pi_lr))), "l_u or r_u not evaluated correctly"
assert eq(add(multiply(G, t_u), multiply(B, pi_t)), addd(V, multiply(T1, u), multiply(T2, u**2 % p))), "t_u not evaluated correctly"
और जानें (Learn more)
यह लेख Bulletproof ZKPs पर एक सीरीज़ का हिस्सा है।