Skip to content
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
1 change: 1 addition & 0 deletions barretenberg/acir_tests/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ function test_cmds {
for t in assert_statement a_1_mul slices verify_honk_proof; do
echo "$sol_prefix $scripts/bb_prove_sol_verify.sh $t --disable_zk"
echo "$sol_prefix $scripts/bb_prove_sol_verify.sh $t"
echo "$sol_prefix USE_OPTIMIZED_CONTRACT=true $scripts/bb_prove_sol_verify.sh $t"
done
# prove with bb cli and verify with bb.js classes
echo "$sol_prefix $scripts/bb_prove_bbjs_verify.sh a_1_mul"
Expand Down
9 changes: 8 additions & 1 deletion barretenberg/acir_tests/scripts/bb_prove_sol_verify.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ for arg in "$@"; do
flags+=" $arg"
done

USE_OPTIMIZED_CONTRACT=${USE_OPTIMIZED_CONTRACT:-false}

write_contract_flags=$flags
if [[ -z "$USE_OPTIMIZED_CONTRACT" ]]; then
write_contract_flags+=" --optimized"
fi

# Check if --disable_zk is in the flags to determine HAS_ZK
if [[ "$flags" == *"--disable_zk"* ]]; then
has_zk="false"
Expand All @@ -29,7 +36,7 @@ trap "rm -rf output-$$" EXIT
# Create a proof, write the solidity contract, write the proof as fields in order to extract the public inputs
$bb prove $flags -b target/program.json --oracle_hash keccak --output_format bytes_and_fields --write_vk -o output-$$
$bb verify $flags --oracle_hash keccak -i output-$$/public_inputs -k output-$$/vk -p output-$$/proof
$bb write_solidity_verifier $flags -k output-$$/vk -o output-$$/Verifier.sol
$bb write_solidity_verifier $write_contract_flags -k output-$$/vk -o output-$$/Verifier.sol

# Use solcjs to compile the generated key contract with the template verifier and test contract
# index.js will start an anvil, on a random port
Expand Down
2 changes: 1 addition & 1 deletion barretenberg/acir_tests/sol-test/HonkTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ contract Test {
verifier = new HonkVerifier();
}

function test(bytes calldata proof, bytes32[] calldata publicInputs) public view returns (bool) {
function test(bytes calldata proof, bytes32[] calldata publicInputs) public returns (bool) {
return verifier.verify(proof, publicInputs);
}
}
3 changes: 3 additions & 0 deletions barretenberg/acir_tests/sol-test/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,9 @@ try {
// Deploy the library
console.log("Deploying ZKTranscriptLib library...");
const libraryAddress = await deploy(signer, libraryAbi, libraryBytecode);

// Wait for the library deployment - for some reason we have an issue with nonces here
await new Promise((resolve) => setTimeout(resolve, 500));
console.log("ZKTranscriptLib deployed at:", libraryAddress);

// Link the library to the verifier bytecode
Expand Down
2 changes: 2 additions & 0 deletions barretenberg/cpp/src/barretenberg/api/api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class API {
bool slow_low_memory{ false }; // use file backed memory for polynomials
bool update_inputs{ false }; // update inputs when check fails

bool optimized_solidity_verifier{ false }; // should we use the optimized sol verifier? (temp)

friend std::ostream& operator<<(std::ostream& os, const Flags& flags)
{
os << "flags: [\n"
Expand Down
4 changes: 3 additions & 1 deletion barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp"
#include "barretenberg/dsl/acir_format/proof_surgeon.hpp"
#include "barretenberg/dsl/acir_proofs/honk_contract.hpp"
#include "barretenberg/dsl/acir_proofs/honk_optimized_contract.hpp"
#include "barretenberg/dsl/acir_proofs/honk_zk_contract.hpp"
#include "barretenberg/honk/proof_system/types/proof.hpp"
#include "barretenberg/numeric/uint256/uint256.hpp"
Expand Down Expand Up @@ -236,7 +237,8 @@ void UltraHonkAPI::write_solidity_verifier(const Flags& flags,
// Convert flags to ProofSystemSettings
bbapi::ProofSystemSettings settings{ .ipa_accumulation = flags.ipa_accumulation,
.oracle_hash_type = flags.oracle_hash_type,
.disable_zk = flags.disable_zk };
.disable_zk = flags.disable_zk,
.optimized_solidity_verifier = flags.optimized_solidity_verifier };

// Execute solidity verifier command
auto response = bbapi::CircuitWriteSolidityVerifier{ .verification_key = vk_bytes, .settings = settings }.execute();
Expand Down
6 changes: 6 additions & 0 deletions barretenberg/cpp/src/barretenberg/bb/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,11 @@ int parse_and_run_cli_command(int argc, char* argv[])
return subcommand->add_flag("--update_inputs", flags.update_inputs, "Update inputs if vk check fails.");
};

const auto add_optimized_solidity_verifier_flag = [&](CLI::App* subcommand) {
return subcommand->add_flag(
"--optimized", flags.optimized_solidity_verifier, "Use the optimized Solidity verifier.");
};

bool print_op_counts = false;
const auto add_print_op_counts_flag = [&](CLI::App* subcommand) {
return subcommand->add_flag("--print_op_counts", print_op_counts, "Print op counts to json on one line.");
Expand Down Expand Up @@ -412,6 +417,7 @@ int parse_and_run_cli_command(int argc, char* argv[])
add_verbose_flag(write_solidity_verifier);
remove_zk_option(write_solidity_verifier);
add_crs_path_option(write_solidity_verifier);
add_optimized_solidity_verifier_flag(write_solidity_verifier);

/***************************************************************************************************************
* Subcommand: OLD_API
Expand Down
5 changes: 4 additions & 1 deletion barretenberg/cpp/src/barretenberg/bbapi/bbapi_shared.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ struct ProofSystemSettings {
*/
bool disable_zk = false;

MSGPACK_FIELDS(ipa_accumulation, oracle_hash_type, disable_zk);
// TODO(md): remove this once considered stable
bool optimized_solidity_verifier = false;

MSGPACK_FIELDS(ipa_accumulation, oracle_hash_type, disable_zk, optimized_solidity_verifier);
bool operator==(const ProofSystemSettings& other) const = default;
};

Expand Down
10 changes: 10 additions & 0 deletions barretenberg/cpp/src/barretenberg/bbapi/bbapi_ultra_honk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp"
#include "barretenberg/dsl/acir_format/serde/witness_stack.hpp"
#include "barretenberg/dsl/acir_proofs/honk_contract.hpp"
#include "barretenberg/dsl/acir_proofs/honk_optimized_contract.hpp"
#include "barretenberg/dsl/acir_proofs/honk_zk_contract.hpp"
#include "barretenberg/flavor/mega_flavor.hpp"
#include "barretenberg/flavor/ultra_flavor.hpp"
Expand Down Expand Up @@ -340,8 +341,17 @@ CircuitWriteSolidityVerifier::Response CircuitWriteSolidityVerifier::execute(BB_
{
using VK = UltraKeccakFlavor::VerificationKey;
auto vk = std::make_shared<VK>(from_buffer<VK>(verification_key));

std::string contract = settings.disable_zk ? get_honk_solidity_verifier(vk) : get_honk_zk_solidity_verifier(vk);

// If in wasm, we dont include the optimized solidity verifier - due to its large bundle size
// This will run generate twice, but this should only be run before deployment and not frequently
#ifndef __wasm__
if (settings.disable_zk && settings.optimized_solidity_verifier) {
contract = get_optimized_honk_solidity_verifier(vk);
}
#endif

return { std::move(contract) };
}

Expand Down
61 changes: 29 additions & 32 deletions barretenberg/cpp/src/barretenberg/dsl/acir_proofs/honk_contract.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ static const char HONK_CONTRACT_SOURCE[] = R"(
pragma solidity ^0.8.27;

interface IVerifier {
function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external view returns (bool);
function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external returns (bool);
}

type Fr is uint256;
Expand Down Expand Up @@ -68,7 +68,7 @@ library FrLib {
mstore(add(free, 0x20), 0x20)
mstore(add(free, 0x40), 0x20)
mstore(add(free, 0x60), v)
mstore(add(free, 0x80), sub(MODULUS, 2))
mstore(add(free, 0x80), sub(MODULUS, 2))
mstore(add(free, 0xa0), MODULUS)
let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)
if iszero(success) {
Expand All @@ -92,7 +92,7 @@ library FrLib {
mstore(add(free, 0x20), 0x20)
mstore(add(free, 0x40), 0x20)
mstore(add(free, 0x60), b)
mstore(add(free, 0x80), v)
mstore(add(free, 0x80), v)
mstore(add(free, 0xa0), MODULUS)
let success := staticcall(gas(), 0x05, free, 0xc0, 0x00, 0x20)
if iszero(success) {
Expand Down Expand Up @@ -674,6 +674,7 @@ library RelationsLib {
accumulateNnfRelation(purportedEvaluations, evaluations, powPartialEval);
accumulatePoseidonExternalRelation(purportedEvaluations, evaluations, powPartialEval);
accumulatePoseidonInternalRelation(purportedEvaluations, evaluations, powPartialEval);

// batch the subrelations with the alpha challenges to obtain the full honk relation
accumulator = scaleAndBatchSubrelations(evaluations, alphas);
}
Expand Down Expand Up @@ -1051,7 +1052,7 @@ library RelationsLib {
ap.index_delta = wire(p, WIRE.W_L_SHIFT) - wire(p, WIRE.W_L);
ap.record_delta = wire(p, WIRE.W_4_SHIFT) - wire(p, WIRE.W_4);

ap.index_is_monotonically_increasing = ap.index_delta * ap.index_delta - ap.index_delta; // deg 2
ap.index_is_monotonically_increasing = ap.index_delta * (ap.index_delta - Fr.wrap(1)); // deg 2

ap.adjacent_values_match_if_adjacent_indices_match = (ap.index_delta * MINUS_ONE + ONE) * ap.record_delta; // deg 2

Expand Down Expand Up @@ -1082,7 +1083,7 @@ library RelationsLib {
* with a WRITE operation.
*/
Fr access_type = (wire(p, WIRE.W_4) - ap.partial_record_check); // will be 0 or 1 for honest Prover; deg 1 or 4
ap.access_check = access_type * access_type - access_type; // check value is 0 or 1; deg 2 or 8
ap.access_check = access_type * (access_type - Fr.wrap(1)); // check value is 0 or 1; deg 2 or 8

// reverse order we could re-use `ap.partial_record_check` 1 - ((w3' * eta + w2') * eta + w1') * eta
// deg 1 or 4
Expand Down Expand Up @@ -1256,7 +1257,7 @@ library RelationsLib {
function accumulatePoseidonExternalRelation(
Fr[NUMBER_OF_ENTITIES] memory p,
Fr[NUMBER_OF_SUBRELATIONS] memory evals,
Fr domainSep // i guess this is the scaling factor?
Fr domainSep
) internal pure {
PoseidonExternalParams memory ep;

Expand Down Expand Up @@ -1354,7 +1355,7 @@ library RelationsLib {
Fr[NUMBER_OF_SUBRELATIONS] memory evaluations,
Fr[NUMBER_OF_ALPHAS] memory subrelationChallenges
) internal pure returns (Fr accumulator) {
accumulator = accumulator + evaluations[0];
accumulator = evaluations[0];

for (uint256 i = 1; i < NUMBER_OF_SUBRELATIONS; ++i) {
accumulator = accumulator + evaluations[i] * subrelationChallenges[i - 1];
Expand Down Expand Up @@ -1421,10 +1422,9 @@ library CommitmentSchemeLib {
);
// Divide by the denominator
batchedEvalRoundAcc = batchedEvalRoundAcc * (challengePower * (ONE - u) + u).invert();
if (i <= logSize) {
batchedEvalAccumulator = batchedEvalRoundAcc;
foldPosEvaluations[i - 1] = batchedEvalRoundAcc;
}

batchedEvalAccumulator = batchedEvalRoundAcc;
foldPosEvaluations[i - 1] = batchedEvalRoundAcc;
}
return foldPosEvaluations;
}
Expand Down Expand Up @@ -2073,27 +2073,24 @@ abstract contract BaseHonkVerifier is IVerifier {
// Compute Shplonk constant term contributions from Aₗ(± r^{2ˡ}) for l = 1, ..., m-1;
// Compute scalar multipliers for each fold commitment
for (uint256 i = 0; i < $LOG_N - 1; ++i) {
bool dummy_round = i >= ($LOG_N - 1);

if (!dummy_round) {
// Update inverted denominators
mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[i + 1]).invert();
mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[i + 1]).invert();

// Compute the scalar multipliers for Aₗ(± r^{2ˡ}) and [Aₗ]
mem.scalingFactorPos = mem.batchingChallenge * mem.posInvertedDenominator;
mem.scalingFactorNeg = mem.batchingChallenge * tp.shplonkNu * mem.negInvertedDenominator;
// [Aₗ] is multiplied by -v^{2l}/(z-r^{2^l}) - v^{2l+1} /(z+ r^{2^l})
scalars[NUMBER_UNSHIFTED + 1 + i] = mem.scalingFactorNeg.neg() + mem.scalingFactorPos.neg();

// Accumulate the const term contribution given by
// v^{2l} * Aₗ(r^{2ˡ}) /(z-r^{2^l}) + v^{2l+1} * Aₗ(-r^{2ˡ}) /(z+ r^{2^l})
Fr accumContribution = mem.scalingFactorNeg * proof.geminiAEvaluations[i + 1];
accumContribution = accumContribution + mem.scalingFactorPos * foldPosEvaluations[i + 1];
mem.constantTermAccumulator = mem.constantTermAccumulator + accumContribution;
// Update the running power of v
mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;
}
// Update inverted denominators
mem.posInvertedDenominator = (tp.shplonkZ - powers_of_evaluation_challenge[i + 1]).invert();
mem.negInvertedDenominator = (tp.shplonkZ + powers_of_evaluation_challenge[i + 1]).invert();

// Compute the scalar multipliers for Aₗ(± r^{2ˡ}) and [Aₗ]
mem.scalingFactorPos = mem.batchingChallenge * mem.posInvertedDenominator;
mem.scalingFactorNeg = mem.batchingChallenge * tp.shplonkNu * mem.negInvertedDenominator;
// [Aₗ] is multiplied by -v^{2l}/(z-r^{2^l}) - v^{2l+1} /(z+ r^{2^l})
scalars[NUMBER_UNSHIFTED + 1 + i] = mem.scalingFactorNeg.neg() + mem.scalingFactorPos.neg();

// Accumulate the const term contribution given by
// v^{2l} * Aₗ(r^{2ˡ}) /(z-r^{2^l}) + v^{2l+1} * Aₗ(-r^{2ˡ}) /(z+ r^{2^l})
Fr accumContribution = mem.scalingFactorNeg * proof.geminiAEvaluations[i + 1];

accumContribution = accumContribution + mem.scalingFactorPos * foldPosEvaluations[i + 1];
mem.constantTermAccumulator = mem.constantTermAccumulator + accumContribution;
// Update the running power of v
mem.batchingChallenge = mem.batchingChallenge * tp.shplonkNu * tp.shplonkNu;

commitments[NUMBER_UNSHIFTED + 1 + i] = proof.geminiFoldComms[i];
}
Expand Down
Loading
Loading