Я пытаюсь проверить zk-SNARK из контракта Solidity в автономном режиме в Rust.
Это проверочный контракт, который проверяет доказательство в сторона твердости.
И это это транзакция, которая содержит доказательства и общедоступные входные данные.
Доказательство действительное, и я смог воспроизвести проверку в автономном режиме с помощью Solidity.
Однако в Rust у меня нет доступа к прекомпиляции Solidity, которая проверяет пары BN254. Поэтому я использую эту реализацию, основанную на arkworks/curve crate:
pub fn check_pairings(g1s: Vec<G1Affine>, g2s: Vec<G2Affine>) -> bool {
assert_eq!(g1s.len(), g2s.len());
пусть mut res = Fp12::one();
для (g1, g2) в g1s.iter().zip(g2s.iter()) {
если g1.is_zero() || g2.is_zero() {
Продолжить;
}
res = res * Bn254::pairing(*g1, *g2);
}
res.is_one()
}
Код основан на Реализация Ethereum BN526 и обратите внимание, что:
Входные данные (вектор точек G1 и G2) эквивалентны реализации твердости. Поэтому я могу быть уверен, что комбинация входных данных, загрузка доказательств и т. д. верна.
Это в основном алгоритм, описанный в оригинале Грот16 статья, стр. 18. Компонент точки A был инвертирован, так что все члены находятся в одной части уравнения.
Это одна и та же кривая в обеих реализациях.
Я что-то пропустил? Есть ли какой-то дополнительный практический шаг при проверке zk-SNARK? Требуется ли нормализация значений?