Skip to content

Commit

Permalink
feat(feature_branch): Private Kernel Circuit (#2740)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Álvaro Rodríguez <sirasistant@gmail.com>
  • Loading branch information
kevaundray and sirasistant authored Oct 27, 2023
1 parent 1073b40 commit f800a36
Show file tree
Hide file tree
Showing 121 changed files with 11,325 additions and 12 deletions.
2 changes: 2 additions & 0 deletions circuits/cpp/src/aztec3/circuits/abis/packers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ struct GeneratorIndexPacker {
int SIGNED_TX_REQUEST = GeneratorIndex::SIGNED_TX_REQUEST;
int GLOBAL_VARIABLES = GeneratorIndex::GLOBAL_VARIABLES;
int PARTIAL_ADDRESS = GeneratorIndex::PARTIAL_ADDRESS;
int BLOCK_HASH = GeneratorIndex::BLOCK_HASH;
int TX_REQUEST = GeneratorIndex::TX_REQUEST;
int SIGNATURE_PAYLOAD = GeneratorIndex::SIGNATURE_PAYLOAD;
int VK = GeneratorIndex::VK;
Expand Down Expand Up @@ -168,6 +169,7 @@ struct GeneratorIndexPacker {
SIGNED_TX_REQUEST,
GLOBAL_VARIABLES,
PARTIAL_ADDRESS,
BLOCK_HASH,
TX_REQUEST,
SIGNATURE_PAYLOAD,
VK,
Expand Down
2 changes: 2 additions & 0 deletions circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ void common_update_end_values(DummyBuilder& builder,
const auto& read_request = read_requests[i];
const auto& witness = read_request_membership_witnesses[i];
if (witness.is_transient) { // only forward transient to public inputs
// TODO (David): This is pushing zeroed read requests for public inputs if they are transient. Is that
// correct?
const auto siloed_read_request =
read_request == 0 ? 0 : silo_commitment<NT>(storage_contract_address, read_request);
array_push(builder,
Expand Down
38 changes: 38 additions & 0 deletions circuits/cpp/src/aztec3/utils/array.test.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#include "array.hpp"

#include "aztec3/circuits/hash.hpp"
#include "aztec3/utils/dummy_circuit_builder.hpp"

#include <gtest/gtest.h>

#include <array>
#include <cstddef>
#include <cstdint>
#include <sstream>
#include <string>

namespace aztec3::utils {
Expand All @@ -22,6 +25,41 @@ void rearrange_and_check(std::array<fr, N>& input, std::array<fr, N> const& expe
}
};

TEST(hash_tests, noir_l2_l1_interop_hashing)
{
// This is an annoying hack to convert the field into a hex string
// We should add a to_hex and from_hex method to field class
auto to_hex = [](const NT::fr& value) -> std::string {
std::stringstream field_as_hex_stream;
field_as_hex_stream << value;
return field_as_hex_stream.str();
};

// All zeroes case
auto address = NT::address(0);
auto res = circuits::compute_l2_to_l1_hash<NT>(address, fr(0), fr(0), fr(0), fr(0));
auto res_as_hex = to_hex(res);
ASSERT_EQ(res_as_hex, "0x2266ac2f9f0c19c015239ef5ea85862fc6fac00db73779b220a4d49c4856c2e1");

// Non-zero case
address = NT::address(1);
res = circuits::compute_l2_to_l1_hash<NT>(address, fr(2), fr(3), fr(4), fr(5));
res_as_hex = to_hex(res);
ASSERT_EQ(res_as_hex, "0x0f24729168d4450a5681beafa5e3a899ac28bd17bf5a4877dab37bcd834e1634");

// Smoke test that sha256_to_field is also the same in Noir
// For an l2_to_l1 hash the maximum size of the buffer that will be sha256'd is 160 bytes
size_t max_buffer_size = 160;
std::vector<uint8_t> buffer(max_buffer_size); // Creating a vector of size 160
for (size_t i = 0; i < 160; ++i) {
buffer[i] = static_cast<uint8_t>(i);
}

res = sha256::sha256_to_field(buffer);
res_as_hex = to_hex(res);
ASSERT_EQ(res_as_hex, "0x142a6d57007171f6eaa33d55976d9dbe739c889c8e920f115f7808dea184c718");
}

TEST(utils_array_tests, rearrange_test_vector1)
{
std::array<fr, 5> test_vec{ fr(2), fr(4), fr(0), fr(12), fr(0) };
Expand Down
1 change: 1 addition & 0 deletions yarn-project/aztec-nr/aztec/src/constants_gen.nr
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ global GENERATOR_INDEX__PUBLIC_DATA_LEAF = 24;
global GENERATOR_INDEX__SIGNED_TX_REQUEST = 25;
global GENERATOR_INDEX__GLOBAL_VARIABLES = 26;
global GENERATOR_INDEX__PARTIAL_ADDRESS = 27;
global GENERATOR_INDEX__BLOCK_HASH = 28;
global GENERATOR_INDEX__TX_REQUEST = 33;
global GENERATOR_INDEX__SIGNATURE_PAYLOAD = 34;
global GENERATOR_INDEX__VK = 41;
Expand Down
1 change: 1 addition & 0 deletions yarn-project/circuits.js/src/cbind/constants.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export enum GeneratorIndex {
SIGNED_TX_REQUEST = 25,
GLOBAL_VARIABLES = 26,
PARTIAL_ADDRESS = 27,
BLOCK_HASH = 28,
TX_REQUEST = 33,
SIGNATURE_PAYLOAD = 34,
VK = 41,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ describe('benchmarks/publish_rollup', () => {
await pxe.stop();
await node.stop();
},
10 * 60_000,
20 * 60_000,
);
});
2 changes: 1 addition & 1 deletion yarn-project/end-to-end/src/e2e_block_building.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe('e2e_block_building', () => {
const deployer = new ContractDeployer(artifact, owner);
const methods = times(TX_COUNT, () => deployer.deploy());

for (const i in methods) {
for (let i = 0; i < TX_COUNT; i++) {
await methods[i].create({ contractAddressSalt: new Fr(BigInt(i + 1)) });
await methods[i].simulate({});
}
Expand Down
6 changes: 3 additions & 3 deletions yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ describe('e2e_cross_chain_messaging', () => {
);
await crossChainTestHarness.redeemShieldPrivatelyOnL2(bridgeAmount, secretForRedeemingMintedNotes);
await crossChainTestHarness.expectPrivateBalanceOnL2(ownerAddress, bridgeAmount);
}, 50_000);
}, 120_000);

it("Bridge can't withdraw my funds if I don't give approval", async () => {
const mintAmountToUser1 = 100n;
Expand All @@ -201,7 +201,7 @@ describe('e2e_cross_chain_messaging', () => {
.methods.exit_to_l1_private(l2Token.address, ethAccount, withdrawAmount, EthAddress.ZERO, nonce)
.simulate(),
).rejects.toThrowError(`Unknown auth witness for message hash 0x${expectedBurnMessageHash.toString('hex')}`);
});
}, 120_000);

it("Can't claim funds publicly if they were deposited privately", async () => {
// 1. Mint tokens on L1
Expand Down Expand Up @@ -234,5 +234,5 @@ describe('e2e_cross_chain_messaging', () => {
).rejects.toThrowError(
"Failed to solve brillig function, reason: explicit trap hit in brillig 'l1_to_l2_message_data.message.content == content'",
);
}, 50_000);
}, 120_000);
});
10 changes: 5 additions & 5 deletions yarn-project/end-to-end/src/e2e_deploy_contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe('e2e_deploy_contract', () => {
const contractAddress = receiptAfterMined.contractAddress!;
expect(await isContractDeployed(pxe, contractAddress)).toBe(true);
expect(await isContractDeployed(pxe, AztecAddress.random())).toBe(false);
}, 30_000);
}, 60_000);

