פיתוח יישומי הוכחה באפס ידע – פתרונות סוהר

רוב הפרויקטים שמגיעים אלינו עם בקשה ל-ZKP נתקלים באחת משתי בעיות: או שהם צריכים להוכיח עובדה מבלי לחשוף נתונים (גיל, יתרה, חברות בקבוצה) או שהם צריכים להוריד חישוב כבד מהשרשרת עם אימות על השרשרת. אלו משימות שונות עם ערכות כלים שונות, ו-

שירותי פיתוח בלוקצ'יין

שאלות נפוצות

העבודות האחרונות

  • image_website-b2b-advance_0.webp
    פיתוח אתר חברה B2B ADVANCE
    1451
  • image_web-applications_feedme_466_0.webp
    פיתוח אפליקציית ווב עבור FEEDME
    1309
  • image_websites_belfingroup_462_0.webp
    פיתוח אתר עבור BELFINGROUP
    1005
  • image_ecommerce_furnoro_435_0.webp
    פיתוח חנות מקוונת לחברת FURNORO
    1270
  • image_logo-advance_0.webp
    עיצוב לוגו לחברת B2B Advance
    719
  • image_crm_enviok_479_0.webp
    פיתוח אפליקציית ווב עבור Enviok
    1011

רוב הפרויקטים שמגיעים אלינו עם בקשה ל-ZKP מתמודדים עם אחת משתי בעיות: או שהם צריכים להוכיח עובדה מבלי לחשוף נתונים (גיל, יתרה, חברות בקבוצה) או שהם צריכים להעביר חישוב כבד מחוץ לשרשרת עם אימות על השרשרת. אלו משימות שונות עם ערימות כלים שונות, ובלבול ביניהן הוא הטעות הראשונה והיקרה ביותר בתחילת הדרך. אנו עוזרים לכם להימנע מטעויות: אנו מעריכים את הפרויקט, בוחרים את הערימה, ומיישמים מפתח-ביד תוך 6–12 שבועות. צרו קשר לייעוץ חינם.

כיצד לבחור את מערכת ההוכחה הנכונה

הבחירה בין Groth16, PLONK, STARK, Halo2 ו-FRI קובעת הכל: גודל ההוכחה, זמן היצירה, דרישות ההתקנה המהימנה ועלות האימות על השרשרת. הטבלה שלהלן משווה ביניהן.

מערכת התקנה מהימנה גודל הוכחה עלות אימות (EVM) זמן מוכיח רקורסיה
Groth16 כן (לכל מעגל) ~200 בתים ~270k גז מהיר קשה
PLONK (KZG) כן (אוניברסלי) ~800 בתים ~400k גז בינוני קל יותר
PLONK (IPA) לא ~1.5KB יקר יותר איטי טוב
STARK לא 40–200KB יקר מאוד ב-EVM איטי מצוין
Halo2 לא ~1–5KB לא-ילידי בינוני מובנה

Groth16 היא הבחירה למערכות ייצור עם מעגל קבוע ודרישות גז מינימליות. בשימוש על ידי: Tornado Cash (לשעבר), Zcash Sapling ורוב גשרי zkSNARK. חיסרון: כל שינוי במעגל דורש טקס חדש. PLONK עם KZG הוא הסטנדרט דה-פקטו למערכות דמויות zkRollup. Gnosis, zkSync Lite ו-Polygon Hermez משתמשות בגרסאות של PLONK. ההתקנה המהימנה האוניברסלית (Powers of Tau) ניתנת לשימוש חוזר — אין צורך בטקס לכל מעגל. STARK נבחרות למשימות שבהן אין צורך בהתקנה מהימנה ורקורסיה נדרשת: StarkNet, Cairo VM. גודל ההוכחה הגדול הופך אימות EVM ילידי לבלתי מעשי — יש צורך בחוזה מאמת נפרד או בגישת L3. Halo2 משמשת את Zcash Orchard ו-Scroll. היא אינה דורשת התקנה מהימנה ויש לה רקורסיה מובנית. הכלים פחות בוגרים, האקוסיסטם קטן יותר, אך מתפתח באופן פעיל.

לרוב המשימות המעשיות (הצבעה פרטית, הוכחת חברות, zkKYC, אימות גיל) — Groth16 דרך circom/snarkjs או PLONK דרך gnark/noir היא נקודת ההתחלה הנכונה. ב-20 gwei, אימות Groth16 אחד עולה בערך $2–5 ברשת הראשית של Ethereum, וב-Arbitrum בערך $0.02–0.05, מה שהופך פריסה ב-L2 למוצדקת כלכלית.

מה פגיע במעגלי ZK? בואו ננתח ב-Circom

Circom היא DSL לכתיבת מעגלים אריתמטיים. המעגל מתקמפל ל-R1CS, ולאחר מכן נוצרת הוכחה דרך snarkjs או rapidsnark.

