From a7d6e2ffe4caca26f4143158c56dc6bb1f99bb24 Mon Sep 17 00:00:00 2001 From: Tom French Date: Tue, 5 Mar 2024 15:24:47 +0000 Subject: [PATCH] git subrepo commit (merge) noir/noir-repo subrepo: subdir: "noir/noir-repo" merged: "a159cf7cbc" upstream: origin: "https://github.com/noir-lang/noir" branch: "master" commit: "5f57ebb7ff" git-subrepo: version: "0.4.6" origin: "???" commit: "???" --- noir/noir-repo/.aztec-sync-commit | 2 +- noir/noir-repo/.gitrepo | 2 +- .../acvm/src/compiler/optimizers/mod.rs | 3 -- noir/noir-repo/aztec_macros/src/lib.rs | 45 +++++++++++++++++-- .../noirc_frontend/src/lexer/token.rs | 3 -- .../src/parser/parser/function.rs | 14 +++--- .../cryptographic_primitives/eddsa.mdx | 11 +++++ noir/noir-repo/noir_stdlib/src/eddsa.nr | 7 +++ .../simple_contract/src/main.nr | 4 +- .../execution_success/eddsa/src/main.nr | 10 ++++- .../src/cli/noir_template_files/contract.nr | 2 +- 11 files changed, 80 insertions(+), 23 deletions(-) diff --git a/noir/noir-repo/.aztec-sync-commit b/noir/noir-repo/.aztec-sync-commit index c97738f7226..78e53d61647 100644 --- a/noir/noir-repo/.aztec-sync-commit +++ b/noir/noir-repo/.aztec-sync-commit @@ -1 +1 @@ -9e246c1289fa40c35c4b28d2f0081dfdc2aa9d19 +73d640a4a033f0c865d45da470ef40c1fb03a844 diff --git a/noir/noir-repo/.gitrepo b/noir/noir-repo/.gitrepo index 935a9753813..24317f85d26 100644 --- a/noir/noir-repo/.gitrepo +++ b/noir/noir-repo/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/noir-lang/noir branch = master - commit = 86a0029b727b74c9ba1157f01c89daa7bfd60788 + commit = 5f57ebb7ff4b810802f90699a10f4325ef904f2e parent = 8307dadd853d5091841e169c841ab6b09c223efb method = merge cmdver = 0.4.6 diff --git a/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/mod.rs index 04d3f99a408..fc16099bd33 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/mod.rs @@ -70,6 +70,3 @@ pub(super) fn optimize_internal(acir: Circuit) -> (Circuit, Vec) { // ConstantBackpropagationOptimizer::backpropagate_constants(acir, acir_opcode_positions); info!("Number of opcodes after: {}", acir.opcodes.len()); - - (acir, acir_opcode_positions) -} diff --git a/noir/noir-repo/aztec_macros/src/lib.rs b/noir/noir-repo/aztec_macros/src/lib.rs index 4257197270f..50e58cf0a31 100644 --- a/noir/noir-repo/aztec_macros/src/lib.rs +++ b/noir/noir-repo/aztec_macros/src/lib.rs @@ -3,7 +3,7 @@ use std::vec; use convert_case::{Case, Casing}; use iter_extended::vecmap; -use noirc_errors::Location; +use noirc_errors::{Location, Spanned}; use noirc_frontend::hir::def_collector::dc_crate::{UnresolvedFunctions, UnresolvedTraitImpl}; use noirc_frontend::hir::def_map::{LocalModuleId, ModuleId}; use noirc_frontend::macros_api::parse_program; @@ -21,7 +21,7 @@ use noirc_frontend::macros_api::{CrateId, FileId}; use noirc_frontend::macros_api::{MacroError, MacroProcessor}; use noirc_frontend::macros_api::{ModuleDefId, NodeInterner, SortedModule, StructId}; use noirc_frontend::node_interner::{FuncId, TraitId, TraitImplId, TraitImplKind}; -use noirc_frontend::Lambda; +use noirc_frontend::{BinaryOpKind, ConstrainKind, ConstrainStatement, InfixExpression, Lambda}; pub struct AztecMacro; impl MacroProcessor for AztecMacro { @@ -221,6 +221,14 @@ fn lambda(parameters: Vec<(Pattern, UnresolvedType)>, body: Expression) -> Expre }))) } +fn make_eq(lhs: Expression, rhs: Expression) -> Expression { + expression(ExpressionKind::Infix(Box::new(InfixExpression { + lhs, + rhs, + operator: Spanned::from(Span::default(), BinaryOpKind::Equal), + }))) +} + macro_rules! chained_path { ( $base:expr ) => { { @@ -420,7 +428,7 @@ fn transform_module( .attributes .secondary .iter() - .any(|attr| is_custom_attribute(&attr, "aztec(initializer)")) + .any(|attr| is_custom_attribute(attr, "aztec(initializer)")) }); for func in module.functions.iter_mut() { @@ -428,6 +436,7 @@ fn transform_module( let mut is_public = false; let mut is_public_vm = false; let mut is_initializer = false; + let mut is_internal = false; let mut insert_init_check = has_initializer; for secondary_attribute in func.def.attributes.secondary.clone() { @@ -438,6 +447,8 @@ fn transform_module( insert_init_check = false; } else if is_custom_attribute(&secondary_attribute, "aztec(noinitcheck)") { insert_init_check = false; + } else if is_custom_attribute(&secondary_attribute, "aztec(internal)") { + is_internal = true; } else if is_custom_attribute(&secondary_attribute, "aztec(public)") { is_public = true; insert_init_check = false; @@ -454,6 +465,7 @@ fn transform_module( storage_defined, is_initializer, insert_init_check, + is_internal, ) .map_err(|err| (err, crate_graph.root_file_id))?; has_transformed_module = true; @@ -646,11 +658,19 @@ fn transform_function( storage_defined: bool, is_initializer: bool, insert_init_check: bool, + is_internal: bool, ) -> Result<(), AztecMacroError> { let context_name = format!("{}Context", ty); let inputs_name = format!("{}ContextInputs", ty); let return_type_name = format!("{}CircuitPublicInputs", ty); + // Add check that msg sender equals this address and flag function as internal + if is_internal { + let is_internal_check = create_internal_check(func.name()); + func.def.body.0.insert(0, is_internal_check); + func.def.is_internal = true; + } + // Add initialization check if insert_init_check { if ty == "Public" { @@ -1166,6 +1186,25 @@ fn create_mark_as_initialized() -> Statement { ))) } +/// Creates a check for internal functions ensuring that the caller is self. +/// +/// ```noir +/// assert(context.msg_sender() == context.this_address(), "Function can only be called internally"); +/// ``` +fn create_internal_check(fname: &str) -> Statement { + make_statement(StatementKind::Constrain(ConstrainStatement( + make_eq( + method_call(variable("context"), "msg_sender", vec![]), + method_call(variable("context"), "this_address", vec![]), + ), + Some(expression(ExpressionKind::Literal(Literal::Str(format!( + "Function {} can only be called internally", + fname + ))))), + ConstrainKind::Assert, + ))) +} + /// Creates the private context object to be accessed within the function, the parameters need to be extracted to be /// appended into the args hash object. /// diff --git a/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs b/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs index 5674ae5a39a..f096c220200 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs @@ -661,7 +661,6 @@ pub enum Keyword { If, Impl, In, - Internal, Let, Mod, Mut, @@ -704,7 +703,6 @@ impl fmt::Display for Keyword { Keyword::If => write!(f, "if"), Keyword::Impl => write!(f, "impl"), Keyword::In => write!(f, "in"), - Keyword::Internal => write!(f, "internal"), Keyword::Let => write!(f, "let"), Keyword::Mod => write!(f, "mod"), Keyword::Mut => write!(f, "mut"), @@ -750,7 +748,6 @@ impl Keyword { "if" => Keyword::If, "impl" => Keyword::Impl, "in" => Keyword::In, - "internal" => Keyword::Internal, "let" => Keyword::Let, "mod" => Keyword::Mod, "mut" => Keyword::Mut, diff --git a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/function.rs b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/function.rs index 42ee484bfc9..7448d84cfe1 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/function.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/function.rs @@ -37,7 +37,8 @@ pub(super) fn function_definition(allow_self: bool) -> impl NoirParser impl NoirParser { choice((is_pub_crate, is_pub, is_private)) } -/// function_modifiers: 'unconstrained'? (visibility)? 'open'? 'internal'? +/// function_modifiers: 'unconstrained'? (visibility)? 'open'? /// -/// returns (is_unconstrained, visibility, is_open, is_internal) for whether each keyword was present -fn function_modifiers() -> impl NoirParser<(bool, FunctionVisibility, bool, bool)> { +/// returns (is_unconstrained, visibility, is_open) for whether each keyword was present +fn function_modifiers() -> impl NoirParser<(bool, FunctionVisibility, bool)> { keyword(Keyword::Unconstrained) .or_not() .then(visibility_modifier()) .then(keyword(Keyword::Open).or_not()) - .then(keyword(Keyword::Internal).or_not()) - .map(|(((unconstrained, visibility), open), internal)| { - (unconstrained.is_some(), visibility, open.is_some(), internal.is_some()) + .map(|((unconstrained, visibility), open)| { + (unconstrained.is_some(), visibility, open.is_some()) }) } diff --git a/noir/noir-repo/docs/docs/noir/standard_library/cryptographic_primitives/eddsa.mdx b/noir/noir-repo/docs/docs/noir/standard_library/cryptographic_primitives/eddsa.mdx index a9c10da6c06..99b7f830a20 100644 --- a/noir/noir-repo/docs/docs/noir/standard_library/cryptographic_primitives/eddsa.mdx +++ b/noir/noir-repo/docs/docs/noir/standard_library/cryptographic_primitives/eddsa.mdx @@ -16,3 +16,14 @@ fn eddsa_poseidon_verify(public_key_x : Field, public_key_y : Field, signature_s ``` + +## eddsa::eddsa_to_pub + +Private to public key conversion. + +Returns `(pub_key_x, pub_key_y)` + +```rust +fn eddsa_to_pub(secret : Field) -> (Field, Field) +``` + diff --git a/noir/noir-repo/noir_stdlib/src/eddsa.nr b/noir/noir-repo/noir_stdlib/src/eddsa.nr index 657e791e9c7..966bc1da2a1 100644 --- a/noir/noir-repo/noir_stdlib/src/eddsa.nr +++ b/noir/noir-repo/noir_stdlib/src/eddsa.nr @@ -38,3 +38,10 @@ pub fn eddsa_poseidon_verify( left.eq(right) } + +// Returns the public key of the given secret key as (pub_key_x, pub_key_y) +pub fn eddsa_to_pub(secret: Field) -> (Field, Field) { + let bjj = baby_jubjub(); + let pub_key = bjj.curve.mul(secret, bjj.curve.gen); + (pub_key.x, pub_key.y) +} diff --git a/noir/noir-repo/test_programs/compile_success_contract/simple_contract/src/main.nr b/noir/noir-repo/test_programs/compile_success_contract/simple_contract/src/main.nr index fea0ae08c22..ed90ac8bd1d 100644 --- a/noir/noir-repo/test_programs/compile_success_contract/simple_contract/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_contract/simple_contract/src/main.nr @@ -5,10 +5,10 @@ contract Foo { fn triple(x: Field) -> pub Field { x * 3 } - internal fn quadruple(x: Field) -> pub Field { + fn quadruple(x: Field) -> pub Field { x * 4 } - open internal fn skibbidy(x: Field) -> pub Field { + open fn skibbidy(x: Field) -> pub Field { x * 5 } // Regression for issue #3344 diff --git a/noir/noir-repo/test_programs/execution_success/eddsa/src/main.nr b/noir/noir-repo/test_programs/execution_success/eddsa/src/main.nr index 12e8ea92785..4404ffe75f7 100644 --- a/noir/noir-repo/test_programs/execution_success/eddsa/src/main.nr +++ b/noir/noir-repo/test_programs/execution_success/eddsa/src/main.nr @@ -1,14 +1,20 @@ use dep::std::compat; use dep::std::ec::consts::te::baby_jubjub; +use dep::std::ec::tecurve::affine::Point as TEPoint; use dep::std::hash; -use dep::std::eddsa::eddsa_poseidon_verify; +use dep::std::eddsa::{eddsa_to_pub, eddsa_poseidon_verify}; + fn main(msg: pub Field, _priv_key_a: Field, _priv_key_b: Field) { // Skip this test for non-bn254 backends if compat::is_bn254() { let bjj = baby_jubjub(); let pub_key_a = bjj.curve.mul(_priv_key_a, bjj.curve.gen); - // let pub_key_b = bjj.curve.mul(_priv_key_b, bjj.curve.gen); + let pub_key_b = bjj.curve.mul(_priv_key_b, bjj.curve.gen); + let (pub_key_a_x, pub_key_a_y) = eddsa_to_pub(_priv_key_a); + let (pub_key_b_x, pub_key_b_y) = eddsa_to_pub(_priv_key_b); + assert(TEPoint::new(pub_key_a_x, pub_key_a_y) == pub_key_a); + assert(TEPoint::new(pub_key_b_x, pub_key_b_y) == pub_key_b); // Manually computed as fields can't use modulo. Importantantly the commitment is within // the subgroup order. Note that choice of hash is flexible for this step. // let r_a = hash::pedersen_commitment([_priv_key_a, msg])[0] % bjj.suborder; // modulus computed manually diff --git a/noir/noir-repo/tooling/nargo_cli/src/cli/noir_template_files/contract.nr b/noir/noir-repo/tooling/nargo_cli/src/cli/noir_template_files/contract.nr index e126726393d..3cd3b5b3766 100644 --- a/noir/noir-repo/tooling/nargo_cli/src/cli/noir_template_files/contract.nr +++ b/noir/noir-repo/tooling/nargo_cli/src/cli/noir_template_files/contract.nr @@ -1,5 +1,5 @@ contract Main { - internal fn double(x: Field) -> pub Field { x * 2 } + fn double(x: Field) -> pub Field { x * 2 } fn triple(x: Field) -> pub Field { x * 3 } fn quadruple(x: Field) -> pub Field { double(double(x)) } }