Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Oct 4, 2024
1 parent b253ce6 commit 92a9cfe
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
22 changes: 18 additions & 4 deletions noir-projects/aztec-nr/aztec/src/macros/notes/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ use crate::note::{note_header::NoteHeader, note_getter_options::PropertySelector

comptime global NOTE_HEADER_TYPE = type_of(NoteHeader::empty());

// A map from note type to (note_struct_definition, serialized_note_length, note_type_id, fields).
// `fields` is an array of tuples where each tuple contains the name of the field/struct member (e.g. `amount`
// in `TokenNote`), the index of where the serialized member starts in the serialized note and a flag indicating
// whether the field is nullable or not.
/// A map from note type to (note_struct_definition, serialized_note_length, note_type_id, fields).
/// `fields` is an array of tuples where each tuple contains the name of the field/struct member (e.g. `amount`
/// in `TokenNote`), the index of where the serialized member starts in the serialized note and a flag indicating
/// whether the field is nullable or not.
comptime mut global NOTES: UHashMap<Type, (StructDefinition, u32, Field, [(Quoted, u32, bool)]), BuildHasherDefault<Poseidon2Hasher>> = UHashMap::default();

/// Computes the note type id by hashing the note name (e.g. `TokenNote`), getting the first 4 bytes of the hash
Expand Down Expand Up @@ -264,6 +264,20 @@ pub(crate) comptime fn generate_note_export(
}
}

/// Generates quotes necessary for multi-scalar multiplication of `indexed_fields` (indexed struct fields). Returns
/// a tuple containing quotes for generators, scalars, arguments and auxiliary variables. For more info on what are
/// auxiliary variables and how they are used, see `flatten_to_fields` function.
///
/// Example return values:
/// generators_list: [aztec::generators::Ga1, aztec::generators::Ga2, aztec::generators::Ga3, aztec::generators::Ga4]
/// scalars_list: [
/// std::hash::from_field_unsafe(amount.lo as Field),
/// std::hash::from_field_unsafe(amount.hi as Field),
/// std::hash::from_field_unsafe(npk_m_hash as Field),
/// std::hash::from_field_unsafe(randomness as Field)
/// ]
/// args_list: [amount: U128, npk_m_hash: Field, randomness: Field]
/// aux_vars: []
comptime fn generate_multi_scalar_mul(indexed_fields: [(Quoted, Type, u32)]) -> ([Quoted], [Quoted], [Quoted], Quoted) {
let mut generators_list = &[];
let mut scalars_list = &[];
Expand Down
11 changes: 11 additions & 0 deletions noir-projects/noir-protocol-circuits/crates/types/src/meta/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -87,21 +87,29 @@ pub comptime fn pack_from_fields<N>(
(result, consumed)
}

/// Flattens `typ` into a list of fields prefixed with `name` while omitting fields in `omit`. Also returns a list of
/// auxiliary variables that are needed for serialization (e.g. "let string_value_as_bytes = string_value.as_bytes()").
pub comptime fn flatten_to_fields(name: Quoted, typ: Type, omit: [Quoted]) -> ([Quoted], [Quoted]) {
let mut fields = &[];
let mut aux_vars = &[];

if omit.all(| to_omit | to_omit != name) {
if typ.is_field() | typ.as_integer().is_some() | typ.is_bool() {
// For field, integer and bool we just cast to Field and add the value to fields
fields = fields.push_back(quote { $name as Field });
} else if typ.as_struct().is_some() {
// For struct we pref
let nested_struct = typ.as_struct().unwrap();
let params = nested_struct.0.fields();
let struct_flattened = params.map(
| (param_name, param_type): (Quoted, Type) | {
let maybe_prefixed_name = if name == quote {} {
// Triggered when the param name is of a value available in the current scope (e.g. a function
// argument) --> then we don't prefix the name with anything.
quote { $param_name }
} else {
// Triggered when we want to prefix the param name with the `name` from function input. This
// can typically be `self` when implementing a method on a struct.
quote { $name.$param_name }
};
flatten_to_fields(quote {$maybe_prefixed_name}, param_type, omit)
Expand All @@ -118,6 +126,7 @@ pub comptime fn flatten_to_fields(name: Quoted, typ: Type, omit: [Quoted]) -> ([
fields = fields.append(struct_flattened_fields);
aux_vars = aux_vars.append(struct_flattened_aux_vars);
} else if typ.as_array().is_some() {
// For array we recursively call flatten_to_fields for each element
let (element_type, array_len) = typ.as_array().unwrap();
let array_len = array_len.as_constant().unwrap();
for i in 0..array_len {
Expand All @@ -126,6 +135,8 @@ pub comptime fn flatten_to_fields(name: Quoted, typ: Type, omit: [Quoted]) -> ([
aux_vars = aux_vars.append(element_aux_vars);
}
} else if typ.as_str().is_some() {
// For string we convert the value to bytes, we store the `as_bytes` in an auxiliary variables and
// then we add each byte to fields as a Field
let length_type = typ.as_str().unwrap();
let str_len = length_type.as_constant().unwrap();
let as_member = name.as_expr().unwrap().as_member_access();
Expand Down

0 comments on commit 92a9cfe

Please sign in to comment.