סכמה בסיסית להוכחת ידיעת תמונת קדם של פונקציית גיבוב:

pragma circom 2.1.4; include "circomlib/circuits/poseidon.circom"; include "circomlib/circuits/comparators.circom"; template ProveBalance() { signal input balance; // private signal input salt; // private signal input commitment; // public signal input threshold; // public component hasher = Poseidon(2); hasher.inputs[0] <== balance; hasher.inputs[1] <== salt; hasher.out === commitment; component rangeCheck = Num2Bits(64); rangeCheck.in <== balance; component gte = GreaterEqThan(64); gte.in[0] <== balance; gte.in[1] <== threshold; gte.out === 1; } component main {public [commitment, threshold]} = ProveBalance(); 

"אותות עם אילוצים חסרים הם מחלקת הבאגים הנפוצה ביותר במעגלי ZK" (תיעוד circom, סעיף אבטחה). אם אות משמש בחישוב אך אין לו מספיק אילוצים, המוכיח יכול להעביר ערך שרירותי והמאמת יקבל את ההוכחה.

דוגמה לקוד פגיע:

// УЯЗВИМО: нет constraint что out это bit template IsZero() { signal input in; signal output out; signal inv; inv <-- in != 0 ? 1/in : 0; out <-- in == 0 ? 1 : 0; // ЗАБЫЛИ: in * out === 0 и (in * inv - 1 + out) === 0 } 

המאמת מקבל כל pragma circom 2.1.4; include "circomlib/circuits/poseidon.circom"; include "circomlib/circuits/comparators.circom"; template ProveBalance() { signal input balance; // private signal input salt; // private signal input commitment; // public signal input threshold; // public component hasher = Poseidon(2); hasher.inputs[0] <== balance; hasher.inputs[1] <== salt; hasher.out === commitment; component rangeCheck = Num2Bits(64); rangeCheck.in <== balance; component gte = GreaterEqThan(64); gte.in[0] <== balance; gte.in[1] <== threshold; gte.out === 1; } component main {public [commitment, threshold]} = ProveBalance(); מכיוון שאין אילוצים המקשרים בין // УЯЗВИМО: нет constraint что out это bit template IsZero() { signal input in; signal output out; signal inv; inv <-- in != 0 ? 1/in : 0; out <-- in == 0 ? 1 : 0; // ЗАБЫЛИ: in * out === 0 и (in * inv - 1 + out) === 0 } ל-p = 21888242871839275222246405745257275088548364400416034343698204186575808495617.

גלישה באריתמטיקת שדה: Circom עובד בשדה הראשוני p. כל פעולה היא מודולו type Circuit struct { PreImage frontend.Variable `gnark:",secret"` Hash frontend.Variable `gnark:",public"` } func (c *Circuit) Define(api frontend.API) error { mimc, err := mimc.NewMiMC(api) if err != nil { return err } mimc.Write(c.PreImage) result := mimc.Sum() api.AssertIsEqual(result, c.Hash) return nil } . אם הקלטים הם מספרים מהעולם האמיתי (גיל, חותמת זמן), הטווח בטוח. אך בעת הכפלת מספרים גדולים, יש צורך בבדיקת טווח מפורשת דרך snarkjs zkey export solidityverifier, כפי שמוצג בדוגמה.

Gnark (Go) למעגלים מורכבים יותר

אנו מציינים: כאשר המעגל מורכב מדי עבור circom (הוכחות רקורסיביות, אימות חתימת BLS, רכיבים דמויי zkEVM) — gnark:

type Circuit struct { PreImage frontend.Variable `gnark:",secret"` Hash frontend.Variable `gnark:",public"` } func (c *Circuit) Define(api frontend.API) error { mimc, err := mimc.NewMiMC(api) if err != nil { return err } mimc.Write(c.PreImage) result := mimc.Sum() api.AssertIsEqual(result, c.Hash) return nil } 

gnark מהיר פי 10–30 מ-snarkjs בזמן מוכיח עבור מעגלים זהים. לייצור עם משתמשים אמיתיים, זה חשוב: יצירת הוכחה בדפדפן דרך WASM אורכת 3–15 שניות עבור מעגל Groth16 במורכבות בינונית, בעוד שבשרת Go זה אורך 0.1–1 שנייה.

אימות על השרשרת

מאמת Solidity נוצר אוטומטית — snarkjs עושה זאת דרך contract BalanceProofVerifier { IGroth16Verifier public immutable verifier; mapping(bytes32 => bool) public usedNullifiers; function verifyAndExecute( uint[2] calldata a, uint[2][2] calldata b, uint[2] calldata c, uint[2] calldata publicInputs // [commitment, threshold] ) external { bytes32 nullifier = keccak256(abi.encodePacked(a, b, c)); require(!usedNullifiers[nullifier], "Proof already used"); require(verifier.verifyProof(a, b, c, publicInputs), "Invalid proof"); usedNullifiers[nullifier] = true; // ... основная логика } } . אך בייצור, החוזה צריך התאמה:

contract BalanceProofVerifier { IGroth16Verifier public immutable verifier; mapping(bytes32 => bool) public usedNullifiers; function verifyAndExecute( uint[2] calldata a, uint[2][2] calldata b, uint[2] calldata c, uint[2] calldata publicInputs // [commitment, threshold] ) external { bytes32 nullifier = keccak256(abi.encodePacked(a, b, c)); require(!usedNullifiers[nullifier], "Proof already used"); require(verifier.verifyProof(a, b, c, publicInputs), "Invalid proof"); usedNullifiers[nullifier] = true; // ... основная логика } } 

עלות הגז של אימות Groth16 היא בערך 270k גז. ברשת הראשית של Ethereum ב-20 gwei, זה בערך $2–5 לכל אימות. למערכות בתדירות גבוהה, פריסה ב-L2 (Arbitrum, Base) מפחיתה את העלות פי 10–50.

תשתית ליצירת הוכחות

מידע נוסף על טקס ההתקנה המהימנה

עבור Groth16, זה חובה. התהליך:

  1. Powers of Tau אוניברסלי (אנו משתמשים במוכן מ-Hermez/EthSnarks — אלו פרמטרים מאומתים פומבית)
  2. טקס שלב 2 ספציפי למעגל שלך: כל משתתף מוסיף אקראיות משלו
  3. Beacon סופי — מקור אקראי ציבורי (hash של בלוק ביטקוין)

אם לפחות משתתף אחד ישר, הפרמטרים מאובטחים. לפרויקטי ייצור: לפחות 10–20 משתתפים, אימות פומבי של התמליל.

יצירה בצד הלקוח (דפדפן)

לפעולות ברמת ארנק, אנו משתמשים בבניית WebAssembly של snarkjs. קובץ ה-.zkey למעגלים מורכבים שוקל 10–500MB — פתרון: פיצול לחלקים (zkey מקוטע) או שימוש בהורדת סטרימינג. לעומסי ייצור, מוכיח בצד השרת ב-Go עם gnark יעיל יותר.

יצירה בצד השרת (שירות הוכחה)

ארכיטקטורה: לקוח → API → תור (Bull/RabbitMQ) → עובד מוכיח → S3 → Webhook. עובד המוכיח הוא שירות Go עם gnark. קנה מידה אופקי: כל עובד עצמאי, משימות אידמפוטנטיות. למעגלים ברמת zkEVM (מיליארדי אילוצים) — הוכחה ב-GPU דרך CUDA עם האצה של פי 100–1000.

כיצד להתחיל לפתח אפליקציית ZK: 5 שלבים

  1. מפרט מעגל: פורמליזציה של המשימה, בחירת מערכת הוכחה, הגדרת קלטים ציבוריים/פרטיים.
  2. פיתוח מעגל: כתיבת קוד ב-circom/gnark/noir, בדיקות יחידה לאילוצים.
  3. ביקורת מעגל: חיפוש אותות עם אילוצים חסרים, בדיקת תקינות עם אימות פורמלי.
  4. חוזה מאמת: יצירת מאמת Solidity, הוספת לוגיקת nullifier, אינטגרציה עם הפרוטוקול הראשי.
  5. תשתית מוכיח: הגדרת בניית WASM או מוכיח שרת, יצירת API.

לוחות זמנים והיקף

שלב תוכן משך
מפרט מעגל פורמליזציה של המשימה, בחירת מערכת הוכחה, עיצוב קלטים ציבוריים/פרטיים שבוע 1
פיתוח מעגל כתיבת circom/gnark/noir, בדיקות יחידה לאילוצים 2–4 שבועות
ביקורת מעגל חיפוש אותות עם אילוצים חסרים, בדיקת תקינות 1–2 שבועות
חוזה מאמת מאמת Solidity + לוגיקת nullifier + אינטגרציה עם הפרוטוקול הראשי 1–2 שבועות
תשתית מוכיח בניית WASM או מוכיח שרת, API 1–2 שבועות
התקנה מהימנה ארגון טקס (אם Groth16/PLONK-KZG) שבוע 1

סה"כ לאפליקציית ZKP טיפוסית (הוכחת חברות, zkKYC, עסקאות פרטיות): 6–12 שבועות ממפרט ל-mainnet. מערכות מורכבות דמויות zkRollup: 6–18 חודשים עם צוות ייעודי.

רוצים לדון בפרויקט שלכם? הזמינו פיתוח אפליקציית ZK — אנו נעריך את המשימה בחינם ונציע את הארכיטקטורה. להבנה כללית של הטכנולוגיה, עיינו בוויקיפדיה. צרו קשר לייעוץ.