FastPQ FastPQ הוא Iroha זה... STARK נתיב הוכחה עבור השפעות ביצועים שנבחרו. זה לא מחליף ביצוע עסקאות רגיל או הסכמה. עסקאות עדיין מתמשכות. ISI, IVM, ו Sumeragi כרגיל; FastPQ הוא צורב את העד של ההפעלה הדטרמיסטית ומופנה את האפקטים הנמכרים לחלקים של ראיות.
לאינטגרציה הנוכחית של המארח יש שלושה דרכים עיקריות:
העברת נכסים ספרותית שקופה שנעצמה במהלך ביצוע הקלפים Nexus רילייים של מסלול ההוכחה של AXT נושאים קישור FastPQ SCCP סיועי אבטחת הודעות שקופים שמסובלים הוכחה FastPQ במעטפה פתוחה לאמת. להעביר את דרכי העדים העברות ספרותיות ברורות יוצרות כתיבה של העברה מבוססת כאשר ההוראה משתנה משקולות.
חשבון המקור, חשבון היעד, הגדרה של נכס וסכום משקל המשלח והמתקבל לפני ואחרי העברה. ההש נקודת כניסה של העסקה המשמשת כמקצת השה רישום הרשויות המוצא מן החשבון המגיש מאכלת פוסיידון לתסריטים של דלתה אחת. העברת הסבבים משתמשת בתסריט אחד עם דלתות מרובות. במקרה זה, התזונה של פוסידון חד-דלקת חסרת.
בעת סיום הבלוק, Iroha מגדירים את התסריטים האלה על ידי האש נקודת הכניסה. עדת ההוצאה לאחר מכן נושאת הן את חבילות התסריט המקורי והן את החבוצות של המעבר FastPQ שהוכנות למבטא.
כל דלתה של העברה הופכת לשני שורות המעבר:
שורה צורת המפתח הערך מראש לאחר ערך דובד המשלוח asset/<asset-definition>/<source-account>משקל המשלוח לפני המשקל של המשלוח לאחר אשראי לקוח asset/<asset-definition>/<destination-account>המשקל של המקבל לפני המשקל של המקבל לאחר
הערכים המספריים נורמליזמים ליחידות ראיות שלמות. ערך מופרך עבור FastPQ המשתתפים אם הוא לא יכול להיות מוצג כ-לא שלילי u64 בקנה מידה דצימלית שנבחר.
כל חבילת המעבר FastPQ נושאת הכניסה ציבורית המחייבת את ההוכחה לקונקסט של הבלוק והביצוע:
הכניסות משמעות dsidזיהוי מסלול נתונים מקודד כבייטים קטנים. slotזמן יצירת בלוק הופך לננו שניות old_rootשורש מדינת ההורים המוצא מהעד להוצאה להורג new_rootשורש פוסט-מדינה המוצא מהעד להוצאה להורג. perm_rootמחויבות של פוסיידון לגבי רשיונות תפקיד פעיל tx_set_hashהאש על העסקה הסורדרת ו- time-trigger entrypoint hashs
המארח משתמש ב- fastpq-lane-balanced כפרמטר קנוני הקבוע עבור סוגי אלה.
מודל מתמטי סעיף זה מתאר את האריתמטיקה המבוצעת על ידי המבחן והמתאשר הנוכחי Rust. כל פעולות השדה הבאות הן מעל שדה ראשוני של Goldilocks:
F = F p , p = 2 64 − 2 32 + 1 F = \mathbb{F}_p,\qquad p = 2^{64} - 2^{32} + 1 F = F p , p = 2 64 − 2 32 + 1
FastPQ משתמש ב-Poseidon2 על פני F עבור מחויבויות שדה. לספוגה יש רוחב t = 3, שיעור r = 2 ויכולת 1. ההש שואב אלמנטים של שדה בלוקי שיעור-2 ומוסיף אלמנט שדה אחד 1 לפני הפערמוטציה הסופית.
H F ( x 0 , … , x m − 1 ) = Poseidon2 F ( x 0 , … , x m − 1 , 1 ) H_F(x_0,\ldots,x_{m-1}) = \operatorname{Poseidon2}_F(x_0,\ldots,x_{m-1},1) H F ( x 0 , … , x m − 1 ) = Poseidon2 F ( x 0 , … , x m − 1 , 1 )
חוטים באייטים מורכבים לצדדים קטנים של 7 בייטים כך שכל צעד הוא מתחת p:
pack ( b ) j = ∑ i = 0 6 b 7 j + i 2 8 i , 0 ≤ pack ( b ) j < p \operatorname{pack}(b)_j = \sum_{i=0}^{6} b_{7j+i}2^{8i},\qquad 0 \leq \operatorname{pack}(b)_j < p pack ( b ) j = i = 0 ∑ 6 b 7 j + i 2 8 i , 0 ≤ pack ( b ) j < p
ה-Hashes של שדות נפרדים על ידי תחום מתייצגים כ:
H D ( m ) = H F ( ∣ pack ( D ) ∣ , pack ( D ) , ∣ pack ( m ) ∣ , pack ( m ) ) H_D(m) = H_F( |\operatorname{pack}(D)|,\operatorname{pack}(D), |\operatorname{pack}(m)|,\operatorname{pack}(m) ) H D ( m ) = H F ( ∣ pack ( D ) ∣ , pack ( D ) , ∣ pack ( m ) ∣ , pack ( m ))
עבור האש'ים שמתחילים מ-byte-domain digests, FastPQ מאפז את שמונה באייטים קטנים הראשונים לתוך השדה:
seed ( D ) = le64 ( Hash ( D ) [ 0..8 ] ) m o d p \operatorname{seed}(D)= \operatorname{le64}(\operatorname{Hash}(D)[0..8])\bmod p seed ( D ) = le64 ( Hash ( D ) [ 0..8 ]) mod p
כאן Hash פירושו iroha_crypto::Hash::new של Iroha, דיגסט של Blake2bVar ב-32 בייטים, אלא אם כן נוסחה מכניסה במפורש את פוזידון2 או SHA-256.
ארתמטיקה של השדה ה- Rust קוד מייצג אלמנטים שדה כקנוניים. u64 הערכים ב [0,p). הוספת וחסרת הן:
a + F b = ( a + b ) m o d p a +_F b = (a+b)\bmod p a + F b = ( a + b ) mod p
a − F b = ( a − b ) m o d p a -_F b = (a-b)\bmod p a − F b = ( a − b ) mod p
ההרכבה מחליטה תחילה את המוצר של 128-ביט:
a ⋅ b = lo + 2 64 hi a\cdot b = \operatorname{lo} + 2^{64}\operatorname{hi} a ⋅ b = lo + 2 64 hi
הפחתת גולדיקים משמשת את זהות:
2 64 ≡ 2 32 − 1 ( m o d p ) 2^{64}\equiv2^{32}-1\pmod p 2 64 ≡ 2 32 − 1 ( mod p )
אם:
hi = hi l o + 2 32 hi h i \operatorname{hi}=\operatorname{hi}_{lo}+2^{32}\operatorname{hi}_{hi} hi = hi l o + 2 32 hi hi
ואז המפחידה מחושבת:
lo + 2 32 hi l o − hi l o − hi h i ( m o d p ) \operatorname{lo} +2^{32}\operatorname{hi}_{lo} -\operatorname{hi}_{lo} -\operatorname{hi}_{hi} \pmod p lo + 2 32 hi l o − hi l o − hi hi ( mod p )
השימוש מוסיף או מוריד p באופן תנאי עד שהתוצאה היא קנוניקה. מספרים שלמים חתומים, כגון דלתות איזון, משולבים על ידי:
field ( x ) = x m o d p , 0 ≤ field ( x ) < p \operatorname{field}(x)=x\bmod p,\qquad 0\leq\operatorname{field}(x)<p field ( x ) = x mod p , 0 ≤ field ( x ) < p
פוסיידון 2 מצב הפרמוטציה של פוסידון2 הוא:
x = ( x 0 , x 1 , x 2 ) ∈ F 3 \mathbf{x}=(x_0,x_1,x_2)\in F^3 x = ( x 0 , x 1 , x 2 ) ∈ F 3
קופסת ה-S שלה היא:
S ( x ) = x 5 S(x)=x^5 S ( x ) = x 5
FastPQ משתמשת בארבעה סיבובים מלאים, חמישים ושבע סיבובים חלקיים, ולאחר מכן ארבעה סיבים מלאים נוספים. סיבוב מלא עם קבועות עגולות c_r = (c_{r,0}, c_{r,1}, c_{r,2}) הוא:
x ′ = M ⋅ [ S ( x 0 + c r , 0 ) S ( x 1 + c r , 1 ) S ( x 2 + c r , 2 ) ] \mathbf{x}' = M\cdot \begin{bmatrix} S(x_0+c_{r,0})\\ S(x_1+c_{r,1})\\ S(x_2+c_{r,2}) \end{bmatrix} x ′ = M ⋅ S ( x 0 + c r , 0 ) S ( x 1 + c r , 1 ) S ( x 2 + c r , 2 )
סיבוב חלקי הוא:
x ′ = M ⋅ [ S ( x 0 + c r , 0 ) x 1 + c r , 1 x 2 + c r , 2 ] \mathbf{x}' = M\cdot \begin{bmatrix} S(x_0+c_{r,0})\\ x_1+c_{r,1}\\ x_2+c_{r,2} \end{bmatrix} x ′ = M ⋅ S ( x 0 + c r , 0 ) x 1 + c r , 1 x 2 + c r , 2
כל התוספות וההפכבות נמצאים F. הקנוניקה MDS המטריקס הוא:
M = [ 0x982513a23d22b592 0xa3115db8cf1d9c90 0x46ba684b9eee84b7 0xbe3dce25491db768 0xfb0a6f731943519f 0xfce5bd953cde1896 0xe624719c41eb1a09 0xd2221b0f1aa2ebc4 0x1ab5e60d03ad44bc ] M= \begin{bmatrix} \texttt{0x982513a23d22b592} & \texttt{0xa3115db8cf1d9c90} & \texttt{0x46ba684b9eee84b7}\\ \texttt{0xbe3dce25491db768} & \texttt{0xfb0a6f731943519f} & \texttt{0xfce5bd953cde1896}\\ \texttt{0xe624719c41eb1a09} & \texttt{0xd2221b0f1aa2ebc4} & \texttt{0x1ab5e60d03ad44bc} \end{bmatrix} M = 0x982513a23d22b592 0xbe3dce25491db768 0xe624719c41eb1a09 0xa3115db8cf1d9c90 0xfb0a6f731943519f 0xd2221b0f1aa2ebc4 0x46ba684b9eee84b7 0xfce5bd953cde1896 0x1ab5e60d03ad44bc
האש של השדה מתחיל ממצב אפס. עבור כל בלוק שלם של שיעור-2 (u,v):
( x 0 , x 1 , x 2 ) ← Poseidon2 ( x 0 + u , x 1 + v , x 2 ) (x_0,x_1,x_2)\leftarrow \operatorname{Poseidon2}(x_0+u,x_1+v,x_2) ( x 0 , x 1 , x 2 ) ← Poseidon2 ( x 0 + u , x 1 + v , x 2 )
בלוק הסופי מוסיף את 1 אלמנט הכביסה לפני שינוי אחרון. התוצאה היא x_0.
המארח מקודד ID של חלל נתונים על ידי כתיבת הערך u64 שלו בשמונה בייטים הראשונים של 16 בייטים:
dsid_bytes ( d ) [ 0..8 ] = le64 ( d ) , dsid_bytes ( d ) [ 8..16 ] = 0 \operatorname{dsid\_bytes}(d)[0..8]=\operatorname{le64}(d), \qquad \operatorname{dsid\_bytes}(d)[8..16]=0 dsid_bytes ( d ) [ 0..8 ] = le64 ( d ) , dsid_bytes ( d ) [ 8..16 ] = 0
זמן היצירה של הבלוק הופך ממילי שניות לננו שניות:
slot = saturating_mul ( creation_time_ms , 1 , 000 , 000 ) \operatorname{slot}=\operatorname{saturating\_mul} (\operatorname{creation\_time\_ms},1{,}000{,}000) slot = saturating_mul ( creation_time_ms , 1 , 000 , 000 )
ה-hash המוגדר עבור העסקאות הוא חיש של בייט דומיין על חשישי נקודת כניסה מסורטת:
tx_set_hash = Hash ( fastpq:v1:tx_set ∥ h 0 ∥ ⋯ ∥ h n − 1 ) \operatorname{tx\_set\_hash} = \operatorname{Hash}( \texttt{fastpq:v1:tx\_set}\|h_0\|\cdots\|h_{n-1} ) tx_set_hash = Hash ( fastpq:v1:tx_set ∥ h 0 ∥ ⋯ ∥ h n − 1 )
כאשר h_i הוא מסוג של העסקאות ו- time-trigger entry point hashes. בתוכנת הציבורית IO, אם perm_root או tx_set_hash כולן אפס, המבטא מילא ערכי ההפוך:
perm_root = { 0 32 , if there are no permission hashes Hash ( fastpq:v1:perm_root ∥ p 0 ∥ ⋯ ∥ p n − 1 ) , otherwise \operatorname{perm\_root} = \begin{cases} 0^{32},& \text{if there are no permission hashes}\\ \operatorname{Hash}(\texttt{fastpq:v1:perm\_root}\|p_0\|\cdots\|p_{n-1}), & \text{otherwise} \end{cases} perm_root = { 0 32 , Hash ( fastpq:v1:perm_root ∥ p 0 ∥ ⋯ ∥ p n − 1 ) , if there are no permission hashes otherwise
tx_set_hash f a l l b a c k = Hash ( fastpq:v1:tx_set ∥ ordering_hash ) \operatorname{tx\_set\_hash}_{fallback} = \operatorname{Hash}(\texttt{fastpq:v1:tx\_set}\|\operatorname{ordering\_hash}) tx_set_hash f a ll ba c k = Hash ( fastpq:v1:tx_set ∥ ordering_hash )
נורמליזציה מספרית עבור כל דלתה של העברה, סולם הדצימלי היעד הוא הסולם המקסימלי שנחתך על פני הכמות ושני תמונות השוויון:
s = max ( scale ( a ) , scale ( f 0 ) , scale ( f 1 ) , scale ( t 0 ) , scale ( t 1 ) ) s = \max( \operatorname{scale}(a), \operatorname{scale}(f_0), \operatorname{scale}(f_1), \operatorname{scale}(t_0), \operatorname{scale}(t_1) ) s = max ( scale ( a ) , scale ( f 0 ) , scale ( f 1 ) , scale ( t 0 ) , scale ( t 1 ))
א Numeric ערך עם mantissa m וסטנדרטים q הוא מקובל רק כאשר m >= 0 ו q <= s. זה FastPQ ערך העדים הוא:
norm s ( m , q ) = m ⋅ 1 0 s − q \operatorname{norm}_s(m,q)=m\cdot10^{s-q} norm s ( m , q ) = m ⋅ 1 0 s − q
תוצאה נורמלית צריכה להתאים ל u64.
הוראות קנוניות לפני בניית עקבות, המגרש מסודר לפי מפתח המעבר, מעמד הפעולה והאינדקס של הזרם המקורי:
r ( Transfer ) = 0 , r ( Mint ) = 1 , r ( Burn ) = 2 , r ( RoleGrant ) = 3 , r ( RoleRevoke ) = 4 , r ( MetaSet ) = 5 r(\operatorname{Transfer})=0,\quad r(\operatorname{Mint})=1,\quad r(\operatorname{Burn})=2,\quad r(\operatorname{RoleGrant})=3,\quad r(\operatorname{RoleRevoke})=4,\quad r(\operatorname{MetaSet})=5 r ( Transfer ) = 0 , r ( Mint ) = 1 , r ( Burn ) = 2 , r ( RoleGrant ) = 3 , r ( RoleRevoke ) = 4 , r ( MetaSet ) = 5
מחויבות ההזמנה היא חיש שדה Poseidon2 על השלט fastpq:v1:ordering והצפנה Norito של המעברים הסורדרים:
ordering_hash = H F ( ∣ P ( D o ) ∣ , P ( D o ) , ∣ P ( E ( T ⋆ ) ) ∣ , P ( E ( T ⋆ ) ) ) \operatorname{ordering\_hash} = H_F( |P(D_o)|,P(D_o),|P(E(T^\star))|,P(E(T^\star)) ) ordering_hash = H F ( ∣ P ( D o ) ∣ , P ( D o ) , ∣ P ( E ( T ⋆ )) ∣ , P ( E ( T ⋆ )))
כאשר P הוא ארגון של 7 בייטים, E הוא הקודינג של Norito, D_o הוא fastpq:v1:ordering, ו T* הוא רשימת המעבר הסורדרת.
משוואות העברה עבור סכום העברה a, משקל המשלח f, ומשקל המתקבל t, FastPQ מאשר את הערכים הנורמליזות של עדים לפני הקמת מעקב:
f 0 ≥ a f_0 \geq a f 0 ≥ a
f 1 = f 0 − a f_1 = f_0 - a f 1 = f 0 − a
t 1 = t 0 + a t_1 = t_0 + a t 1 = t 0 + a
השורות של המעבר ע"י:
Δ sender = f 1 − f 0 = − a \Delta_{\text{sender}} = f_1 - f_0 = -a Δ sender = f 1 − f 0 = − a
Δ receiver = t 1 − t 0 = a \Delta_{\text{receiver}} = t_1 - t_0 = a Δ receiver = t 1 − t 0 = a
בתוך עקבות, דלתות חתומות מופחתות ל F:
δ i = ( post i − pre i ) m o d p \delta_i = (\operatorname{post}_i - \operatorname{pre}_i)\bmod p δ i = ( post i − pre i ) mod p
הדגיזת העברת דלתה אחת אופציונלית מחייבת את תמונת העברה המוצפנת:
d transfer = PoseidonHashBytes ( E ( from ) ∥ E ( to ) ∥ E ( asset ) ∥ E ( a ) ∥ batch_hash ) d_{\text{transfer}} = \operatorname{PoseidonHashBytes}( E(\text{from})\|E(\text{to})\|E(\text{asset})\|E(a)\|\text{batch\_hash} ) d transfer = PoseidonHashBytes ( E ( from ) ∥ E ( to ) ∥ E ( asset ) ∥ E ( a ) ∥ batch_hash )
עבור תמונות העברת דלתות רבות, פורמט הנוכחי דורש כי תרגום רמה הגבוהה ביותר הזה יהיה חסר.
הרשות המארחת מאכלת לתוצאות העברה היא:
d authority = Hash ( iroha:fastpq:v1:authority| ∥ E ( authority_account ) ) d_{\text{authority}} = \operatorname{Hash}(\texttt{iroha:fastpq:v1:authority|}\|E(\text{authority\_account})) d authority = Hash ( iroha:fastpq:v1:authority| ∥ E ( authority_account ))
שורות עקבות תן לרשימת המעבר הסורדרת להכיל שורות אמיתיות n. אורך עקבות הוא הכוח הבא של שני:
N = 2 ⌈ log 2 ( max ( 1 , n ) ) ⌉ N = 2^{\lceil\log_2(\max(1,n))\rceil} N = 2 ⌈ l o g 2 ( m a x ( 1 , n ))⌉
שורות 0..n-1 פעילות; שורות n..N-1 הן שורות של כביסה. לכל שורה אמיתית יש קבוצה אחת של סלקטור פעולה:
s active = s transfer + s mint + s burn + s role_grant + s role_revoke + s meta_set s_{\text{active}} = s_{\text{transfer}}+ s_{\text{mint}}+ s_{\text{burn}}+ s_{\text{role\_grant}}+ s_{\text{role\_revoke}}+ s_{\text{meta\_set}} s active = s transfer + s mint + s burn + s role_grant + s role_revoke + s meta_set
כל עמודי הסלקטור הם בוליים:
s ( s − 1 ) = 0 s(s-1)=0 s ( s − 1 ) = 0
שורות חיפוש רשיונות הן בדיוק שורות של סיוע לתפקידים ושל ביטול תפקידים:
s perm = s role_grant + s role_revoke s_{\text{perm}} = s_{\text{role\_grant}} + s_{\text{role\_revoke}} s perm = s role_grant + s role_revoke
עבור שורות ניצול מספרים:
δ i = value_new i , 0 − value_old i , 0 \delta_i = \operatorname{value\_new}_{i,0} - \operatorname{value\_old}_{i,0} δ i = value_new i , 0 − value_old i , 0
הבניין גם עוקב אחרי דלתות שפועלות לפי נכס:
R i ( a ) = R i − 1 ( a ) + δ i for transfer, mint, and burn rows of asset a R_i(a)=R_{i-1}(a)+\delta_i \quad\text{for transfer, mint, and burn rows of asset }a R i ( a ) = R i − 1 ( a ) + δ i for transfer, mint, and burn rows of asset a
רק שורות מנטה ומשרפות מעודכנות את ספירת האספקה:
S i ( a ) = S i − 1 ( a ) + { δ i , if row i is mint or burn 0 , otherwise S_i(a)=S_{i-1}(a)+ \begin{cases} \delta_i,& \text{if row }i\text{ is mint or burn}\\ 0,& \text{otherwise} \end{cases} S i ( a ) = S i − 1 ( a ) + { δ i , 0 , if row i is mint or burn otherwise
עמודי מעקב של נתונים ומרחבי נתונים הם חשיש שדה המוצא לפני מתרייליזציה בשורה:
metadata_hash = { 0 , if metadata is empty H D ( E ( metadata ) ) , otherwise \operatorname{metadata\_hash} = \begin{cases} 0,& \text{if metadata is empty}\\ H_D(E(\text{metadata})),& \text{otherwise} \end{cases} metadata_hash = { 0 , H D ( E ( metadata )) , if metadata is empty otherwise
dsid_trace = H D ( public_input_dsid ) \operatorname{dsid\_trace}=H_D(\operatorname{public\_input\_dsid}) dsid_trace = H D ( public_input_dsid )
ה- metadata hash, ה- dataspace hash, ו- slot הם יציבים לאורך שורות עקבות סמוכות:
metadata_hash i = metadata_hash i + 1 \operatorname{metadata\_hash}_i=\operatorname{metadata\_hash}_{i+1} metadata_hash i = metadata_hash i + 1
dsid i = dsid i + 1 \operatorname{dsid}_i=\operatorname{dsid}_{i+1} dsid i = dsid i + 1
slot i = slot i + 1 \operatorname{slot}_i=\operatorname{slot}_{i+1} slot i = slot i + 1
להעביר עמודי מרקל שורות העברה נושאות מסלול מרקל נדיר של 32 מדרגות. אם הוכחה מארחת חסרה, הסבר סינתז מסלול דטרמיניסטי מפתח השורה, לפני איזון, ואם השורה היא הצד המשלח או הקבל.
למסלולים סינתטיים, מלח הטעם הוא fastpq:smt:from עבור שורות המשלוחים ו fastpq:smt:to עבור שורות הקבל:
K = Hash ( fastpq:smt:key| ∥ salt ∥ key ) K = \operatorname{Hash}(\texttt{fastpq:smt:key|}\|\operatorname{salt}\|\operatorname{key}) K = Hash ( fastpq:smt:key| ∥ salt ∥ key )
V = Hash ( fastpq:smt:value| ∥ salt ∥ le64 ( balance ) ) V = \operatorname{Hash}(\texttt{fastpq:smt:value|}\|\operatorname{salt}\|\operatorname{le64}(\operatorname{balance})) V = Hash ( fastpq:smt:value| ∥ salt ∥ le64 ( balance ))
b ℓ = bit ℓ ( K ) b_\ell = \operatorname{bit}_\ell(K) b ℓ = bit ℓ ( K )
s ℓ = Hash ( fastpq:smt:sibling| ∥ le64 ( ℓ ) ∥ K ∥ le64 ( balance ) ∥ salt ) s_\ell = \operatorname{Hash}( \texttt{fastpq:smt:sibling|}\| \operatorname{le64}(\ell)\|K\|\operatorname{le64}(\operatorname{balance})\|\operatorname{salt} ) s ℓ = Hash ( fastpq:smt:sibling| ∥ le64 ( ℓ ) ∥ K ∥ le64 ( balance ) ∥ salt )
העלים הסינתטיים והרכיבים הפנימיים הם:
L = Hash ( fastpq:smt:leaf| ∥ K ∥ V ) L = \operatorname{Hash}( \texttt{fastpq:smt:leaf|}\| K\|V ) L = Hash ( fastpq:smt:leaf| ∥ K ∥ V )
N ℓ + 1 = Hash ( fastpq:smt:node| ∥ left ℓ ∥ right ℓ ) N_{\ell+1} = \operatorname{Hash}( \texttt{fastpq:smt:node|}\| \operatorname{left}_\ell\| \operatorname{right}_\ell ) N ℓ + 1 = Hash ( fastpq:smt:node| ∥ left ℓ ∥ right ℓ )
האתר רשום את הביט b_l, אחיו s_l, הערך הכניסה x_l, והערך ההוצא x_{l+1} בכל רמה. עם קונבנציון ענף של הקוד:
( left ℓ , right ℓ ) = { ( s ℓ , x ℓ ) , b ℓ = 0 ( x ℓ , s ℓ ) , b ℓ = 1 (\operatorname{left}_\ell,\operatorname{right}_\ell)= \begin{cases} (s_\ell,x_\ell),& b_\ell=0\\ (x_\ell,s_\ell),& b_\ell=1 \end{cases} ( left ℓ , right ℓ ) = { ( s ℓ , x ℓ ) , ( x ℓ , s ℓ ) , b ℓ = 0 b ℓ = 1
חשיבות רשות שורות תורם וביטול תפקיד האש את העד הרשאה:
h perm = H F ( P ( role_id ∥ permission_id ∥ epoch l e ) ) h_{\text{perm}} = H_F(P(\operatorname{role\_id}\|\operatorname{permission\_id}\|\operatorname{epoch}_{le})) h perm = H F ( P ( role_id ∥ permission_id ∥ epoch l e ))
טבלה הרשיונות המארחת מסווגת את הכניסות לפי בייטים תפקיד, בייטים רשיון, ובייטים תקופה, ואז יוצרת עץ Poseidon2 Merkle:
M 0 [ j ] = h perm , j M_0[j]=h_{\text{perm},j} M 0 [ j ] = h perm , j
M k + 1 [ j ] = H F ( seed ( fastpq:v1:poseidon_node ) , M k [ 2 j ] , M k [ 2 j + 1 ] ) M_{k+1}[j] = H_F(\operatorname{seed}(\texttt{fastpq:v1:poseidon\_node}),M_k[2j],M_k[2j+1]) M k + 1 [ j ] = H F ( seed ( fastpq:v1:poseidon_node ) , M k [ 2 j ] , M k [ 2 j + 1 ])
רמות רוחב מוזר משכפלות את האלמנט האחרון.
התחייבות למעקב עבור כל עמודת עקבות c, FastPQ מפרט תחילה את הערכים של העמודה על שטח עקבות ומכניס את וקטור הקואפיצנט.
C c = H F ( seed ( fastpq:v1:trace:column: c ) , coeffs ( c ) ) C_c = H_F( \operatorname{seed}(\texttt{fastpq:v1:trace:column:}c), \operatorname{coeffs}(c) ) C c = H F ( seed ( fastpq:v1:trace:column: c ) , coeffs ( c ))
שורש העקבות הוא שורש פוזידון2 מרקל על מחויבות עמודות:
R trace = MerkleRoot ( C 0 , … , C m − 1 ) R_{\text{trace}} = \operatorname{MerkleRoot}(C_0,\ldots,C_{m-1}) R trace = MerkleRoot ( C 0 , … , C m − 1 )
ההתחייבות הסופית של עקבות היא חישב בייט על השטח, קבוצת פרמטרים, צורה של עקבות, דיגסטות עמודות וקור עקבות:
commitment = Hash ( len ( D c ) ∥ D c ∥ len ( parameter ) ∥ parameter ∥ n ∥ N ∥ m ∥ C 0 ∥ ⋯ ∥ C m − 1 ∥ R trace ) \operatorname{commitment} = \operatorname{Hash}( \operatorname{len}(D_c)\|D_c\| \operatorname{len}(\text{parameter})\|\text{parameter}\| n\|N\|m\|C_0\|\cdots\|C_{m-1}\|R_{\text{trace}} ) commitment = Hash ( len ( D c ) ∥ D c ∥ len ( parameter ) ∥ parameter ∥ n ∥ N ∥ m ∥ C 0 ∥ ⋯ ∥ C m − 1 ∥ R trace )
כאשר D_c הוא fastpq:v1:trace_commitment.
AIR מרכיב ערך הרכב V1 AIR הוא שילוב ליניארי של שרידים מקומיים בשורה. הדגימות של הטרנסקריפט מציגות שני אתגרים:
α 0 , α 1 ∈ F \alpha_0,\alpha_1 \in F α 0 , α 1 ∈ F
עבור כל זוג שורות סמוך (i,i+1), המבחן מחושב:
A i = ∑ j α j m o d 2 ρ i , j A_i=\sum_j \alpha_{j\bmod2}\rho_{i,j} A i = j ∑ α j mod 2 ρ i , j
השאריות rho הן, בסדר הקוד:
ρ = s ( s − 1 ) for each selector column \rho=s(s-1) \quad\text{for each selector column} ρ = s ( s − 1 ) for each selector column
ρ = s active − ( s transfer + s mint + s burn + s role_grant + s role_revoke + s meta_set ) \rho = s_{\text{active}} - (s_{\text{transfer}}+s_{\text{mint}}+s_{\text{burn}}+ s_{\text{role\_grant}}+s_{\text{role\_revoke}}+s_{\text{meta\_set}}) ρ = s active − ( s transfer + s mint + s burn + s role_grant + s role_revoke + s meta_set )
ρ = s perm − ( s role_grant + s role_revoke ) \rho = s_{\text{perm}}-(s_{\text{role\_grant}}+s_{\text{role\_revoke}}) ρ = s perm − ( s role_grant + s role_revoke )
ρ = s active , i + 1 ( 1 − s active , i ) \rho = s_{\text{active},i+1}(1-s_{\text{active},i}) ρ = s active , i + 1 ( 1 − s active , i )
עבור שורות עם עמודות מספריות:
ρ = ( s transfer + s mint + s burn ) ⋅ ( ( value_new 0 − value_old 0 ) − δ ) \rho = (s_{\text{transfer}}+s_{\text{mint}}+s_{\text{burn}}) \cdot ((\operatorname{value\_new}_{0}-\operatorname{value\_old}_{0})-\delta) ρ = ( s transfer + s mint + s burn ) ⋅ (( value_new 0 − value_old 0 ) − δ )
ובשביל עמודי ההקשר של הסבקה יציבים:
ρ = metadata_hash i − metadata_hash i + 1 \rho = \operatorname{metadata\_hash}_i-\operatorname{metadata\_hash}_{i+1} ρ = metadata_hash i − metadata_hash i + 1
ρ = dsid i − dsid i + 1 \rho = \operatorname{dsid}_i-\operatorname{dsid}_{i+1} ρ = dsid i − dsid i + 1
ρ = slot i − slot i + 1 \rho = \operatorname{slot}_i-\operatorname{slot}_{i+1} ρ = slot i − slot i + 1
המבחין מחשוב מחדש את A_i עבור פתיחות שורות שנלקחו בדגם ומבדק אותו עם הערך המרכיב שהוכרז על פי שורש מרקל של AIR.
מוצר חיפוש אספנת החיפוש הרשיונות משתמשת באתגר Fiat-Shamir gamma. במהלך הערכות ההרחבה במדרגה נמוכה של s_perm וperm_hash, המוצר המשך הוא:
z 0 = 1 z_0=1 z 0 = 1
z i + 1 = { z i ⋅ ( w i + γ ) , s perm , i ≠ 0 z i , s perm , i = 0 z_{i+1}= \begin{cases} z_i\cdot(w_i+\gamma),& s_{\text{perm},i}\ne0\\ z_i,& s_{\text{perm},i}=0 \end{cases} z i + 1 = { z i ⋅ ( w i + γ ) , z i , s perm , i = 0 s perm , i = 0
רישומי ההוכחה:
lookup_grand_product = H F ( z 0 , z 1 , … ) \operatorname{lookup\_grand\_product}=H_F(z_0,z_1,\ldots) lookup_grand_product = H F ( z 0 , z 1 , … )
התרחבות בקנה מידה נמוך אם omega_T הוא הגנרטור של תחום עקבות, omega_E הוא גנרטור תחום הערכה, ו g הוא הקוסט המוגדר. עבור עמוד עקבות עם ערכים v_i, האינטרפולציה מייצרת קואפצינטים a_j כגון:
f ( ω T i ) = v i f(\omega_T^i)=v_i f ( ω T i ) = v i
התרחבות של מעלות נמוכות מעריכה את אותו פולינום על הקוסט:
LDE f ( i ) = f ( g ⋅ ω E i ) \operatorname{LDE}_f(i)=f(g\cdot\omega_E^i) LDE f ( i ) = f ( g ⋅ ω E i )
ההשפעה מחליטה את זה על ידי כפול הקואפיצ'ינטים בכוחות של הקוסט המוקלף לפני FFT:
a j ′ = a j g j a'_j = a_j g^j a j ′ = a j g j
ולאחר מכן הערכה a' על תחום ההערכה.
CPU FFT הוא טרנספורמציה קולי-טוקי רידקטיבית של רדיקס-2 על פני הכניסות הפוכה בביט. באורך שלב L, אורך חצי שלב H=L/2, וקור שלב:
ω L = ω N / L \omega_L=\omega^{N/L} ω L = ω N / L
כל פרפר מחשוב:
u = x j u=x_j u = x j
v = x j + H ⋅ ω L j v=x_{j+H}\cdot\omega_L^j v = x j + H ⋅ ω L j
x j ′ = u + v , x j + H ′ = u − v x_j'=u+v,\qquad x_{j+H}'=u-v x j ′ = u + v , x j + H ′ = u − v
ההפך FFT מבצע את אותו טרנספורמציה עם omega^{-1} ומגדלים על ידי גודל תחום ההפוך:
IFFT ( x ) = N − 1 ⋅ FFT ω − 1 ( x ) \operatorname{IFFT}(x)=N^{-1}\cdot\operatorname{FFT}_{\omega^{-1}}(x) IFFT ( x ) = N − 1 ⋅ FFT ω − 1 ( x )
שורשים קטלוג מתואמים לפני השימוש:
ω 2 k = 1 \omega^{2^k}=1 ω 2 k = 1
ω 2 k − 1 ≠ 1 ( k > 0 ) \omega^{2^{k-1}}\ne1\qquad(k>0) ω 2 k − 1 = 1 ( k > 0 )
עבור דומנים קטלניים יותר המוצאים מהשורש של הקאטלוג, הגנרטור הוא:
ω ℓ = ω max 2 k max − ℓ \omega_{\ell}=\omega_{\max}^{2^{k_{\max}-\ell}} ω ℓ = ω m a x 2 k m a x − ℓ
רצועות ופרחים לאחר LDE, FastPQ מסדרת את כל שורה בכל עמודי LDE. עבור עמודות m:
r i = H F ( i , m , x i , 0 , x i , 1 , … , x i , m − 1 ) r_i = H_F(i,m,x_{i,0},x_{i,1},\ldots,x_{i,m-1}) r i = H F ( i , m , x i , 0 , x i , 1 , … , x i , m − 1 )
אם ה-hashes של שורות עדיין נמצאים על תחום העקבות ולא על תחום ההערכה, הסבר מרחיב ומרחיב את עמוד ה-hush של שורה אחת עם אותו תהליך coset LDE.
פתיחות מרקל הערכים LDE מתקבצים לחתיכות של:
B lde = 8 ⋅ fri_arity B_{\text{lde}}=8\cdot\operatorname{fri\_arity} B lde = 8 ⋅ fri_arity
כל חתיכה של עץ היא:
L j = H D ( j ∥ v j B ∥ ⋯ ∥ v j B + B − 1 ) L_j=H_D(j\|v_{jB}\|\cdots\|v_{jB+B-1}) L j = H D ( j ∥ v j B ∥ ⋯ ∥ v j B + B − 1 )
הוריו של מרקל הם:
P j = H F ( seed ( fastpq:v1:trace:node ) , L 2 j , L 2 j + 1 ) P_j = H_F(\operatorname{seed}(\texttt{fastpq:v1:trace:node}),L_{2j},L_{2j+1}) P j = H F ( seed ( fastpq:v1:trace:node ) , L 2 j , L 2 j + 1 )
רמות מוזרות משכפלות את הערך האחרון. נתיבי השאלות מאושרים על ידי חיש שמאל או ימין בהתאם לשוויון האינדקס של דף השאלות בכל רמה.
עבור עץ עם אינדקס i, מסלול (s_0,\ldots,s_{d-1}) מתבונן נגד שורש R על ידי חוזר:
y 0 = L i y_0=L_i y 0 = L i
y k + 1 = { H F ( seed ( fastpq:v1:trace:node ) , y k , s k ) , ⌊ i / 2 k ⌋ ≡ 0 ( m o d 2 ) H F ( seed ( fastpq:v1:trace:node ) , s k , y k ) , ⌊ i / 2 k ⌋ ≡ 1 ( m o d 2 ) y_{k+1}= \begin{cases} H_F(\operatorname{seed}(\texttt{fastpq:v1:trace:node}),y_k,s_k), & \lfloor i/2^k\rfloor \equiv 0 \pmod 2\\ H_F(\operatorname{seed}(\texttt{fastpq:v1:trace:node}),s_k,y_k), & \lfloor i/2^k\rfloor \equiv 1 \pmod 2 \end{cases} y k + 1 = { H F ( seed ( fastpq:v1:trace:node ) , y k , s k ) , H F ( seed ( fastpq:v1:trace:node ) , s k , y k ) , ⌊ i / 2 k ⌋ ≡ 0 ( mod 2 ) ⌊ i / 2 k ⌋ ≡ 1 ( mod 2 )
הצ'ק עובר רק כאשר:
y d = R y_d=R y d = R
AIR רצועות עורות של עקבות הן:
L i air = H D ( i ∥ m ∥ x i , 0 ∥ ⋯ ∥ x i , m − 1 ) L^{\text{air}}_i = H_D(i\|m\|x_{i,0}\|\cdots\|x_{i,m-1}) L i air = H D ( i ∥ m ∥ x i , 0 ∥ ⋯ ∥ x i , m − 1 )
AIR עלים מרכיבים הם:
L i comp = H D ( i ∥ A i ) L^{\text{comp}}_i = H_D(i\|A_i) L i comp = H D ( i ∥ A i )
פתיחת השאלות LDE בודקת גם אם הערך שנפתח באינדקס ההערכה i נוכח בחלקו המאודן:
chunk_index = ⌊ i B lde ⌋ \operatorname{chunk\_index}=\left\lfloor\frac{i}{B_{\text{lde}}}\right\rfloor chunk_index = ⌊ B lde i ⌋
chunk_offset = i m o d B lde \operatorname{chunk\_offset}=i\bmod B_{\text{lde}} chunk_offset = i mod B lde
chunk [ chunk_offset ] = v i \operatorname{chunk}[\operatorname{chunk\_offset}]=v_i chunk [ chunk_offset ] = v i
FRI קפד FRI מחויב AIR הערכות הרכב. לכל סיבוב l, הדגימות של הטרנסקריפט מאתגר. beta_l. שכבה מופשטת למספר רב של האריטי על ידי חזרה על הערך האחרון. כל קבוצה בגודל האריטי מתפוגגת ל:
y l + 1 , j = ∑ k = 0 a − 1 y l , j a + k β l k y_{l+1,j} = \sum_{k=0}^{a-1} y_{l,ja+k}\beta_l^k y l + 1 , j = k = 0 ∑ a − 1 y l , ja + k β l k
כאשר a הוא האריטי של FRI. המבחין בודק, עבור כל שרשרת חיפוש שנבחרה בדוגמה, כי:
y l + 1 , ⌊ i / a ⌋ = ∑ k = 0 a − 1 y l , ⌊ i / a ⌋ a + k β l k y_{l+1,\lfloor i/a\rfloor} = \sum_{k=0}^{a-1} y_{l,\lfloor i/a\rfloor a+k}\beta_l^k y l + 1 , ⌊ i / a ⌋ = k = 0 ∑ a − 1 y l , ⌊ i / a ⌋ a + k β l k
ומזהה את כל קבוצת FRI שנפתחה נגד שורש שכבה FRI המתאים.
תרגום של פיאט-שמיר קטלוג הפרמטרים הקנוניים מצביע את האש של התסריט כ: SHA3-256. יישום ה-prover ו-verifier הנוכחי מביא בייטים מאתגרים עם iroha_crypto::Hash::new, אשר הוא 32-בייט Blake2bVar מאכלס, ואז מקטין את שמונה בייטים הראשונים קטנים-endian F:
χ ( tag ) = le64 ( Hash ( state ∥ len ( tag ) ∥ tag ) [ 0..8 ] ) m o d p \chi(\text{tag}) = \operatorname{le64}(\operatorname{Hash}(\text{state}\|\operatorname{len}(\text{tag})\|\text{tag})[0..8]) \bmod p χ ( tag ) = le64 ( Hash ( state ∥ len ( tag ) ∥ tag ) [ 0..8 ]) mod p
שיחות האתגר מוסיפים את ההזנה המלאה למצב העתיקה.
ציבורי IO, גרסה של פרוטוקול, גרסת הפרמטרים ושם הפרמטרים. LDE שורש וורש עקבות gammaAIR מאתגרים על הרכב alpha_0, alpha_1 AIR שורש עקבות וקור מרכיב AIR מוצר גדול שורשי שכבה FRI ואתגרים של beta_l אינדיקטורי שאלת דגימה קבלת דגימות מבקשת ממשיכה לצייר סימנים של מאתגר ב-32 בייטים ולקרוא אותם כחלקים קטנים u64 עד שיהיה להם את המספר הנדרש של אינדיקסים ייחודיים:
q = le64 ( digest chunk ) m o d N eval q = \operatorname{le64}(\text{digest chunk})\bmod N_{\text{eval}} q = le64 ( digest chunk ) mod N eval
קבוצת הדגימות חוזרת בסדר מסורט.
שיחזור בדיקת המבחין מחשוב מחדש תחילה את התחייבות הקצבה:
commitment e x p e c t e d = trace_commitment ( params , batch ) \operatorname{commitment}_{expected} =\operatorname{trace\_commitment}(\operatorname{params},\operatorname{batch}) commitment e x p ec t e d = trace_commitment ( params , batch )
ודורש:
commitment e x p e c t e d = proof.trace_commitment \operatorname{commitment}_{expected} =\operatorname{proof.trace\_commitment} commitment e x p ec t e d = proof.trace_commitment
הוא גם משיב את הציבור IO:
PublicIO = ( dsid , slot , old_root , new_root , perm_root , tx_set_hash , ordering_hash , permission_hashes ) \operatorname{PublicIO}= (\operatorname{dsid},\operatorname{slot},\operatorname{old\_root}, \operatorname{new\_root},\operatorname{perm\_root}, \operatorname{tx\_set\_hash},\operatorname{ordering\_hash}, \operatorname{permission\_hashes}) PublicIO = ( dsid , slot , old_root , new_root , perm_root , tx_set_hash , ordering_hash , permission_hashes )
כל שדה חייב להתאים את IO בייט על בייט של ההוכחה. המבחין משך מחדש את אותו התסריט ומוצא אותו:
γ , α 0 , α 1 , β 0 , … , β ℓ − 1 , q 0 , … , q t − 1 \gamma,\quad \alpha_0,\alpha_1,\quad \beta_0,\ldots,\beta_{\ell-1},\quad q_0,\ldots,q_{t-1} γ , α 0 , α 1 , β 0 , … , β ℓ − 1 , q 0 , … , q t − 1
עבור כל שאלת הדגימה q, הוא בודק:
MerkleVerify ( R lde , L ⌊ q / B lde ⌋ , ⌊ q / B lde ⌋ , π lde ) \operatorname{MerkleVerify}( R_{\text{lde}}, L_{\lfloor q/B_{\text{lde}}\rfloor}, \lfloor q/B_{\text{lde}}\rfloor, \pi_{\text{lde}} ) MerkleVerify ( R lde , L ⌊ q / B lde ⌋ , ⌊ q / B lde ⌋ , π lde )
MerkleVerify ( R air , L q air , q , π air,current ) \operatorname{MerkleVerify}( R_{\text{air}}, L^{\text{air}}_q, q, \pi_{\text{air,current}} ) MerkleVerify ( R air , L q air , q , π air,current )
MerkleVerify ( R air , L q + 1 m o d N eval air , q + 1 m o d N eval , π air,next ) \operatorname{MerkleVerify}( R_{\text{air}}, L^{\text{air}}_{q+1\bmod N_{\text{eval}}}, q+1\bmod N_{\text{eval}}, \pi_{\text{air,next}} ) MerkleVerify ( R air , L q + 1 mod N eval air , q + 1 mod N eval , π air,next )
ו:
A q = AIRComposition ( row q , row q + 1 , α 0 , α 1 ) A_q = \operatorname{AIRComposition}( \operatorname{row}_q,\operatorname{row}_{q+1},\alpha_0,\alpha_1 ) A q = AIRComposition ( row q , row q + 1 , α 0 , α 1 )
ה- AIR פתיחת הרכב חייבת להיות מאותית תחת R_air_composition. ה- FRI שרשרת אז מתחילים מאותו A_q ועליי לסיים בהסכם סופי מאושר. FRI עץ מתחת לתרום FRI שורש.
מה Proverb בודק לפני בניית עקבות, המבטא FastPQ קאנוניקליז את סדר הקבוצה על ידי מפתח מעבר, רשימת הפעולה, וסדר הכנסת. שורות העברה דורשות גם מטדאטה של כתיבה. קבוצה עם שורות העברת אבל אין כתיבות העברה היא לא חוקית .
עבור מסמכי העברה, בדיקות בצד הסבר כוללות:
המשקל של המשלוח לא חייב לזרום. sender_after חייב להיות שווה ל- sender_before - amountreceiver_after חייב להיות שווה ל- receiver_before + amountהתסריט חייב לכסות את כל שורה של העברה בלהט צירוף Poseidon של דלטה אחת, כאשר הוא קיים, חייב להתאים לתמונה הקודמת של התסריט אם הוכחות מרקל נדירות יש לפתור את הגרסה 1; הנתיבים החסרים מלאים באוכחות סינתטיות דטרמיסטיות. מעקב מכיל עמודי סלקטור עבור העברה, מנטה, שריפה, מתן תפקיד, ביטול תפקיד, קבוצת מטא נתונים ושורות חיפוש רשות. שורות ניתוח מספרים גם נושאים דלטה חתומות, פועלות לדלטה לכל נכס ומספרים אספקה.
פרובור ליין irohad מתחיל את FastPQ מסלול הסבר בהתחלה אם ניתן להפעיל את האחורי של הסבר. המסלול הוא משימת רקע עם שורה מוגבלת. לאחר שחגור מייצר עדות ביצוע, מסלול ההפעלה שולח עבודה סבר המכילה את ה-block hash, גובה, תצוגה ועידה.
אם המסלול לא פועל או שהצורה מלאה, התפקיד הופספס והמעבודת הבלוק הרגילה ממשיכה. זה אומר כי המסלול של ה-background prover אינו שער הכניסה למבצעים או שער הסכמה. הוא מסלול ההפקה על מצב שכבר נעשה.
המסלול בונה סבר עם:
text parameter = "fastpq-lane-balanced"
execution_mode = auto | cpu | gpu
poseidon_mode = auto | cpu | gpu auto מאפשר למבחין לבחור את הפסק האחורי הזמין. ביצוע פינים cpu לעומת ביצוע CPU. gpu מעדיפה ביצוע GPU, עם ההפסקות של CPU כאשר הפסק האחור אינו יכול להשתמש בכשירים המבוקשים.
אימות בדיקת הוכחה FastPQ מבצעת מחדש את ההתחייבות הקנוניקה של הסבב ומחזירה את התסריט הציבורי. הבדיקן בודק את גרסת הפרוטוקול, גרסה המוגדרת פרמטרים, גבולות החזרה, התחייבות למעקב, הכניסות ציבוריות, פתיחות מרקל שנבחרו, פתיחת AIR ושרשרת שאילת FRI.
גבולות ההשחקה המקובלים כוללים:
הגבול. דפוס שורות מעבר 256 גודל המשאב הפועל של הקבוצה 256 KiB FRI שכבות 16 פתיחות שאלות 128
Nexus רלעים מבוקשים Nexus AXT מעטפות ראיות יכולות להכיל את AxtFastpqBinding. כאשר RegisterVerifiedLaneRelay מבצע, Iroha:
מתבונן על חליפת ריליי המסלול ואת החומר ההוכיח FastPQ בודק את חלל הנתונים ואת שורש המניפסט. פירוש המעטה של ההוכחה AXT דורש fastpq_binding מייצג מחדש את המגרש FastPQ מתוך קשר זה. פירוק את ההוכחה המשולבת FastPQ קורא למבחין FastPQ על החתיכה המוקדמת מחדש והראיה אם הבדיקות מצליחות, Iroha מאחסן VerifiedLaneRelayRecord המכיל את התייחסות הרחבה, המעטה המקורי, ההש של עומס תועלת הוכחה, גובה הבדיקות, שורש מוניפסט, ואת קישור FastPQ.
מעטפות מרחבת המסלול מובילות גם חומר ראיה קומפקטי FastPQ. החומר הוא דיגסט מעל איד המסלול, איד חלל נתונים, גובה בלוק, גובה לאישור, האש של כותרת הבלוק, האש ההתיישבות והשורש המוניפסט. רלוף הוא מקובל להתמזג רק אם יש לו גם חומר ראיה QC וגם חומר ראוי FastPQ.
AXT מתמטיקה מחייבת עבור מעטפות Nexus AXT, AxtFastpqBinding קנוניקליזת לפני שיחזור הראיות. הערכים של הפרמטרים ריקים כפ default ל fastpq-lane-balanced; id בדיקת ריקה וגרסה מקובלת ל fastpq ו v1; סוג התביעה נחתוך ונחתך.
הכניסה הציבורית AXT FastPQ היא חישיית בייט דטרמיסטית:
dsid = dsid_bytes ( source_dsid ) \operatorname{dsid}=\operatorname{dsid\_bytes}(\operatorname{source\_dsid}) dsid = dsid_bytes ( source_dsid )
slot = le64 ( source_tx_commitment [ 0..8 ] ) \operatorname{slot}=\operatorname{le64}(\operatorname{source\_tx\_commitment}[0..8]) slot = le64 ( source_tx_commitment [ 0..8 ])
old_root = Hash ( fastpq-json:old_root ∥ source_tx_commitment ∥ policy_commitment ∥ effect_type ) \operatorname{old\_root} = \operatorname{Hash}( \texttt{fastpq-json:old\_root}\| \operatorname{source\_tx\_commitment}\| \operatorname{policy\_commitment}\| \operatorname{effect\_type} ) old_root = Hash ( fastpq-json:old_root ∥ source_tx_commitment ∥ policy_commitment ∥ effect_type )
new_root = Hash ( fastpq-json:new_root ∥ source_tx_commitment ∥ claim_digest ∥ effect_type ) \operatorname{new\_root} = \operatorname{Hash}( \texttt{fastpq-json:new\_root}\| \operatorname{source\_tx\_commitment}\| \operatorname{claim\_digest}\| \operatorname{effect\_type} ) new_root = Hash ( fastpq-json:new_root ∥ source_tx_commitment ∥ claim_digest ∥ effect_type )
perm_root = Hash ( fastpq-json:perm_root ∥ policy_commitment ∥ verifier_id ∥ verifier_version ) \operatorname{perm\_root} = \operatorname{Hash}( \texttt{fastpq-json:perm\_root}\| \operatorname{policy\_commitment}\| \operatorname{verifier\_id}\| \operatorname{verifier\_version} ) perm_root = Hash ( fastpq-json:perm_root ∥ policy_commitment ∥ verifier_id ∥ verifier_version )
tx_set_hash = Hash ( fastpq-json:tx_set_hash ∥ source_tx_commitment ∥ claim_digest ∥ witness_commitment ) \operatorname{tx\_set\_hash} = \operatorname{Hash}( \texttt{fastpq-json:tx\_set\_hash}\| \operatorname{source\_tx\_commitment}\| \operatorname{claim\_digest}\| \operatorname{witness\_commitment} ) tx_set_hash = Hash ( fastpq-json:tx_set_hash ∥ source_tx_commitment ∥ claim_digest ∥ witness_commitment )
המפתחות המעבר AXT הן:
key ( prefix , x , y ) = prefix ∥ / ∥ x ∥ / ∥ y \operatorname{key}(\operatorname{prefix},x,y)= \operatorname{prefix}\|\texttt{/}\|x\|\texttt{/}\|y key ( prefix , x , y ) = prefix ∥ / ∥ x ∥ / ∥ y
בתביעה authorization מפרסמת שורה של תורמים:
role_id = claim_digest \operatorname{role\_id}=\operatorname{claim\_digest} role_id = claim_digest
permission_id = witness_commitment \operatorname{permission\_id}=\operatorname{witness\_commitment} permission_id = witness_commitment
epoch = le64 ( policy_commitment [ 0..8 ] ) \operatorname{epoch}= \operatorname{le64}(\operatorname{policy\_commitment}[0..8]) epoch = le64 ( policy_commitment [ 0..8 ])
ושורה של מטא נתונים מחייבת את מדיניות ההסמכים. בקשה compliance מוסיפה שתי שורות של מטא-נתונים: אחת עבור מדיניות ואחת עבור מספרי הנתונים המטרה.
עבור tx_predicate ו value_conservation, יש להשתמש בסכום השפעה מפורש כאשר הקשר מכיל סכום מקור או יעד חיובי. אחרת הקוד מוציא סכום דטרמיניסטי מוגבל.
bounded ( d , min , span ) = min + ( le64 ( d [ 0..8 ] ) m o d max ( span , 1 ) ) \operatorname{bounded}(d,\min,\operatorname{span}) = \min + (\operatorname{le64}(d[0..8])\bmod\max(\operatorname{span},1)) bounded ( d , min , span ) = min + ( le64 ( d [ 0..8 ]) mod max ( span , 1 ))
ואז משתמשים באותם משוואות העברה:
sender_after = sender_before − a \operatorname{sender\_after}=\operatorname{sender\_before}-a sender_after = sender_before − a
receiver_after = receiver_before + a \operatorname{receiver\_after}=\operatorname{receiver\_before}+a receiver_after = receiver_before + a
זיהוי החשבון של המשלח והמתקבל סינתטי נוצר מהזרעים המרכזיים:
seed = Hash ( label ∥ entropy ) [ 0..32 ] \operatorname{seed}= \operatorname{Hash}(\operatorname{label}\|\operatorname{entropy})[0..32] seed = Hash ( label ∥ entropy ) [ 0..32 ]
ה-Hash של הקבוצת העברה הוא:
batch_hash = Hash ( label ∥ corridor ∥ source_tx_commitment ∥ claim_digest ) \operatorname{batch\_hash} = \operatorname{Hash}( \operatorname{label}\| \operatorname{corridor}\| \operatorname{source\_tx\_commitment}\| \operatorname{claim\_digest} ) batch_hash = Hash ( label ∥ corridor ∥ source_tx_commitment ∥ claim_digest )
ה- AXT מכתב המפרט של הקבוצת הוא SHA-256 מעל קודי Norito של החיבור הקנוני:
manifest_digest = SHA256 ( E ( canonical_binding ) ) \operatorname{manifest\_digest} = \operatorname{SHA256}(E(\operatorname{canonical\_binding})) manifest_digest = SHA256 ( E ( canonical_binding ))
SCCP ראיות של הודעות שקופות קופסת העזרה של SCCP משתמשת גם ב- FastPQ כדי להוכיח הודעות חיוות בין שרשרת. הנתיב הזה נפרד מ- irohad מסלול ההצהרה של רקע. הוא בונה כיסוי FastPQ ישירות מתוך חבורת ראיות של הודעות SCCP ומניפסט, ולאחר מכן מקיף את הראיה המוצאת לאישור פתוח. .
הקבוצת SCCP משתמשת ב- fastpq-lane-balanced ובשלוש המעברים של מטא נתונים:
המפתח. מבצע sccp:transparent:v1:statementMetaSetsccp:transparent:v1:contextMetaSetsccp:transparent:v1:payloadMetaSet
הכניסה הציבורית שלה נובעת מן ההוכחה הפנימית שקופה של SCCP:
FastPQ הכניסות SCCP מקור dsid16 באייטים הראשונים של מבריק2ב מזיזים על הודעת האש. slotגובה סיום old_rootחשיפת המטען . new_rootשורש התחייבות perm_rootבלוק הסיום האש . tx_set_hashהודעות האש
SCCP מקודרים קנוניים כותבים מספרים שלמים קטנים ומצליחים לקודור מערכות בייטות אורך משתנה כמו:
vec ( x ) = le32 ( ∣ x ∣ ) ∥ x \operatorname{vec}(x)=\operatorname{le32}(|x|)\|x vec ( x ) = le32 ( ∣ x ∣ ) ∥ x
שרשרת בייט כניסה ציבורית שקופה היא:
P = version ∥ message_id ∥ payload_hash ∥ le32 ( target_domain ) ∥ commitment_root ∥ le64 ( finality_height ) ∥ finality_block_hash P = \operatorname{version}\| \operatorname{message\_id}\| \operatorname{payload\_hash}\| \operatorname{le32}(\operatorname{target\_domain})\| \operatorname{commitment\_root}\| \operatorname{le64}(\operatorname{finality\_height})\| \operatorname{finality\_block\_hash} P = version ∥ message_id ∥ payload_hash ∥ le32 ( target_domain ) ∥ commitment_root ∥ le64 ( finality_height ) ∥ finality_block_hash
בייטים של הצהרה שקופה הם הקשר בין הגרסה, משפחת שרשרת, תחומים מקומיים ושל הצדדים האחרים, מודל אבטחה, ממשלת מעגל, קודק חשבון, מודל סיום, מטרה של המבחין, משפחת ה-backend של המבחנים, שדות רשת/הגבול/מניפסט מונפסטיד בגודל, חישוב חיבורי יעדה, מפתח קודק חשבון, סוג של עומס תועלת, בייטים הכניסה ציבוריים, והשח של עומס התועלת. ההשח של הצהרה הוא:
statement_hash = Blake2bVar 32 ( sccp:transparent:statement:v1 ∥ statement ) \operatorname{statement\_hash} = \operatorname{Blake2bVar}_{32}( \texttt{sccp:transparent:statement:v1}\|\operatorname{statement} ) statement_hash = Blake2bVar 32 ( sccp:transparent:statement:v1 ∥ statement )
איד החלל הנתונים FastPQ למסלול ההוכחה הזה הוא השישה עשר בייטים הראשונים של דיג'סט Blake2b מקודם נוסף:
dsid = Blake2bVar 32 ( sccp:transparent:fastpq:dsid:v1 ∥ statement_hash ) [ 0..16 ] \operatorname{dsid} = \operatorname{Blake2bVar}_{32}( \texttt{sccp:transparent:fastpq:dsid:v1}\|\operatorname{statement\_hash} )[0..16] dsid = Blake2bVar 32 ( sccp:transparent:fastpq:dsid:v1 ∥ statement_hash ) [ 0..16 ]
הסבב SCCP FastPQ הוא בדיוק:
( sccp:transparent:v1:statement , ∅ , statement , MetaSet ) (\texttt{sccp:transparent:v1:statement},\varnothing,\operatorname{statement},\operatorname{MetaSet}) ( sccp:transparent:v1:statement , ∅ , statement , MetaSet )
( sccp:transparent:v1:context , ∅ , E ( inner_proof ) , MetaSet ) (\texttt{sccp:transparent:v1:context},\varnothing,E(\operatorname{inner\_proof}),\operatorname{MetaSet}) ( sccp:transparent:v1:context , ∅ , E ( inner_proof ) , MetaSet )
( sccp:transparent:v1:payload , ∅ , canonical_payload , MetaSet ) (\texttt{sccp:transparent:v1:payload},\varnothing,\operatorname{canonical\_payload},\operatorname{MetaSet}) ( sccp:transparent:v1:payload , ∅ , canonical_payload , MetaSet )
לאחר מכן מסווג על ידי אותו כלל ההזמנה FastPQ.
ההתחייבות למבחין OpenVerify היא SHA-256 על שמו של הודעת האחורי של הודעה SCCP ועל תיאור המבחין הקנוני של FastPQ:
vk_hash = SHA256 ( message_backend ∥ verifier_descriptor ) \operatorname{vk\_hash} = \operatorname{SHA256}( \operatorname{message\_backend}\|\operatorname{verifier\_descriptor} ) vk_hash = SHA256 ( message_backend ∥ verifier_descriptor )
החומרי FastPQ הוכחה היא Norito-מוצפן לתוך StarkFriOpenProofV1, ואז עטוף ב OpenVerifyEnvelope עם קצה אחורי Stark. SCCP בדיקת חוזרת את אותו FastPQ הקצבה מהחבילה והמניפסט, בודקת את הנתונים המטאטאריים של מעטפת ההמתנה פתוחה, ומקרא את FastPQ בדיקת על המגרש שנבנה מחדש והוכחה.
מערכות פרמטרים קטלוג הפרמטרים הקנוניים חושף שני קבוצות פרמטרים. מסלול המובילה משתמש כיום fastpq-lane-balanced.
פרמטר מטרה. שדה חישות FRI fastpq-lane-balancedסיבוב סבר מאוזן ארגזת קוואדראטית של גולדילוקס התחייבות של Poseidon2, קטלוג SHA3 סעיף 8, פיצוץ 8, 46 שאלות fastpq-lane-latencyכבישים רגישים לטיחות ארגזת קוואדראטית של גולדילוקס התחייבות של Poseidon2, קטלוג SHA3 סעיף 16, פיצוץ 16, 34 שאלות
שניהם מכוונים לביטחון 128-ביט ומשתמשים בגודל תחום מעקב של 2^16. קוד ההשתקפות של התסריט Rust V1 משמש כיום את בייטות האתגר Fiat-Shamir עם iroha_crypto::Hash::new במקום להתקשר ישירות אל SHA3-256.
קבועות הקייטלוג המדויקות המשמשות על ידי Rust הם:
קבוע. fastpq-lane-balancedfastpq-lane-latencytarget_security128 128 grinding_bits23 21 trace_log_size16 16 trace_root0x002a247f81c6f8500x6a9f4eb38fb9b892lde_log_size19 20 lde_root0x60263388dbbf9b2a0x9c9c3a571b6f89acpermutation_size65,536 65,536 lookup_log_size19 20 omega_coset0x6af325e825ad5c180x3a5fd4171e3c3a4dfri_arity8 16 fri_blowup8 16 fri_max_reductions8 6 fri_queries46 34
הגדרות הקונפיגרציה של FastPQ נמצאת תחת zk.fastpq.
toml [ zk . fastpq ]
execution_mode = "auto"
poseidon_mode = "auto"
# Optional telemetry labels.
device_class = "apple-m4"
chip_family = "m4"
gpu_kind = "integrated"
# Optional Metal backend tuning.
metal_queue_fanout = 3
metal_queue_column_threshold = 24
metal_max_in_flight = 5
metal_threadgroup_width = 128
metal_trace = false
metal_debug_enum = false
metal_debug_fused = false את אותן תוויות הביצוע והטלמטריה ניתן לשבור מ- irohad:
shell irohad --fastpq-execution-mode auto
irohad --fastpq-poseidon-mode cpu
irohad --fastpq-device-class apple-m4
irohad --fastpq-chip-family m4
irohad --fastpq-gpu-kind integrated משתנים סביבתיים תומכים גם בשדות ההסדרות. FastPQ- משתנים ספציפיים כוללים:
FASTPQ_EXECUTION_MODEFASTPQ_POSEIDON_MODEFASTPQ_DEVICE_CLASSFASTPQ_CHIP_FAMILYFASTPQ_GPU_KINDFASTPQ_METAL_QUEUE_FANOUTFASTPQ_METAL_COLUMN_THRESHOLDFASTPQ_METAL_MAX_IN_FLIGHTFASTPQ_METAL_THREADGROUPFASTPQ_METAL_TRACEFASTPQ_DEBUG_METAL_ENUMFASTPQ_DEBUG_FUSEDמדדים כאשר טלמטריה מופעלת, FastPQ מייצרת מדדים עבור הבחירה ב-backend וההתנהגות של Metal runtime:
מטריק משמעות fastpq_execution_mode_totalמצב ההפעלה הנדרש והפתר על ידי תוויות האחורי והתקן fastpq_poseidon_pipeline_totalהנתיב של צינור פוסיידון מבוקש ופתר fastpq_metal_queue_depthגבול קו מתכת, מספר מקסימום בטיסה, מספר משלוחים וחלון הדגימות fastpq_metal_queue_ratioשורה מתכת עמוסה ותחפיפות יחסים fastpq_zero_fill_duration_msתוחלת מילוי אפס עבור מטאל ריצה fastpq_zero_fill_bandwidth_gbpsנרחב קו ה-zero-fill
לטיפול ביצועים כלליים, השתמשו בהם עם אותות ההסכמה והצורה המפורטים ב- ביצועים ומטריקות .