diff --git a/compiler/noirc_driver/src/lib.rs b/compiler/noirc_driver/src/lib.rs index 4fa169992c4..8d74825a9b6 100644 --- a/compiler/noirc_driver/src/lib.rs +++ b/compiler/noirc_driver/src/lib.rs @@ -260,17 +260,17 @@ fn compile_contract_inner( continue; } }; - let func_meta = context.def_interner.function_meta(&function_id); - let func_type = func_meta + let modifiers = context.def_interner.function_modifiers(&function_id); + let func_type = modifiers .contract_function_type .expect("Expected contract function to have a contract visibility"); - let function_type = ContractFunctionType::new(func_type, func_meta.is_unconstrained); + let function_type = ContractFunctionType::new(func_type, modifiers.is_unconstrained); functions.push(ContractFunction { name, function_type, - is_internal: func_meta.is_internal.unwrap_or(false), + is_internal: modifiers.is_internal.unwrap_or(false), abi: function.abi, bytecode: function.circuit, debug: function.debug, diff --git a/compiler/noirc_frontend/src/ast/expression.rs b/compiler/noirc_frontend/src/ast/expression.rs index 62e033b3332..3febee7f527 100644 --- a/compiler/noirc_frontend/src/ast/expression.rs +++ b/compiler/noirc_frontend/src/ast/expression.rs @@ -364,6 +364,9 @@ pub struct FunctionDefinition { /// True if this function was defined with the 'unconstrained' keyword pub is_unconstrained: bool, + /// True if this function was defined with the 'pub' keyword + pub is_public: bool, + pub generics: UnresolvedGenerics, pub parameters: Vec<(Pattern, UnresolvedType, Visibility)>, pub body: BlockExpression, @@ -649,6 +652,7 @@ impl FunctionDefinition { is_open: false, is_internal: false, is_unconstrained: false, + is_public: false, generics: generics.clone(), parameters: p, body: body.clone(), diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index 63aabe5399b..0e4c1710ce8 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -850,8 +850,7 @@ fn resolve_function_set( vecmap(unresolved_functions.functions, |(mod_id, func_id, func)| { let module_id = ModuleId { krate: crate_id, local_id: mod_id }; - let path_resolver = - StandardPathResolver::new(ModuleId { local_id: mod_id, krate: crate_id }); + let path_resolver = StandardPathResolver::new(module_id); let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file_id); // Must use set_generics here to ensure we re-use the same generics from when @@ -860,7 +859,7 @@ fn resolve_function_set( resolver.set_generics(impl_generics.clone()); resolver.set_self_type(self_type.clone()); - let (hir_func, func_meta, errs) = resolver.resolve_function(func, func_id, module_id); + let (hir_func, func_meta, errs) = resolver.resolve_function(func, func_id); interner.push_fn_meta(func_meta, func_id); interner.update_fn(func_id, hir_func); extend_errors(errors, file_id, errs); diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index 63539787e1f..86e4eb50de3 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -9,8 +9,9 @@ use crate::{ def_collector::dc_crate::{UnresolvedStruct, UnresolvedTrait}, def_map::ScopeResolveError, }, - node_interner::TraitId, + node_interner::{FunctionModifiers, TraitId}, parser::SubModule, + token::Attributes, FunctionDefinition, Ident, LetStatement, NoirFunction, NoirStruct, NoirTrait, NoirTraitImpl, NoirTypeAlias, ParsedModule, TraitImplItem, TraitItem, TypeImpl, }; @@ -71,11 +72,11 @@ pub fn collect_defs( collector.collect_type_aliases(context, ast.type_aliases, errors); - collector.collect_functions(context, ast.functions, errors); + collector.collect_functions(context, ast.functions, crate_id, errors); - collector.collect_trait_impls(context, ast.trait_impls, errors); + collector.collect_trait_impls(context, ast.trait_impls, crate_id, errors); - collector.collect_impls(context, ast.impls); + collector.collect_impls(context, ast.impls, crate_id); } impl<'a> ModCollector<'a> { @@ -114,14 +115,16 @@ impl<'a> ModCollector<'a> { } } - fn collect_impls(&mut self, context: &mut Context, impls: Vec) { + fn collect_impls(&mut self, context: &mut Context, impls: Vec, krate: CrateId) { + let module_id = ModuleId { krate, local_id: self.module_id }; + for r#impl in impls { let mut unresolved_functions = UnresolvedFunctions { file_id: self.file_id, functions: Vec::new() }; for method in r#impl.methods { let func_id = context.def_interner.push_empty_fn(); - context.def_interner.push_function_definition(method.name().to_owned(), func_id); + context.def_interner.push_function(func_id, &method.def, module_id); unresolved_functions.push_fn(self.module_id, func_id, method); } @@ -135,8 +138,11 @@ impl<'a> ModCollector<'a> { &mut self, context: &mut Context, impls: Vec, + krate: CrateId, errors: &mut Vec, ) { + let module_id = ModuleId { krate, local_id: self.module_id }; + for trait_impl in impls { let trait_name = &trait_impl.trait_name; let module = &self.def_collector.def_map.modules[self.module_id.0]; @@ -149,13 +155,13 @@ impl<'a> ModCollector<'a> { context, &trait_impl, &collected_trait.trait_def, + krate, errors, ); for (_, func_id, noir_function) in &unresolved_functions.functions { - let name = noir_function.name().to_owned(); - - context.def_interner.push_function_definition(name, *func_id); + let function = &noir_function.def; + context.def_interner.push_function(*func_id, function, module_id); } let unresolved_trait_impl = UnresolvedTraitImpl { @@ -200,17 +206,18 @@ impl<'a> ModCollector<'a> { context: &mut Context, trait_impl: &NoirTraitImpl, trait_def: &NoirTrait, + krate: CrateId, errors: &mut Vec, ) -> UnresolvedFunctions { let mut unresolved_functions = UnresolvedFunctions { file_id: self.file_id, functions: Vec::new() }; + let module = ModuleId { krate, local_id: self.module_id }; + for item in &trait_impl.items { if let TraitImplItem::Function(impl_method) = item { let func_id = context.def_interner.push_empty_fn(); - context - .def_interner - .push_function_definition(impl_method.name().to_owned(), func_id); + context.def_interner.push_function(func_id, &impl_method.def, module); unresolved_functions.push_fn(self.module_id, func_id, impl_method.clone()); } } @@ -244,7 +251,21 @@ impl<'a> ModCollector<'a> { // if there's a default implementation for the method, use it let method_name = name.0.contents.clone(); let func_id = context.def_interner.push_empty_fn(); - context.def_interner.push_function_definition(method_name, func_id); + let modifiers = FunctionModifiers { + // trait functions are always public + visibility: crate::Visibility::Public, + attributes: Attributes::empty(), + is_unconstrained: false, + contract_function_type: None, + is_internal: None, + }; + + context.def_interner.push_function_definition( + method_name, + func_id, + modifiers, + module, + ); let impl_method = NoirFunction::normal(FunctionDefinition::normal( name, generics, @@ -292,18 +313,21 @@ impl<'a> ModCollector<'a> { &mut self, context: &mut Context, functions: Vec, + krate: CrateId, errors: &mut Vec, ) { let mut unresolved_functions = UnresolvedFunctions { file_id: self.file_id, functions: Vec::new() }; + let module = ModuleId { krate, local_id: self.module_id }; + for mut function in functions { let name = function.name_ident().clone(); + let func_id = context.def_interner.push_empty_fn(); // First create dummy function in the DefInterner // So that we can get a FuncId - let func_id = context.def_interner.push_empty_fn(); - context.def_interner.push_function_definition(name.0.contents.clone(), func_id); + context.def_interner.push_function(func_id, &function.def, module); // Then go over the where clause and assign trait_ids to the constraints for constraint in &mut function.def.where_clause { diff --git a/compiler/noirc_frontend/src/hir/def_map/mod.rs b/compiler/noirc_frontend/src/hir/def_map/mod.rs index 2c880e33242..017027a1da2 100644 --- a/compiler/noirc_frontend/src/hir/def_map/mod.rs +++ b/compiler/noirc_frontend/src/hir/def_map/mod.rs @@ -139,10 +139,11 @@ impl CrateDefMap { self.modules.iter().flat_map(|(_, module)| { module.value_definitions().filter_map(|id| { if let Some(func_id) = id.as_function() { - let func_meta = interner.function_meta(&func_id); - match func_meta.attributes.function { + let attributes = interner.function_attributes(&func_id); + match &attributes.function { Some(FunctionAttribute::Test(scope)) => { - Some(TestFunction::new(func_id, scope, func_meta.name.location)) + let location = interner.function_meta(&func_id).name.location; + Some(TestFunction::new(func_id, scope.clone(), location)) } _ => None, } diff --git a/compiler/noirc_frontend/src/hir/mod.rs b/compiler/noirc_frontend/src/hir/mod.rs index eb67fbaa8ad..63f057a63d3 100644 --- a/compiler/noirc_frontend/src/hir/mod.rs +++ b/compiler/noirc_frontend/src/hir/mod.rs @@ -79,11 +79,11 @@ impl Context { let name = self.def_interner.function_name(id); - let meta = self.def_interner.function_meta(id); - let module = self.module(meta.module_id); + let module_id = self.def_interner.function_module(*id); + let module = self.module(module_id); let parent = - def_map.get_module_path_with_separator(meta.module_id.local_id.0, module.parent, "::"); + def_map.get_module_path_with_separator(module_id.local_id.0, module.parent, "::"); if parent.is_empty() { name.into() diff --git a/compiler/noirc_frontend/src/hir/resolution/errors.rs b/compiler/noirc_frontend/src/hir/resolution/errors.rs index 93304ac151c..80a0b557465 100644 --- a/compiler/noirc_frontend/src/hir/resolution/errors.rs +++ b/compiler/noirc_frontend/src/hir/resolution/errors.rs @@ -76,6 +76,8 @@ pub enum ResolverError { NumericConstantInFormatString { name: String, span: Span }, #[error("Closure environment must be a tuple or unit type")] InvalidClosureEnvironment { typ: Type, span: Span }, + #[error("{name} is private and not visible from the current module")] + PrivateFunctionCalled { name: String, span: Span }, } impl ResolverError { @@ -288,6 +290,10 @@ impl From for Diagnostic { ResolverError::InvalidClosureEnvironment { span, typ } => Diagnostic::simple_error( format!("{typ} is not a valid closure environment type"), "Closure environment must be a tuple or unit type".to_string(), span), + // This will be upgraded to an error in future versions + ResolverError::PrivateFunctionCalled { span, name } => Diagnostic::simple_warning( + format!("{name} is private and not visible from the current module"), + format!("{name} is private"), span), } } } diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index 4231e493457..78388eacb94 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -25,7 +25,7 @@ use std::collections::{BTreeMap, HashSet}; use std::rc::Rc; use crate::graph::CrateId; -use crate::hir::def_map::{ModuleDefId, ModuleId, TryFromModuleDefId, MAIN_FUNCTION}; +use crate::hir::def_map::{LocalModuleId, ModuleDefId, TryFromModuleDefId, MAIN_FUNCTION}; use crate::hir_def::stmt::{HirAssignStatement, HirLValue, HirPattern}; use crate::node_interner::{ DefinitionId, DefinitionKind, ExprId, FuncId, NodeInterner, StmtId, StructId, TraitId, @@ -146,7 +146,6 @@ impl<'a> Resolver<'a> { mut self, func: NoirFunction, func_id: FuncId, - module_id: ModuleId, ) -> (HirFunction, FuncMeta, Vec) { self.scopes.start_function(); @@ -155,7 +154,7 @@ impl<'a> Resolver<'a> { self.add_generics(&func.def.generics); - let (hir_func, func_meta) = self.intern_function(func, func_id, module_id); + let (hir_func, func_meta) = self.intern_function(func, func_id); let func_scope_tree = self.scopes.end_function(); self.check_for_unused_variables_in_scope_tree(func_scope_tree); @@ -314,13 +313,8 @@ impl<'a> Resolver<'a> { } } - fn intern_function( - &mut self, - func: NoirFunction, - id: FuncId, - module_id: ModuleId, - ) -> (HirFunction, FuncMeta) { - let func_meta = self.extract_meta(&func, id, module_id); + fn intern_function(&mut self, func: NoirFunction, id: FuncId) -> (HirFunction, FuncMeta) { + let func_meta = self.extract_meta(&func, id); let hir_func = match func.kind { FunctionKind::Builtin | FunctionKind::LowLevel | FunctionKind::Oracle => { HirFunction::empty() @@ -686,12 +680,7 @@ impl<'a> Resolver<'a> { /// to be used in analysis and intern the function parameters /// Prerequisite: self.add_generics() has already been called with the given /// function's generics, including any generics from the impl, if any. - fn extract_meta( - &mut self, - func: &NoirFunction, - func_id: FuncId, - module_id: ModuleId, - ) -> FuncMeta { + fn extract_meta(&mut self, func: &NoirFunction, func_id: FuncId) -> FuncMeta { let location = Location::new(func.name_ident().span(), self.file); let id = self.interner.function_definition_id(func_id); let name_ident = HirIdent { id, location }; @@ -765,14 +754,12 @@ impl<'a> Resolver<'a> { self.interner.push_definition_type(name_ident.id, typ.clone()); + self.handle_function_type(&func_id); + self.handle_is_function_internal(&func_id); + FuncMeta { name: name_ident, kind: func.kind, - attributes, - module_id, - contract_function_type: self.handle_function_type(func), - is_internal: self.handle_is_function_internal(func), - is_unconstrained: func.def.is_unconstrained, location, typ, parameters: parameters.into(), @@ -804,31 +791,23 @@ impl<'a> Resolver<'a> { } } - fn handle_function_type(&mut self, func: &NoirFunction) -> Option { - if func.def.is_open { - if self.in_contract() { - Some(ContractFunctionType::Open) - } else { - self.push_err(ResolverError::ContractFunctionTypeInNormalFunction { - span: func.name_ident().span(), - }); - None - } - } else { - Some(ContractFunctionType::Secret) + fn handle_function_type(&mut self, function: &FuncId) { + let function_type = self.interner.function_modifiers(function).contract_function_type; + + if !self.in_contract() && function_type == Some(ContractFunctionType::Open) { + let span = self.interner.function_ident(function).span(); + self.errors.push(ResolverError::ContractFunctionTypeInNormalFunction { span }); + self.interner.function_modifiers_mut(function).contract_function_type = None; } } - fn handle_is_function_internal(&mut self, func: &NoirFunction) -> Option { - if self.in_contract() { - Some(func.def.is_internal) - } else { - if func.def.is_internal { - self.push_err(ResolverError::ContractFunctionInternalInNormalFunction { - span: func.name_ident().span(), - }); + fn handle_is_function_internal(&mut self, function: &FuncId) { + if !self.in_contract() { + if self.interner.function_modifiers(function).is_internal == Some(true) { + let span = self.interner.function_ident(function).span(); + self.push_err(ResolverError::ContractFunctionInternalInNormalFunction { span }); } - None + self.interner.function_modifiers_mut(function).is_internal = None; } } @@ -996,6 +975,40 @@ impl<'a> Resolver<'a> { } } + // Issue an error if the given private function is being called from a non-child module + fn check_can_reference_private_function(&mut self, func: FuncId, span: Span) { + let function_module = self.interner.function_module(func); + let current_module = self.path_resolver.module_id(); + + let same_crate = function_module.krate == current_module.krate; + let krate = function_module.krate; + let current_module = current_module.local_id; + + if !same_crate + || !self.module_descendent_of_target(krate, function_module.local_id, current_module) + { + let name = self.interner.function_name(&func).to_string(); + self.errors.push(ResolverError::PrivateFunctionCalled { span, name }); + } + } + + // Returns true if `current` is a (potentially nested) child module of `target`. + // This is also true if `current == target`. + fn module_descendent_of_target( + &self, + krate: CrateId, + target: LocalModuleId, + current: LocalModuleId, + ) -> bool { + if current == target { + return true; + } + + self.def_maps[&krate].modules[current.0] + .parent + .map_or(false, |parent| self.module_descendent_of_target(krate, target, parent)) + } + fn resolve_local_variable(&mut self, hir_ident: HirIdent, var_scope_index: usize) { let mut transitive_capture_index: Option = None; @@ -1065,7 +1078,12 @@ impl<'a> Resolver<'a> { if hir_ident.id != DefinitionId::dummy_id() { match self.interner.definition(hir_ident.id).kind { - DefinitionKind::Function(_) => {} + DefinitionKind::Function(id) => { + if self.interner.function_visibility(id) == Visibility::Private { + let span = hir_ident.location.span; + self.check_can_reference_private_function(id, span); + } + } DefinitionKind::Global(_) => {} DefinitionKind::GenericType(_) => { // Initialize numeric generics to a polymorphic integer type in case @@ -1554,7 +1572,6 @@ mod test { use crate::graph::CrateId; use crate::hir_def::expr::HirExpression; - use crate::hir_def::function::HirFunction; use crate::hir_def::stmt::HirStatement; use crate::node_interner::{FuncId, NodeInterner}; use crate::ParsedModule; @@ -1607,9 +1624,7 @@ mod test { init_src_code_resolution(src); let func_ids = vecmap(&func_namespace, |name| { - let id = interner.push_fn(HirFunction::empty()); - interner.push_function_definition(name.to_string(), id); - id + interner.push_test_function_definition(name.to_string()) }); for (name, id) in func_namespace.into_iter().zip(func_ids) { @@ -1618,11 +1633,10 @@ mod test { let mut errors = Vec::new(); for func in program.functions { - let id = interner.push_fn(HirFunction::empty()); - interner.push_function_definition(func.name().to_string(), id); + let id = interner.push_test_function_definition(func.name().to_string()); let resolver = Resolver::new(&mut interner, &path_resolver, &def_maps, file); - let (_, _, err) = resolver.resolve_function(func, id, ModuleId::dummy_id()); + let (_, _, err) = resolver.resolve_function(func, id); errors.extend(err); } @@ -1635,12 +1649,12 @@ mod test { let mut all_captures: Vec> = Vec::new(); for func in program.functions { - let id = interner.push_fn(HirFunction::empty()); - interner.push_function_definition(func.name().to_string(), id); + let name = func.name().to_string(); + let id = interner.push_test_function_definition(name); path_resolver.insert_func(func.name().to_owned(), id); let resolver = Resolver::new(&mut interner, &path_resolver, &def_maps, file); - let (hir_func, _, _) = resolver.resolve_function(func, id, ModuleId::dummy_id()); + let (hir_func, _, _) = resolver.resolve_function(func, id); // Iterate over function statements and apply filtering function parse_statement_blocks( diff --git a/compiler/noirc_frontend/src/hir/type_check/expr.rs b/compiler/noirc_frontend/src/hir/type_check/expr.rs index 3b5d3758c4b..fdec07ae62d 100644 --- a/compiler/noirc_frontend/src/hir/type_check/expr.rs +++ b/compiler/noirc_frontend/src/hir/type_check/expr.rs @@ -24,8 +24,8 @@ impl<'interner> TypeChecker<'interner> { if let Some(DefinitionKind::Function(func_id)) = self.interner.try_definition(id).map(|def| &def.kind) { - let meta = self.interner.function_meta(func_id); - if let Some(note) = meta.attributes.get_deprecated_note() { + let attributes = self.interner.function_attributes(func_id); + if let Some(note) = attributes.get_deprecated_note() { self.errors.push(TypeCheckError::CallDeprecated { name: self.interner.definition_name(id).to_string(), note, diff --git a/compiler/noirc_frontend/src/hir/type_check/mod.rs b/compiler/noirc_frontend/src/hir/type_check/mod.rs index 162622f0af0..11af0869fd5 100644 --- a/compiler/noirc_frontend/src/hir/type_check/mod.rs +++ b/compiler/noirc_frontend/src/hir/type_check/mod.rs @@ -184,7 +184,6 @@ mod test { stmt::HirStatement, }; use crate::node_interner::{DefinitionKind, FuncId, NodeInterner}; - use crate::token::Attributes; use crate::{ hir::{ def_map::{CrateDefMap, LocalModuleId, ModuleDefId}, @@ -254,12 +253,7 @@ mod test { let func_meta = FuncMeta { name, kind: FunctionKind::Normal, - module_id: ModuleId::dummy_id(), - attributes: Attributes::empty(), location, - contract_function_type: None, - is_internal: None, - is_unconstrained: false, typ: Type::Function( vec![Type::FieldElement, Type::FieldElement], Box::new(Type::Unit), @@ -420,14 +414,10 @@ mod test { errors ); - let main_id = interner.push_fn(HirFunction::empty()); - interner.push_function_definition("main".into(), main_id); + let main_id = interner.push_test_function_definition("main".into()); - let func_ids = vecmap(&func_namespace, |name| { - let id = interner.push_fn(HirFunction::empty()); - interner.push_function_definition(name.into(), id); - id - }); + let func_ids = + vecmap(&func_namespace, |name| interner.push_test_function_definition(name.into())); let mut path_resolver = TestPathResolver(HashMap::new()); for (name, id) in func_namespace.into_iter().zip(func_ids.clone()) { @@ -453,8 +443,7 @@ mod test { let func_meta = vecmap(program.functions, |nf| { let resolver = Resolver::new(&mut interner, &path_resolver, &def_maps, file); - let (hir_func, func_meta, resolver_errors) = - resolver.resolve_function(nf, main_id, ModuleId::dummy_id()); + let (hir_func, func_meta, resolver_errors) = resolver.resolve_function(nf, main_id); assert_eq!(resolver_errors, vec![]); (hir_func, func_meta) }); diff --git a/compiler/noirc_frontend/src/hir_def/function.rs b/compiler/noirc_frontend/src/hir_def/function.rs index 89f3c1745bc..6e4490af5de 100644 --- a/compiler/noirc_frontend/src/hir_def/function.rs +++ b/compiler/noirc_frontend/src/hir_def/function.rs @@ -4,10 +4,9 @@ use noirc_errors::{Location, Span}; use super::expr::{HirBlockExpression, HirExpression, HirIdent}; use super::stmt::HirPattern; use super::traits::TraitConstraint; -use crate::hir::def_map::ModuleId; use crate::node_interner::{ExprId, NodeInterner}; -use crate::{token::Attributes, FunctionKind}; -use crate::{ContractFunctionType, Distinctness, FunctionReturnType, Type, Visibility}; +use crate::FunctionKind; +use crate::{Distinctness, FunctionReturnType, Type, Visibility}; /// A Hir function is a block expression /// with a list of statements @@ -97,24 +96,6 @@ pub struct FuncMeta { pub kind: FunctionKind, - pub module_id: ModuleId, - - /// A function's attributes are the `#[...]` items above the function - /// definition. - /// Function Attributes will alter the function kind, secondary attributes do not - pub attributes: Attributes, - - /// This function's type in its contract. - /// If this function is not in a contract, this is always 'Secret'. - pub contract_function_type: Option, - - /// This function's visibility. - /// If this function is internal can only be called by itself. - /// Will be None if not in contract. - pub is_internal: Option, - - pub is_unconstrained: bool, - pub parameters: Parameters, pub return_type: FunctionReturnType, diff --git a/compiler/noirc_frontend/src/monomorphization/mod.rs b/compiler/noirc_frontend/src/monomorphization/mod.rs index d90d47645ea..c912464695e 100644 --- a/compiler/noirc_frontend/src/monomorphization/mod.rs +++ b/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -142,17 +142,17 @@ impl<'interner> Monomorphizer<'interner> { Some(id) => Definition::Function(*id), None => { // Function has not been monomorphized yet - let meta = self.interner.function_meta(&id); - match meta.kind { + let attributes = self.interner.function_attributes(&id); + match self.interner.function_meta(&id).kind { FunctionKind::LowLevel => { - let attribute = meta.attributes.function.expect("all low level functions must contain a function attribute which contains the opcode which it links to"); + let attribute = attributes.function.clone().expect("all low level functions must contain a function attribute which contains the opcode which it links to"); let opcode = attribute.foreign().expect( "ice: function marked as foreign, but attribute kind does not match this", ); Definition::LowLevel(opcode) } FunctionKind::Builtin => { - let attribute = meta.attributes.function.expect("all low level functions must contain a primary attribute which contains the opcode which it links to"); + let attribute = attributes.function.clone().expect("all low level functions must contain a function attribute which contains the opcode which it links to"); let opcode = attribute.builtin().expect( "ice: function marked as builtin, but attribute kind does not match this", ); @@ -163,9 +163,9 @@ impl<'interner> Monomorphizer<'interner> { Definition::Function(id) } FunctionKind::Oracle => { - let attr = meta - .attributes + let attr = attributes .function + .clone() .expect("Oracle function must have an oracle attribute"); match attr { @@ -198,13 +198,14 @@ impl<'interner> Monomorphizer<'interner> { fn function(&mut self, f: node_interner::FuncId, id: FuncId) { let meta = self.interner.function_meta(&f); + let modifiers = self.interner.function_modifiers(&f); let name = self.interner.function_name(&f).to_owned(); let return_type = Self::convert_type(meta.return_type()); let parameters = self.parameters(meta.parameters); let body = self.expr(*self.interner.function(&f).as_expr()); - let unconstrained = meta.is_unconstrained - || matches!(meta.contract_function_type, Some(ContractFunctionType::Open)); + let unconstrained = modifiers.is_unconstrained + || matches!(modifiers.contract_function_type, Some(ContractFunctionType::Open)); let function = ast::Function { id, name, parameters, body, return_type, unconstrained }; self.push_function(id, function); @@ -1344,7 +1345,6 @@ mod tests { import::PathResolutionError, path_resolver::PathResolver, resolver::Resolver, }, }, - hir_def::function::HirFunction, node_interner::{FuncId, NodeInterner}, parse_program, }; @@ -1361,14 +1361,10 @@ mod tests { // the whole vec if the assert fails rather than just two booleans assert_eq!(errors, vec![]); - let main_id = interner.push_fn(HirFunction::empty()); - interner.push_function_definition("main".into(), main_id); + let main_id = interner.push_test_function_definition("main".into()); - let func_ids = vecmap(&func_namespace, |name| { - let id = interner.push_fn(HirFunction::empty()); - interner.push_function_definition(name.into(), id); - id - }); + let func_ids = + vecmap(&func_namespace, |name| interner.push_test_function_definition(name.into())); let mut path_resolver = TestPathResolver(HashMap::new()); for (name, id) in func_namespace.into_iter().zip(func_ids.clone()) { @@ -1394,8 +1390,7 @@ mod tests { let func_meta = vecmap(program.functions, |nf| { let resolver = Resolver::new(&mut interner, &path_resolver, &def_maps, file); - let (hir_func, func_meta, _resolver_errors) = - resolver.resolve_function(nf, main_id, ModuleId::dummy_id()); + let (hir_func, func_meta, _resolver_errors) = resolver.resolve_function(nf, main_id); // TODO: not sure why, we do get an error here, // but otherwise seem to get an ok monomorphization result // assert_eq!(resolver_errors, vec![]); diff --git a/compiler/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs index ae99f10157c..26c98de7feb 100644 --- a/compiler/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -21,8 +21,8 @@ use crate::hir_def::{ }; use crate::token::Attributes; use crate::{ - Generics, Shared, TypeAliasType, TypeBinding, TypeBindings, TypeVariable, TypeVariableId, - TypeVariableKind, + ContractFunctionType, FunctionDefinition, Generics, Shared, TypeAliasType, TypeBinding, + TypeBindings, TypeVariable, TypeVariableId, TypeVariableKind, Visibility, }; #[derive(Eq, PartialEq, Hash, Clone)] @@ -43,6 +43,14 @@ pub struct NodeInterner { func_meta: HashMap, function_definition_ids: HashMap, + // For a given function ID, this gives the function's modifiers which includes + // its visibility and whether it is unconstrained, among other information. + // Unlike func_meta, this map is filled out during definition collection rather than name resolution. + function_modifiers: HashMap, + + // Contains the source module each function was defined in + function_modules: HashMap, + // Map each `Index` to it's own location id_to_location: HashMap, @@ -106,6 +114,38 @@ pub struct NodeInterner { primitive_methods: HashMap<(TypeMethodKey, String), FuncId>, } +pub struct FunctionModifiers { + /// Whether the function is `pub` or not. + pub visibility: Visibility, + + pub attributes: Attributes, + + pub is_unconstrained: bool, + + /// This function's type in its contract. + /// If this function is not in a contract, this is always 'Secret'. + pub contract_function_type: Option, + + /// This function's contract visibility. + /// If this function is internal can only be called by itself. + /// Will be None if not in contract. + pub is_internal: Option, +} + +impl FunctionModifiers { + /// A semi-reasonable set of default FunctionModifiers used for testing. + #[cfg(test)] + pub fn new() -> Self { + Self { + visibility: Visibility::Public, + attributes: Attributes::empty(), + is_unconstrained: false, + is_internal: None, + contract_function_type: None, + } + } +} + #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] pub struct DefinitionId(usize); @@ -312,6 +352,8 @@ impl Default for NodeInterner { nodes: Arena::default(), func_meta: HashMap::new(), function_definition_ids: HashMap::new(), + function_modifiers: HashMap::new(), + function_modules: HashMap::new(), id_to_location: HashMap::new(), definitions: vec![], id_to_type: HashMap::new(), @@ -529,10 +571,62 @@ impl NodeInterner { id } - pub fn push_function_definition(&mut self, name: String, func: FuncId) -> DefinitionId { + /// Push a function with the default modifiers and moduleid for testing + #[cfg(test)] + pub fn push_test_function_definition(&mut self, name: String) -> FuncId { + let id = self.push_fn(HirFunction::empty()); + let modifiers = FunctionModifiers::new(); + let module = ModuleId::dummy_id(); + self.push_function_definition(name, id, modifiers, module); + id + } + + pub fn push_function( + &mut self, + id: FuncId, + function: &FunctionDefinition, + module: ModuleId, + ) -> DefinitionId { + use ContractFunctionType::*; + let name = function.name.0.contents.clone(); + + // We're filling in contract_function_type and is_internal now, but these will be verified + // later during name resolution. + let modifiers = FunctionModifiers { + visibility: if function.is_public { Visibility::Public } else { Visibility::Private }, + attributes: function.attributes.clone(), + is_unconstrained: function.is_unconstrained, + contract_function_type: Some(if function.is_open { Open } else { Secret }), + is_internal: Some(function.is_internal), + }; + self.push_function_definition(name, id, modifiers, module) + } + + pub fn push_function_definition( + &mut self, + name: String, + func: FuncId, + modifiers: FunctionModifiers, + module: ModuleId, + ) -> DefinitionId { + self.function_modifiers.insert(func, modifiers); + self.function_modules.insert(func, module); self.push_definition(name, false, DefinitionKind::Function(func)) } + /// Returns the visibility of the given function. + /// + /// The underlying function_visibilities map is populated during def collection, + /// so this function can be called anytime afterward. + pub fn function_visibility(&self, func: FuncId) -> Visibility { + self.function_modifiers[&func].visibility + } + + /// Returns the module this function was defined within + pub fn function_module(&self, func: FuncId) -> ModuleId { + self.function_modules[&func] + } + /// Returns the interned HIR function corresponding to `func_id` // // Cloning HIR structures is cheap, so we return owned structures @@ -565,8 +659,16 @@ impl NodeInterner { self.definition_name(name_id) } - pub fn function_attributes(&self, func_id: &FuncId) -> Attributes { - self.function_meta(func_id).attributes + pub fn function_modifiers(&self, func_id: &FuncId) -> &FunctionModifiers { + &self.function_modifiers[func_id] + } + + pub fn function_modifiers_mut(&mut self, func_id: &FuncId) -> &mut FunctionModifiers { + self.function_modifiers.get_mut(func_id).expect("func_id should always have modifiers") + } + + pub fn function_attributes(&self, func_id: &FuncId) -> &Attributes { + &self.function_modifiers[func_id].attributes } /// Returns the interned statement corresponding to `stmt_id` diff --git a/compiler/noirc_frontend/src/parser/parser.rs b/compiler/noirc_frontend/src/parser/parser.rs index 5f33606010b..13385108603 100644 --- a/compiler/noirc_frontend/src/parser/parser.rs +++ b/compiler/noirc_frontend/src/parser/parser.rs @@ -184,6 +184,7 @@ fn function_definition(allow_self: bool) -> impl NoirParser { is_unconstrained: modifiers.0, is_open: modifiers.1, is_internal: modifiers.2, + is_public: modifiers.3, generics, parameters, body, @@ -199,13 +200,14 @@ fn function_definition(allow_self: bool) -> impl NoirParser { /// function_modifiers: 'unconstrained'? 'open'? 'internal'? /// /// returns (is_unconstrained, is_open, is_internal) for whether each keyword was present -fn function_modifiers() -> impl NoirParser<(bool, bool, bool)> { +fn function_modifiers() -> impl NoirParser<(bool, bool, bool, bool)> { keyword(Keyword::Unconstrained) .or_not() + .then(keyword(Keyword::Pub).or_not()) .then(keyword(Keyword::Open).or_not()) .then(keyword(Keyword::Internal).or_not()) - .map(|((unconstrained, open), internal)| { - (unconstrained.is_some(), open.is_some(), internal.is_some()) + .map(|(((unconstrained, public), open), internal)| { + (unconstrained.is_some(), open.is_some(), internal.is_some(), public.is_some()) }) } diff --git a/noir_stdlib/src/array.nr b/noir_stdlib/src/array.nr index c1e7cfdcfe6..bcdf56dd7aa 100644 --- a/noir_stdlib/src/array.nr +++ b/noir_stdlib/src/array.nr @@ -3,13 +3,13 @@ // by the methods in the `slice` module impl [T; N] { #[builtin(array_len)] - fn len(_self: Self) -> Field {} + pub fn len(_self: Self) -> Field {} #[builtin(arraysort)] - fn sort(_self: Self) -> Self {} + pub fn sort(_self: Self) -> Self {} // Sort with a custom sorting function. - fn sort_via(mut a: Self, ordering: fn[Env](T, T) -> bool) -> Self { + pub fn sort_via(mut a: Self, ordering: fn[Env](T, T) -> bool) -> Self { for i in 1 .. a.len() { for j in 0..i { if ordering(a[i], a[j]) { @@ -23,7 +23,7 @@ impl [T; N] { } // Converts an array into a slice. - fn as_slice(self) -> [T] { + pub fn as_slice(self) -> [T] { let mut slice = []; for elem in self { slice = slice.push_back(elem); @@ -33,7 +33,7 @@ impl [T; N] { // Apply a function to each element of an array, returning a new array // containing the mapped elements. - fn map(self, f: fn[Env](T) -> U) -> [U; N] { + pub fn map(self, f: fn[Env](T) -> U) -> [U; N] { let first_elem = f(self[0]); let mut ret = [first_elem; N]; @@ -47,7 +47,7 @@ impl [T; N] { // Apply a function to each element of the array and an accumulator value, // returning the final accumulated value. This function is also sometimes // called `foldl`, `fold_left`, `reduce`, or `inject`. - fn fold(self, mut accumulator: U, f: fn[Env](U, T) -> U) -> U { + pub fn fold(self, mut accumulator: U, f: fn[Env](U, T) -> U) -> U { for elem in self { accumulator = f(accumulator, elem); } @@ -57,7 +57,7 @@ impl [T; N] { // Apply a function to each element of the array and an accumulator value, // returning the final accumulated value. Unlike fold, reduce uses the first // element of the given array as its starting accumulator value. - fn reduce(self, f: fn[Env](T, T) -> T) -> T { + pub fn reduce(self, f: fn[Env](T, T) -> T) -> T { let mut accumulator = self[0]; for i in 1 .. self.len() { accumulator = f(accumulator, self[i]); @@ -66,7 +66,7 @@ impl [T; N] { } // Returns true if all elements in the array satisfy the predicate - fn all(self, predicate: fn[Env](T) -> bool) -> bool { + pub fn all(self, predicate: fn[Env](T) -> bool) -> bool { let mut ret = true; for elem in self { ret &= predicate(elem); @@ -75,7 +75,7 @@ impl [T; N] { } // Returns true if any element in the array satisfies the predicate - fn any(self, predicate: fn[Env](T) -> bool) -> bool { + pub fn any(self, predicate: fn[Env](T) -> bool) -> bool { let mut ret = false; for elem in self { ret |= predicate(elem); diff --git a/noir_stdlib/src/collections/vec.nr b/noir_stdlib/src/collections/vec.nr index 303dc4db029..0308236799b 100644 --- a/noir_stdlib/src/collections/vec.nr +++ b/noir_stdlib/src/collections/vec.nr @@ -5,27 +5,27 @@ struct Vec { // A mutable vector type implemented as a wrapper around immutable slices. // A separate type is technically not needed but helps differentiate which operations are mutable. impl Vec { - fn new() -> Self { + pub fn new() -> Self { Self { slice: [] } } // Create a Vec containing each element from the given slice. // Mutations to the resulting Vec will not affect the original slice. - fn from_slice(slice: [T]) -> Self { + pub fn from_slice(slice: [T]) -> Self { Self { slice } } /// Get an element from the vector at the given index. /// Panics if the given index /// points beyond the end of the vector. - fn get(&mut self, index: Field) -> T { + pub fn get(&mut self, index: Field) -> T { self.slice[index] } /// Push a new element to the end of the vector, returning a /// new vector with a length one greater than the /// original unmodified vector. - fn push(&mut self, elem: T) { + pub fn push(&mut self, elem: T) { self.slice = self.slice.push_back(elem); } @@ -33,7 +33,7 @@ impl Vec { /// a new vector with a length of one less than the given vector, /// as well as the popped element. /// Panics if the given vector's length is zero. - fn pop(&mut self) -> T { + pub fn pop(&mut self) -> T { let (popped_slice, last_elem) = self.slice.pop_back(); self.slice = popped_slice; last_elem @@ -41,20 +41,20 @@ impl Vec { /// Insert an element at a specified index, shifting all elements /// after it to the right - fn insert(&mut self, index: Field, elem: T) { + pub fn insert(&mut self, index: Field, elem: T) { self.slice = self.slice.insert(index, elem); } /// Remove an element at a specified index, shifting all elements /// after it to the left, returning the removed element - fn remove(&mut self, index: Field) -> T { + pub fn remove(&mut self, index: Field) -> T { let (new_slice, elem) = self.slice.remove(index); self.slice = new_slice; elem } /// Returns the number of elements in the vector - fn len(self: Self) -> Field { + pub fn len(self: Self) -> Field { self.slice.len() } } \ No newline at end of file diff --git a/noir_stdlib/src/compat.nr b/noir_stdlib/src/compat.nr index 65ae22c5aba..5d80c422c33 100644 --- a/noir_stdlib/src/compat.nr +++ b/noir_stdlib/src/compat.nr @@ -1,4 +1,4 @@ -fn is_bn254() -> bool { +pub fn is_bn254() -> bool { // bn254 truncates its curve order to 0 21888242871839275222246405745257275088548364400416034343698204186575808495617 == 0 } diff --git a/noir_stdlib/src/ec.nr b/noir_stdlib/src/ec.nr index 59a0731b9aa..8b426f46825 100644 --- a/noir_stdlib/src/ec.nr +++ b/noir_stdlib/src/ec.nr @@ -148,7 +148,7 @@ global C5 = 19103219067921713944291392827692070036145651957329286315305642004821 //} // TODO: Make this built-in. -fn safe_inverse(x: Field) -> Field { +pub fn safe_inverse(x: Field) -> Field { if x == 0 { 0 } else { @@ -157,7 +157,7 @@ fn safe_inverse(x: Field) -> Field { } // Boolean indicating whether Field element is a square, i.e. whether there exists a y in Field s.t. x = y*y. -fn is_square(x: Field) -> bool { +pub fn is_square(x: Field) -> bool { let v = pow(x, 0 - 1/2); v*(v-1) == 0 @@ -165,7 +165,7 @@ fn is_square(x: Field) -> bool { // Power function of two Field arguments of arbitrary size. // Adapted from std::field::pow_32. -fn pow(x: Field, y: Field) -> Field { // As in tests with minor modifications +pub fn pow(x: Field, y: Field) -> Field { // As in tests with minor modifications let N_BITS = crate::field::modulus_num_bits(); let mut r = 1 as Field; @@ -184,7 +184,7 @@ fn pow(x: Field, y: Field) -> Field { // As in tests with minor modifications // as well as C3 = (C2 - 1)/2, where C2 = (p-1)/(2^c1), // and C5 = ZETA^C2, where ZETA is a non-square element of Field. // These are pre-computed above as globals. -fn sqrt(x: Field) -> Field { +pub fn sqrt(x: Field) -> Field { let mut z = pow(x, C3); let mut t = z*z*x; z *= x; diff --git a/noir_stdlib/src/ec/consts/te.nr b/noir_stdlib/src/ec/consts/te.nr index 8a5bdae5127..b5847e77f34 100644 --- a/noir_stdlib/src/ec/consts/te.nr +++ b/noir_stdlib/src/ec/consts/te.nr @@ -8,7 +8,7 @@ struct BabyJubjub { suborder: Field, } -fn baby_jubjub() -> BabyJubjub { +pub fn baby_jubjub() -> BabyJubjub { assert(compat::is_bn254()); BabyJubjub { diff --git a/noir_stdlib/src/ec/montcurve.nr b/noir_stdlib/src/ec/montcurve.nr index e698a7841e5..6a57f258c8e 100644 --- a/noir_stdlib/src/ec/montcurve.nr +++ b/noir_stdlib/src/ec/montcurve.nr @@ -30,7 +30,7 @@ mod affine { impl Point { // Point constructor - fn new(x: Field, y: Field) -> Self { + pub fn new(x: Field, y: Field) -> Self { Self {x, y, infty: false} } @@ -40,7 +40,7 @@ mod affine { } // Check if zero - fn is_zero(self) -> bool { + pub fn is_zero(self) -> bool { self.infty } @@ -55,7 +55,7 @@ mod affine { } // Additive identity - fn zero() -> Self { + pub fn zero() -> Self { Self {x: 0, y: 0, infty: true} } @@ -80,7 +80,7 @@ mod affine { impl Curve { // Curve constructor - fn new(j: Field, k: Field, gen: Point) -> Self { + pub fn new(j: Field, k: Field, gen: Point) -> Self { // Check curve coefficients assert(k != 0); assert(j*j != 4); @@ -99,7 +99,7 @@ mod affine { } // Membership check - fn contains(self, p: Point) -> bool { + pub fn contains(self, p: Point) -> bool { let Self {j, k, gen: _gen} = self; let Point {x, y, infty: infty} = p; @@ -107,7 +107,7 @@ mod affine { } // Point addition - fn add(self, p1: Point, p2: Point) -> Point { + pub fn add(self, p1: Point, p2: Point) -> Point { self.into_tecurve().add(p1.into_tecurve(), p2.into_tecurve()).into_montcurve() } @@ -145,7 +145,7 @@ mod affine { } // Conversion to equivalent Short Weierstraß curve - fn into_swcurve(self) -> SWCurve { + pub fn into_swcurve(self) -> SWCurve { let j = self.j; let k = self.k; let a0 = (3-j*j)/(3*k*k); @@ -155,7 +155,7 @@ mod affine { } // Point mapping into equivalent Short Weierstraß curve - fn map_into_swcurve(self, p: Point) -> SWPoint { + pub fn map_into_swcurve(self, p: Point) -> SWPoint { if p.is_zero() { SWPoint::zero() } else { @@ -238,7 +238,7 @@ mod curvegroup { impl Point { // Point constructor - fn new(x: Field, y: Field, z: Field) -> Self { + pub fn new(x: Field, y: Field, z: Field) -> Self { Self {x, y, z} } @@ -248,7 +248,7 @@ mod curvegroup { } // Check if zero - fn is_zero(self) -> bool { + pub fn is_zero(self) -> bool { self.z == 0 } @@ -263,7 +263,7 @@ mod curvegroup { } // Additive identity - fn zero() -> Self { + pub fn zero() -> Self { Self {x: 0, y: 1,z: 0} } @@ -282,7 +282,7 @@ mod curvegroup { impl Curve { // Curve constructor - fn new(j: Field, k: Field, gen: Point) -> Self { + pub fn new(j: Field, k: Field, gen: Point) -> Self { // Check curve coefficients assert(k != 0); assert(j*j != 4); @@ -301,7 +301,7 @@ mod curvegroup { } // Membership check - fn contains(self, p: Point) -> bool { + pub fn contains(self, p: Point) -> bool { let Self {j, k, gen: _gen} = self; let Point {x, y, z} = p; @@ -309,7 +309,7 @@ mod curvegroup { } // Point addition - fn add(self, p1: Point, p2: Point) -> Point { + pub fn add(self, p1: Point, p2: Point) -> Point { self.into_affine().add(p1.into_affine(), p2.into_affine()).into_group() } @@ -320,7 +320,7 @@ mod curvegroup { } // Scalar multiplication (p + ... + p n times) - fn mul(self, n: Field, p: Point) -> Point { + pub fn mul(self, n: Field, p: Point) -> Point { self.into_tecurve().mul(n, p.into_tecurve()).into_montcurve() } @@ -336,7 +336,7 @@ mod curvegroup { } // Point subtraction - fn subtract(self, p1: Point, p2: Point) -> Point { + pub fn subtract(self, p1: Point, p2: Point) -> Point { self.add(p1, p2.negate()) } @@ -358,7 +358,7 @@ mod curvegroup { } // Point mapping into equivalent Short Weierstraß curve - fn map_into_swcurve(self, p: Point) -> SWPoint { + pub fn map_into_swcurve(self, p: Point) -> SWPoint { self.into_affine().map_into_swcurve(p.into_affine()).into_group() } diff --git a/noir_stdlib/src/ec/swcurve.nr b/noir_stdlib/src/ec/swcurve.nr index 3e4f57c1fa3..4aa210f6df3 100644 --- a/noir_stdlib/src/ec/swcurve.nr +++ b/noir_stdlib/src/ec/swcurve.nr @@ -26,7 +26,7 @@ mod affine { impl Point { // Point constructor - fn new(x: Field, y: Field) -> Self { + pub fn new(x: Field, y: Field) -> Self { Self {x, y, infty: false} } @@ -40,7 +40,7 @@ mod affine { } // Check if zero - fn is_zero(self) -> bool { + pub fn is_zero(self) -> bool { self.eq(Point::zero()) } @@ -56,7 +56,7 @@ mod affine { } // Additive identity - fn zero() -> Self { + pub fn zero() -> Self { Self {x: 0, y: 0, infty: true} } @@ -69,7 +69,7 @@ mod affine { impl Curve { // Curve constructor - fn new(a: Field, b: Field, gen: Point) -> Curve { + pub fn new(a: Field, b: Field, gen: Point) -> Curve { // Check curve coefficients assert(4*a*a*a + 27*b*b != 0); @@ -89,13 +89,13 @@ mod affine { } // Membership check - fn contains(self, p: Point) -> bool { + pub fn contains(self, p: Point) -> bool { let Point {x, y, infty} = p; infty | (y*y == x*x*x + self.a*x + self.b) } // Point addition, implemented in terms of mixed addition for reasons of efficiency - fn add(self, p1: Point, p2: Point) -> Point { + pub fn add(self, p1: Point, p2: Point) -> Point { self.mixed_add(p1, p2.into_group()).into_affine() } @@ -139,12 +139,12 @@ mod affine { } // Scalar multiplication (p + ... + p n times) - fn mul(self, n: Field, p: Point) -> Point { + pub fn mul(self, n: Field, p: Point) -> Point { self.into_group().mul(n, p.into_group()).into_affine() } // Multi-scalar multiplication (n[0]*p[0] + ... + n[N]*p[N], where * denotes scalar multiplication) - fn msm(self, n: [Field; N], p: [Point; N]) -> Point { + pub fn msm(self, n: [Field; N], p: [Point; N]) -> Point { let mut out = Point::zero(); for i in 0..N { @@ -155,7 +155,7 @@ mod affine { } // Point subtraction - fn subtract(self, p1: Point, p2: Point) -> Point { + pub fn subtract(self, p1: Point, p2: Point) -> Point { self.add(p1, p2.negate()) } @@ -203,7 +203,7 @@ mod curvegroup { impl Point { // Point constructor - fn new(x: Field, y: Field, z: Field) -> Self { + pub fn new(x: Field, y: Field, z: Field) -> Self { Self {x, y, z} } @@ -216,12 +216,12 @@ mod curvegroup { } // Check if zero - fn is_zero(self) -> bool { + pub fn is_zero(self) -> bool { self.eq(Point::zero()) } // Conversion to affine coordinates - fn into_affine(self) -> affine::Point { + pub fn into_affine(self) -> affine::Point { let Self {x, y, z} = self; if z == 0 { @@ -232,7 +232,7 @@ mod curvegroup { } // Additive identity - fn zero() -> Self { + pub fn zero() -> Self { Self {x: 0, y: 0, z: 0} } @@ -246,7 +246,7 @@ mod curvegroup { impl Curve { // Curve constructor - fn new(a: Field, b: Field, gen: Point) -> Curve { + pub fn new(a: Field, b: Field, gen: Point) -> Curve { // Check curve coefficients assert(4*a*a*a + 27*b*b != 0); @@ -259,14 +259,14 @@ mod curvegroup { } // Conversion to affine coordinates - fn into_affine(self) -> affine::Curve { + pub fn into_affine(self) -> affine::Curve { let Curve{a, b, gen} = self; affine::Curve {a, b, gen: gen.into_affine()} } // Membership check - fn contains(self, p: Point) -> bool { + pub fn contains(self, p: Point) -> bool { let Point {x, y, z} = p; if z == 0 { true @@ -276,7 +276,7 @@ mod curvegroup { } // Addition - fn add(self, p1: Point, p2: Point) -> Point { + pub fn add(self, p1: Point, p2: Point) -> Point { if p1.is_zero() { p2 @@ -309,7 +309,7 @@ mod curvegroup { } // Point doubling - fn double(self, p: Point) -> Point { + pub fn double(self, p: Point) -> Point { let Point {x, y, z} = p; if p.is_zero() { @@ -342,7 +342,7 @@ mod curvegroup { } // Scalar multiplication (p + ... + p n times) - fn mul(self, n: Field, p: Point) -> Point { + pub fn mul(self, n: Field, p: Point) -> Point { let N_BITS = crate::field::modulus_num_bits(); // TODO: temporary workaround until issue 1354 is solved @@ -367,7 +367,7 @@ mod curvegroup { } // Point subtraction - fn subtract(self, p1: Point, p2: Point) -> Point { + pub fn subtract(self, p1: Point, p2: Point) -> Point { self.add(p1, p2.negate()) } diff --git a/noir_stdlib/src/ec/tecurve.nr b/noir_stdlib/src/ec/tecurve.nr index 90be8833206..54b59e99a54 100644 --- a/noir_stdlib/src/ec/tecurve.nr +++ b/noir_stdlib/src/ec/tecurve.nr @@ -27,7 +27,7 @@ mod affine { impl Point { // Point constructor - fn new(x: Field, y: Field) -> Self { + pub fn new(x: Field, y: Field) -> Self { Self { x, y } } @@ -40,7 +40,7 @@ mod affine { } // Check if zero - fn is_zero(self) -> bool { + pub fn is_zero(self) -> bool { self.eq(Point::zero()) } @@ -52,7 +52,7 @@ mod affine { } // Additive identity - fn zero() -> Self { + pub fn zero() -> Self { Point::new(0,1) } @@ -79,7 +79,7 @@ mod affine { impl Curve { // Curve constructor - fn new(a: Field, d: Field, gen: Point) -> Curve { + pub fn new(a: Field, d: Field, gen: Point) -> Curve { // Check curve coefficients assert(a*d*(a-d) != 0); @@ -99,13 +99,13 @@ mod affine { } // Membership check - fn contains(self, p: Point) -> bool { + pub fn contains(self, p: Point) -> bool { let Point {x, y} = p; self.a*x*x + y*y == 1 + self.d*x*x*y*y } // Point addition, implemented in terms of mixed addition for reasons of efficiency - fn add(self, p1: Point, p2: Point) -> Point { + pub fn add(self, p1: Point, p2: Point) -> Point { self.mixed_add(p1, p2.into_group()).into_affine() } @@ -158,7 +158,7 @@ mod affine { } // Conversion to equivalent Montgomery curve - fn into_montcurve(self) -> MCurve { + pub fn into_montcurve(self) -> MCurve { let j = 2*(self.a + self.d)/(self.a - self.d); let k = 4/(self.a - self.d); let gen_montcurve = self.gen.into_montcurve(); @@ -167,12 +167,12 @@ mod affine { } // Conversion to equivalent Short Weierstraß curve - fn into_swcurve(self) -> SWCurve { + pub fn into_swcurve(self) -> SWCurve { self.into_montcurve().into_swcurve() } // Point mapping into equivalent Short Weierstraß curve - fn map_into_swcurve(self, p: Point) -> SWPoint { + pub fn map_into_swcurve(self, p: Point) -> SWPoint { self.into_montcurve().map_into_swcurve(p.into_montcurve()) } @@ -221,7 +221,7 @@ mod curvegroup { impl Point { // Point constructor - fn new(x: Field, y: Field, t: Field, z: Field) -> Self { + pub fn new(x: Field, y: Field, t: Field, z: Field) -> Self { Self {x, y, t, z} } @@ -234,20 +234,20 @@ mod curvegroup { } // Check if zero - fn is_zero(self) -> bool { + pub fn is_zero(self) -> bool { let Self {x, y, t, z} = self; (x == 0) & (y == z) & (y != 0) & (t == 0) } // Conversion to affine coordinates - fn into_affine(self) -> affine::Point { + pub fn into_affine(self) -> affine::Point { let Self {x, y, t: _t, z} = self; affine::Point::new(x/z, y/z) } // Additive identity - fn zero() -> Self { + pub fn zero() -> Self { Point::new(0,1,0,1) } @@ -266,7 +266,7 @@ mod curvegroup { impl Curve { // Curve constructor - fn new(a: Field, d: Field, gen: Point) -> Curve { + pub fn new(a: Field, d: Field, gen: Point) -> Curve { // Check curve coefficients assert(a*d*(a-d) != 0); @@ -279,21 +279,21 @@ mod curvegroup { } // Conversion to affine coordinates - fn into_affine(self) -> affine::Curve { + pub fn into_affine(self) -> affine::Curve { let Curve{a, d, gen} = self; affine::Curve {a, d, gen: gen.into_affine()} } // Membership check - fn contains(self, p: Point) -> bool { + pub fn contains(self, p: Point) -> bool { let Point {x, y, t, z} = p; (z != 0) & (z*t == x*y) & (z*z*(self.a*x*x + y*y) == z*z*z*z + self.d*x*x*y*y) } // Point addition - fn add(self, p1: Point, p2: Point) -> Point { + pub fn add(self, p1: Point, p2: Point) -> Point { let Point{x: x1, y: y1, t: t1, z: z1} = p1; let Point{x: x2, y: y2, t: t2, z: z2} = p2; @@ -315,7 +315,7 @@ mod curvegroup { } // Point doubling, cf. §3.3 - fn double(self, p: Point) -> Point { + pub fn double(self, p: Point) -> Point { let Point{x, y, t: _t, z} = p; let a = x*x; @@ -350,7 +350,7 @@ mod curvegroup { } // Scalar multiplication (p + ... + p n times) - fn mul(self, n: Field, p: Point) -> Point { + pub fn mul(self, n: Field, p: Point) -> Point { let N_BITS = crate::field::modulus_num_bits(); // TODO: temporary workaround until issue 1354 is solved @@ -390,7 +390,7 @@ mod curvegroup { } // Point mapping into equivalent short Weierstraß curve - fn map_into_swcurve(self, p: Point) -> SWPoint { + pub fn map_into_swcurve(self, p: Point) -> SWPoint { self.into_montcurve().map_into_swcurve(p.into_montcurve()) } diff --git a/noir_stdlib/src/ecdsa_secp256k1.nr b/noir_stdlib/src/ecdsa_secp256k1.nr index c46380e1988..1ad25811b8a 100644 --- a/noir_stdlib/src/ecdsa_secp256k1.nr +++ b/noir_stdlib/src/ecdsa_secp256k1.nr @@ -1,2 +1,2 @@ #[foreign(ecdsa_secp256k1)] -fn verify_signature(_public_key_x : [u8; 32], _public_key_y : [u8; 32], _signature: [u8; 64], _message_hash: [u8; N]) -> bool {} +pub fn verify_signature(_public_key_x : [u8; 32], _public_key_y : [u8; 32], _signature: [u8; 64], _message_hash: [u8; N]) -> bool {} diff --git a/noir_stdlib/src/ecdsa_secp256r1.nr b/noir_stdlib/src/ecdsa_secp256r1.nr index 77744384f52..b47b69fa276 100644 --- a/noir_stdlib/src/ecdsa_secp256r1.nr +++ b/noir_stdlib/src/ecdsa_secp256r1.nr @@ -1,2 +1,2 @@ #[foreign(ecdsa_secp256r1)] -fn verify_signature(_public_key_x : [u8; 32], _public_key_y : [u8; 32], _signature: [u8; 64], _message_hash: [u8; N]) -> bool {} +pub fn verify_signature(_public_key_x : [u8; 32], _public_key_y : [u8; 32], _signature: [u8; 64], _message_hash: [u8; N]) -> bool {} diff --git a/noir_stdlib/src/eddsa.nr b/noir_stdlib/src/eddsa.nr index 1db61825011..ff8c1da1397 100644 --- a/noir_stdlib/src/eddsa.nr +++ b/noir_stdlib/src/eddsa.nr @@ -23,7 +23,7 @@ fn lt_bytes32(x: Field, y: Field) -> bool { } // Returns true if signature is valid -fn eddsa_poseidon_verify( +pub fn eddsa_poseidon_verify( pub_key_x: Field, pub_key_y: Field, signature_s: Field, diff --git a/noir_stdlib/src/field.nr b/noir_stdlib/src/field.nr index 5d3581689f5..fe887aa89b0 100644 --- a/noir_stdlib/src/field.nr +++ b/noir_stdlib/src/field.nr @@ -1,28 +1,28 @@ impl Field { #[builtin(to_le_bits)] - fn to_le_bits(_x : Field, _bit_size: u32) -> [u1] {} + pub fn to_le_bits(_x : Field, _bit_size: u32) -> [u1] {} #[builtin(to_be_bits)] - fn to_be_bits(_x : Field, _bit_size: u32) -> [u1] {} + pub fn to_be_bits(_x : Field, _bit_size: u32) -> [u1] {} - fn to_le_bytes(x : Field, byte_size: u32) -> [u8] { + pub fn to_le_bytes(x : Field, byte_size: u32) -> [u8] { x.to_le_radix(256, byte_size) } - fn to_be_bytes(x : Field, byte_size: u32) -> [u8] { + pub fn to_be_bytes(x : Field, byte_size: u32) -> [u8] { x.to_be_radix(256, byte_size) } #[builtin(to_le_radix)] //decompose _x into a _result_len vector over the _radix basis //_radix must be less than 256 - fn to_le_radix(_x : Field, _radix: u32, _result_len: u32) -> [u8] {} + pub fn to_le_radix(_x : Field, _radix: u32, _result_len: u32) -> [u8] {} #[builtin(to_be_radix)] - fn to_be_radix(_x : Field, _radix: u32, _result_len: u32) -> [u8] {} + pub fn to_be_radix(_x : Field, _radix: u32, _result_len: u32) -> [u8] {} // Returns self to the power of the given exponent value. // Caution: we assume the exponent fits into 32 bits // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits - fn pow_32(self, exponent: Field) -> Field { + pub fn pow_32(self, exponent: Field) -> Field { let mut r: Field = 1; let b = exponent.to_le_bits(32); @@ -34,22 +34,22 @@ impl Field { } // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x ∈ {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1. - fn sgn0(self) -> u1 { + pub fn sgn0(self) -> u1 { self as u1 } } #[builtin(modulus_num_bits)] -fn modulus_num_bits() -> Field {} +pub fn modulus_num_bits() -> Field {} #[builtin(modulus_be_bits)] -fn modulus_be_bits() -> [u1] {} +pub fn modulus_be_bits() -> [u1] {} #[builtin(modulus_le_bits)] -fn modulus_le_bits() -> [u1] {} +pub fn modulus_le_bits() -> [u1] {} #[builtin(modulus_be_bytes)] -fn modulus_be_bytes() -> [u8] {} +pub fn modulus_be_bytes() -> [u8] {} #[builtin(modulus_le_bytes)] -fn modulus_le_bytes() -> [u8] {} +pub fn modulus_le_bytes() -> [u8] {} diff --git a/noir_stdlib/src/hash.nr b/noir_stdlib/src/hash.nr index 5b0db2f2941..78e71aefb65 100644 --- a/noir_stdlib/src/hash.nr +++ b/noir_stdlib/src/hash.nr @@ -1,23 +1,23 @@ mod poseidon; #[foreign(sha256)] -fn sha256(_input : [u8; N]) -> [u8; 32] {} +pub fn sha256(_input : [u8; N]) -> [u8; 32] {} #[foreign(blake2s)] -fn blake2s(_input : [u8; N]) -> [u8; 32] {} +pub fn blake2s(_input : [u8; N]) -> [u8; 32] {} -fn pedersen(input : [Field; N]) -> [Field; 2] { +pub fn pedersen(input : [Field; N]) -> [Field; 2] { pedersen_with_separator(input, 0) } #[foreign(pedersen)] -fn pedersen_with_separator(_input : [Field; N], _separator : u32) -> [Field; 2] {} +pub fn pedersen_with_separator(_input : [Field; N], _separator : u32) -> [Field; 2] {} #[foreign(hash_to_field_128_security)] -fn hash_to_field(_input : [Field; N]) -> Field {} +pub fn hash_to_field(_input : [Field; N]) -> Field {} #[foreign(keccak256)] -fn keccak256(_input : [u8; N], _message_size: u32) -> [u8; 32] {} +pub fn keccak256(_input : [u8; N], _message_size: u32) -> [u8; 32] {} // mimc-p/p implementation // constants are (publicly generated) random numbers, for instance using keccak as a ROM. @@ -39,7 +39,7 @@ fn mimc(x: Field, k: Field, constants: [Field; N], exp : Field) -> Field { global MIMC_BN254_ROUNDS = 91; //mimc implementation with hardcoded parameters for BN254 curve. -fn mimc_bn254(array: [Field; N]) -> Field { +pub fn mimc_bn254(array: [Field; N]) -> Field { //mimc parameters let exponent = 7; //generated from seed "mimc" using keccak256 diff --git a/noir_stdlib/src/hash/poseidon.nr b/noir_stdlib/src/hash/poseidon.nr index cb97716d987..c0a31f2d0ea 100644 --- a/noir_stdlib/src/hash/poseidon.nr +++ b/noir_stdlib/src/hash/poseidon.nr @@ -11,7 +11,7 @@ struct PoseidonConfig { mds: [Field; N] // MDS Matrix in row-major order } -fn config( +pub fn config( t: Field, rf: u8, rp: u8, diff --git a/noir_stdlib/src/hash/poseidon/bn254.nr b/noir_stdlib/src/hash/poseidon/bn254.nr index 0b4e5b5bf41..fadf45138ab 100644 --- a/noir_stdlib/src/hash/poseidon/bn254.nr +++ b/noir_stdlib/src/hash/poseidon/bn254.nr @@ -7,7 +7,7 @@ use crate::hash::poseidon::apply_matrix; // Optimised permutation for this particular field; uses hardcoded rf and rp values, // which should agree with those in pos_conf. -fn permute( +pub fn permute( pos_conf: PoseidonConfig, mut state: [Field; O]) -> [Field; O] { @@ -98,13 +98,13 @@ fn absorb( } // Variable-length Poseidon-128 sponge as suggested in second bullet point of §3 of https://eprint.iacr.org/2019/458.pdf -fn sponge(msg: [Field; N]) -> Field { +pub fn sponge(msg: [Field; N]) -> Field { absorb(consts::x5_5_config(), [0;5], 4, 1, msg)[1] } // Various instances of the Poseidon hash function // Consistent with Circom's implementation -fn hash_1(input: [Field; 1]) -> Field { +pub fn hash_1(input: [Field; 1]) -> Field { let mut state = [0; 2]; for i in 0..input.len() { state[i+1] = input[i]; @@ -113,7 +113,7 @@ fn hash_1(input: [Field; 1]) -> Field { perm::x5_2(state)[0] } -fn hash_2(input: [Field; 2]) -> Field { +pub fn hash_2(input: [Field; 2]) -> Field { let mut state = [0; 3]; for i in 0..input.len() { state[i+1] = input[i]; @@ -122,7 +122,7 @@ fn hash_2(input: [Field; 2]) -> Field { perm::x5_3(state)[0] } -fn hash_3(input: [Field; 3]) -> Field { +pub fn hash_3(input: [Field; 3]) -> Field { let mut state = [0; 4]; for i in 0..input.len() { state[i+1] = input[i]; @@ -131,7 +131,7 @@ fn hash_3(input: [Field; 3]) -> Field { perm::x5_4(state)[0] } -fn hash_4(input: [Field; 4]) -> Field { +pub fn hash_4(input: [Field; 4]) -> Field { let mut state = [0; 5]; for i in 0..input.len() { state[i+1] = input[i]; @@ -140,7 +140,7 @@ fn hash_4(input: [Field; 4]) -> Field { perm::x5_5(state)[0] } -fn hash_5(input: [Field; 5]) -> Field { +pub fn hash_5(input: [Field; 5]) -> Field { let mut state = [0; 6]; for i in 0..input.len() { state[i+1] = input[i]; @@ -149,7 +149,7 @@ fn hash_5(input: [Field; 5]) -> Field { perm::x5_6(state)[0] } -fn hash_6(input: [Field; 6]) -> Field { +pub fn hash_6(input: [Field; 6]) -> Field { let mut state = [0; 7]; for i in 0..input.len() { state[i+1] = input[i]; @@ -158,7 +158,7 @@ fn hash_6(input: [Field; 6]) -> Field { perm::x5_7(state)[0] } -fn hash_7(input: [Field; 7]) -> Field { +pub fn hash_7(input: [Field; 7]) -> Field { let mut state = [0; 8]; for i in 0..input.len() { state[i+1] = input[i]; @@ -167,7 +167,7 @@ fn hash_7(input: [Field; 7]) -> Field { perm::x5_8(state)[0] } -fn hash_8(input: [Field; 8]) -> Field { +pub fn hash_8(input: [Field; 8]) -> Field { let mut state = [0; 9]; for i in 0..input.len() { state[i+1] = input[i]; @@ -176,7 +176,7 @@ fn hash_8(input: [Field; 8]) -> Field { perm::x5_9(state)[0] } -fn hash_9(input: [Field; 9]) -> Field { +pub fn hash_9(input: [Field; 9]) -> Field { let mut state = [0; 10]; for i in 0..input.len() { state[i+1] = input[i]; @@ -185,7 +185,7 @@ fn hash_9(input: [Field; 9]) -> Field { perm::x5_10(state)[0] } -fn hash_10(input: [Field; 10]) -> Field { +pub fn hash_10(input: [Field; 10]) -> Field { let mut state = [0; 11]; for i in 0..input.len() { state[i+1] = input[i]; @@ -194,7 +194,7 @@ fn hash_10(input: [Field; 10]) -> Field { perm::x5_11(state)[0] } -fn hash_11(input: [Field; 11]) -> Field { +pub fn hash_11(input: [Field; 11]) -> Field { let mut state = [0; 12]; for i in 0..input.len() { state[i+1] = input[i]; @@ -203,7 +203,7 @@ fn hash_11(input: [Field; 11]) -> Field { perm::x5_12(state)[0] } -fn hash_12(input: [Field; 12]) -> Field { +pub fn hash_12(input: [Field; 12]) -> Field { let mut state = [0; 13]; for i in 0..input.len() { state[i+1] = input[i]; @@ -212,7 +212,7 @@ fn hash_12(input: [Field; 12]) -> Field { perm::x5_13(state)[0] } -fn hash_13(input: [Field; 13]) -> Field { +pub fn hash_13(input: [Field; 13]) -> Field { let mut state = [0; 14]; for i in 0..input.len() { state[i+1] = input[i]; @@ -221,7 +221,7 @@ fn hash_13(input: [Field; 13]) -> Field { perm::x5_14(state)[0] } -fn hash_14(input: [Field; 14]) -> Field { +pub fn hash_14(input: [Field; 14]) -> Field { let mut state = [0; 15]; for i in 0..input.len() { state[i+1] = input[i]; @@ -230,7 +230,7 @@ fn hash_14(input: [Field; 14]) -> Field { perm::x5_15(state)[0] } -fn hash_15(input: [Field; 15]) -> Field { +pub fn hash_15(input: [Field; 15]) -> Field { let mut state = [0; 16]; for i in 0..input.len() { state[i+1] = input[i]; @@ -239,7 +239,7 @@ fn hash_15(input: [Field; 15]) -> Field { perm::x5_16(state)[0] } -fn hash_16(input: [Field; 16]) -> Field { +pub fn hash_16(input: [Field; 16]) -> Field { let mut state = [0; 17]; for i in 0..input.len() { state[i+1] = input[i]; diff --git a/noir_stdlib/src/hash/poseidon/bn254/consts.nr b/noir_stdlib/src/hash/poseidon/bn254/consts.nr index 83923eff6ef..ef4d5a6fce4 100644 --- a/noir_stdlib/src/hash/poseidon/bn254/consts.nr +++ b/noir_stdlib/src/hash/poseidon/bn254/consts.nr @@ -17,7 +17,7 @@ fn alpha() -> Field { } // Poseidon configurations for states of size 2 to 17. -fn x5_2_config() -> PoseidonConfig<128, 4> { +pub fn x5_2_config() -> PoseidonConfig<128, 4> { config( 2, 8, @@ -28,7 +28,7 @@ fn x5_2_config() -> PoseidonConfig<128, 4> { ) } -fn x5_3_config() -> PoseidonConfig<195, 9> { +pub fn x5_3_config() -> PoseidonConfig<195, 9> { config( 3, 8, @@ -39,7 +39,7 @@ fn x5_3_config() -> PoseidonConfig<195, 9> { } -fn x5_4_config() -> PoseidonConfig<256, 16> { +pub fn x5_4_config() -> PoseidonConfig<256, 16> { config( 4, 8, @@ -50,7 +50,7 @@ fn x5_4_config() -> PoseidonConfig<256, 16> { ) } -fn x5_5_config() -> PoseidonConfig<340, 25> { +pub fn x5_5_config() -> PoseidonConfig<340, 25> { config( 5, 8, @@ -61,7 +61,7 @@ fn x5_5_config() -> PoseidonConfig<340, 25> { ) } -fn x5_6_config() -> PoseidonConfig<408, 36> { +pub fn x5_6_config() -> PoseidonConfig<408, 36> { config( 6, 8, @@ -72,7 +72,7 @@ fn x5_6_config() -> PoseidonConfig<408, 36> { ) } -fn x5_7_config() -> PoseidonConfig<497, 49> { +pub fn x5_7_config() -> PoseidonConfig<497, 49> { config( 7, 8, @@ -83,7 +83,7 @@ fn x5_7_config() -> PoseidonConfig<497, 49> { ) } -fn x5_8_config() -> PoseidonConfig<576, 64> { +pub fn x5_8_config() -> PoseidonConfig<576, 64> { config( 8, 8, @@ -94,7 +94,7 @@ fn x5_8_config() -> PoseidonConfig<576, 64> { ) } -fn x5_9_config() -> PoseidonConfig<639, 81> { +pub fn x5_9_config() -> PoseidonConfig<639, 81> { config( 9, 8, @@ -105,7 +105,7 @@ fn x5_9_config() -> PoseidonConfig<639, 81> { ) } -fn x5_10_config() -> PoseidonConfig<680, 100> { +pub fn x5_10_config() -> PoseidonConfig<680, 100> { config( 10, 8, @@ -116,7 +116,7 @@ fn x5_10_config() -> PoseidonConfig<680, 100> { ) } -fn x5_11_config() -> PoseidonConfig<814, 121> { +pub fn x5_11_config() -> PoseidonConfig<814, 121> { config( 11, 8, @@ -127,7 +127,7 @@ fn x5_11_config() -> PoseidonConfig<814, 121> { ) } -fn x5_12_config() -> PoseidonConfig<816, 144> { +pub fn x5_12_config() -> PoseidonConfig<816, 144> { config( 12, 8, @@ -138,7 +138,7 @@ fn x5_12_config() -> PoseidonConfig<816, 144> { ) } -fn x5_13_config() -> PoseidonConfig<949, 169> { +pub fn x5_13_config() -> PoseidonConfig<949, 169> { config( 13, 8, @@ -149,7 +149,7 @@ fn x5_13_config() -> PoseidonConfig<949, 169> { ) } -fn x5_14_config() -> PoseidonConfig<1092, 196> { +pub fn x5_14_config() -> PoseidonConfig<1092, 196> { config( 14, 8, @@ -160,7 +160,7 @@ fn x5_14_config() -> PoseidonConfig<1092, 196> { ) } -fn x5_15_config() -> PoseidonConfig<1020, 225> { +pub fn x5_15_config() -> PoseidonConfig<1020, 225> { config( 15, 8, @@ -171,7 +171,7 @@ fn x5_15_config() -> PoseidonConfig<1020, 225> { ) } -fn x5_16_config() -> PoseidonConfig<1152, 256> { +pub fn x5_16_config() -> PoseidonConfig<1152, 256> { config( 16, 8, @@ -182,7 +182,7 @@ fn x5_16_config() -> PoseidonConfig<1152, 256> { ) } -fn x5_17_config() -> PoseidonConfig<1292, 289> { +pub fn x5_17_config() -> PoseidonConfig<1292, 289> { config( 17, 8, diff --git a/noir_stdlib/src/hash/poseidon/bn254/perm.nr b/noir_stdlib/src/hash/poseidon/bn254/perm.nr index 561747b5229..8b2f93c2d92 100644 --- a/noir_stdlib/src/hash/poseidon/bn254/perm.nr +++ b/noir_stdlib/src/hash/poseidon/bn254/perm.nr @@ -3,7 +3,7 @@ use crate::hash::poseidon::bn254::consts; use crate::hash::poseidon::bn254::permute; use crate::hash::poseidon::PoseidonConfig; -fn x5_2(mut state: [Field; 2]) -> [Field; 2] { +pub fn x5_2(mut state: [Field; 2]) -> [Field; 2] { state = permute( consts::x5_2_config(), state); @@ -11,7 +11,7 @@ fn x5_2(mut state: [Field; 2]) -> [Field; 2] { state } -fn x5_3(mut state: [Field; 3]) -> [Field; 3] { +pub fn x5_3(mut state: [Field; 3]) -> [Field; 3] { state = permute( consts::x5_3_config(), state); @@ -19,7 +19,7 @@ fn x5_3(mut state: [Field; 3]) -> [Field; 3] { state } -fn x5_4(mut state: [Field; 4]) -> [Field; 4] { +pub fn x5_4(mut state: [Field; 4]) -> [Field; 4] { state = permute( consts::x5_4_config(), state); @@ -27,7 +27,7 @@ fn x5_4(mut state: [Field; 4]) -> [Field; 4] { state } -fn x5_5(mut state: [Field; 5]) -> [Field; 5] { +pub fn x5_5(mut state: [Field; 5]) -> [Field; 5] { state = permute( consts::x5_5_config(), state); @@ -35,7 +35,7 @@ fn x5_5(mut state: [Field; 5]) -> [Field; 5] { state } -fn x5_6(mut state: [Field; 6]) -> [Field; 6] { +pub fn x5_6(mut state: [Field; 6]) -> [Field; 6] { state = permute( consts::x5_6_config(), state); @@ -43,7 +43,7 @@ fn x5_6(mut state: [Field; 6]) -> [Field; 6] { state } -fn x5_7(mut state: [Field; 7]) -> [Field; 7] { +pub fn x5_7(mut state: [Field; 7]) -> [Field; 7] { state = permute( consts::x5_7_config(), state); @@ -51,7 +51,7 @@ fn x5_7(mut state: [Field; 7]) -> [Field; 7] { state } -fn x5_8(mut state: [Field; 8]) -> [Field; 8] { +pub fn x5_8(mut state: [Field; 8]) -> [Field; 8] { state = permute( consts::x5_8_config(), state); @@ -59,7 +59,7 @@ fn x5_8(mut state: [Field; 8]) -> [Field; 8] { state } -fn x5_9(mut state: [Field; 9]) -> [Field; 9] { +pub fn x5_9(mut state: [Field; 9]) -> [Field; 9] { state = permute( consts::x5_9_config(), state); @@ -67,7 +67,7 @@ fn x5_9(mut state: [Field; 9]) -> [Field; 9] { state } -fn x5_10(mut state: [Field; 10]) -> [Field; 10] { +pub fn x5_10(mut state: [Field; 10]) -> [Field; 10] { state = permute( consts::x5_10_config(), state); @@ -75,7 +75,7 @@ fn x5_10(mut state: [Field; 10]) -> [Field; 10] { state } -fn x5_11(mut state: [Field; 11]) -> [Field; 11] { +pub fn x5_11(mut state: [Field; 11]) -> [Field; 11] { state = permute( consts::x5_11_config(), state); @@ -83,7 +83,7 @@ fn x5_11(mut state: [Field; 11]) -> [Field; 11] { state } -fn x5_12(mut state: [Field; 12]) -> [Field; 12] { +pub fn x5_12(mut state: [Field; 12]) -> [Field; 12] { state = permute( consts::x5_12_config(), state); @@ -91,7 +91,7 @@ fn x5_12(mut state: [Field; 12]) -> [Field; 12] { state } -fn x5_13(mut state: [Field; 13]) -> [Field; 13] { +pub fn x5_13(mut state: [Field; 13]) -> [Field; 13] { state = permute( consts::x5_13_config(), state); @@ -99,7 +99,7 @@ fn x5_13(mut state: [Field; 13]) -> [Field; 13] { state } -fn x5_14(mut state: [Field; 14]) -> [Field; 14] { +pub fn x5_14(mut state: [Field; 14]) -> [Field; 14] { state = permute( consts::x5_14_config(), state); @@ -107,7 +107,7 @@ fn x5_14(mut state: [Field; 14]) -> [Field; 14] { state } -fn x5_15(mut state: [Field; 15]) -> [Field; 15] { +pub fn x5_15(mut state: [Field; 15]) -> [Field; 15] { state = permute( consts::x5_15_config(), state); @@ -115,7 +115,7 @@ fn x5_15(mut state: [Field; 15]) -> [Field; 15] { state } -fn x5_16(mut state: [Field; 16]) -> [Field; 16] { +pub fn x5_16(mut state: [Field; 16]) -> [Field; 16] { state = permute( consts::x5_16_config(), state); @@ -123,7 +123,7 @@ fn x5_16(mut state: [Field; 16]) -> [Field; 16] { state } -fn x5_17(mut state: [Field; 17]) -> [Field; 17] { +pub fn x5_17(mut state: [Field; 17]) -> [Field; 17] { state = permute( consts::x5_17_config(), state); diff --git a/noir_stdlib/src/lib.nr b/noir_stdlib/src/lib.nr index faade2a30aa..db2f0fc59b6 100644 --- a/noir_stdlib/src/lib.nr +++ b/noir_stdlib/src/lib.nr @@ -24,18 +24,21 @@ mod string; #[oracle(println)] unconstrained fn println_oracle(_input: T) {} -unconstrained fn println(input: T) { +unconstrained pub fn println(input: T) { println_oracle(input); } #[foreign(recursive_aggregation)] -fn verify_proof(_verification_key : [Field], _proof : [Field], _public_inputs : [Field], _key_hash : Field, _input_aggregation_object : [Field; N]) -> [Field; N] {} +pub fn verify_proof(_verification_key : [Field], _proof : [Field], _public_inputs : [Field], _key_hash : Field, _input_aggregation_object : [Field; N]) -> [Field; N] {} // Asserts that the given value is known at compile-time. // Useful for debugging for-loop bounds. #[builtin(assert_constant)] -fn assert_constant(_x: T) {} +pub fn assert_constant(_x: T) {} +// from_field and as_field are private since they are not valid for every type. +// `as` should be the default for users to cast between primitive types, and in the future +// traits can be used to work with generic types. #[builtin(from_field)] fn from_field(x : Field) -> T {} @@ -43,20 +46,19 @@ fn from_field(x : Field) -> T {} fn as_field(x : T) -> Field {} -fn wrapping_add(x : T, y: T) -> T { +pub fn wrapping_add(x : T, y: T) -> T { crate::from_field(crate::as_field(x) + crate::as_field(y)) } - -fn wrapping_sub(x : T, y: T) -> T { +pub fn wrapping_sub(x : T, y: T) -> T { //340282366920938463463374607431768211456 is 2^128, it is used to avoid underflow crate::from_field(crate::as_field(x) + 340282366920938463463374607431768211456 - crate::as_field(y)) } -fn wrapping_mul(x : T, y: T) -> T { +pub fn wrapping_mul(x : T, y: T) -> T { crate::from_field(crate::as_field(x) * crate::as_field(y)) } -fn wrapping_shift_left(x : T, y: T) -> T { +pub fn wrapping_shift_left(x : T, y: T) -> T { crate::from_field(crate::as_field(x) * 2.pow_32(crate::as_field(y))) -} \ No newline at end of file +} diff --git a/noir_stdlib/src/merkle.nr b/noir_stdlib/src/merkle.nr index 07588a52a5a..0bad55f93f4 100644 --- a/noir_stdlib/src/merkle.nr +++ b/noir_stdlib/src/merkle.nr @@ -3,7 +3,7 @@ // XXX: In the future we can add an arity parameter // Returns the merkle root of the tree from the provided leaf, its hashpath, using a pedersen hash function. -fn compute_merkle_root(leaf: Field, index: Field, hash_path: [Field; N]) -> Field { +pub fn compute_merkle_root(leaf: Field, index: Field, hash_path: [Field; N]) -> Field { let n = hash_path.len(); let index_bits = index.to_le_bits(n as u32); let mut current = leaf; diff --git a/noir_stdlib/src/option.nr b/noir_stdlib/src/option.nr index 11a632011b0..137d57f33db 100644 --- a/noir_stdlib/src/option.nr +++ b/noir_stdlib/src/option.nr @@ -5,27 +5,27 @@ struct Option { impl Option { /// Constructs a None value - fn none() -> Self { + pub fn none() -> Self { Self { _is_some: false, _value: crate::unsafe::zeroed() } } /// Constructs a Some wrapper around the given value - fn some(_value: T) -> Self { + pub fn some(_value: T) -> Self { Self { _is_some: true, _value } } /// True if this Option is None - fn is_none(self) -> bool { + pub fn is_none(self) -> bool { !self._is_some } /// True if this Option is Some - fn is_some(self) -> bool { + pub fn is_some(self) -> bool { self._is_some } /// Asserts `self.is_some()` and returns the wrapped value. - fn unwrap(self) -> T { + pub fn unwrap(self) -> T { assert(self._is_some); self._value } @@ -33,12 +33,12 @@ impl Option { /// Returns the inner value without asserting `self.is_some()` /// Note that if `self` is `None`, there is no guarantee what value will be returned, /// only that it will be of type `T`. - fn unwrap_unchecked(self) -> T { + pub fn unwrap_unchecked(self) -> T { self._value } /// Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value. - fn unwrap_or(self, default: T) -> T { + pub fn unwrap_or(self, default: T) -> T { if self._is_some { self._value } else { @@ -48,7 +48,7 @@ impl Option { /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return /// a default value. - fn unwrap_or_else(self, default: fn[Env]() -> T) -> T { + pub fn unwrap_or_else(self, default: fn[Env]() -> T) -> T { if self._is_some { self._value } else { @@ -57,7 +57,7 @@ impl Option { } /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`. - fn map(self, f: fn[Env](T) -> U) -> Option { + pub fn map(self, f: fn[Env](T) -> U) -> Option { if self._is_some { Option::some(f(self._value)) } else { @@ -66,7 +66,7 @@ impl Option { } /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value. - fn map_or(self, default: U, f: fn[Env](T) -> U) -> U { + pub fn map_or(self, default: U, f: fn[Env](T) -> U) -> U { if self._is_some { f(self._value) } else { @@ -75,7 +75,7 @@ impl Option { } /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`. - fn map_or_else(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U { + pub fn map_or_else(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U { if self._is_some { f(self._value) } else { @@ -84,7 +84,7 @@ impl Option { } /// Returns None if self is None. Otherwise, this returns `other`. - fn and(self, other: Self) -> Self { + pub fn and(self, other: Self) -> Self { if self.is_none() { Option::none() } else { @@ -96,7 +96,7 @@ impl Option { /// with the Some value contained within self, and returns the result of that call. /// /// In some languages this function is called `flat_map` or `bind`. - fn and_then(self, f: fn[Env](T) -> Option) -> Option { + pub fn and_then(self, f: fn[Env](T) -> Option) -> Option { if self._is_some { f(self._value) } else { @@ -105,7 +105,7 @@ impl Option { } /// If self is Some, return self. Otherwise, return `other`. - fn or(self, other: Self) -> Self { + pub fn or(self, other: Self) -> Self { if self._is_some { self } else { @@ -114,7 +114,7 @@ impl Option { } /// If self is Some, return self. Otherwise, return `default()`. - fn or_else(self, default: fn[Env]() -> Self) -> Self { + pub fn or_else(self, default: fn[Env]() -> Self) -> Self { if self._is_some { self } else { @@ -124,7 +124,7 @@ impl Option { // If only one of the two Options is Some, return that option. // Otherwise, if both options are Some or both are None, None is returned. - fn xor(self, other: Self) -> Self { + pub fn xor(self, other: Self) -> Self { if self._is_some { if other._is_some { Option::none() @@ -140,7 +140,7 @@ impl Option { /// Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true. /// Otherwise, this returns `None` - fn filter(self, predicate: fn[Env](T) -> bool) -> Self { + pub fn filter(self, predicate: fn[Env](T) -> bool) -> Self { if self._is_some { if predicate(self._value) { self @@ -154,7 +154,7 @@ impl Option { /// Flattens an Option> into a Option. /// This returns None if the outer Option is None. Otherwise, this returns the inner Option. - fn flatten(option: Option>) -> Option { + pub fn flatten(option: Option>) -> Option { if option._is_some { option._value } else { diff --git a/noir_stdlib/src/scalar_mul.nr b/noir_stdlib/src/scalar_mul.nr index fe017efbde4..f654a810461 100644 --- a/noir_stdlib/src/scalar_mul.nr +++ b/noir_stdlib/src/scalar_mul.nr @@ -5,4 +5,4 @@ // The embedded curve being used is decided by the // underlying proof system. #[foreign(fixed_base_scalar_mul)] -fn fixed_base_embedded_curve(_low : Field, _high : Field) -> [Field; 2] {} +pub fn fixed_base_embedded_curve(_low : Field, _high : Field) -> [Field; 2] {} diff --git a/noir_stdlib/src/schnorr.nr b/noir_stdlib/src/schnorr.nr index 1e69bcec821..c78eae37243 100644 --- a/noir_stdlib/src/schnorr.nr +++ b/noir_stdlib/src/schnorr.nr @@ -1,2 +1,2 @@ #[foreign(schnorr_verify)] -fn verify_signature(_public_key_x: Field, _public_key_y: Field, _signature: [u8; 64], _message: [u8; N]) -> bool {} +pub fn verify_signature(_public_key_x: Field, _public_key_y: Field, _signature: [u8; 64], _message: [u8; N]) -> bool {} diff --git a/noir_stdlib/src/sha256.nr b/noir_stdlib/src/sha256.nr index 63107442bf8..f6c22aa1d5f 100644 --- a/noir_stdlib/src/sha256.nr +++ b/noir_stdlib/src/sha256.nr @@ -99,7 +99,7 @@ fn msg_u8_to_u32(msg: [u8; 64]) -> [u32; 16] } // SHA-256 hash function -fn digest(msg: [u8; N]) -> [u8; 32] { +pub fn digest(msg: [u8; N]) -> [u8; 32] { let mut msg_block: [u8; 64] = [0; 64]; let mut h: [u32; 8] = [1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]; // Intermediate hash, starting with the canonical initial value let mut c: [u32; 8] = [0; 8]; // Compression of current message block as sequence of u32 diff --git a/noir_stdlib/src/sha512.nr b/noir_stdlib/src/sha512.nr index 1617af8e598..e5cac7b1554 100644 --- a/noir_stdlib/src/sha512.nr +++ b/noir_stdlib/src/sha512.nr @@ -98,7 +98,7 @@ fn msg_u8_to_u64(msg: [u8; 128]) -> [u64; 16] } // SHA-512 hash function -fn digest(msg: [u8; N]) -> [u8; 64] +pub fn digest(msg: [u8; N]) -> [u8; 64] { let mut msg_block: [u8; 128] = [0; 128]; let mut h: [u64; 8] = [7640891576956012808, 13503953896175478587, 4354685564936845355, 11912009170470909681, 5840696475078001361, 11170449401992604703, 2270897969802886507, 6620516959819538809]; // Intermediate hash, starting with the canonical initial value diff --git a/noir_stdlib/src/slice.nr b/noir_stdlib/src/slice.nr index 053a8acacb6..249c39d3ae7 100644 --- a/noir_stdlib/src/slice.nr +++ b/noir_stdlib/src/slice.nr @@ -4,25 +4,25 @@ impl [T] { /// new slice with a length one greater than the /// original unmodified slice. #[builtin(slice_push_back)] - fn push_back(_self: Self, _elem: T) -> Self { } + pub fn push_back(_self: Self, _elem: T) -> Self { } /// Push a new element to the front of the slice, returning a /// new slice with a length one greater than the /// original unmodified slice. #[builtin(slice_push_front)] - fn push_front(_self: Self, _elem: T) -> Self { } + pub fn push_front(_self: Self, _elem: T) -> Self { } /// Remove the last element of the slice, returning the /// popped slice and the element in a tuple #[builtin(slice_pop_back)] - fn pop_back(_self: Self) -> (Self, T) { } + pub fn pop_back(_self: Self) -> (Self, T) { } /// Remove the first element of the slice, returning the /// element and the popped slice in a tuple #[builtin(slice_pop_front)] - fn pop_front(_self: Self) -> (T, Self) { } + pub fn pop_front(_self: Self) -> (T, Self) { } - fn insert(self, _index: Field, _elem: T) -> Self { + pub fn insert(self, _index: Field, _elem: T) -> Self { // TODO(#2462): Slice insert with a dynamic index crate::assert_constant(_index); self.__slice_insert(_index, _elem) @@ -33,7 +33,7 @@ impl [T] { #[builtin(slice_insert)] fn __slice_insert(_self: Self, _index: Field, _elem: T) -> Self { } - fn remove(self, _index: Field) -> (Self, T) { + pub fn remove(self, _index: Field) -> (Self, T) { // TODO(#2462): Slice remove with a dynamic index crate::assert_constant(_index); self.__slice_remove(_index) @@ -47,7 +47,7 @@ impl [T] { // Append each element of the `other` slice to the end of `self`. // This returns a new slice and leaves both input slices unchanged. - fn append(mut self, other: Self) -> Self { + pub fn append(mut self, other: Self) -> Self { for elem in other { self = self.push_back(elem); } diff --git a/noir_stdlib/src/string.nr b/noir_stdlib/src/string.nr index e24bb567681..8b0c02f3dd0 100644 --- a/noir_stdlib/src/string.nr +++ b/noir_stdlib/src/string.nr @@ -2,10 +2,10 @@ use crate::collections::vec::Vec; impl str { /// Converts the given string into a byte array #[builtin(str_as_bytes)] - fn as_bytes(_self: Self) -> [u8; N] { } + pub fn as_bytes(_self: Self) -> [u8; N] { } /// return a byte vector of the str content - fn as_bytes_vec(self: Self) -> Vec { + pub fn as_bytes_vec(self: Self) -> Vec { Vec::from_slice(self.as_bytes().as_slice()) } } \ No newline at end of file diff --git a/noir_stdlib/src/unsafe.nr b/noir_stdlib/src/unsafe.nr index a28549d5011..542bd31fa84 100644 --- a/noir_stdlib/src/unsafe.nr +++ b/noir_stdlib/src/unsafe.nr @@ -2,4 +2,4 @@ /// all of its fields to 0. This is considered to be unsafe since there /// is no guarantee that all zeroes is a valid bit pattern for every type. #[builtin(zeroed)] -fn zeroed() -> T {} +pub fn zeroed() -> T {} diff --git a/tooling/nargo_cli/tests/execution_success/global_consts/src/baz.nr b/tooling/nargo_cli/tests/execution_success/global_consts/src/baz.nr index 626477a89d0..d5b13407574 100644 --- a/tooling/nargo_cli/tests/execution_success/global_consts/src/baz.nr +++ b/tooling/nargo_cli/tests/execution_success/global_consts/src/baz.nr @@ -1,4 +1,4 @@ -fn from_baz(x : [Field; crate::foo::MAGIC_NUMBER]) { +pub fn from_baz(x : [Field; crate::foo::MAGIC_NUMBER]) { for i in 0..crate::foo::MAGIC_NUMBER { assert(x[i] == crate::foo::MAGIC_NUMBER); }; diff --git a/tooling/nargo_cli/tests/execution_success/global_consts/src/foo.nr b/tooling/nargo_cli/tests/execution_success/global_consts/src/foo.nr index 6aa27be61ca..2d28111728b 100644 --- a/tooling/nargo_cli/tests/execution_success/global_consts/src/foo.nr +++ b/tooling/nargo_cli/tests/execution_success/global_consts/src/foo.nr @@ -4,7 +4,7 @@ global N: Field = 5; global MAGIC_NUMBER: Field = 3; global TYPE_INFERRED = 42; -fn from_foo(x : [Field; bar::N]) { +pub fn from_foo(x : [Field; bar::N]) { for i in 0..bar::N { assert(x[i] == bar::N); }; diff --git a/tooling/nargo_cli/tests/execution_success/global_consts/src/foo/bar.nr b/tooling/nargo_cli/tests/execution_success/global_consts/src/foo/bar.nr index 1b4d472b1e8..b839ff28ac6 100644 --- a/tooling/nargo_cli/tests/execution_success/global_consts/src/foo/bar.nr +++ b/tooling/nargo_cli/tests/execution_success/global_consts/src/foo/bar.nr @@ -1,5 +1,5 @@ global N: Field = 5; -fn from_bar(x : Field) -> Field { +pub fn from_bar(x : Field) -> Field { x * N } \ No newline at end of file diff --git a/tooling/nargo_cli/tests/execution_success/global_consts/src/main.nr b/tooling/nargo_cli/tests/execution_success/global_consts/src/main.nr index b4c72d1cff9..e741de50c86 100644 --- a/tooling/nargo_cli/tests/execution_success/global_consts/src/main.nr +++ b/tooling/nargo_cli/tests/execution_success/global_consts/src/main.nr @@ -85,7 +85,7 @@ mod mysubmodule { assert(x | y == 1); } - fn my_helper() -> Field { + pub fn my_helper() -> Field { let N: Field = 15; // Like in Rust, local variables override globals let x = N; x diff --git a/tooling/nargo_cli/tests/execution_success/import/src/import.nr b/tooling/nargo_cli/tests/execution_success/import/src/import.nr index f557b362183..3dfa96992ad 100644 --- a/tooling/nargo_cli/tests/execution_success/import/src/import.nr +++ b/tooling/nargo_cli/tests/execution_success/import/src/import.nr @@ -1,4 +1,4 @@ -fn hello(x : Field) -> Field { +pub fn hello(x : Field) -> Field { x } \ No newline at end of file diff --git a/tooling/nargo_cli/tests/execution_success/modules/src/foo.nr b/tooling/nargo_cli/tests/execution_success/modules/src/foo.nr index 1f771fa9425..1f10d8ddd8d 100644 --- a/tooling/nargo_cli/tests/execution_success/modules/src/foo.nr +++ b/tooling/nargo_cli/tests/execution_success/modules/src/foo.nr @@ -1,3 +1,3 @@ -fn hello(x : Field) -> Field { +pub fn hello(x : Field) -> Field { x } \ No newline at end of file diff --git a/tooling/nargo_cli/tests/execution_success/modules_more/src/foo/bar.nr b/tooling/nargo_cli/tests/execution_success/modules_more/src/foo/bar.nr index a92fb81dceb..4f459b040d6 100644 --- a/tooling/nargo_cli/tests/execution_success/modules_more/src/foo/bar.nr +++ b/tooling/nargo_cli/tests/execution_success/modules_more/src/foo/bar.nr @@ -1,3 +1,3 @@ -fn from_bar(x : Field) -> Field { +pub fn from_bar(x : Field) -> Field { x } \ No newline at end of file diff --git a/tooling/nargo_cli/tests/execution_success/submodules/src/main.nr b/tooling/nargo_cli/tests/execution_success/submodules/src/main.nr index 3b8807ddb37..47f80f1bd4d 100644 --- a/tooling/nargo_cli/tests/execution_success/submodules/src/main.nr +++ b/tooling/nargo_cli/tests/execution_success/submodules/src/main.nr @@ -6,10 +6,10 @@ fn main(x: u1, y: u1) { } mod mysubmodule { - fn my_bool_or(x: u1, y: u1) { + pub fn my_bool_or(x: u1, y: u1) { assert(x | y == 1); } - fn my_helper() {} + pub fn my_helper() {} } diff --git a/tooling/nargo_cli/tests/test_libraries/diamond_deps_1/src/lib.nr b/tooling/nargo_cli/tests/test_libraries/diamond_deps_1/src/lib.nr index cecb2715104..d63b835c8a7 100644 --- a/tooling/nargo_cli/tests/test_libraries/diamond_deps_1/src/lib.nr +++ b/tooling/nargo_cli/tests/test_libraries/diamond_deps_1/src/lib.nr @@ -1,5 +1,5 @@ use dep::dep2::call_dep2; -fn call_dep1_then_dep2(x : Field, y : Field) -> Field { +pub fn call_dep1_then_dep2(x : Field, y : Field) -> Field { call_dep2(x, y) } diff --git a/tooling/nargo_cli/tests/test_libraries/diamond_deps_2/src/lib.nr b/tooling/nargo_cli/tests/test_libraries/diamond_deps_2/src/lib.nr index f7745efd679..7ee59d2bc9d 100644 --- a/tooling/nargo_cli/tests/test_libraries/diamond_deps_2/src/lib.nr +++ b/tooling/nargo_cli/tests/test_libraries/diamond_deps_2/src/lib.nr @@ -1,6 +1,6 @@ global RESOLVE_THIS = 3; -fn call_dep2(x : Field, y : Field) -> Field { +pub fn call_dep2(x : Field, y : Field) -> Field { x + y }