В этой серии из двух частей мы поговорим о том, как начать работу с библиотекойlibsnark
. Мы рассмотрим два очень
полезных руководства и попутно дадим дополнительные комментарии.
Учебник Говарда Ву
Для новичка вашим первым портом захода должен стать превосходный
учебник одного из главных участников libsnark
— Говарда Ву. В README содержатся пошаговые инструкции по
созданию простого приложения, которое генерирует пример доказательства zk-SNARK (на основе
протокола Groth-16) и проверяет его. Хотя вы можете просто клонировать
репозиторий и перейти непосредственно к созданию и запуску приложения, очень
поучительно выполнить шаги, чтобы увидеть, как структурирован проект на основе libsnark
. В оставшейся части этого поста предполагается, что вам удалось собрать и запустить учебник.
Суть учебника
Чтобы дать общее описание того, что происходит в приложении, давайте
сократим функцию run_r1cs_gg_ppzksnark
до самых важных элементов:
template<typename ppT> bool run_r1cs_gg_ppzksnark(const r1cs_example<libff::Fr<ppT> > &example) { r1cs_gg_ppzksnark_keypair<ppT> keypair = r1cs_gg_ppzksnark_generator<ppT>(example.constraint_system);
r1cs_gg_ppzksnark_proof<ppT> proof = r1cs_gg_ppzksnark_prover<ppT>(keypair.pk, example.primary_input, example.auxiliary_input);
const bool ans = r1cs_gg_ppzksnark_verifier_strong_IC<ppT>(keypair.vk, example.primary_input, proof); // ... etc. }
Эти три вызова функций описывают основной рабочий процесс, общий для большинства протоколов zk-SNARK:
- Учитывая R1CS (система ограничений ранга 1) — здесь она называется
example
—
функцияr1cs_gg_ppzksnark_generator
генерируетkeypair
— одну для доказывающего, а другую
для верификатора. - Проверяющая берет свой ключ и вместе с входными данными
example
R1CS
создаетproof
сr1cs_gg_ppzksnark_prover
. Обратите внимание, что входные данные
включают как общедоступные значения (primary_input
— известны также проверяющему), так и
частные «свидетельские» значения (auxiliary_input
— не сообщаются проверяющему). - Вместе с общедоступными входными данными и ключом проверки верификатор проверяет
proof
сr1cs_gg_ppzksnark_verifier_strong_IC
, что должно возвращать
истину, еслиproof
действительно был предоставлен подтверждающим свидетельством.
Используемые libsnark
функции будут отличаться от одной программы к другой, но базовый шаблон
останется таким же, как и выше.
libsnark
функций
Здесь следует отметить, что конкретные используемые функции и типы будут
зависеть от ряда факторов. В данном случае мы работаем с Groth-16
zk-SNARK, который определяет, что следует использовать функции с префиксом r1cs_gg_ppzksnark_
.
На самом деле конкретная функция проверки, которую следует вызывать, зависит не менее чем от трех факторов:
- Как уже упоминалось, SNARK для использования.
- Ключ проверки – обработанные ключи, содержащие небольшое постоянное количество
дополнительной предварительно вычисленной информации, позволяющей сократить время проверки.
В этом случае верификатор называется онлайн верификатор. - Слабая и сильная согласованность входных данных (IC) — сильная IC означает, что количество
первичных входных данных точно соответствует количеству входных данных системы ограничений
, тогда как слабая IC ослабляет это требование.
В приведенном выше примере для проверки используется стандартный необработанный ключ с
строгой согласованностью ввода:
template<typename ppT>
bool r1cs_gg_ppzksnark_verifier_strong_IC(
const r1cs_gg_ppzksnark_verification_key<ppT> &vk,
const r1cs_gg_ppzksnark_primary_input<ppT> &primary_input,
const r1cs_gg_ppzksnark_proof<ppT> &proof);
В качестве другого примера, тот же SNARK, но с обработанным ключом проверки и только слабой
непротиворечивостью ввода, вместо этого будет использовать следующую функцию проверки:
template<typename ppT>
bool r1cs_gg_ppzksnark_online_verifier_weak_IC(
const r1cs_gg_ppzksnark_processed_verification_key<ppT> &pvk,
const r1cs_gg_ppzksnark_primary_input<ppT> &input,
const r1cs_gg_ppzksnark_proof<ppT> &proof);
Использование этого онлайн-верификатора предполагает некоторую дополнительную обработку стандартного
ключа проверки путем передачи его функцииr1cs_gg_ppzksnark_verifier_process_vk
для созданияr1cs_gg_ppzksnark_processed_verification_key
.
См. исходный код libsnark
для более подробной информации.
Хотя руководство Говарда Ву показывает пример этого очень важного шаблона
работы с zk-SNARK, в нем мало говорится о том, как на самом деле происходит
создание объектов R1CS. Это (и многое другое) будет темой следующего поста.