Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proof generation and verification methods that use pk/vk #21

Merged
merged 6 commits into from
Feb 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,12 @@ void read_witness(TurboComposer& composer, std::vector<barretenberg::fr> witness
}
}

TurboComposer create_circuit(const standard_format& constraint_system)
kevaundray marked this conversation as resolved.
Show resolved Hide resolved
void create_circuit(TurboComposer& composer, const standard_format& constraint_system)
{
if (constraint_system.public_inputs.size() > constraint_system.varnum) {
std::cout << "too many public inputs!" << std::endl;
}

auto composer = TurboComposer();

for (size_t i = 1; i < constraint_system.varnum; ++i) {
// If the index is in the public inputs vector, then we add it as a public input

Expand Down Expand Up @@ -129,8 +127,6 @@ TurboComposer create_circuit(const standard_format& constraint_system)
for (const auto& constraint : constraint_system.hash_to_field_constraints) {
create_hash_to_field_constraints(composer, constraint);
}

return composer;
}

TurboComposer create_circuit(const standard_format& constraint_system,
Expand Down
1 change: 1 addition & 0 deletions barretenberg/src/aztec/plonk/composer/turbo_composer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,7 @@ std::shared_ptr<verification_key> TurboComposer::compute_verification_key()

circuit_verification_key =
turbo_composer::compute_verification_key(circuit_proving_key, crs_factory_->get_verifier_crs());

circuit_verification_key->composer_type = type;
circuit_verification_key->recursive_proof_public_input_indices =
std::vector<uint32_t>(recursive_proof_public_input_indices.begin(), recursive_proof_public_input_indices.end());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,17 @@ struct verification_key {
size_t program_width = 3;
};

template <typename B> inline void read(B& buf, verification_key const& key)
{
using serialize::read;
read(buf, key.composer_type);
read(buf, static_cast<uint32_t>(key.n));
read(buf, static_cast<uint32_t>(key.num_public_inputs));
read(buf, key.constraint_selectors);
read(buf, key.permutation_selectors);
read(buf, key.contains_recursive_proof);
read(buf, key.recursive_proof_public_input_indices);
}
template <typename B> inline void write(B& buf, verification_key const& key)
{
using serialize::write;
Expand Down
33 changes: 33 additions & 0 deletions barretenberg/src/aztec/rollup/proofs/standard_example/c_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,39 @@ WASM_EXPORT bool standard_example__verify_proof(uint8_t* proof, uint32_t length)
}
}

extern "C" {

WASM_EXPORT size_t c_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf)
{
return rollup::proofs::standard_example::c_init_proving_key(constraint_system_buf, pk_buf);
}

WASM_EXPORT size_t c_init_verification_key(void* pippenger,
uint8_t const* g2x,
uint8_t const* pk_buf,
uint8_t const** vk_buf)
{
return rollup::proofs::standard_example::c_init_verification_key(pippenger, g2x, pk_buf, vk_buf);
}

WASM_EXPORT size_t c_new_proof(void* pippenger,
uint8_t const* g2x,
uint8_t const* pk_buf,
uint8_t const* constraint_system_buf,
uint8_t const* witness_buf,
uint8_t** proof_data_buf)
{
return rollup::proofs::standard_example::c_new_proof(
pippenger, g2x, pk_buf, constraint_system_buf, witness_buf, proof_data_buf);
}

WASM_EXPORT bool c_verify_proof(
uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length)
{
return rollup::proofs::standard_example::c_verify_proof(g2x, vk_buf, constraint_system_buf, proof, length);
}
}

// standard format stuff

using namespace waffle;
Expand Down
19 changes: 19 additions & 0 deletions barretenberg/src/aztec/rollup/proofs/standard_example/c_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,23 @@ WASM_EXPORT size_t composer__new_proof(void* pippenger,
uint8_t** proof_data_buf);
WASM_EXPORT bool composer__verify_proof(
void* pippenger, uint8_t const* g2x, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length);

// Construct composer using prover and verifier key buffers
WASM_EXPORT size_t c_init_proving_key(uint8_t const* constraint_system_buf,
uint8_t const** pk_buf);
WASM_EXPORT size_t c_init_verification_key(void* pippenger,
uint8_t const* g2x,
uint8_t const* pk_buf,
uint8_t const** vk_buf);
WASM_EXPORT size_t c_new_proof(void* pippenger,
uint8_t const* g2x,
uint8_t const* pk_buf,
uint8_t const* constraint_system_buf,
uint8_t const* witness_buf,
uint8_t** proof_data_buf);
WASM_EXPORT bool c_verify_proof(uint8_t const* g2x,
uint8_t const* vk_buf,
uint8_t const* constraint_system_buf,
uint8_t* proof,
uint32_t length);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
#include <common/log.hpp>
#include <plonk/composer/turbo/compute_verification_key.hpp>
#include <plonk/proof_system/commitment_scheme/kate_commitment_scheme.hpp>
#include <plonk/proof_system/proving_key/serialize.hpp>
#include <dsl/standard_format/standard_format.hpp>
#include <plonk/reference_string/pippenger_reference_string.hpp>
#include <plonk/proof_system/verification_key/sol_gen.hpp>
#include <plonk/proof_system/verification_key/verification_key.hpp>
#include <sstream>
#include <iostream>
#include <common/streams.hpp>
Expand Down Expand Up @@ -170,6 +172,120 @@ uint32_t c_composer__smart_contract(void* pippenger,
return static_cast<uint32_t>(buffer.size());
}

