Skip to content

Commit

Permalink
feat: Proving the rollup circuits (AztecProtocol/aztec-packages#5599)
Browse files Browse the repository at this point in the history
This PR implements a first stage of proving the rollup circuits. We
introduce the bb binary and use it to produce verification keys,
generate proofs and later verify those proofs for all of the rollup
circuits, currently demonstrated in a unit test.
  • Loading branch information
AztecBot committed Apr 12, 2024
1 parent 305bcdc commit dad8e65
Show file tree
Hide file tree
Showing 13 changed files with 61 additions and 101 deletions.
2 changes: 1 addition & 1 deletion .aztec-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
10d9ad99200a5897417ff5669763ead4e38d87fa
145cbcda61fd73f4e135348b31c59c774cfae965
5 changes: 2 additions & 3 deletions acvm-repo/acvm_js/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ function run_if_available {
require_command jq
require_command cargo
require_command wasm-bindgen
require_command wasm-opt

self_path=$(dirname "$(readlink -f "$0")")
pname=$(cargo read-manifest | jq -r '.name')
Expand All @@ -49,5 +48,5 @@ BROWSER_WASM=${BROWSER_DIR}/${pname}_bg.wasm
run_or_fail cargo build --lib --release --target $TARGET --package ${pname}
run_or_fail wasm-bindgen $WASM_BINARY --out-dir $NODE_DIR --typescript --target nodejs
run_or_fail wasm-bindgen $WASM_BINARY --out-dir $BROWSER_DIR --typescript --target web
run_or_fail wasm-opt $NODE_WASM -o $NODE_WASM -O
run_or_fail wasm-opt $BROWSER_WASM -o $BROWSER_WASM -O
run_if_available wasm-opt $NODE_WASM -o $NODE_WASM -O
run_if_available wasm-opt $BROWSER_WASM -o $BROWSER_WASM -O
6 changes: 0 additions & 6 deletions compiler/noirc_evaluator/src/ssa/function_builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,12 +326,6 @@ impl FunctionBuilder {
self.insert_instruction(Instruction::DecrementRc { value }, None);
}

/// Insert an enable_side_effects_if instruction. These are normally only automatically
/// inserted during the flattening pass when branching is removed.
pub(crate) fn insert_enable_side_effects_if(&mut self, condition: ValueId) {
self.insert_instruction(Instruction::EnableSideEffects { condition }, None);
}

/// Terminates the current block with the given terminator instruction
/// if the current block does not already have a terminator instruction.
fn terminate_block_with(&mut self, terminator: TerminatorInstruction) {
Expand Down
8 changes: 1 addition & 7 deletions compiler/noirc_evaluator/src/ssa/ir/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ impl Instruction {
// In ACIR, a division with a false predicate outputs (0,0), so it cannot replace another instruction unless they have the same predicate
bin.operator != BinaryOp::Div
}
Cast(_, _) | Truncate { .. } | Not(_) => true,
Cast(_, _) | Truncate { .. } | Not(_) | ArrayGet { .. } | ArraySet { .. } => true,

// These either have side-effects or interact with memory
Constrain(..)
Expand All @@ -266,12 +266,6 @@ impl Instruction {
| DecrementRc { .. }
| RangeCheck { .. } => false,

// These can have different behavior depending on the EnableSideEffectsIf context.
// Enabling constant folding for these potentially enables replacing an enabled
// array get with one that was disabled. See
// https://github.com/noir-lang/noir/pull/4716#issuecomment-2047846328.
ArrayGet { .. } | ArraySet { .. } => false,

Call { func, .. } => match dfg[*func] {
Value::Intrinsic(intrinsic) => !intrinsic.has_side_effects(),
_ => false,
Expand Down
51 changes: 0 additions & 51 deletions compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,55 +607,4 @@ mod test {
assert_eq!(main.dfg[instructions[4]], Instruction::Constrain(v1, v_true, None));
assert_eq!(main.dfg[instructions[5]], Instruction::Constrain(v2, v_false, None));
}

// Regression for #4600
#[test]
fn array_get_regression() {
// fn main f0 {
// b0(v0: u1, v1: u64):
// enable_side_effects_if v0
// v2 = array_get [Field 0, Field 1], index v1
// v3 = not v0
// enable_side_effects_if v3
// v4 = array_get [Field 0, Field 1], index v1
// }
//
// We want to make sure after constant folding both array_gets remain since they are
// under different enable_side_effects_if contexts and thus one may be disabled while
// the other is not. If one is removed, it is possible e.g. v4 is replaced with v2 which
// is disabled (only gets from index 0) and thus returns the wrong result.
let main_id = Id::test_new(0);

// Compiling main
let mut builder = FunctionBuilder::new("main".into(), main_id);
let v0 = builder.add_parameter(Type::bool());
let v1 = builder.add_parameter(Type::unsigned(64));

builder.insert_enable_side_effects_if(v0);

let zero = builder.field_constant(0u128);
let one = builder.field_constant(1u128);

let typ = Type::Array(Rc::new(vec![Type::field()]), 2);
let array = builder.array_constant(vec![zero, one].into(), typ);

let _v2 = builder.insert_array_get(array, v1, Type::field());
let v3 = builder.insert_not(v0);

builder.insert_enable_side_effects_if(v3);
let _v4 = builder.insert_array_get(array, v1, Type::field());

// Expected output is unchanged
let ssa = builder.finish();
let main = ssa.main();
let instructions = main.dfg[main.entry_block()].instructions();
let starting_instruction_count = instructions.len();
assert_eq!(starting_instruction_count, 5);

let ssa = ssa.fold_constants();
let main = ssa.main();
let instructions = main.dfg[main.entry_block()].instructions();
let ending_instruction_count = instructions.len();
assert_eq!(starting_instruction_count, ending_instruction_count);
}
}
7 changes: 3 additions & 4 deletions tooling/acvm_cli/src/cli/execute_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ use bn254_blackbox_solver::Bn254BlackBoxSolver;
use clap::Args;

use crate::cli::fs::inputs::{read_bytecode_from_file, read_inputs_from_file};
use crate::cli::fs::witness::save_witness_to_dir;
use crate::errors::CliError;
use nargo::ops::{execute_program, DefaultForeignCallExecutor};

use super::fs::witness::create_output_witness_string;
use super::fs::witness::{create_output_witness_string, save_witness_to_dir};

/// Executes a circuit to calculate its return value
#[derive(Debug, Clone, Args)]
Expand Down Expand Up @@ -46,9 +45,9 @@ fn run_command(args: ExecuteCommand) -> Result<String, CliError> {
)?;
if args.output_witness.is_some() {
save_witness_to_dir(
&output_witness_string,
&args.working_directory,
output_witness,
&args.output_witness.unwrap(),
&args.working_directory,
)?;
}
Ok(output_witness_string)
Expand Down
47 changes: 34 additions & 13 deletions tooling/acvm_cli/src/cli/fs/witness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,29 @@ use std::{
path::{Path, PathBuf},
};

use acvm::acir::native_types::WitnessMap;
use acvm::acir::native_types::{WitnessMap, WitnessStack};

use crate::errors::{CliError, FilesystemError};

/// Saves the provided output witnesses to a toml file created at the given location
pub(crate) fn save_witness_to_dir<P: AsRef<Path>>(
output_witness: &String,
witness_dir: P,
file_name: &String,
) -> Result<PathBuf, FilesystemError> {
let witness_path = witness_dir.as_ref().join(file_name);
fn create_named_dir(named_dir: &Path, name: &str) -> PathBuf {
std::fs::create_dir_all(named_dir)
.unwrap_or_else(|_| panic!("could not create the `{name}` directory"));

PathBuf::from(named_dir)
}

let mut file = File::create(&witness_path)
.map_err(|_| FilesystemError::OutputWitnessCreationFailed(file_name.clone()))?;
write!(file, "{}", output_witness)
.map_err(|_| FilesystemError::OutputWitnessWriteFailed(file_name.clone()))?;
fn write_to_file(bytes: &[u8], path: &Path) -> String {
let display = path.display();

Ok(witness_path)
let mut file = match File::create(path) {
Err(why) => panic!("couldn't create {display}: {why}"),
Ok(file) => file,
};

match file.write_all(bytes) {
Err(why) => panic!("couldn't write to {display}: {why}"),
Ok(_) => display.to_string(),
}
}

/// Creates a toml representation of the provided witness map
Expand All @@ -34,3 +39,19 @@ pub(crate) fn create_output_witness_string(witnesses: &WitnessMap) -> Result<Str

toml::to_string(&witness_map).map_err(|_| CliError::OutputWitnessSerializationFailed())
}

pub(crate) fn save_witness_to_dir<P: AsRef<Path>>(
witnesses: WitnessStack,
witness_name: &str,
witness_dir: P,
) -> Result<PathBuf, FilesystemError> {
create_named_dir(witness_dir.as_ref(), "witness");
let witness_path = witness_dir.as_ref().join(witness_name).with_extension("gz");

let buf: Vec<u8> = witnesses
.try_into()
.map_err(|_op| FilesystemError::OutputWitnessCreationFailed(witness_name.to_string()))?;
write_to_file(buf.as_slice(), &witness_path);

Ok(witness_path)
}
3 changes: 0 additions & 3 deletions tooling/acvm_cli/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ pub(crate) enum FilesystemError {

#[error(" Error: failed to create output witness file {0}.")]
OutputWitnessCreationFailed(String),

#[error(" Error: failed to write output witness file {0}.")]
OutputWitnessWriteFailed(String),
}

#[derive(Debug, Error)]
Expand Down
2 changes: 1 addition & 1 deletion tooling/bb_abstraction_leaks/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use const_format::formatcp;

const USERNAME: &str = "AztecProtocol";
const REPO: &str = "aztec-packages";
const VERSION: &str = "0.34.0";
const VERSION: &str = "0.33.0";
const TAG: &str = formatcp!("aztec-packages-v{}", VERSION);

const API_URL: &str =
Expand Down
2 changes: 1 addition & 1 deletion tooling/noir_js_backend_barretenberg/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0"
},
"dependencies": {
"@aztec/bb.js": "0.34.0",
"@aztec/bb.js": "portal:../../../../barretenberg/ts",
"@noir-lang/types": "workspace:*",
"fflate": "^0.8.0"
},
Expand Down
5 changes: 2 additions & 3 deletions tooling/noirc_abi_wasm/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ function run_if_available {
require_command jq
require_command cargo
require_command wasm-bindgen
require_command wasm-opt

self_path=$(dirname "$(readlink -f "$0")")
pname=$(cargo read-manifest | jq -r '.name')
Expand All @@ -49,5 +48,5 @@ BROWSER_WASM=${BROWSER_DIR}/${pname}_bg.wasm
run_or_fail cargo build --lib --release --target $TARGET --package ${pname}
run_or_fail wasm-bindgen $WASM_BINARY --out-dir $NODE_DIR --typescript --target nodejs
run_or_fail wasm-bindgen $WASM_BINARY --out-dir $BROWSER_DIR --typescript --target web
run_or_fail wasm-opt $NODE_WASM -o $NODE_WASM -O
run_or_fail wasm-opt $BROWSER_WASM -o $BROWSER_WASM -O
run_if_available wasm-opt $NODE_WASM -o $NODE_WASM -O
run_if_available wasm-opt $BROWSER_WASM -o $BROWSER_WASM -O
11 changes: 10 additions & 1 deletion tooling/noirc_abi_wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// See Cargo.toml for explanation.
use getrandom as _;

use acvm::acir::native_types::WitnessMap;
use acvm::acir::native_types::{WitnessMap, WitnessStack};
use iter_extended::try_btree_map;
use noirc_abi::{
errors::InputParserError,
Expand Down Expand Up @@ -113,3 +113,12 @@ pub fn abi_decode(abi: JsAbi, witness_map: JsWitnessMap) -> Result<JsValue, JsAb
<wasm_bindgen::JsValue as JsValueSerdeExt>::from_serde(&return_struct)
.map_err(|err| err.to_string().into())
}

#[wasm_bindgen(js_name = serializeWitness)]
pub fn serialise_witness(witness_map: JsWitnessMap) -> Result<Vec<u8>, JsAbiError> {

Check warning on line 118 in tooling/noirc_abi_wasm/src/lib.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (serialise)
console_error_panic_hook::set_once();
let converted_witness: WitnessMap = witness_map.into();
let witness_stack: WitnessStack = converted_witness.into();
let output = witness_stack.try_into();
output.map_err(|_| JsAbiError::new("Failed to convert to Vec<u8>".to_string()))
}
13 changes: 6 additions & 7 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -221,19 +221,18 @@ __metadata:
languageName: node
linkType: hard

"@aztec/bb.js@npm:0.34.0":
version: 0.34.0
resolution: "@aztec/bb.js@npm:0.34.0"
"@aztec/bb.js@portal:../../../../barretenberg/ts::locator=%40noir-lang%2Fbackend_barretenberg%40workspace%3Atooling%2Fnoir_js_backend_barretenberg":
version: 0.0.0-use.local
resolution: "@aztec/bb.js@portal:../../../../barretenberg/ts::locator=%40noir-lang%2Fbackend_barretenberg%40workspace%3Atooling%2Fnoir_js_backend_barretenberg"
dependencies:
comlink: ^4.4.1
commander: ^10.0.1
debug: ^4.3.4
tslib: ^2.4.0
bin:
bb.js: dest/node/main.js
checksum: 9d07834d81ed19e4d6fd5c1f3b07c565648df1165c30115f020ece9660b2b8599a5ed894a2090410f14020e73dd290484b30b76c9c71e863b8390fa2b7c1b729
bb.js: ./dest/node/main.js
languageName: node
linkType: hard
linkType: soft

"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.11, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.8.3":
version: 7.23.5
Expand Down Expand Up @@ -4396,7 +4395,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@noir-lang/backend_barretenberg@workspace:tooling/noir_js_backend_barretenberg"
dependencies:
"@aztec/bb.js": 0.34.0
"@aztec/bb.js": "portal:../../../../barretenberg/ts"
"@noir-lang/types": "workspace:*"
"@types/node": ^20.6.2
"@types/prettier": ^3
Expand Down

0 comments on commit dad8e65

Please sign in to comment.