Încerc să verific un zk-SNARK dintr-un contract de soliditate offline, în Rust.
Acesta este contractul de verificare care verifică dovada în partea de soliditate.
Și acest este tranzacția care poartă dovada și intrările publice.
Dovada este validă și am reușit să reproduc validarea offline folosind Solidity.
Cu toate acestea, în Rust nu am acces la precompilarea solidității care verifică perechile BN254. Deci folosesc această implementare bazată în arkworks/curve crate:
pub fn check_pairings(g1s: Vec<G1Affine>, g2s: Vec<G2Affine>) -> bool {
assert_eq!(g1s.len(), g2s.len());
let mut res = Fp12::one();
pentru (g1, g2) în g1s.iter().zip(g2s.iter()) {
dacă g1.este_zero() || g2.is_zero() {
continua;
}
res = res * Bn254::pairing(*g1, *g2);
}
res.is_one()
}
Codul se bazează în Implementarea Ethereum BN526 și vă rugăm să rețineți că:
Intrările (vectorul punctelor G1 și G2) sunt echivalente cu implementarea solidității. Deci, pot fi sigur că combinația de intrări, încărcarea dovezilor etc. este corectă.
Este practic algoritmul descris în original Creșterea16 lucrare, pagina 18. Componenta punctului A a fost negat astfel încât toți termenii să fie în aceeași parte a ecuației.
Este aceeași curbă în ambele implementări.
Am pierdut ceva? Există vreun pas practic suplimentar atunci când verificați un zk-SNARK? Este necesară o normalizare a valorilor?