Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
honk_key_gen.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Completed, auditors: [Sergei], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
8
10#include <array>
11#include <ostream>
12#include <string>
13#include <string_view>
14#include <type_traits>
15#include <utility>
16
27inline void output_vk_sol_ultra_honk(std::ostream& os,
28 auto const& key,
29 std::string const& class_name,
30 bool include_types_import = false)
31{
32 const auto print_u256_const = [&](const auto& element, const std::string& name) {
33 os << "uint256 constant " << name << " = " << element << ";" << std::endl;
34 };
35
36 const auto print_u256 = [&](const auto& element, const std::string& name) {
37 os << " " << name << ": uint256(" << element << ")," << std::endl;
38 };
39
40 const auto print_g1 = [&](const auto& element, const std::string& name, const bool last = false) {
41 // Route through U256Codec so the EIP-196 canonical (0, 0) is emitted for
42 // points at infinity (e.g. selectors that commit to identically-zero polys),
43 // matching the proof-side transcript codec.
44 const auto coords =
45 bb::U256Codec::template serialize_to_fields<std::remove_cvref_t<decltype(element)>>(element);
46 os << " " << name << ": Honk.G1Point({ \n"
47 << " x: uint256(" << coords[0] << "),\n"
48 << " y: uint256(" << coords[1] << ")\n"
49 << " })";
50
51 // only include comma if we are not the last element
52 if (!last) {
53 os << ",\n";
54 } else {
55 os << "\n";
56 }
57 };
58
59 // Include the types import if working with the local test suite
60 const auto print_types_import = [&]() {
61 if (include_types_import) {
62 os << "import { Honk } from \"../HonkTypes.sol\";\n";
63 }
64 };
65
66 // clang-format off
67 os <<
68"// SPDX-License-Identifier: Apache-2.0\n"
69 "// Copyright 2022 Aztec\n"
70 "pragma solidity >=0.8.21;\n"
71 "\n"
72 "";
73 print_types_import();
74 print_u256_const(1 << key->log_circuit_size, "N");
75 print_u256_const(key->log_circuit_size, "LOG_N");
76 print_u256_const(key->num_public_inputs, "NUMBER_OF_PUBLIC_INPUTS");
77 print_u256_const(key->hash(), "VK_HASH");
78 os << ""
79 "library " << class_name << " {\n"
80 " function loadVerificationKey() internal pure returns (Honk.VerificationKey memory) {\n"
81 " Honk.VerificationKey memory vk = Honk.VerificationKey({\n";
82 print_u256(1 << key->log_circuit_size, "circuitSize");
83 print_u256(key->log_circuit_size, "logCircuitSize");
84 print_u256(key->num_public_inputs, "publicInputsSize");
85 using Commitment = std::remove_cvref_t<decltype(key->q_l())>;
86
87 // (commitment, Solidity field name) pairs in on-chain VK struct order. The array length is the
88 // single source of truth for the number of emitted G1 points; the static_assert pins it to the
89 // flavor so adding/removing a precomputed entity fails to compile here rather than silently
90 // drifting the emitted Solidity VK out of sync with the C++ layout.
91 const auto precomputed_commitments = std::to_array<std::pair<Commitment, std::string_view>>({
92 { key->q_l(), "ql" },
93 { key->q_r(), "qr" },
94 { key->q_o(), "qo" },
95 { key->q_4(), "q4" },
96 { key->q_m(), "qm" },
97 { key->q_c(), "qc" },
98 { key->q_lookup(), "qLookup" },
99 { key->q_arith(), "qArith" },
100 { key->q_delta_range(), "qDeltaRange" },
101 { key->q_elliptic(), "qElliptic" },
102 { key->q_memory(), "qMemory" },
103 { key->q_nnf(), "qNnf" },
104 { key->q_poseidon2_external(), "qPoseidon2External" },
105 { key->q_poseidon2_internal(), "qPoseidon2Internal" },
106 { key->sigma_1(), "s1" },
107 { key->sigma_2(), "s2" },
108 { key->sigma_3(), "s3" },
109 { key->sigma_4(), "s4" },
110 { key->table_1(), "t1" },
111 { key->table_2(), "t2" },
112 { key->table_3(), "t3" },
113 { key->table_4(), "t4" },
114 { key->id_1(), "id1" },
115 { key->id_2(), "id2" },
116 { key->id_3(), "id3" },
117 { key->id_4(), "id4" },
118 { key->lagrange_first(), "lagrangeFirst" },
119 { key->lagrange_last(), "lagrangeLast" },
120 });
121
122 // lhs = no of precomputed commitments listed above
123 // rhs = no of precomputed commitments in the verification key
124 static_assert(std::tuple_size_v<decltype(precomputed_commitments)> ==
125 std::remove_cvref_t<decltype(*key)>::size(),
126 "honk_key_gen G1 emission list is out of sync with the flavor's precomputed entity count");
127
128 // print the precomputed commitments
129 for (size_t i = 0; i < precomputed_commitments.size(); ++i) {
130 const auto& [commitment, name] = precomputed_commitments[i];
131 print_g1(commitment, std::string(name), /*last=*/i + 1 == precomputed_commitments.size());
132 }
133 os <<
134 " });\n"
135 " return vk;\n"
136 " }\n"
137 "}\n";
138
139 os << std::flush;
140}
141
142
void output_vk_sol_ultra_honk(std::ostream &os, auto const &key, std::string const &class_name, bool include_types_import=false)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string name