size_t c_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf)
{
auto constraint_system = from_buffer<waffle::standard_format>(constraint_system_buf);
// We know that we don't actually need any CRS to create a proving key, so just feed in a nothing.
// Hacky, but, right now it needs *something*.
auto crs_factory = std::make_unique<waffle::ReferenceStringFactory>();
auto composer = create_circuit(constraint_system, std::move(crs_factory));
auto proving_key = composer.compute_proving_key();

// Computing the size of the serialized key is non trivial. We know it's ~331mb.
// Allocate a buffer large enough to hold it, and abort if we overflow.
// This is to keep memory usage down.
size_t total_buf_len = 350 * 1024 * 1024;
auto raw_buf = (uint8_t*)malloc(total_buf_len);
auto raw_buf_end = raw_buf;
write(raw_buf_end, *proving_key);
*pk_buf = raw_buf;
auto len = static_cast<uint32_t>(raw_buf_end - raw_buf);
if (len > total_buf_len) {
info("Buffer overflow serializing proving key.");
std::abort();
}
return len;
}

size_t c_init_verification_key(void* pippenger, uint8_t const* g2x, uint8_t const* pk_buf, uint8_t const** vk_buf)
{
std::shared_ptr<waffle::ProverReferenceString> crs;
waffle::proving_key_data pk_data;
read(pk_buf, pk_data);
auto proving_key = std::make_shared<waffle::proving_key>(std::move(pk_data), crs);

auto crs_factory = std::make_unique<waffle::PippengerReferenceStringFactory>(
reinterpret_cast<scalar_multiplication::Pippenger*>(pippenger), g2x);
proving_key->reference_string = crs_factory->get_prover_crs(proving_key->n);

waffle::TurboComposer composer(proving_key, nullptr);
auto verification_key =
waffle::turbo_composer::compute_verification_key(proving_key, crs_factory->get_verifier_crs());

// The composer_type has not yet been set. We need to set the composer_type for when we later read in and
// construct the verification key so that we have the correct polynomial manifest
verification_key->composer_type = waffle::ComposerType::TURBO;

auto buffer = to_buffer(*verification_key);
auto raw_buf = (uint8_t*)malloc(buffer.size());
memcpy(raw_buf, (void*)buffer.data(), buffer.size());
*vk_buf = raw_buf;

return buffer.size();
}

size_t c_new_proof(void* pippenger,
uint8_t const* g2x,
uint8_t const* pk_buf,
uint8_t const* constraint_system_buf,
uint8_t const* witness_buf,
uint8_t** proof_data_buf)
{
auto constraint_system = from_buffer<waffle::standard_format>(constraint_system_buf);

std::shared_ptr<waffle::ProverReferenceString> crs;
waffle::proving_key_data pk_data;
read(pk_buf, pk_data);
auto proving_key = std::make_shared<waffle::proving_key>(std::move(pk_data), crs);

auto witness = from_buffer<std::vector<fr>>(witness_buf);

auto crs_factory = std::make_unique<waffle::PippengerReferenceStringFactory>(
reinterpret_cast<scalar_multiplication::Pippenger*>(pippenger), g2x);
proving_key->reference_string = crs_factory->get_prover_crs(proving_key->n);

waffle::TurboComposer composer(proving_key, nullptr);
create_circuit_with_witness(composer, constraint_system, witness);

auto prover = composer.create_prover();
auto heapProver = new Prover(std::move(prover));
auto& proof_data = heapProver->construct_proof().proof_data;
*proof_data_buf = proof_data.data();

return proof_data.size();
}

bool c_verify_proof(
uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length)
{
bool verified = false;

#ifndef __wasm__
try {
#endif
auto constraint_system = from_buffer<waffle::standard_format>(constraint_system_buf);

auto crs = std::make_shared<waffle::VerifierMemReferenceString>(g2x);
waffle::verification_key_data vk_data;
read(vk_buf, vk_data);
auto verification_key = std::make_shared<waffle::verification_key>(std::move(vk_data), crs);

waffle::TurboComposer composer(nullptr, verification_key);
create_circuit(composer, constraint_system);
waffle::plonk_proof pp = { std::vector<uint8_t>(proof, proof + length) };

auto verifier = composer.create_verifier();

verified = verifier.verify_proof(pp);
#ifndef __wasm__
} catch (const std::exception& e) {
verified = false;
info(e.what());
}
#endif
return verified;
}

} // namespace standard_example
} // namespace proofs
} // namespace rollup
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ uint32_t c_composer__smart_contract(void* pippenger,
uint8_t const* g2x,
uint8_t const* constraint_system_buf,
uint8_t** output_buf);

