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: codegen public input columns #56

Merged
merged 10 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
8 changes: 5 additions & 3 deletions asm_to_pil/src/vm_to_constrained.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ impl<T: FieldElement> ASMPILConverter<T> {
ty,
},
);
self.pil.push(witness_column(start, name, None));
self.pil.push(witness_column(start, name, None, false));
}

fn handle_instruction_def(
Expand Down Expand Up @@ -846,7 +846,7 @@ impl<T: FieldElement> ASMPILConverter<T> {
),
)
});
witness_column(0, free_value, prover_query)
witness_column(0, free_value, prover_query, false)
})
.collect::<Vec<_>>();
self.pil.extend(free_value_pil);
Expand Down Expand Up @@ -877,7 +877,7 @@ impl<T: FieldElement> ASMPILConverter<T> {
/// Creates a pair of witness and fixed column and matches them in the lookup.
fn create_witness_fixed_pair(&mut self, start: usize, name: &str) {
let fixed_name = format!("p_{name}");
self.pil.push(witness_column(start, name, None));
self.pil.push(witness_column(start, name, None, false));
self.line_lookup
.push((name.to_string(), fixed_name.clone()));
self.rom_constant_names.push(fixed_name);
Expand Down Expand Up @@ -1082,6 +1082,7 @@ fn witness_column<S: Into<String>, T>(
start: usize,
name: S,
def: Option<FunctionDefinition<T>>,
is_public: bool,
) -> PilStatement<T> {
PilStatement::PolynomialCommitDeclaration(
start,
Expand All @@ -1090,6 +1091,7 @@ fn witness_column<S: Into<String>, T>(
array_size: None,
}],
def,
is_public,
)
}

Expand Down
7 changes: 4 additions & 3 deletions ast/src/parsed/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,12 +375,13 @@ impl<T: Display> Display for PilStatement<T> {
PilStatement::PolynomialConstantDefinition(_, name, definition) => {
write!(f, "pol constant {name}{definition};")
}
PilStatement::PolynomialCommitDeclaration(_, names, value) => {
PilStatement::PolynomialCommitDeclaration(_, names, value, public) => {
write!(
f,
"pol commit {}{};",
"pol commit {}{}{};",
if *public { "public " } else { " " },
names.iter().format(", "),
value.as_ref().map(|v| format!("{v}")).unwrap_or_default()
value.as_ref().map(|v| format!("{v}")).unwrap_or_default(),
)
}
PilStatement::PolynomialIdentity(_, _attr, expression) => {
Expand Down
7 changes: 6 additions & 1 deletion ast/src/parsed/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ pub enum PilStatement<T> {
),
PolynomialConstantDeclaration(usize, Vec<PolynomialName<T>>),
PolynomialConstantDefinition(usize, String, FunctionDefinition<T>),
PolynomialCommitDeclaration(usize, Vec<PolynomialName<T>>, Option<FunctionDefinition<T>>),
PolynomialCommitDeclaration(
usize,
Vec<PolynomialName<T>>,
Option<FunctionDefinition<T>>,
/*public=*/ bool,
),
PolynomialIdentity(usize, Option<String>, Expression<T>),
PlookupIdentity(
usize,
Expand Down
8 changes: 4 additions & 4 deletions ast/src/parsed/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,10 @@ impl<T> ExpressionVisitable<Expression<T, NamespacedPolynomialReference>> for Pi
.try_for_each(|e| e.visit_expressions_mut(f, o)),

PilStatement::PolynomialConstantDefinition(_, _, fundef)
| PilStatement::PolynomialCommitDeclaration(_, _, Some(fundef)) => {
| PilStatement::PolynomialCommitDeclaration(_, _, Some(fundef), _) => {
fundef.visit_expressions_mut(f, o)
}
PilStatement::PolynomialCommitDeclaration(_, _, None)
PilStatement::PolynomialCommitDeclaration(_, _, None, _)
| PilStatement::Include(_, _)
| PilStatement::PolynomialConstantDeclaration(_, _)
| PilStatement::LetStatement(_, _, None) => ControlFlow::Continue(()),
Expand Down Expand Up @@ -260,10 +260,10 @@ impl<T> ExpressionVisitable<Expression<T, NamespacedPolynomialReference>> for Pi
.try_for_each(|e| e.visit_expressions(f, o)),

PilStatement::PolynomialConstantDefinition(_, _, fundef)
| PilStatement::PolynomialCommitDeclaration(_, _, Some(fundef)) => {
| PilStatement::PolynomialCommitDeclaration(_, _, Some(fundef), _) => {
fundef.visit_expressions(f, o)
}
PilStatement::PolynomialCommitDeclaration(_, _, None)
PilStatement::PolynomialCommitDeclaration(_, _, None, _)
| PilStatement::Include(_, _)
| PilStatement::PolynomialConstantDeclaration(_, _)
| PilStatement::LetStatement(_, _, None) => ControlFlow::Continue(()),
Expand Down
7 changes: 7 additions & 0 deletions bberg/src/flavor_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,14 @@ fn create_commitment_labels(all_ents: &[String]) -> String {
)
}

/// Create the compute_logderivative_inverses function
///
/// If we do not have any lookups, we do not need to include this round
fn create_compute_logderivative_inverses(flavor_name: &str, lookups: &[String]) -> String {
if lookups.is_empty() {
return "".to_string();
}

let compute_inverse_transformation = |lookup_name: &String| {
format!("bb::compute_logderivative_inverse<{flavor_name}Flavor, {lookup_name}_relation<FF>>(prover_polynomials, relation_parameters, this->circuit_size);")
};
Expand Down
14 changes: 12 additions & 2 deletions bberg/src/prover_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub trait ProverBuilder {
impl ProverBuilder for BBFiles {
fn create_prover_hpp(&mut self, name: &str) {
let include_str = includes_hpp(&snake_case(name));

let prover_hpp = format!("
{include_str}
namespace bb {{
Expand Down Expand Up @@ -91,7 +92,16 @@ impl ProverBuilder for BBFiles {
let include_str = includes_cpp(&snake_case(name));

let polynomial_commitment_phase = create_commitments_phase(commitment_polys);
let log_derivative_inverse_phase = create_log_derivative_inverse_round(lookup_names);

let (call_log_derivative_phase, log_derivative_inverse_phase): (String, String) =
if lookup_names.is_empty() {
("".to_owned(), "".to_owned())
} else {
(
"execute_log_derivative_inverse_round();".to_owned(),
create_log_derivative_inverse_round(lookup_names),
)
};

let prover_cpp = format!("
{include_str}
Expand Down Expand Up @@ -208,7 +218,7 @@ impl ProverBuilder for BBFiles {
execute_wire_commitments_round();

// Compute sorted list accumulator and commitment
execute_log_derivative_inverse_round();
{call_log_derivative_phase}

// Fiat-Shamir: alpha
// Run sumcheck subprotocol.
Expand Down
95 changes: 86 additions & 9 deletions bberg/src/verifier_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,25 @@ use crate::{
};

pub trait VerifierBuilder {
fn create_verifier_cpp(&mut self, name: &str, witness: &[String], inverses: &[String]);
fn create_verifier_cpp(
&mut self,
name: &str,
witness: &[String],
inverses: &[String],
public_cols: &[String],
);

fn create_verifier_hpp(&mut self, name: &str);
fn create_verifier_hpp(&mut self, name: &str, public_cols: &[String]);
}

impl VerifierBuilder for BBFiles {
fn create_verifier_cpp(&mut self, name: &str, witness: &[String], inverses: &[String]) {
fn create_verifier_cpp(
&mut self,
name: &str,
witness: &[String],
inverses: &[String],
public_cols: &[String],
) {
let include_str = includes_cpp(&snake_case(name));

let wire_transformation = |n: &String| {
Expand All @@ -19,12 +31,63 @@ impl VerifierBuilder for BBFiles {
)
};
let wire_commitments = map_with_newline(witness, wire_transformation);

let has_public_input_columns = !public_cols.is_empty();
let has_inverses = !inverses.is_empty();

let get_inverse_challenges = if has_inverses {
"
auto [beta, gamm] = transcript->template get_challenges<FF>(\"beta\", \"gamma\");
relation_parameters.beta = beta;
relation_parameters.gamma = gamm;
"
.to_string()
} else {
"".to_owned()
};

let verify_proof_function_declaration: String = if has_public_input_columns {
format!("bool {name}Verifier::verify_proof(const HonkProof& proof, const std::vector<FF>& public_inputs)")
} else {
format!("bool {name}Verifier::verify_proof(const HonkProof& proof)")
};

let (public_inputs_check, evaluate_public_inputs) = if has_public_input_columns {
let public_inputs_column = public_cols[0].clone(); // asserted to be 1 for the meantime, this will be generalized when required
let inputs_check = format!(
"
FF public_column_evaluation = evaluate_public_input_column(public_inputs, multivariate_challenge);
if (public_column_evaluation != claimed_evaluations.{public_inputs_column}) {{
return false;
}}
"
);
let evaluate_public_inputs = format!(
"

using FF = {name}Flavor::FF;

// Evaluate the given public input column over the multivariate challenge points
[[maybe_unused]] FF evaluate_public_input_column(std::vector<FF> points, std::vector<FF> challenges) {{
Polynomial<FF> polynomial(points);
return polynomial.evaluate_mle(challenges);
}}
"
);

(inputs_check, evaluate_public_inputs)
} else {
("".to_owned(), "".to_owned())
};

let inverse_commitments = map_with_newline(inverses, wire_transformation);

let ver_cpp = format!("
{include_str}

namespace bb {{


{name}Verifier::{name}Verifier(std::shared_ptr<Flavor::VerificationKey> verifier_key)
: key(verifier_key)
{{}}
Expand All @@ -41,12 +104,15 @@ impl VerifierBuilder for BBFiles {
commitments.clear();
return *this;
}}

{evaluate_public_inputs}


/**
* @brief This function verifies an {name} Honk proof for given program settings.
*
*/
bool {name}Verifier::verify_proof(const HonkProof& proof)
{verify_proof_function_declaration}
{{
using Flavor = {name}Flavor;
using FF = Flavor::FF;
Expand All @@ -72,9 +138,7 @@ impl VerifierBuilder for BBFiles {
// Get commitments to VM wires
{wire_commitments}

auto [beta, gamm] = transcript->template get_challenges<FF>(\"beta\", \"gamma\");
relation_parameters.beta = beta;
relation_parameters.gamma = gamm;
{get_inverse_challenges}

// Get commitments to inverses
{inverse_commitments}
Expand All @@ -97,6 +161,8 @@ impl VerifierBuilder for BBFiles {
if (sumcheck_verified.has_value() && !sumcheck_verified.value()) {{
return false;
}}

{public_inputs_check}

// Execute ZeroMorph rounds. See https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view for a complete description of the
// unrolled protocol.
Expand Down Expand Up @@ -126,8 +192,18 @@ impl VerifierBuilder for BBFiles {
);
}

fn create_verifier_hpp(&mut self, name: &str) {
fn create_verifier_hpp(&mut self, name: &str, public_cols: &[String]) {
let include_str = include_hpp(&snake_case(name));

// If there are public input columns, then the generated verifier must take them in as an argument for the verify_proof
// TODO: cleanup
Maddiaa0 marked this conversation as resolved.
Show resolved Hide resolved
let verify_proof = if !public_cols.is_empty() {
"bool verify_proof(const HonkProof& proof, const std::vector<FF>& public_inputs);"
.to_string()
} else {
"bool verify_proof(const HonkProof& proof);".to_owned()
};

let ver_hpp = format!(
"
{include_str}
Expand All @@ -149,7 +225,7 @@ impl VerifierBuilder for BBFiles {
{name}Verifier& operator=(const {name}Verifier& other) = delete;
{name}Verifier& operator=({name}Verifier&& other) noexcept;

bool verify_proof(const HonkProof& proof);
{verify_proof}

std::shared_ptr<VerificationKey> key;
std::map<std::string, Commitment> commitments;
Expand Down Expand Up @@ -188,6 +264,7 @@ fn includes_cpp(name: &str) -> String {
#include \"./{name}_verifier.hpp\"
#include \"barretenberg/commitment_schemes/zeromorph/zeromorph.hpp\"
#include \"barretenberg/numeric/bitop/get_msb.hpp\"
#include \"barretenberg/polynomials/polynomial.hpp\"
#include \"barretenberg/transcript/transcript.hpp\"
"
)
Expand Down
Loading
Loading