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

feat: solidity honk verifier #5485

Merged
merged 32 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
fa6a841
feat(honk): verifier start
Maddiaa0 Feb 26, 2024
fabd169
temp
Maddiaa0 Mar 4, 2024
43cd61a
Merge branch 'master' into md/02-26-feat_honk_verifier_start
Maddiaa0 Mar 19, 2024
323e7b0
temp - get it compiling
Maddiaa0 Mar 20, 2024
ff22c01
Merge branch 'master' into md/02-26-feat_honk_verifier_start
Maddiaa0 Mar 20, 2024
1ed41cb
temp
Maddiaa0 Mar 20, 2024
78d45b0
temp 2
Maddiaa0 Mar 20, 2024
b7881f1
feat: fiat shamir complete
Maddiaa0 Mar 20, 2024
a724d30
feat: experiment with a custom Fr type
Maddiaa0 Mar 21, 2024
dd85f2d
feat: oink verifier stages
Maddiaa0 Mar 21, 2024
538f432
feat: arith, perm, lookup, gen perm relation
Maddiaa0 Mar 23, 2024
654ab55
feat: field inversions
Maddiaa0 Mar 23, 2024
b9fe7ba
feat: elliptic relation
Maddiaa0 Mar 23, 2024
7f94eb2
feat: sumcheck complete
Maddiaa0 Mar 25, 2024
b510ca8
feat: start zm
Maddiaa0 Mar 26, 2024
1da70e0
feat: more zm
Maddiaa0 Mar 26, 2024
6c5da89
feat: honk verification
Maddiaa0 Mar 27, 2024
d131397
chore: remove logs for gas accounting
Maddiaa0 Mar 27, 2024
b914b69
🧹
Maddiaa0 Mar 30, 2024
1443210
🧹
Maddiaa0 Mar 30, 2024
ecd7af6
🧹
Maddiaa0 Mar 30, 2024
2f9a5d0
🧹
Maddiaa0 Apr 1, 2024
60e2a7a
chore: add verifier for 3 circuit types
Maddiaa0 Apr 1, 2024
56c28fb
fix: fix fuzz tests
Maddiaa0 Apr 1, 2024
3f5a478
fix: add extra check and invert checkSum result
Maddiaa0 Apr 16, 2024
f08a0ec
Merge branch 'master' into md/02-26-feat_honk_verifier_start
Maddiaa0 Jul 16, 2024
9d7a651
temp
Maddiaa0 Jul 17, 2024
10a8eea
fix: Update honk implementation: add logderiv, scaled etas
Maddiaa0 Jul 21, 2024
b2e9eee
fix
Maddiaa0 Jul 21, 2024
eaa1c0e
Merge branch 'master' into md/02-26-feat_honk_verifier_start
Maddiaa0 Jul 21, 2024
4d26743
fix: clean up comments
Maddiaa0 Jul 21, 2024
d2906cf
fix: remove box commit
Maddiaa0 Jul 22, 2024
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 @@ -30,9 +30,10 @@ template <typename Curve_> class KZG {
* computed
* @param prover_transcript Prover transcript
*/
template <typename Transcript>
static void compute_opening_proof(std::shared_ptr<CK> ck,
const ProverOpeningClaim<Curve>& opening_claim,
const std::shared_ptr<NativeTranscript>& prover_trancript)
const std::shared_ptr<Transcript>& prover_trancript)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed because we need Keccak hashing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