size_t c_init_proving_key(uint8_t const* constraint_system_buf, uint8_t const** pk_buf);
size_t c_init_verification_key(void* pippenger, uint8_t const* g2x, uint8_t const* pk_buf, uint8_t const** vk_buf);
size_t c_new_proof(void* pippenger,
uint8_t const* g2x,
uint8_t const* pk_buf,
uint8_t const* constraint_system_buf,
uint8_t const* witness_buf,
uint8_t** proof_data_buf);
bool c_verify_proof(
uint8_t const* g2x, uint8_t const* vk_buf, uint8_t const* constraint_system_buf, uint8_t* proof, uint32_t length);

} // namespace standard_example
} // namespace proofs
} // namespace rollup
8 changes: 4 additions & 4 deletions barretenberg_wrapper/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,17 +214,17 @@ fn link_lib_omp(toolchain: &'static str) {
match toolchain {
INTEL_LINUX | ARM_LINUX => {
let llvm_dir = find_llvm_linux_path();
println!("cargo:rustc-link-search={}/lib", llvm_dir)
println!("cargo:rustc-link-search={llvm_dir}/lib")
}
INTEL_APPLE => {
let brew_prefix = find_brew_prefix();
println!("cargo:rustc-link-search={}/opt/libomp/lib", brew_prefix)
println!("cargo:rustc-link-search={brew_prefix}/opt/libomp/lib")
}
ARM_APPLE => {
let brew_prefix = find_brew_prefix();
println!("cargo:rustc-link-search={}/opt/libomp/lib", brew_prefix)
println!("cargo:rustc-link-search={brew_prefix}/opt/libomp/lib")
}
&_ => unimplemented!("lomp linking of {} is not supported", toolchain),
&_ => unimplemented!("lomp linking of {toolchain} is not supported"),
}
match toolchain {
ARM_LINUX | INTEL_APPLE | ARM_APPLE => {
Expand Down
59 changes: 59 additions & 0 deletions barretenberg_wrapper/src/composer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,62 @@ pub unsafe fn verify(
proof.len() as u32,
)
}

/// # Safety
/// cs_prt must point to a valid constraints system structure of type standard_format
pub unsafe fn init_proving_key(cs_ptr: &[u8], pk_data_ptr: *mut *mut u8) -> u64 {
let cs_ptr = cs_ptr.as_ptr() as *const u8;
c_init_proving_key(cs_ptr, pk_data_ptr as *const *mut u8 as *mut *const u8)
}

/// # Safety
/// pippenger must point to a valid Pippenger object
pub unsafe fn init_verification_key(
pippenger: *mut ::std::os::raw::c_void,
g2_ptr: &[u8],
pk_ptr: &[u8],
vk_data_ptr: *mut *mut u8,
) -> u64 {
c_init_verification_key(
pippenger,
g2_ptr.as_ptr() as *const u8,
pk_ptr.as_ptr() as *const u8,
vk_data_ptr as *const *mut u8 as *mut *const u8,
)
}

/// # Safety
/// pippenger must point to a valid Pippenger object
pub unsafe fn create_proof_with_pk(
pippenger: *mut ::std::os::raw::c_void,
g2_ptr: &[u8],
pk_ptr: &[u8],
cs_ptr: &[u8],
witness_ptr: &[u8],
proof_data_ptr: *mut *mut u8,
) -> u64 {
let cs_ptr = cs_ptr.as_ptr() as *const u8;
let pk_ptr = pk_ptr.as_ptr() as *const u8;
c_new_proof(
pippenger,
g2_ptr.as_ptr() as *const u8,
pk_ptr,
cs_ptr,
witness_ptr.as_ptr() as *const u8,
proof_data_ptr as *const *mut u8 as *mut *mut u8,
)
}

/// # Safety
/// cs_prt must point to a valid constraints system structure of type standard_format
pub unsafe fn verify_with_vk(g2_ptr: &[u8], vk_ptr: &[u8], cs_ptr: &[u8], proof: &[u8]) -> bool {
let proof_ptr = proof.as_ptr() as *const u8;

c_verify_proof(
g2_ptr.as_ptr() as *const u8,
vk_ptr.as_ptr() as *const u8,
cs_ptr.as_ptr() as *const u8,
proof_ptr as *mut u8,
proof.len() as u32,
)
}