-
Notifications
You must be signed in to change notification settings - Fork 200
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
# Description ## Problem\* aztec private kernel is doing a lot of proof recursion along the call stack of contract calls, resulting in a lot of public inputs required for the aztec ABI. These amount of public inputs have an impact on the performance, which can be mitigated by having instead the public inputs as private and a public commitment of these inputs. We can then leverage the proving system capability for proving/verifying efficiently commitments, outside of the noir program. ## Summary\* In order to interface with the proving system, the user can declare some inputs as call_data (instead of pub) and the return values as return_data (instead of pub). The compiler will abstract these into specific immutable arrays that the proving system will use. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [X] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [X] I have tested the changes locally. - [X] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: Tom French <tom@tomfren.ch>
- Loading branch information
1 parent
e5b981b
commit 6b0bdbc
Showing
32 changed files
with
402 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
144 changes: 144 additions & 0 deletions
144
compiler/noirc_evaluator/src/ssa/function_builder/data_bus.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
use std::rc::Rc; | ||
|
||
use crate::ssa::ir::{types::Type, value::ValueId}; | ||
use acvm::FieldElement; | ||
use fxhash::FxHashMap as HashMap; | ||
use noirc_frontend::hir_def::function::FunctionSignature; | ||
|
||
use super::FunctionBuilder; | ||
|
||
/// Used to create a data bus, which is an array of private inputs | ||
/// replacing public inputs | ||
pub(crate) struct DataBusBuilder { | ||
pub(crate) values: im::Vector<ValueId>, | ||
index: usize, | ||
pub(crate) map: HashMap<ValueId, usize>, | ||
pub(crate) databus: Option<ValueId>, | ||
} | ||
|
||
impl DataBusBuilder { | ||
pub(crate) fn new() -> DataBusBuilder { | ||
DataBusBuilder { | ||
index: 0, | ||
map: HashMap::default(), | ||
databus: None, | ||
values: im::Vector::new(), | ||
} | ||
} | ||
|
||
/// Generates a boolean vector telling which (ssa) parameter from the given function signature | ||
/// are tagged with databus visibility | ||
pub(crate) fn is_databus(main_signature: &FunctionSignature) -> Vec<bool> { | ||
let mut params_is_databus = Vec::new(); | ||
|
||
for param in &main_signature.0 { | ||
let is_databus = match param.2 { | ||
noirc_frontend::Visibility::Public | noirc_frontend::Visibility::Private => false, | ||
noirc_frontend::Visibility::DataBus => true, | ||
}; | ||
let len = param.1.field_count() as usize; | ||
params_is_databus.extend(vec![is_databus; len]); | ||
} | ||
params_is_databus | ||
} | ||
} | ||
|
||
#[derive(Clone, Default, Debug)] | ||
pub(crate) struct DataBus { | ||
pub(crate) call_data: Option<ValueId>, | ||
pub(crate) call_data_map: HashMap<ValueId, usize>, | ||
pub(crate) return_data: Option<ValueId>, | ||
} | ||
|
||
impl DataBus { | ||
/// Updates the databus values with the provided function | ||
pub(crate) fn map_values(&self, mut f: impl FnMut(ValueId) -> ValueId) -> DataBus { | ||
let mut call_data_map = HashMap::default(); | ||
for (k, v) in self.call_data_map.iter() { | ||
call_data_map.insert(f(*k), *v); | ||
} | ||
DataBus { | ||
call_data: self.call_data.map(&mut f), | ||
call_data_map, | ||
return_data: self.return_data.map(&mut f), | ||
} | ||
} | ||
|
||
/// Construct a databus from call_data and return_data data bus builders | ||
pub(crate) fn get_data_bus(call_data: DataBusBuilder, return_data: DataBusBuilder) -> DataBus { | ||
DataBus { | ||
call_data: call_data.databus, | ||
call_data_map: call_data.map, | ||
return_data: return_data.databus, | ||
} | ||
} | ||
} | ||
|
||
impl FunctionBuilder { | ||
/// Insert a value into a data bus builder | ||
fn add_to_data_bus(&mut self, value: ValueId, databus: &mut DataBusBuilder) { | ||
assert!(databus.databus.is_none(), "initialising finalized call data"); | ||
let typ = self.current_function.dfg[value].get_type().clone(); | ||
match typ { | ||
Type::Numeric(_) => { | ||
databus.values.push_back(value); | ||
databus.index += 1; | ||
} | ||
Type::Reference(_) => unreachable!(), | ||
Type::Array(typ, len) => { | ||
assert!(typ.len() == 1, "unsupported composite type"); | ||
databus.map.insert(value, databus.index); | ||
for i in 0..len { | ||
// load each element of the array | ||
let index = self | ||
.current_function | ||
.dfg | ||
.make_constant(FieldElement::from(i as i128), Type::field()); | ||
let element = self.insert_array_get(value, index, typ[0].clone()); | ||
self.add_to_data_bus(element, databus); | ||
} | ||
} | ||
Type::Slice(_) => unreachable!(), | ||
Type::Function => unreachable!(), | ||
} | ||
} | ||
|
||
/// Create a data bus builder from a list of values | ||
pub(crate) fn initialize_data_bus( | ||
&mut self, | ||
values: &[ValueId], | ||
mut databus: DataBusBuilder, | ||
) -> DataBusBuilder { | ||
for value in values { | ||
self.add_to_data_bus(*value, &mut databus); | ||
} | ||
let len = databus.values.len(); | ||
|
||
let array = if len > 0 { | ||
let array = | ||
self.array_constant(databus.values, Type::Array(Rc::new(vec![Type::field()]), len)); | ||
Some(array) | ||
} else { | ||
None | ||
}; | ||
|
||
DataBusBuilder { index: 0, map: databus.map, databus: array, values: im::Vector::new() } | ||
} | ||
|
||
/// Generate the data bus for call-data, based on the parameters of the entry block | ||
/// and a boolean vector telling which ones are call-data | ||
pub(crate) fn call_data_bus(&mut self, is_params_databus: Vec<bool>) -> DataBusBuilder { | ||
//filter parameters of the first block that have call-data visilibity | ||
let first_block = self.current_function.entry_block(); | ||
let params = self.current_function.dfg[first_block].parameters(); | ||
let mut databus_param = Vec::new(); | ||
for (param, is_databus) in params.iter().zip(is_params_databus) { | ||
if is_databus { | ||
databus_param.push(param.to_owned()); | ||
} | ||
} | ||
// create the call-data-bus from the filtered list | ||
let call_data = DataBusBuilder::new(); | ||
self.initialize_data_bus(&databus_param, call_data) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
pub(crate) mod data_bus; | ||
|
||
use std::{borrow::Cow, rc::Rc}; | ||
|
||
use acvm::FieldElement; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.