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: add poseidon relations to UltraKeccak flavor and Solidity verifier #8243

Merged
merged 31 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7ed2034
ensure UltraKeccak Flavor works with Poseidon relations added
maramihali Aug 21, 2024
ccd4310
solidity work
maramihali Aug 27, 2024
ca90281
it works?
maramihali Aug 30, 2024
83b1676
actually reduce contract size
maramihali Sep 3, 2024
1f31dbf
actually reduce contract size
maramihali Sep 3, 2024
5f66aeb
deployed external libraries separately, change constants
maramihali Sep 3, 2024
b959b99
Merge remote-tracking branch 'refs/remotes/origin/mm/poseidon-in-soli…
maramihali Sep 4, 2024
b112c01
Merge remote-tracking branch 'origin/master' into mm/poseidon-in-soli…
maramihali Sep 4, 2024
ed4b6ee
handle the changes in sol-test so that it still works for both honk a…
maramihali Sep 4, 2024
061cb0c
Merge branch 'master' into mm/poseidon-in-solidity
maramihali Sep 4, 2024
bd23c9b
cleanup
maramihali Sep 4, 2024
af21066
Merge remote-tracking branch 'refs/remotes/origin/mm/poseidon-in-soli…
maramihali Sep 4, 2024
8b7d4f9
Merge remote-tracking branch 'origin/master' into mm/poseidon-in-soli…
maramihali Sep 4, 2024
ddf4195
undelete yarn.lock
maramihali Sep 4, 2024
83060a9
redo the console.logs
maramihali Sep 4, 2024
cbb44f9
Merge branch 'master' into mm/poseidon-in-solidity
maramihali Sep 4, 2024
7df58d2
Merge branch 'master' into mm/poseidon-in-solidity
maramihali Sep 4, 2024
0b96a88
Merge branch 'master' into mm/poseidon-in-solidity
maramihali Sep 4, 2024
f1823e6
Merge branch 'master' into mm/poseidon-in-solidity
maramihali Sep 4, 2024
9aad525
Merge remote-tracking branch 'origin/master' into mm/poseidon-in-soli…
maramihali Sep 5, 2024
5ad2e2a
revert unwanted changes to vk hashes
maramihali Sep 5, 2024
53a074c
Resolve review comments
maramihali Sep 5, 2024
ee3bb3e
Merge branch 'master' into mm/poseidon-in-solidity
maramihali Sep 5, 2024
d2877c0
fix comment
maramihali Sep 5, 2024
52a9429
Merge remote-tracking branch 'refs/remotes/origin/mm/poseidon-in-soli…
maramihali Sep 5, 2024
62f2b06
fix comment
maramihali Sep 5, 2024
17e5b2f
update comment
maramihali Sep 5, 2024
4daa0f7
make external functions internal to fix e2e prover
maramihali Sep 5, 2024
fae8cfb
Merge remote-tracking branch 'origin/master' into mm/poseidon-in-soli…
maramihali Sep 5, 2024
7202723
Merge branch 'master' into mm/poseidon-in-solidity
maramihali Sep 5, 2024
63436d3
Merge branch 'master' into mm/poseidon-in-solidity
maramihali Sep 5, 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
2 changes: 1 addition & 1 deletion barretenberg/acir_tests/flows/honk_sol.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export VERIFIER_PATH="$(pwd)/Verifier.sol"
export TEST_PATH=$(realpath "../../sol-test/HonkTest.sol")
export TESTING_HONK="true"

# Use solcjs to compile the generated key contract with the template verifier and test contract
# 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
# Deploy the verifier then send a test transaction
export TEST_NAME=$(basename $(pwd))
Expand Down
108 changes: 83 additions & 25 deletions barretenberg/acir_tests/sol-test/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ const { readFileSync, promises: fsPromises } = fs;
import { spawn } from "child_process";
import { ethers } from "ethers";
import solc from "solc";
import linker from "solc/linker.js";

const NUMBER_OF_FIELDS_IN_PLONK_PROOF = 93;
const NUMBER_OF_FIELDS_IN_HONK_PROOF = 393;
// This excludes the public inputs which are sent separately to the Solidity verifier
const NUMBER_OF_FIELDS_IN_HONK_PROOF = 423;

// We use the solcjs compiler version in this test, although it is slower than foundry, to run the test end to end
// it simplifies of parallelising the test suite
Expand Down Expand Up @@ -47,6 +49,9 @@ const [test, verifier] = await Promise.all([
fsPromises.readFile(verifierPath, encoding),
]);

// 1. figure out how to deploy the libraries
maramihali marked this conversation as resolved.
Show resolved Hide resolved
// 2. call linker.linkBytecode providing the libraries name and address

