Skip to content

Commit

Permalink
chore: purging calldata hash (AztecProtocol/aztec-packages#4984)
Browse files Browse the repository at this point in the history
Fixes #4844.

Purges calldata hash and txs hash to replace both with txs effects hash.

Also moves the compute tx effects hash function from the base rollup and
into the components as was the intention.
  • Loading branch information
AztecBot committed Mar 7, 2024
1 parent fe8f277 commit 46737e6
Show file tree
Hide file tree
Showing 15 changed files with 419 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .aztec-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7ff9b71d8d87fc93ae7dbd8ba63f5176b0cd17be
f6f34b7cebc757aa7974cd2c947815132ec703d6
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ members = [
"tooling/nargo_toml",
"tooling/noirc_abi",
"tooling/noirc_abi_wasm",
"tooling/acvm_cli",
# ACVM
"acvm-repo/acir_field",
"acvm-repo/acir",
Expand All @@ -36,7 +37,7 @@ members = [
"acvm-repo/blackbox_solver",
"acvm-repo/bn254_blackbox_solver",
]
default-members = ["tooling/nargo_cli"]
default-members = ["tooling/nargo_cli", "tooling/acvm_cli"]
resolver = "2"

[workspace.package]
Expand Down Expand Up @@ -78,6 +79,7 @@ noir_lsp = { path = "tooling/lsp" }
noir_debugger = { path = "tooling/debugger" }
noirc_abi = { path = "tooling/noirc_abi" }
bb_abstraction_leaks = { path = "tooling/bb_abstraction_leaks" }
acvm_cli = { path = "tooling/acvm_cli" }

# LSP
async-lsp = { version = "0.1.0", default-features = false }
Expand Down
22 changes: 22 additions & 0 deletions bootstrap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -eu

cd $(dirname "$0")

CMD=${1:-}

if [ -n "$CMD" ]; then
if [ "$CMD" = "clean" ]; then
git clean -fdx
exit 0
else
echo "Unknown command: $CMD"
exit 1
fi
fi

# Attempt to just pull artefacts from CI and exit on success.
[ -n "${USE_CACHE:-}" ] && ./bootstrap_cache.sh && exit

./scripts/bootstrap_native.sh
./scripts/bootstrap_packages.sh
13 changes: 13 additions & 0 deletions bootstrap_cache.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -eu

cd "$(dirname "$0")"
source ../build-system/scripts/setup_env '' '' mainframe_$USER > /dev/null

echo -e "\033[1mRetrieving noir packages from remote cache...\033[0m"
extract_repo noir-packages /usr/src/noir/packages ./
echo -e "\033[1mRetrieving nargo from remote cache...\033[0m"
extract_repo noir /usr/src/noir/target/release ./target/

remove_old_images noir-packages
remove_old_images noir
2 changes: 1 addition & 1 deletion docs/scripts/codegen_nargo_reference.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ sidebar_position: 0
---
" > $NARGO_REFERENCE

cargo run -F codegen-docs -- info >> $NARGO_REFERENCE
cargo run --bin nargo -F codegen-docs -- info >> $NARGO_REFERENCE
42 changes: 21 additions & 21 deletions test_programs/execution_success/brillig_cow_regression/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ global MAX_NEW_CONTRACTS_PER_TX: u64 = 1;
global NUM_ENCRYPTED_LOGS_HASHES_PER_TX: u64 = 1;
global NUM_UNENCRYPTED_LOGS_HASHES_PER_TX: u64 = 1;
global NUM_FIELDS_PER_SHA256 = 2;
global CALLDATA_HASH_INPUT_SIZE = 169;
global CALL_DATA_HASH_LOG_FIELDS = 4;
global CALL_DATA_HASH_FULL_FIELDS = 165;
global TX_EFFECT_HASH_INPUT_SIZE = 169;
global TX_EFFECT_HASH_LOG_FIELDS = 4;
global TX_EFFECT_HASH_FULL_FIELDS = 165;

struct PublicDataUpdateRequest {
leaf_slot : Field,
Expand Down Expand Up @@ -99,7 +99,7 @@ impl U256 {
}

unconstrained fn main(kernel_data: DataToHash) -> pub [Field; NUM_FIELDS_PER_SHA256] {
let mut calldata_hash_inputs = [0; CALLDATA_HASH_INPUT_SIZE];
let mut tx_effects_hash_inputs = [0; TX_EFFECT_HASH_INPUT_SIZE];

let new_note_hashes = kernel_data.new_note_hashes;
let new_nullifiers = kernel_data.new_nullifiers;
Expand All @@ -111,65 +111,65 @@ unconstrained fn main(kernel_data: DataToHash) -> pub [Field; NUM_FIELDS_PER_SHA
let mut offset = 0;

for j in 0..MAX_NEW_NOTE_HASHES_PER_TX {
calldata_hash_inputs[offset + j] = new_note_hashes[j];
tx_effects_hash_inputs[offset + j] = new_note_hashes[j];
}
offset += MAX_NEW_NOTE_HASHES_PER_TX ;

for j in 0..MAX_NEW_NULLIFIERS_PER_TX {
calldata_hash_inputs[offset + j] = new_nullifiers[j];
tx_effects_hash_inputs[offset + j] = new_nullifiers[j];
}
offset += MAX_NEW_NULLIFIERS_PER_TX ;

for j in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX {
calldata_hash_inputs[offset + j * 2] =
tx_effects_hash_inputs[offset + j * 2] =
public_data_update_requests[j].leaf_slot;
calldata_hash_inputs[offset + j * 2 + 1] =
tx_effects_hash_inputs[offset + j * 2 + 1] =
public_data_update_requests[j].new_value;
}
offset += MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX * 2;

for j in 0..MAX_NEW_L2_TO_L1_MSGS_PER_TX {
calldata_hash_inputs[offset + j] = newL2ToL1msgs[j];
tx_effects_hash_inputs[offset + j] = newL2ToL1msgs[j];
}
offset += MAX_NEW_L2_TO_L1_MSGS_PER_TX;

let contract_leaf = kernel_data.new_contracts[0];
calldata_hash_inputs[offset] = contract_leaf.hash();
tx_effects_hash_inputs[offset] = contract_leaf.hash();

offset += MAX_NEW_CONTRACTS_PER_TX;

let new_contracts = kernel_data.new_contracts;
calldata_hash_inputs[offset] = new_contracts[0].contract_address;
tx_effects_hash_inputs[offset] = new_contracts[0].contract_address;

calldata_hash_inputs[offset + 1] = new_contracts[0].portal_contract_address;
tx_effects_hash_inputs[offset + 1] = new_contracts[0].portal_contract_address;

offset += MAX_NEW_CONTRACTS_PER_TX * 2;

for j in 0..NUM_FIELDS_PER_SHA256 {
calldata_hash_inputs[offset + j] = encryptedLogsHash[j];
tx_effects_hash_inputs[offset + j] = encryptedLogsHash[j];
}

offset += NUM_ENCRYPTED_LOGS_HASHES_PER_TX * NUM_FIELDS_PER_SHA256;

for j in 0..NUM_FIELDS_PER_SHA256 {
calldata_hash_inputs[offset + j] = unencryptedLogsHash[j];
tx_effects_hash_inputs[offset + j] = unencryptedLogsHash[j];
}

offset += NUM_UNENCRYPTED_LOGS_HASHES_PER_TX * NUM_FIELDS_PER_SHA256;
assert_eq(offset, CALLDATA_HASH_INPUT_SIZE); // Sanity check
assert_eq(offset, TX_EFFECT_HASH_INPUT_SIZE); // Sanity check

let mut hash_input_flattened = [0; CALL_DATA_HASH_FULL_FIELDS * 32 + CALL_DATA_HASH_LOG_FIELDS * 16];
for offset in 0..CALL_DATA_HASH_FULL_FIELDS {
let input_as_bytes = calldata_hash_inputs[offset].to_be_bytes(32);
let mut hash_input_flattened = [0; TX_EFFECT_HASH_FULL_FIELDS * 32 + TX_EFFECT_HASH_LOG_FIELDS * 16];
for offset in 0..TX_EFFECT_HASH_FULL_FIELDS {
let input_as_bytes = tx_effects_hash_inputs[offset].to_be_bytes(32);
for byte_index in 0..32 {
hash_input_flattened[offset * 32 + byte_index] = input_as_bytes[byte_index];
}
}

for log_field_index in 0..CALL_DATA_HASH_LOG_FIELDS {
let input_as_bytes = calldata_hash_inputs[CALL_DATA_HASH_FULL_FIELDS + log_field_index].to_be_bytes(16);
for log_field_index in 0..TX_EFFECT_HASH_LOG_FIELDS {
let input_as_bytes = tx_effects_hash_inputs[TX_EFFECT_HASH_FULL_FIELDS + log_field_index].to_be_bytes(16);
for byte_index in 0..16 {
hash_input_flattened[CALL_DATA_HASH_FULL_FIELDS * 32 + log_field_index * 16 + byte_index] = input_as_bytes[byte_index];
hash_input_flattened[TX_EFFECT_HASH_FULL_FIELDS * 32 + log_field_index * 16 + byte_index] = input_as_bytes[byte_index];
}
}

Expand Down
38 changes: 38 additions & 0 deletions tooling/acvm_cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[package]
name = "acvm_cli"
description = "The entrypoint for executing the ACVM"
# x-release-please-start-version
version = "0.40.0"
# x-release-please-end
authors.workspace = true
edition.workspace = true
license.workspace = true
rust-version.workspace = true
repository.workspace = true

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

# Rename binary from `acvm_cli` to `acvm`
[[bin]]
name = "acvm"
path = "src/main.rs"

[dependencies]
thiserror.workspace = true
toml.workspace = true
color-eyre = "0.6.2"
clap.workspace = true
acvm.workspace = true
nargo.workspace = true
const_format.workspace = true
bn254_blackbox_solver.workspace = true
acir.workspace = true

# Logs
tracing-subscriber.workspace = true
tracing-appender = "0.2.3"

[dev-dependencies]
rand = "0.8.5"
proptest = "1.2.0"
paste = "1.0.14"
79 changes: 79 additions & 0 deletions tooling/acvm_cli/src/cli/execute_cmd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use std::io::{self, Write};

use acir::circuit::Circuit;
use acir::native_types::WitnessMap;
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_circuit, DefaultForeignCallExecutor};

use super::fs::witness::create_output_witness_string;

/// Executes a circuit to calculate its return value
#[derive(Debug, Clone, Args)]
pub(crate) struct ExecuteCommand {
/// Write the execution witness to named file
#[clap(long, short)]
output_witness: Option<String>,

/// The name of the toml file which contains the input witness map
#[clap(long, short)]
input_witness: String,

/// The name of the binary file containing circuit bytecode
#[clap(long, short)]
bytecode: String,

/// The working directory
#[clap(long, short)]
working_directory: String,

/// Set to print output witness to stdout
#[clap(long, short, action)]
print: bool,
}

fn run_command(args: ExecuteCommand) -> Result<String, CliError> {
let bytecode = read_bytecode_from_file(&args.working_directory, &args.bytecode)?;
let circuit_inputs = read_inputs_from_file(&args.working_directory, &args.input_witness)?;
let output_witness = execute_program_from_witness(&circuit_inputs, &bytecode, None)?;
let output_witness_string = create_output_witness_string(&output_witness)?;
if args.output_witness.is_some() {
save_witness_to_dir(
&output_witness_string,
&args.working_directory,
&args.output_witness.unwrap(),
)?;
}
Ok(output_witness_string)
}

pub(crate) fn run(args: ExecuteCommand) -> Result<String, CliError> {
let print = args.print;
let output_witness_string = run_command(args)?;
if print {
io::stdout().write_all(output_witness_string.as_bytes()).unwrap();
}
Ok(output_witness_string)
}

pub(crate) fn execute_program_from_witness(
inputs_map: &WitnessMap,
bytecode: &Vec<u8>,
foreign_call_resolver_url: Option<&str>,
) -> Result<WitnessMap, CliError> {
let blackbox_solver = Bn254BlackBoxSolver::new();
let circuit: Circuit = Circuit::deserialize_circuit(&bytecode)
.map_err(|_| CliError::CircuitDeserializationError())?;
let result = execute_circuit(
&circuit,
inputs_map.clone(),
&blackbox_solver,
&mut DefaultForeignCallExecutor::new(true, foreign_call_resolver_url),
)
.map_err(|e| CliError::CircuitExecutionError(e));
result
}
54 changes: 54 additions & 0 deletions tooling/acvm_cli/src/cli/fs/inputs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use acir::{
native_types::{Witness, WitnessMap},
FieldElement,
};
use toml::Table;

use crate::errors::{CliError, FilesystemError};
use std::{fs::read, path::Path};

/// Returns the circuit's parameters parsed from a toml file at the given location
pub(crate) fn read_inputs_from_file<P: AsRef<Path>>(
working_directory: P,
file_name: &String,
) -> Result<WitnessMap, CliError> {
let file_path = working_directory.as_ref().join(file_name);
if !file_path.exists() {
return Err(CliError::FilesystemError(FilesystemError::MissingTomlFile(
file_name.to_owned(),
file_path,
)));
}

let input_string = std::fs::read_to_string(file_path)
.map_err(|_| FilesystemError::InvalidTomlFile(file_name.clone()))?;
let input_map = input_string
.parse::<Table>()
.map_err(|_| FilesystemError::InvalidTomlFile(file_name.clone()))?;
let mut witnesses: WitnessMap = WitnessMap::new();
for (key, value) in input_map.into_iter() {
let index =
Witness(key.trim().parse().map_err(|_| CliError::WitnessIndexError(key.clone()))?);
if !value.is_str() {
return Err(CliError::WitnessValueError(key.clone()));
}
let field = FieldElement::from_hex(value.as_str().unwrap()).unwrap();
witnesses.insert(index, field);
}

Ok(witnesses)
}

/// Returns the circuit's bytecode read from the file at the given location
pub(crate) fn read_bytecode_from_file<P: AsRef<Path>>(
working_directory: P,
file_name: &String,
) -> Result<Vec<u8>, FilesystemError> {
let file_path = working_directory.as_ref().join(file_name);
if !file_path.exists() {
return Err(FilesystemError::MissingBytecodeFile(file_name.to_owned(), file_path));
}
let bytecode: Vec<u8> =
read(file_path).map_err(|_| FilesystemError::InvalidBytecodeFile(file_name.clone()))?;
Ok(bytecode)
}
2 changes: 2 additions & 0 deletions tooling/acvm_cli/src/cli/fs/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub(super) mod inputs;
pub(super) mod witness;
Loading

0 comments on commit 46737e6

Please sign in to comment.