{
Polynomial quotient = opening_claim.polynomial;
OpeningPair<Curve> pair = opening_claim.opening_pair;
Expand All @@ -56,7 +57,9 @@ template <typename Curve_> class KZG {
* - P₀ = C − v⋅[1]₁ + r⋅[W(x)]₁
* - P₁ = [W(x)]₁
*/
static VerifierAccumulator reduce_verify(const OpeningClaim<Curve>& claim, const auto& verifier_transcript)
template <typename Transcript>
static VerifierAccumulator reduce_verify(const OpeningClaim<Curve>& claim,
const std::shared_ptr<Transcript>& verifier_transcript)
{
auto quotient_commitment = verifier_transcript->template receive_from_prover<Commitment>("KZG:W");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,14 +322,15 @@ template <typename Curve> class ZeroMorphProver_ {
*
* @todo https://github.com/AztecProtocol/barretenberg/issues/1030: document concatenation trick
*/
template <typename Transcript>
static OpeningClaim prove(FF circuit_size,
RefSpan<Polynomial> f_polynomials,
RefSpan<Polynomial> g_polynomials,
RefSpan<FF> f_evaluations,
RefSpan<FF> g_shift_evaluations,
std::span<FF> multilinear_challenge,
const std::shared_ptr<CommitmentKey<Curve>>& commitment_key,
const std::shared_ptr<NativeTranscript>& transcript,
const std::shared_ptr<Transcript>& transcript,
RefSpan<Polynomial> concatenated_polynomials = {},
RefSpan<FF> concatenated_evaluations = {},
const std::vector<RefVector<Polynomial>>& concatenation_groups = {})
Expand Down Expand Up @@ -725,14 +726,15 @@ template <typename Curve> class ZeroMorphVerifier_ {
* @param transcript
* @return VerifierAccumulator Inputs to the final PCS verification check that will be accumulated
*/
template <typename Transcript>
static OpeningClaim<Curve> verify(FF circuit_size,
RefSpan<Commitment> unshifted_commitments,
RefSpan<Commitment> to_be_shifted_commitments,
RefSpan<FF> unshifted_evaluations,
RefSpan<FF> shifted_evaluations,
std::span<FF> multivariate_challenge,
const Commitment& g1_identity,
auto& transcript,
const std::shared_ptr<Transcript>& transcript,
const std::vector<RefVector<Commitment>>& concatenation_group_commitments = {},
RefSpan<FF> concatenated_evaluations = {})
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp"
#include "barretenberg/stdlib_circuit_builders/mega_flavor.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_keccak.hpp"
namespace bb {

template <class Flavor>
Expand Down Expand Up @@ -162,6 +163,7 @@ void ExecutionTrace_<Flavor>::add_ecc_op_wires_to_proving_key(Builder& builder,
}

template class ExecutionTrace_<UltraFlavor>;
template class ExecutionTrace_<UltraKeccakFlavor>;
template class ExecutionTrace_<MegaFlavor>;
template class ExecutionTrace_<plonk::flavor::Standard>;
template class ExecutionTrace_<plonk::flavor::Ultra>;
Expand Down
11 changes: 7 additions & 4 deletions barretenberg/cpp/src/barretenberg/flavor/flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ template <typename Tuple, std::size_t Index = 0> static constexpr auto create_tu
namespace bb {
class UltraFlavor;
class ECCVMFlavor;
class UltraKeccakFlavor;
class MegaFlavor;
class TranslatorFlavor;
template <typename BuilderType> class UltraRecursiveFlavor_;
Expand Down Expand Up @@ -383,16 +384,16 @@ template <typename T>
concept IsPlonkFlavor = IsAnyOf<T, plonk::flavor::Standard, plonk::flavor::Ultra>;

template <typename T>
concept IsUltraPlonkFlavor = IsAnyOf<T, plonk::flavor::Ultra>;
concept IsUltraPlonkFlavor = IsAnyOf<T, plonk::flavor::Ultra, UltraKeccakFlavor>;

template <typename T>
concept IsUltraPlonkOrHonk = IsAnyOf<T, plonk::flavor::Ultra, UltraFlavor, MegaFlavor>;
concept IsUltraPlonkOrHonk = IsAnyOf<T, plonk::flavor::Ultra, UltraFlavor, UltraKeccakFlavor, MegaFlavor>;

template <typename T>
concept IsHonkFlavor = IsAnyOf<T, UltraFlavor, MegaFlavor>;
concept IsHonkFlavor = IsAnyOf<T, UltraFlavor, UltraKeccakFlavor, MegaFlavor>;

template <typename T>
concept IsUltraFlavor = IsAnyOf<T, UltraFlavor, MegaFlavor>;
concept IsUltraFlavor = IsAnyOf<T, UltraFlavor, UltraKeccakFlavor, MegaFlavor>;

template <typename T>
concept IsGoblinFlavor = IsAnyOf<T, MegaFlavor,
Expand All @@ -417,6 +418,8 @@ template <typename T> concept IsECCVMRecursiveFlavor = IsAnyOf<T, ECCVMRecursive
template <typename T> concept IsGrumpkinFlavor = IsAnyOf<T, ECCVMFlavor>;

template <typename T> concept IsFoldingFlavor = IsAnyOf<T, UltraFlavor,
// Note(md): must be here to use oink prover
UltraKeccakFlavor,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah something has clearly gone wrong with the use of this concept...

MegaFlavor,
UltraRecursiveFlavor_<UltraCircuitBuilder>,
UltraRecursiveFlavor_<MegaCircuitBuilder>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
barretenberg_module(stdlib_solidity_helpers stdlib_sha256 stdlib_blake3s stdlib_blake2s stdlib_pedersen_commitment plonk)
barretenberg_module(stdlib_solidity_helpers ultra_honk stdlib_sha256 stdlib_blake3s stdlib_blake2s stdlib_pedersen_commitment plonk)

if (NOT(FUZZING))
# Honk
add_executable(honk_solidity_key_gen honk_key_gen.cpp)

target_link_libraries(
honk_solidity_key_gen
stdlib_solidity_helpers
)

add_executable(honk_solidity_proof_gen honk_proof_gen.cpp)

target_link_libraries(
honk_solidity_proof_gen
stdlib_solidity_helpers
)

# Plonk
add_executable(solidity_key_gen key_gen.cpp)

add_executable(solidity_proof_gen proof_gen.cpp)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "barretenberg/stdlib/primitives/field/field.hpp"
#include "barretenberg/stdlib/primitives/witness/witness.hpp"

namespace bb {

template <typename Builder> class EcdsaCircuit {
public:
using field_ct = stdlib::field_t<Builder>;
Expand Down Expand Up @@ -89,4 +91,6 @@ template <typename Builder> class EcdsaCircuit {

return builder;
}
};
};

} // namespace bb
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@

#include <iostream>
#include <memory>

#include "barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp"
#include "barretenberg/ultra_honk/ultra_prover.hpp"
#include "barretenberg/ultra_honk/ultra_verifier.hpp"

#include "./honk_sol_gen.hpp"

#include "circuits/add_2_circuit.hpp"
#include "circuits/blake_circuit.hpp"
#include "circuits/ecdsa_circuit.hpp"

using namespace bb;

using ProverInstance = ProverInstance_<UltraKeccakFlavor>;
using VerificationKey = UltraKeccakFlavor::VerificationKey;

template <template <typename> typename Circuit>
void generate_keys_honk(std::string output_path, std::string flavour_prefix, std::string circuit_name)
{
uint256_t public_inputs[4] = { 0, 0, 0, 0 };
UltraCircuitBuilder builder = Circuit<UltraCircuitBuilder>::generate(public_inputs);

auto instance = std::make_shared<ProverInstance>(builder);
UltraKeccakProver prover(instance);
auto verification_key = std::make_shared<VerificationKey>(instance->proving_key);

// Make verification key file upper case
circuit_name.at(0) = static_cast<char>(std::toupper(static_cast<unsigned char>(circuit_name.at(0))));
flavour_prefix.at(0) = static_cast<char>(std::toupper(static_cast<unsigned char>(flavour_prefix.at(0))));

std::string vk_class_name = circuit_name + flavour_prefix + "VerificationKey";
std::string base_class_name = "Base" + flavour_prefix + "Verifier";
std::string instance_class_name = circuit_name + flavour_prefix + "Verifier";

{
auto vk_filename = output_path + "/keys/" + vk_class_name + ".sol";
std::ofstream os(vk_filename);
bb::output_vk_sol_ultra_honk(os, verification_key, vk_class_name);
info("VK contract written to: ", vk_filename);
}
}

/*
* @brief Main entry point for the verification key generator
*
* 1. project_root_path: path to the solidity project root
* 2. srs_path: path to the srs db
*/
int main(int argc, char** argv)
{
std::vector<std::string> args(argv, argv + argc);

if (args.size() < 5) {
info("usage: ", args[0], "[plonk flavour] [circuit flavour] [output path] [srs path]");
return 1;
}

const std::string plonk_flavour = args[1];
const std::string circuit_flavour = args[2];
const std::string output_path = args[3];
const std::string srs_path = args[4];

bb::srs::init_crs_factory(srs_path);
// @todo - Add support for unrolled standard verifier. Needs a new solidity verifier contract.

if (plonk_flavour != "honk") {
info("honk");
return 1;
}

info("Generating ", plonk_flavour, " keys for ", circuit_flavour, " circuit");

if (plonk_flavour == "honk") {
if (circuit_flavour == "add2") {
generate_keys_honk<Add2Circuit>(output_path, plonk_flavour, circuit_flavour);
} else if (circuit_flavour == "blake") {
generate_keys_honk<BlakeCircuit>(output_path, plonk_flavour, circuit_flavour);
} else if (circuit_flavour == "ecdsa") {
generate_keys_honk<bb::EcdsaCircuit>(output_path, plonk_flavour, circuit_flavour);
// TODO: recursive proofs
} else {
info("Unsupported circuit");
return 1;
}
}
return 0;
} // namespace bb
105 changes: 105 additions & 0 deletions barretenberg/cpp/src/barretenberg/solidity_helpers/honk_proof_gen.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@

#include "barretenberg/honk/proof_system/types/proof.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp"
#include "barretenberg/ultra_honk/ultra_prover.hpp"
#include "barretenberg/ultra_honk/ultra_verifier.hpp"

#include "circuits/add_2_circuit.hpp"
#include "circuits/blake_circuit.hpp"
#include "circuits/ecdsa_circuit.hpp"
#include "utils/utils.hpp"

#include <iostream>
#include <sstream>

using namespace bb;
using numeric::uint256_t;

using ProverInstance = ProverInstance_<UltraKeccakFlavor>;
using VerificationKey = UltraKeccakFlavor::VerificationKey;
using Prover = UltraKeccakProver;
using Verifier = UltraKeccakVerifier;

template <template <typename> typename Circuit> void generate_proof(uint256_t inputs[])
{

UltraCircuitBuilder builder = Circuit<UltraCircuitBuilder>::generate(inputs);

auto instance = std::make_shared<ProverInstance>(builder);
Prover prover(instance);
auto verification_key = std::make_shared<VerificationKey>(instance->proving_key);
Verifier verifier(verification_key);

HonkProof proof = prover.construct_proof();
{
if (!verifier.verify_proof(proof)) {
throw_or_abort("Verification failed");
}

std::vector<uint8_t> proof_bytes = to_buffer(proof);
std::string p = bytes_to_hex_string(proof_bytes);
std::cout << p;
}
}

std::string pad_left(std::string input, size_t length)
{
return std::string(length - std::min(length, input.length()), '0') + input;
}

/**
* @brief Main entry point for the proof generator.
* Expected inputs:
* 1. plonk_flavour: ultra
* 2. circuit_flavour: blake, add2
* 3. public_inputs: comma separated list of public inputs
* 4. project_root_path: path to the solidity project root
* 5. srs_path: path to the srs db
*/
int main(int argc, char** argv)
{
std::vector<std::string> args(argv, argv + argc);

if (args.size() < 5) {
info("usage: ", args[0], "[plonk flavour] [circuit flavour] [srs path] [public inputs]");
return 1;
}

const std::string plonk_flavour = args[1];
const std::string circuit_flavour = args[2];
const std::string srs_path = args[3];
const std::string string_input = args[4];

bb::srs::init_crs_factory(srs_path);

// @todo dynamically allocate this
uint256_t inputs[] = { 0, 0, 0, 0, 0, 0 };

size_t count = 0;
std::stringstream s_stream(string_input);
while (s_stream.good()) {
std::string sub;
getline(s_stream, sub, ',');
if (sub.substr(0, 2) == "0x") {
sub = sub.substr(2);
}
std::string padded = pad_left(sub, 64);
inputs[count++] = uint256_t(padded);
}

if (plonk_flavour != "honk") {
info("Only honk flavor allowed");
return 1;
}

if (circuit_flavour == "blake") {
generate_proof<BlakeCircuit>(inputs);
} else if (circuit_flavour == "add2") {
generate_proof<Add2Circuit>(inputs);
} else if (circuit_flavour == "ecdsa") {
generate_proof<EcdsaCircuit>(inputs);
} else {
info("Invalid circuit flavour: " + circuit_flavour);
return 1;
}
}
Loading
Loading