export const compilationInput = {
language: "Solidity",
sources: {
Expand All @@ -73,28 +78,26 @@ export const compilationInput = {

// If testing honk is set, then we compile the honk test suite
const testingHonk = getEnvVarCanBeUndefined("TESTING_HONK");
const NUMBER_OF_FIELDS_IN_PROOF = testingHonk ? NUMBER_OF_FIELDS_IN_HONK_PROOF : NUMBER_OF_FIELDS_IN_PLONK_PROOF;
const NUMBER_OF_FIELDS_IN_PROOF = testingHonk
? NUMBER_OF_FIELDS_IN_HONK_PROOF
: NUMBER_OF_FIELDS_IN_PLONK_PROOF;
if (!testingHonk) {
const keyPath = getEnvVar("KEY_PATH");
const basePath = getEnvVar("BASE_PATH");
const [key, base] = await Promise.all([
fsPromises.readFile(keyPath, encoding),
fsPromises.readFile(basePath, encoding),
]);

const keyPath = getEnvVar("KEY_PATH");
const basePath = getEnvVar("BASE_PATH");
const [key, base] = await Promise.all(
[
fsPromises.readFile(keyPath, encoding),
fsPromises.readFile(basePath, encoding),
]
);

compilationInput.sources["BaseUltraVerifier.sol"] = {
content: base,
};
compilationInput.sources["Key.sol"] = {
content: key,
};
compilationInput.sources["BaseUltraVerifier.sol"] = {
content: base,
};
compilationInput.sources["Key.sol"] = {
content: key,
};
}

var output = JSON.parse(solc.compile(JSON.stringify(compilationInput)));

const contract = output.contracts["Test.sol"]["Test"];
const bytecode = contract.evm.bytecode.object;
const abi = contract.abi;
Expand Down Expand Up @@ -133,7 +136,7 @@ const launchAnvil = async (port) => {
* Deploys the contract
* @param {ethers.Signer} signer
*/
const deploy = async (signer) => {
const deploy = async (signer, abi, bytecode) => {
const factory = new ethers.ContractFactory(abi, bytecode, signer);
const deployment = await factory.deploy();
const deployed = await deployment.waitForDeployment();
Expand All @@ -147,14 +150,14 @@ const deploy = async (signer) => {
*/
const readPublicInputs = (proofAsFields) => {
const publicInputs = [];
// A proof with no public inputs is 93 fields long
// Compute the number of public inputs, not accounted for in the constant NUMBER_OF_FIELDS_IN_PROOF
const numPublicInputs = proofAsFields.length - NUMBER_OF_FIELDS_IN_PROOF;
let publicInputsOffset = 0;

// Honk proofs contain 3 pieces of metadata before the public inputs, while plonk does not
if (testingHonk) {
publicInputsOffset = 3;
}
}

for (let i = 0; i < numPublicInputs; i++) {
publicInputs.push(proofAsFields[publicInputsOffset + i]);
Expand Down Expand Up @@ -215,7 +218,7 @@ try {
proofStr = proofStr.substring(8);
// Get the part before and after the public inputs
const proofStart = proofStr.slice(0, 64 * 3);
const proofEnd = proofStr.substring((64 * 3) + (64 * numPublicInputs));
const proofEnd = proofStr.substring(64 * 3 + 64 * numPublicInputs);
proofStr = proofStart + proofEnd;
} else {
proofStr = proofStr.substring(64 * numPublicInputs);
Expand All @@ -228,8 +231,63 @@ try {
const provider = await getProvider(randomPort);
const signer = new ethers.Wallet(key, provider);

// deploy
const address = await deploy(signer);
// if testing honk we need to link the external libraries to the contract's bytecode before deploying it, otherise we can just deploy the contract directly
// note ABI stays unchanged
const getDeployedContractAdress = async () => {
if (testingHonk) {
// Get the bytecode and abi of the two libraries with external calls that need to be deployed separately
const transcriptLib = output.contracts["Verifier.sol"]["TranscriptLib"];
const transcriptLibBytecode = transcriptLib.evm.bytecode.object;
const transcriptLibAbi = transcriptLib.abi;

const relationsLib = output.contracts["Verifier.sol"]["RelationsLib"];
const relationsLibBytecode = relationsLib.evm.bytecode.object;
const relationsLibAbi = relationsLib.abi;

// Deploy the two libraries, awaiting to ensure the nonce is modified correctly to prevent race conditions.
console.log(await signer.getNonce());
maramihali marked this conversation as resolved.
Show resolved Hide resolved
const transcriptLibAddress = await deploy(
signer,
transcriptLibAbi,
transcriptLibBytecode
);

// TODO: maybe this can be done in a better way
console.log(await signer.getNonce());

const relationsLibAddress = await deploy(
signer,
relationsLibAbi,
relationsLibBytecode
);

const libraries = {
TranscriptLib: transcriptLibAddress,
RelationsLib: relationsLibAddress,
};
const linkerInput = {
"Verifier.sol": {
TranscriptLib: libraries["TranscriptLib"],
RelationsLib: libraries["RelationsLib"],
},
};

// Link the libraries in the contract bytecode
const linkedBytecode = linker.linkBytecode(bytecode, linkerInput);

console.log(await signer.getNonce());

// Deploy the verifier contract
const address = await deploy(signer, abi, linkedBytecode);
return address;
} else {
const address = await deploy(signer, abi, bytecode);
return address;
}
};

const address = await getDeployedContractAdress();

const contract = new ethers.Contract(address, abi, signer);

const result = await contract.test(proofStr, publicInputs);
Expand Down
3 changes: 1 addition & 2 deletions barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include "barretenberg/serialize/cbind.hpp"
#include "barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_keccak.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_keccak_flavor.hpp"

#include <cstddef>
#ifndef DISABLE_AZTEC_VM
Expand Down Expand Up @@ -1085,7 +1085,6 @@ void prove_honk(const std::string& bytecodePath, const std::string& witnessPath,
// Construct Honk proof
Prover prover = compute_valid_prover<Flavor>(bytecodePath, witnessPath);
auto proof = prover.construct_proof();

if (outputPath == "-") {
writeRawBytesToStdout(to_buffer</*include_size=*/true>(proof));
vinfo("proof written to stdout");
Expand Down
Loading
Loading