/**
* Verify that we can produce multiple rollups.
Expand All @@ -67,7 +67,7 @@ describe('e2e_deploy_contract', () => {
const receipt = await deployer.deploy().send({ contractAddressSalt: Fr.random() }).wait({ wallet });
expect(receipt.status).toBe(TxStatus.MINED);
}
}, 30_000);
}, 60_000);

/**
* Verify that we can deploy multiple contracts and interact with all of them.
Expand All @@ -83,7 +83,7 @@ describe('e2e_deploy_contract', () => {
logger(`Sending TX to contract ${index + 1}...`);
await contract.methods.get_public_key(accounts[0].address).send().wait();
}
}, 30_000);
}, 60_000);

/**
* Milestone 1.2.
Expand All @@ -106,7 +106,7 @@ describe('e2e_deploy_contract', () => {
/A settled tx with equal hash/,
);
}
}, 30_000);
}, 60_000);

it('should deploy a contract connected to a portal contract', async () => {
const deployer = new ContractDeployer(TestContractArtifact, wallet);
Expand All @@ -124,7 +124,7 @@ describe('e2e_deploy_contract', () => {
expect((await pxe.getExtendedContractData(contractAddress))?.contractData.portalContractAddress.toString()).toEqual(
portalContract.toString(),
);
});
}, 60_000);

it('it should not deploy a contract which failed the public part of the execution', async () => {
sequencer?.updateSequencerConfig({
Expand Down
4 changes: 4 additions & 0 deletions yarn-project/end-to-end/src/e2e_ordering.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ import { toBigInt } from '@aztec/foundation/serialize';
import { ChildContract, ParentContract } from '@aztec/noir-contracts/types';
import { PXE, TxStatus } from '@aztec/types';

import { jest } from '@jest/globals';

import { setup } from './fixtures/utils.js';

jest.setTimeout(30_000);

// See https://github.com/AztecProtocol/aztec-packages/issues/1601
describe('e2e_ordering', () => {
let pxe: PXE;
Expand Down
2 changes: 2 additions & 0 deletions yarn-project/noir-compiler/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export { generateNoirContractInterface } from './contract-interface-gen/noir.js'
export { generateTypescriptContractInterface } from './contract-interface-gen/typescript.js';
export { generateContractArtifact };

export * from './noir_artifact.js';

/**
* Compile Aztec.nr contracts in project path using a nargo binary available in the shell.
* @param projectPath - Path to project.
Expand Down
18 changes: 17 additions & 1 deletion yarn-project/noir-compiler/src/noir_artifact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ABIParameter, ABIType, DebugFileMap, DebugInfo, EventAbi } from '@aztec
type NoirFunctionType = 'Open' | 'Secret' | 'Unconstrained';

/** The ABI of an Aztec.nr function. */
interface NoirFunctionAbi {
export interface NoirFunctionAbi {
/** The parameters of the function. */
parameters: ABIParameter[];
/** The witness indices of the parameters. Indexed by parameter name. */
Expand Down Expand Up @@ -49,6 +49,22 @@ export interface NoirCompiledContract {
events: EventAbi[];
}

/**
* The compilation result of an Aztec.nr contract.
*/
export interface NoirCompiledCircuit {
/** The hash of the circuit. */
hash: number;
/** Compilation backend. */
backend: string;
/**
* The ABI of the function.
*/
abi: NoirFunctionAbi;
/** The bytecode of the circuit in base64. */
bytecode: string;
}

/**
* The debug metadata of an Aztec.nr contract.
*/
Expand Down
1 change: 1 addition & 0 deletions yarn-project/noir-private-kernel/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('@aztec/foundation/eslint');
3 changes: 3 additions & 0 deletions yarn-project/noir-private-kernel/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
proofs/
Prover.toml
Verifier.toml
3 changes: 3 additions & 0 deletions yarn-project/noir-private-kernel/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
src/crates
src/target
src/types
1 change: 1 addition & 0 deletions yarn-project/noir-private-kernel/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Noir Private Kernel
59 changes: 59 additions & 0 deletions yarn-project/noir-private-kernel/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"name": "@aztec/noir-private-kernel",
"version": "0.1.0",
"type": "module",
"exports": {
".": "./dest/index.js",
"./types": "./dest/types/index.js"
},
"scripts": {
"build": "yarn clean && tsc -b",
"build:dev": "tsc -b --watch",
"clean": "rm -rf ./dest .tsbuildinfo",
"formatting": "run -T prettier --check ./src && run -T eslint ./src",
"formatting:fix": "run -T prettier -w ./src",
"noir:build": "cd src && nargo compile --no-backend && rm -rf ./target/debug_*",
"noir:types": "yarn ts-node --esm src/scripts/generate_ts_from_abi.ts",
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --passWithNoTests"
},
"inherits": [
"../package.common.json"
],
"jest": {
"preset": "ts-jest/presets/default-esm",
"moduleNameMapper": {
"^(\\.{1,2}/.*)\\.m?js$": "$1"
},
"testRegex": "./src/.*\\.test\\.(js|mjs|ts)$",
"rootDir": "./src"
},
"dependencies": {
"@aztec/circuits.js": "workspace:^",
"@aztec/foundation": "workspace:^",
"@aztec/noir-compiler": "workspace:^",
"@noir-lang/acvm_js": "^0.30.0",
"@noir-lang/backend_barretenberg": "^0.7.10",
"@noir-lang/noir_js": "^0.16.0",
"@noir-lang/noirc_abi": "^0.16.0",
"tslib": "^2.4.0"
},
"devDependencies": {
"@jest/globals": "^29.5.0",
"@rushstack/eslint-patch": "^1.1.4",
"@types/jest": "^29.5.0",
"@types/node": "^18.7.23",
"jest": "^29.5.0",
"ts-jest": "^29.1.0",
"ts-node": "^10.9.1",
"typescript": "^5.0.4"
},
"files": [
"dest",
"src",
"!*.test.*"
],
"types": "./dest/index.d.ts",
"engines": {
"node": ">=18"
}
}
10 changes: 10 additions & 0 deletions yarn-project/noir-private-kernel/src/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[workspace]
members = [
"crates/private-kernel-lib",
"crates/private-kernel-init",
"crates/private-kernel-init-simulated",
"crates/private-kernel-inner",
"crates/private-kernel-inner-simulated",
"crates/private-kernel-ordering",
"crates/private-kernel-ordering-simulated",
]
Loading

0 comments on commit f800a36

Please sign in to comment.