Skip to content

Commit

Permalink
feat: Check initializer msg.sender matches deployer from address prei…
Browse files Browse the repository at this point in the history
…mage (AztecProtocol/aztec-packages#5222)

Checks that the msg.sender in initializer calls matches the deployer
address defined in the address preimage, unless when it's set to zero.
  • Loading branch information
AztecBot committed Mar 15, 2024
1 parent d4213a0 commit 3778f01
Show file tree
Hide file tree
Showing 97 changed files with 1,941 additions and 1,553 deletions.
2 changes: 1 addition & 1 deletion .aztec-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
aa90f6ed7bfae06bdf6990816d154bbd24993689
438d16f71db4cbac8a8fd06e2d6db4c3209633aa
125 changes: 124 additions & 1 deletion acvm-repo/acir/codegen/acir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,31 @@ namespace Circuit {
static Div bincodeDeserialize(std::vector<uint8_t>);
};

struct IntegerDiv {
friend bool operator==(const IntegerDiv&, const IntegerDiv&);
std::vector<uint8_t> bincodeSerialize() const;
static IntegerDiv bincodeDeserialize(std::vector<uint8_t>);
};

struct Equals {
friend bool operator==(const Equals&, const Equals&);
std::vector<uint8_t> bincodeSerialize() const;
static Equals bincodeDeserialize(std::vector<uint8_t>);
};

std::variant<Add, Sub, Mul, Div, Equals> value;
struct LessThan {
friend bool operator==(const LessThan&, const LessThan&);
std::vector<uint8_t> bincodeSerialize() const;
static LessThan bincodeDeserialize(std::vector<uint8_t>);
};

struct LessThanEquals {
friend bool operator==(const LessThanEquals&, const LessThanEquals&);
std::vector<uint8_t> bincodeSerialize() const;
static LessThanEquals bincodeDeserialize(std::vector<uint8_t>);
};

std::variant<Add, Sub, Mul, Div, IntegerDiv, Equals, LessThan, LessThanEquals> value;

friend bool operator==(const BinaryFieldOp&, const BinaryFieldOp&);
std::vector<uint8_t> bincodeSerialize() const;
Expand Down Expand Up @@ -1317,6 +1335,41 @@ Circuit::BinaryFieldOp::Div serde::Deserializable<Circuit::BinaryFieldOp::Div>::
return obj;
}

namespace Circuit {

inline bool operator==(const BinaryFieldOp::IntegerDiv &lhs, const BinaryFieldOp::IntegerDiv &rhs) {
return true;
}

inline std::vector<uint8_t> BinaryFieldOp::IntegerDiv::bincodeSerialize() const {
auto serializer = serde::BincodeSerializer();
serde::Serializable<BinaryFieldOp::IntegerDiv>::serialize(*this, serializer);
return std::move(serializer).bytes();
}

inline BinaryFieldOp::IntegerDiv BinaryFieldOp::IntegerDiv::bincodeDeserialize(std::vector<uint8_t> input) {
auto deserializer = serde::BincodeDeserializer(input);
auto value = serde::Deserializable<BinaryFieldOp::IntegerDiv>::deserialize(deserializer);
if (deserializer.get_buffer_offset() < input.size()) {
throw serde::deserialization_error("Some input bytes were not read");
}
return value;
}

} // end of namespace Circuit

template <>
template <typename Serializer>
void serde::Serializable<Circuit::BinaryFieldOp::IntegerDiv>::serialize(const Circuit::BinaryFieldOp::IntegerDiv &obj, Serializer &serializer) {
}

template <>
template <typename Deserializer>
Circuit::BinaryFieldOp::IntegerDiv serde::Deserializable<Circuit::BinaryFieldOp::IntegerDiv>::deserialize(Deserializer &deserializer) {
Circuit::BinaryFieldOp::IntegerDiv obj;
return obj;
}

