Skip to content

Commit

Permalink
4944: Fix zeromorph verification for TS integration
Browse files Browse the repository at this point in the history
  • Loading branch information
jeanmon committed Aug 21, 2024
1 parent 239db9b commit 7ea9fee
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 26 deletions.
49 changes: 38 additions & 11 deletions barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,13 @@ std::string to_json(std::vector<bb::fr>& data)
return format("[", join(map(data, [](auto fr) { return format("\"", fr, "\""); })), "]");
}

std::string vk_to_json(std::vector<bb::fr>& data)
std::string vk_to_json(std::vector<bb::fr> const& data)
{
// We need to move vk_hash to the front...
std::rotate(data.begin(), data.end() - 1, data.end());
std::vector<bb::fr> rotated(data.begin(), data.end() - 1);
rotated.insert(rotated.begin(), data.at(data.size() - 1));

return format("[", join(map(data, [](auto fr) { return format("\"", fr, "\""); })), "]");
return format("[", join(map(rotated, [](auto fr) { return format("\"", fr, "\""); })), "]");
}

std::string honk_vk_to_json(std::vector<bb::fr>& data)
Expand Down Expand Up @@ -950,18 +951,25 @@ void avm_prove(const std::filesystem::path& bytecode_path,
auto const [verification_key, proof] =
AVM_TRACK_TIME_V("prove/all", avm_trace::Execution::prove(bytecode, calldata, public_inputs_vec, avm_hints));

// TODO(ilyas): <#4887>: Currently we only need these two parts of the vk, look into pcs_verification key reqs
std::vector<uint64_t> vk_vector = { verification_key.circuit_size, verification_key.num_public_inputs };
std::vector<fr> vk_as_fields = { verification_key.circuit_size, verification_key.num_public_inputs };
std::string vk_json = vk_to_json(vk_as_fields);
std::vector<fr> vk_as_fields = { fr(verification_key.circuit_size), fr(verification_key.num_public_inputs) };

for (auto const& comm : verification_key.get_all()) {
std::vector<fr> comm_as_fields = field_conversion::convert_to_bn254_frs(comm);
vk_as_fields.insert(vk_as_fields.end(), comm_as_fields.begin(), comm_as_fields.end());
}

vinfo("vk fields size: ", vk_as_fields.size());
vinfo("circuit size: ", vk_as_fields[0]);
vinfo("num of pub inputs: ", vk_as_fields[1]);

std::string vk_json = to_json(vk_as_fields);
const auto proof_path = output_path / "proof";
const auto vk_path = output_path / "vk";
const auto vk_fields_path = output_path / "vk_fields.json";

write_file(proof_path, to_buffer(proof));
vinfo("proof written to: ", proof_path);
write_file(vk_path, to_buffer(vk_vector));
write_file(vk_path, to_buffer(vk_as_fields));
vinfo("vk written to: ", vk_path);
write_file(vk_fields_path, { vk_json.begin(), vk_json.end() });
vinfo("vk as fields written to: ", vk_fields_path);
Expand All @@ -988,11 +996,30 @@ void avm_prove(const std::filesystem::path& bytecode_path,
*/
bool avm_verify(const std::filesystem::path& proof_path, const std::filesystem::path& vk_path)
{
using Commitment = AvmFlavorSettings::Commitment;
std::vector<fr> const proof = many_from_buffer<fr>(read_file(proof_path));
std::vector<uint8_t> vk_bytes = read_file(vk_path);
auto circuit_size = from_buffer<size_t>(vk_bytes, 0);
auto num_public_inputs = from_buffer<size_t>(vk_bytes, sizeof(size_t));
auto vk = AvmFlavor::VerificationKey(circuit_size, num_public_inputs);
std::vector<fr> vk_as_fields = many_from_buffer<fr>(vk_bytes);

vinfo("initializing crs with size: ", avm_trace::Execution::SRS_SIZE);
init_bn254_crs(avm_trace::Execution::SRS_SIZE);

auto circuit_size = uint64_t(vk_as_fields[0]);
auto num_public_inputs = uint64_t(vk_as_fields[1]);
std::span vk_span(vk_as_fields);

vinfo("vk fields size: ", vk_as_fields.size());
vinfo("circuit size: ", circuit_size);
vinfo("num of pub inputs: ", num_public_inputs);

ASSERT(vk_as_fields.size() == 4 * AvmFlavor::NUM_PRECOMPUTED_ENTITIES + 2);

std::array<Commitment, AvmFlavor::NUM_PRECOMPUTED_ENTITIES> precomputed_cmts;
for (size_t i = 0; i < AvmFlavor::NUM_PRECOMPUTED_ENTITIES; i++) {
precomputed_cmts[i] = field_conversion::convert_from_bn254_frs<Commitment>(vk_span.subspan(4 * i + 2, 4));
}

auto vk = AvmFlavor::VerificationKey(circuit_size, num_public_inputs, precomputed_cmts);

const bool verified = AVM_TRACK_TIME_V("verify/all", avm_trace::Execution::verify(vk, proof));
vinfo("verified: ", verified);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ using namespace bb::srs::factories;

class MemVerifierCrs : public VerifierCrs<curve::BN254> {
public:
MemVerifierCrs(g2::affine_element const& g2_point)
: g2_x(g2_point)
MemVerifierCrs(g2::affine_element g2_point, g1::affine_element const& g1_identity)
: g1_identityx(g1_identity)
, g2_x(std::move(g2_point))
, precomputed_g2_lines(
static_cast<pairing::miller_lines*>(aligned_alloc(64, sizeof(bb::pairing::miller_lines) * 2)))
{

bb::pairing::precompute_miller_lines(bb::g2::one, precomputed_g2_lines[0]);
bb::pairing::precompute_miller_lines(g2_x, precomputed_g2_lines[1]);
}
Expand All @@ -43,8 +43,14 @@ namespace bb::srs::factories {
MemBn254CrsFactory::MemBn254CrsFactory(std::vector<g1::affine_element> const& points,
g2::affine_element const& g2_point)
: prover_crs_(std::make_shared<MemProverCrs<curve::BN254>>(points))
, verifier_crs_(std::make_shared<MemVerifierCrs>(g2_point))
{}
{
auto g1_identity = g1::affine_element();
if (!points.empty()) {
g1_identity = points[0];
}

verifier_crs_ = std::make_shared<MemVerifierCrs>(g2_point, g1_identity);
}

std::shared_ptr<bb::srs::factories::ProverCrs<curve::BN254>> MemBn254CrsFactory::get_prover_crs(size_t)
{
Expand Down
6 changes: 5 additions & 1 deletion barretenberg/cpp/src/barretenberg/srs/io.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,11 @@ template <typename Curve> class IO {
size_t num_read = 0;
std::string path = get_transcript_path(dir, num);

while (is_file_exist(path) && num_read < degree) {
if (!is_file_exist(path)) {
throw_or_abort(format("File path for transcript g1 ", path, " is invalid."));
}

while (num_read < degree) {
Manifest manifest;
read_manifest(path, manifest);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,7 @@ AvmProver AvmComposer::create_prover(CircuitConstructor& circuit_constructor)
AvmVerifier AvmComposer::create_verifier(CircuitConstructor& circuit_constructor)
{
auto verification_key = compute_verification_key(circuit_constructor);

AvmVerifier output_state(verification_key);

auto pcs_verification_key = std::make_unique<VerifierCommitmentKey>();

output_state.pcs_verification_key = std::move(pcs_verification_key);

return output_state;
return AvmVerifier(verification_key);
}

std::shared_ptr<Flavor::ProvingKey> AvmComposer::compute_proving_key(CircuitConstructor& circuit_constructor)
Expand Down
10 changes: 10 additions & 0 deletions barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,16 @@ class AvmFlavor {
commitment = proving_key->commitment_key->commit(polynomial);
}
}

VerificationKey(const size_t circuit_size,
const size_t num_public_inputs,
std::array<Commitment, NUM_PRECOMPUTED_ENTITIES> const& precomputed_cmts)
: VerificationKey_(circuit_size, num_public_inputs)
{
for (auto [vk_cmt, cmt] : zip_view(this->get_all(), precomputed_cmts)) {
vk_cmt = cmt;
}
}
};

class AllValues : public AllEntities<FF> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace bb {

AvmVerifier::AvmVerifier(std::shared_ptr<Flavor::VerificationKey> verifier_key)
: key(verifier_key)
, pcs_verification_key(std::make_shared<VerifierCommitmentKey>())
{}

AvmVerifier::AvmVerifier(AvmVerifier&& other) noexcept
Expand Down
9 changes: 8 additions & 1 deletion yarn-project/bb-prover/src/avm_proving.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,14 @@ const proveAndVerifyAvmTestContract = async (
// Then we test VK extraction.
const succeededRes = proofRes as BBSuccess;
const verificationKey = await extractVkData(succeededRes.vkPath!);
expect(verificationKey.keyAsBytes).toHaveLength(16);

// VK is composed of
// - circuit size encoded as a fr field element (32 bytes)
// - num of inputs encoded as a fr field element (32 bytes)
// - 16 affine elements (curve base field fq) encoded as fr elements takes (16 * 4 * 32 bytes)
// 16 above refers to the constant AvmFlavor::NUM_PRECOMPUTED_ENTITIES
// Total number of bytes = 2112
expect(verificationKey.keyAsBytes).toHaveLength(2112);

// Then we verify.
const rawVkPath = path.join(succeededRes.vkPath!, 'vk');
Expand Down

0 comments on commit 7ea9fee

Please sign in to comment.