namespace Circuit {

inline bool operator==(const BinaryFieldOp::Equals &lhs, const BinaryFieldOp::Equals &rhs) {
Expand Down Expand Up @@ -1352,6 +1405,76 @@ Circuit::BinaryFieldOp::Equals serde::Deserializable<Circuit::BinaryFieldOp::Equ
return obj;
}

namespace Circuit {

inline bool operator==(const BinaryFieldOp::LessThan &lhs, const BinaryFieldOp::LessThan &rhs) {
return true;
}

inline std::vector<uint8_t> BinaryFieldOp::LessThan::bincodeSerialize() const {
auto serializer = serde::BincodeSerializer();
serde::Serializable<BinaryFieldOp::LessThan>::serialize(*this, serializer);
return std::move(serializer).bytes();
}

inline BinaryFieldOp::LessThan BinaryFieldOp::LessThan::bincodeDeserialize(std::vector<uint8_t> input) {
auto deserializer = serde::BincodeDeserializer(input);
auto value = serde::Deserializable<BinaryFieldOp::LessThan>::deserialize(deserializer);
if (deserializer.get_buffer_offset() < input.size()) {
throw serde::deserialization_error("Some input bytes were not read");
}
return value;
}

} // end of namespace Circuit

template <>
template <typename Serializer>
void serde::Serializable<Circuit::BinaryFieldOp::LessThan>::serialize(const Circuit::BinaryFieldOp::LessThan &obj, Serializer &serializer) {
}

template <>
template <typename Deserializer>
Circuit::BinaryFieldOp::LessThan serde::Deserializable<Circuit::BinaryFieldOp::LessThan>::deserialize(Deserializer &deserializer) {
Circuit::BinaryFieldOp::LessThan obj;
return obj;
}

namespace Circuit {

inline bool operator==(const BinaryFieldOp::LessThanEquals &lhs, const BinaryFieldOp::LessThanEquals &rhs) {
return true;
}

inline std::vector<uint8_t> BinaryFieldOp::LessThanEquals::bincodeSerialize() const {
auto serializer = serde::BincodeSerializer();
serde::Serializable<BinaryFieldOp::LessThanEquals>::serialize(*this, serializer);
return std::move(serializer).bytes();
}

inline BinaryFieldOp::LessThanEquals BinaryFieldOp::LessThanEquals::bincodeDeserialize(std::vector<uint8_t> input) {
auto deserializer = serde::BincodeDeserializer(input);
auto value = serde::Deserializable<BinaryFieldOp::LessThanEquals>::deserialize(deserializer);
if (deserializer.get_buffer_offset() < input.size()) {
throw serde::deserialization_error("Some input bytes were not read");
}
return value;
}

} // end of namespace Circuit

template <>
template <typename Serializer>
void serde::Serializable<Circuit::BinaryFieldOp::LessThanEquals>::serialize(const Circuit::BinaryFieldOp::LessThanEquals &obj, Serializer &serializer) {
}

template <>
template <typename Deserializer>
Circuit::BinaryFieldOp::LessThanEquals serde::Deserializable<Circuit::BinaryFieldOp::LessThanEquals>::deserialize(Deserializer &deserializer) {
Circuit::BinaryFieldOp::LessThanEquals obj;
return obj;
}

namespace Circuit {

inline bool operator==(const BinaryIntOp &lhs, const BinaryIntOp &rhs) {
Expand Down
7 changes: 7 additions & 0 deletions acvm-repo/brillig/src/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,16 @@ pub enum BinaryFieldOp {
Add,
Sub,
Mul,
/// Field division
Div,
/// Integer division
IntegerDiv,
/// (==) equal
Equals,
/// (<) Field less than
LessThan,
/// (<=) field less or equal
LessThanEquals,
}

/// Binary fixed-length integer expressions
Expand Down
9 changes: 9 additions & 0 deletions acvm-repo/brillig_vm/src/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,16 @@ pub(crate) fn evaluate_binary_field_op(
BinaryFieldOp::Sub => a - b,
BinaryFieldOp::Mul => a * b,
BinaryFieldOp::Div => a / b,
BinaryFieldOp::IntegerDiv => {
let a_big = BigUint::from_bytes_be(&a.to_be_bytes());
let b_big = BigUint::from_bytes_be(&b.to_be_bytes());

let result = a_big / b_big;
FieldElement::from_be_bytes_reduce(&result.to_bytes_be())
}
BinaryFieldOp::Equals => (a == b).into(),
BinaryFieldOp::LessThan => (a < b).into(),
BinaryFieldOp::LessThanEquals => (a <= b).into(),
}
}

Expand Down
9 changes: 0 additions & 9 deletions aztec_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,6 @@ fn transform_module(
crate_graph.root_file_id,
));
}

let constructor_defined = module.functions.iter().any(|func| func.name() == "constructor");
if !constructor_defined {
let crate_graph = &context.crate_graph[crate_id];
return Err((
AztecMacroError::ContractConstructorMissing { span: Span::default() },
crate_graph.root_file_id,
));
}
}

Ok(has_transformed_module)
Expand Down
16 changes: 8 additions & 8 deletions aztec_macros/src/transforms/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,9 @@ pub fn transform_function(
func.def.body.0.insert(0, init_check);
}

// Add assertion for initialization arguments
// Add assertion for initialization arguments and sender
if is_initializer {
let assert_init_args = create_assert_init_args();
func.def.body.0.insert(0, assert_init_args);
func.def.body.0.insert(0, create_assert_initializer());
}

// Add access to the storage struct
Expand Down Expand Up @@ -211,18 +210,19 @@ fn create_internal_check(fname: &str) -> Statement {
)))
}

/// Creates a call to assert_initialization_args_match_address_preimage to ensure
/// the initialization arguments used in the init call match the address preimage.
/// Creates a call to assert_initialization_matches_address_preimage to be inserted
/// in the initializer. Checks that the args and sender to the initializer match the
/// commitments from the address preimage.
///
/// ```noir
/// assert_initialization_args_match_address_preimage(context);
/// assert_initialization_matches_address_preimage(context);
/// ```
fn create_assert_init_args() -> Statement {
fn create_assert_initializer() -> Statement {
make_statement(StatementKind::Expression(call(
variable_path(chained_dep!(
"aztec",
"initializer",
"assert_initialization_args_match_address_preimage"
"assert_initialization_matches_address_preimage"
)),
vec![variable("context")],
)))
Expand Down
6 changes: 0 additions & 6 deletions aztec_macros/src/utils/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use super::constants::MAX_CONTRACT_PRIVATE_FUNCTIONS;
pub enum AztecMacroError {
AztecDepNotFound,
ContractHasTooManyPrivateFunctions { span: Span },
ContractConstructorMissing { span: Span },
UnsupportedFunctionArgumentType { span: Span, typ: UnresolvedTypeData },
UnsupportedStorageType { span: Option<Span>, typ: UnresolvedTypeData },
CouldNotAssignStorageSlots { secondary_message: Option<String> },
Expand All @@ -29,11 +28,6 @@ impl From<AztecMacroError> for MacroError {
secondary_message: None,
span: Some(span),
},
AztecMacroError::ContractConstructorMissing { span } => MacroError {
primary_message: "Contract must have a constructor function".to_owned(),
secondary_message: None,
span: Some(span),
},
AztecMacroError::UnsupportedFunctionArgumentType { span, typ } => MacroError {
primary_message: format!("Provided parameter type `{typ:?}` is not supported in Aztec contract interface"),
secondary_message: None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ pub(crate) fn convert_black_box_call(
) = (function_arguments, function_results)
{
let message_hash = convert_array_or_vector(brillig_context, message, bb_func);
let signature = brillig_context.array_to_vector(signature);
let signature = brillig_context.array_to_vector_instruction(signature);
brillig_context.black_box_op_instruction(BlackBoxOp::SchnorrVerify {
public_key_x: public_key_x.address,
public_key_y: public_key_y.address,
Expand Down Expand Up @@ -368,7 +368,7 @@ fn convert_array_or_vector(
bb_func: &BlackBoxFunc,
) -> BrilligVector {
match array_or_vector {
BrilligVariable::BrilligArray(array) => brillig_context.array_to_vector(array),
BrilligVariable::BrilligArray(array) => brillig_context.array_to_vector_instruction(array),
BrilligVariable::BrilligVector(vector) => *vector,
_ => unreachable!(
"ICE: {} expected an array or a vector, but got {:?}",
Expand Down
Loading

0 comments on commit 3778f01

Please sign in to comment.