From 2dbb46b9ae03092e5134e2a6d539dbaa11a6a828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Fri, 17 Jul 2026 18:34:32 +0000 Subject: [PATCH 1/6] chore: remove dead constants from constants.nr Remove 22 unused constants from the noir-protocol-circuits types crate (and their generated mirror in constants.gen.ts). None are referenced by any circuit, contract, TypeScript, C++, PIL, or Solidity code. 13 are directly unreferenced. The other 9 are only used to build the removed ones, so they become dead in the same pass -- e.g. PRIVATE_ACCUMULATED_DATA_LENGTH and PRIVATE_VALIDATION_REQUESTS_LENGTH fed only PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH. Also drop the two ContractClassRegistry function-broadcast magic values along with their assertions in constants_tests.nr, shrinking the HashedValueTester capacity from 78 to 76. --- .../crates/types/src/constants.nr | 62 +------------------ .../crates/types/src/constants_tests.nr | 24 +++---- 2 files changed, 9 insertions(+), 77 deletions(-) diff --git a/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants.nr index 0da946df4b89..c61dab2ef3ef 100644 --- a/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants.nr @@ -76,7 +76,6 @@ pub global MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: u32 = (1 as u8 << PUBLIC_DATA_SUBTREE_HEIGHT as u8) as u32; pub global MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: u32 = MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX - PROTOCOL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX; -pub global MAX_PUBLIC_DATA_READS_PER_TX: u32 = 64; pub global MAX_L2_TO_L1_MSGS_PER_TX: u32 = 8; // Leave at 8, because it results in sha256 hashing in the Tx Base Rollup pub global MAX_PRIVATE_LOGS_PER_TX: u32 = MAX_NOTE_HASHES_PER_TX; pub global MAX_CONTRACT_CLASS_LOGS_PER_TX: u32 = 1; @@ -179,7 +178,6 @@ pub global TOTAL_COUNTED_SIDE_EFFECTS_PER_CALL: u32 = GLOBAL_INDEX_CONTRACT_MIN_ + 1 /* min_revertible_side_effect_counter */; // MISC CONSTANTS -pub global FUNCTION_SELECTOR_NUM_BYTES: Field = 4; pub global INITIAL_CHECKPOINT_NUMBER: Field = 1; pub global INITIAL_L2_BLOCK_NUM: Field = 1; pub global FIELDS_PER_BLOB: u32 = 4096; @@ -199,8 +197,6 @@ pub global MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS: u32 = 3000; // Arbitrary. // Bytecode size for private functions is per function, not for the entire contract. // Note that private functions bytecode includes a mix of acir and brillig. pub global MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS: u32 = 3000; // Arbitrary. -// Same for utility functions: the size is per function. -pub global MAX_PACKED_BYTECODE_SIZE_PER_UTILITY_FUNCTION_IN_FIELDS: u32 = 3000; // Arbitrary. // How many fields are on the serialized ClassPrivateFunctionBroadcasted event in addition to MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS. pub global CLASS_REGISTRY_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS: u32 =/* magic value */ 1 @@ -215,24 +211,10 @@ pub global CLASS_REGISTRY_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS: u32 =/ + 1 /* function metadata_hash */ + 1 /* function vk_hash */; -// How many fields are on the serialized ClassUtilityFunctionBroadcasted event in addition to MAX_PACKED_BYTECODE_SIZE_PER_UTILITY_FUNCTION_IN_FIELDS. -pub global CLASS_REGISTRY_UTILITY_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS: u32 =/* magic value */ 1 - + 1 /* contract_class_id */ - + 1 /* artifact_metadata_hash */ - + 1 /* private_functions_artifact_tree_root */ - + ARTIFACT_FUNCTION_TREE_MAX_HEIGHT /* artifact_function_tree_sibling_path */ - + 1 /* artifact_function_tree_leaf_index */ - + 1 /* function selector */ - + 1 /* function metadata_hash */; - // We use these magic values to identify events emitted by the ContractClassRegistry and ContractInstanceRegistry. // The values were generated and checked in `constants_tests.nr`. pub global CONTRACT_CLASS_PUBLISHED_MAGIC_VALUE: Field = 0x20f5895a4e837356c2d551743df6bf642756dcd93cd31cbd37c556c90bf7f244; -pub global CONTRACT_CLASS_REGISTRY_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE: Field = - 0x0ea9d22f6c3686a6866f103431c5796d2be7b7a3d0c3abcf7636b064ab09e618; -pub global CONTRACT_CLASS_REGISTRY_UTILITY_FUNCTION_BROADCASTED_MAGIC_VALUE: Field = - 0x06549ee6586be1c25c81f2d579c06a4c3f31255def74dd729903811d90ba2369; pub global CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE: Field = 0x174c6b3d0fd14728e4fc5e53f7b262ab943546a7e125e2ed5e9fde3cf0b3e22f; pub global CONTRACT_INSTANCE_UPDATED_MAGIC_VALUE: Field = @@ -342,10 +324,8 @@ pub global CONTRACT_STORAGE_READ_LENGTH: u32 = 3; pub global CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH: u32 = 3; pub global ETH_ADDRESS_LENGTH: u32 = 1; pub global FUNCTION_DATA_LENGTH: u32 = 2; -pub global FUNCTION_LEAF_PREIMAGE_LENGTH: u32 = 5; pub global GLOBAL_VARIABLES_LENGTH: u32 = 7 + GAS_FEES_LENGTH; pub global APPEND_ONLY_TREE_SNAPSHOT_LENGTH: u32 = 2; -pub global APPEND_ONLY_TREE_SNAPSHOT_LENGTH_BYTES: u32 = 36; pub global SPONGE_BLOB_LENGTH: u32 = 10; pub global BLS12_FR_LIMBS: u32 = 3; // TODO(#14646): get this from bignum pub global BLS12_FQ_LIMBS: u32 = 4; // TODO(#14646): get this from bignum @@ -360,17 +340,14 @@ pub global FINAL_BLOB_ACCUMULATOR_LENGTH: u32 = 1 /* blob_commitments_hash */ + 1 /* z */ + BLS12_FR_LIMBS /* y */ + 2 /* c */; -pub global L1_TO_L2_MESSAGE_LENGTH: u32 = 6; pub global L2_TO_L1_MESSAGE_LENGTH: u32 = 1 /* recipient */ + 1 /* content */; pub global COUNTED_L2_TO_L1_MESSAGE_LENGTH: u32 = L2_TO_L1_MESSAGE_LENGTH + 1; pub global SCOPED_L2_TO_L1_MESSAGE_LENGTH: u32 = L2_TO_L1_MESSAGE_LENGTH + 1; -pub global SCOPED_COUNTED_L2_TO_L1_MESSAGE_LENGTH: u32 = COUNTED_L2_TO_L1_MESSAGE_LENGTH + 1; pub global KEY_VALIDATION_REQUEST_LENGTH: u32 = 2; pub global KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH: u32 = KEY_VALIDATION_REQUEST_LENGTH + 1; pub global SCOPED_KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH: u32 = KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH + 1; pub global PARTIAL_STATE_REFERENCE_LENGTH: u32 = 6; -pub global TREE_LEAF_READ_REQUEST_LENGTH: u32 = 2; pub global PRIVATE_LOG_SIZE_IN_FIELDS: u32 = 16; pub global PRIVATE_LOG_LENGTH: u32 = PRIVATE_LOG_SIZE_IN_FIELDS + 1 /* length */; pub global PRIVATE_LOG_DATA_LENGTH: u32 = PRIVATE_LOG_LENGTH @@ -380,7 +357,6 @@ pub global PRIVATE_LOG_DATA_LENGTH: u32 = PRIVATE_LOG_LENGTH /// because, unlike public logs, it is expected that private logs are encrypted (though this is not /// mandatory). pub global PRIVATE_LOG_CIPHERTEXT_LEN: u32 = PRIVATE_LOG_SIZE_IN_FIELDS - 1; // -1 for the tag -pub global SCOPED_PRIVATE_LOG_DATA_LENGTH: u32 = PRIVATE_LOG_DATA_LENGTH + 1 /* contract_address */; // Below are constants for the entire PublicLogs struct. pub global FLAT_PUBLIC_LOGS_HEADER_LENGTH: u32 = 1 /* length */; pub global FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH: u32 = 4096; @@ -401,11 +377,8 @@ pub global CONTRACT_CLASS_LOG_LENGTH: u32 = CONTRACT_CLASS_LOG_SIZE_IN_FIELDS pub global LOG_HASH_LENGTH: u32 = 1 /* value */ + 1 /* length */; pub global COUNTED_LOG_HASH_LENGTH: u32 = LOG_HASH_LENGTH + 1 /* counter */; pub global SCOPED_LOG_HASH_LENGTH: u32 = LOG_HASH_LENGTH + 1 /* contract_address */; -pub global SCOPED_COUNTED_LOG_HASH_LENGTH: u32 = SCOPED_LOG_HASH_LENGTH + 1 /* counter */; pub global NOTE_HASH_LENGTH: u32 = 2; -pub global SCOPED_NOTE_HASH_LENGTH: u32 = NOTE_HASH_LENGTH + 1; pub global NULLIFIER_LENGTH: u32 = 3; -pub global SCOPED_NULLIFIER_LENGTH: u32 = NULLIFIER_LENGTH + 1; pub global PUBLIC_DATA_WRITE_LENGTH: u32 = 2; pub global PUBLIC_CALL_STACK_ITEM_COMPRESSED_LENGTH: u32 = AZTEC_ADDRESS_LENGTH + CALL_CONTEXT_LENGTH + 3 + 2 * GAS_LENGTH; @@ -415,8 +388,6 @@ pub global PUBLIC_CALL_REQUEST_LENGTH: u32 = AZTEC_ADDRESS_LENGTH /* msg_sender + 1 /* is_static_call */ + 1 /* calldata_hash */; pub global COUNTED_PUBLIC_CALL_REQUEST_LENGTH: u32 = PUBLIC_CALL_REQUEST_LENGTH + 1; -pub global PUBLIC_INNER_CALL_REQUEST_LENGTH: u32 = - PUBLIC_CALL_STACK_ITEM_COMPRESSED_LENGTH + 1 /* counter */; pub global STATE_REFERENCE_LENGTH: u32 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH; pub global TREE_SNAPSHOTS_LENGTH: u32 = APPEND_ONLY_TREE_SNAPSHOT_LENGTH * 4; @@ -489,14 +460,6 @@ pub global HIDING_KERNEL_IO_PUBLIC_INPUTS_SIZE: u32 = 28; pub global PAIRING_POINTS_SIZE: u32 = 8; pub global IPA_CLAIM_SIZE: u32 = 6; -pub global PUBLIC_DATA_READ_LENGTH: u32 = 3; -// The `(... + 1)` is because these arrays include a `length` field. -pub global PRIVATE_VALIDATION_REQUESTS_LENGTH: u32 = ( - SCOPED_READ_REQUEST_LEN * MAX_NOTE_HASH_READ_REQUESTS_PER_TX + 1 -) - + (SCOPED_READ_REQUEST_LEN * MAX_NULLIFIER_READ_REQUESTS_PER_TX + 1) - + (SCOPED_KEY_VALIDATION_REQUEST_AND_GENERATOR_LENGTH * MAX_KEY_VALIDATION_REQUESTS_PER_TX + 1); - pub global PRIVATE_TO_ROLLUP_ACCUMULATED_DATA_LENGTH: u32 = MAX_NOTE_HASHES_PER_TX + MAX_NULLIFIERS_PER_TX + (MAX_L2_TO_L1_MSGS_PER_TX * SCOPED_L2_TO_L1_MESSAGE_LENGTH) @@ -507,26 +470,6 @@ pub global TX_CONSTANT_DATA_LENGTH: u32 = BLOCK_HEADER_LENGTH + TX_CONTEXT_LENGTH + 1 /* vk_tree_root */ + 1 /* protocol_contracts_hash */; -pub global COMBINED_CONSTANT_DATA_LENGTH: u32 = TX_CONSTANT_DATA_LENGTH + GLOBAL_VARIABLES_LENGTH; - -pub global PRIVATE_ACCUMULATED_DATA_LENGTH: u32 = - // The `(... + 1)` is because these arrays include a `length` field. - (SCOPED_NOTE_HASH_LENGTH * MAX_NOTE_HASHES_PER_TX + 1) - + (SCOPED_NULLIFIER_LENGTH * MAX_NULLIFIERS_PER_TX + 1) - + (MAX_L2_TO_L1_MSGS_PER_TX * SCOPED_COUNTED_L2_TO_L1_MESSAGE_LENGTH + 1) - + (SCOPED_PRIVATE_LOG_DATA_LENGTH * MAX_PRIVATE_LOGS_PER_TX + 1) - + (SCOPED_COUNTED_LOG_HASH_LENGTH * MAX_CONTRACT_CLASS_LOGS_PER_TX + 1) - + (PRIVATE_CALL_REQUEST_LENGTH * MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX + 1) - + (COUNTED_PUBLIC_CALL_REQUEST_LENGTH * MAX_ENQUEUED_CALLS_PER_TX + 1); -pub global PRIVATE_KERNEL_CIRCUIT_PUBLIC_INPUTS_LENGTH: u32 = TX_CONSTANT_DATA_LENGTH - + 1 /* min_revertible_side_effect_counter */ - + PRIVATE_VALIDATION_REQUESTS_LENGTH - + PRIVATE_ACCUMULATED_DATA_LENGTH - + PUBLIC_CALL_REQUEST_LENGTH - + AZTEC_ADDRESS_LENGTH - + 1 /* expiration_timestamp */ - + 1 /* is private only */ - + 1 /* claimed_revertible_counter */; pub global PRIVATE_TO_PUBLIC_ACCUMULATED_DATA_LENGTH: u32 = MAX_NOTE_HASHES_PER_TX + MAX_NULLIFIERS_PER_TX @@ -685,9 +628,8 @@ pub global CHONK_VK_LENGTH_IN_FIELDS: u32 = MEGA_ZK_VK_LENGTH_IN_FIELDS; // size pub global AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS: u32 = 2 + 21 * 4; // Setting limits for MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS -// This value is determined by the length of the AVM trace and the MAX_PUBLIC_BYTECODE_SIZE_IN_BYTES -// (i.e. 2^21 / MAX_PUBLIC_BYTECODE_SIZE_IN_BYTES ==> 2^21 / 96,000 = 21 -pub global MAX_PUBLIC_BYTECODE_SIZE_IN_BYTES: u32 = MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS * 32; +// This value is determined by the length of the AVM trace and the max public bytecode size in bytes +// (MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS * 32 = 96,000), i.e. 2^21 / 96,000 = 21 pub global MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS: u32 = 21; // --------------------------------------------------------------- diff --git a/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants_tests.nr b/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants_tests.nr index 3e1b6f41b2b4..ec50093d2527 100644 --- a/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants_tests.nr +++ b/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants_tests.nr @@ -2,14 +2,12 @@ use crate::{ address::AztecAddress, constants::{ BLOCK_END_PREFIX, CHECKPOINT_END_PREFIX, CONTRACT_CLASS_PUBLISHED_MAGIC_VALUE, - CONTRACT_CLASS_REGISTRY_BYTECODE_CAPSULE_SLOT, - CONTRACT_CLASS_REGISTRY_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE, - CONTRACT_CLASS_REGISTRY_UTILITY_FUNCTION_BROADCASTED_MAGIC_VALUE, - CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE, CONTRACT_INSTANCE_UPDATED_MAGIC_VALUE, - DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, DOM_SEP__AUTHWIT_INNER, DOM_SEP__AUTHWIT_NULLIFIER, - DOM_SEP__AUTHWIT_OUTER, DOM_SEP__BLOB_CHALLENGE_Z, DOM_SEP__BLOB_GAMMA_ACC, - DOM_SEP__BLOB_GAMMA_FINAL, DOM_SEP__BLOB_HASHED_Y_LIMBS, DOM_SEP__BLOB_Z_ACC, - DOM_SEP__BLOCK_HEADER_HASH, DOM_SEP__BLOCK_HEADERS_HASH, DOM_SEP__CONSTRAINED_MSG_LOG_TAG, + CONTRACT_CLASS_REGISTRY_BYTECODE_CAPSULE_SLOT, CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE, + CONTRACT_INSTANCE_UPDATED_MAGIC_VALUE, DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, + DOM_SEP__AUTHWIT_INNER, DOM_SEP__AUTHWIT_NULLIFIER, DOM_SEP__AUTHWIT_OUTER, + DOM_SEP__BLOB_CHALLENGE_Z, DOM_SEP__BLOB_GAMMA_ACC, DOM_SEP__BLOB_GAMMA_FINAL, + DOM_SEP__BLOB_HASHED_Y_LIMBS, DOM_SEP__BLOB_Z_ACC, DOM_SEP__BLOCK_HEADER_HASH, + DOM_SEP__BLOCK_HEADERS_HASH, DOM_SEP__CONSTRAINED_MSG_LOG_TAG, DOM_SEP__CONSTRAINED_MSG_NULLIFIER, DOM_SEP__CONSTRAINED_MSG_SENDER_SECRET, DOM_SEP__CONTRACT_ADDRESS_V2, DOM_SEP__CONTRACT_CLASS_ID, DOM_SEP__ECDH_FIELD_MASK, DOM_SEP__ECDH_SUBKEY, DOM_SEP__EVENT_COMMITMENT, DOM_SEP__EVENT_LOG_TAG, DOM_SEP__FBSK_M, @@ -146,7 +144,7 @@ impl HashedValueTester::new(); + let mut tester = HashedValueTester::<76, 71>::new(); // ----------------- // Domain separators @@ -299,14 +297,6 @@ fn hashed_values_match_derived() { CONTRACT_CLASS_PUBLISHED_MAGIC_VALUE, "contract_class_published", ); - tester.assert_aztec_nr_values_matches_derived( - CONTRACT_CLASS_REGISTRY_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE, - "contract_class_registry_private_function_broadcasted", - ); - tester.assert_aztec_nr_values_matches_derived( - CONTRACT_CLASS_REGISTRY_UTILITY_FUNCTION_BROADCASTED_MAGIC_VALUE, - "contract_class_registry_utility_function_broadcasted", - ); tester.assert_aztec_nr_values_matches_derived( CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE, "contract_instance_published", From 3ff48d230e8fc2b5e8fc6876691932753acd5064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Fri, 17 Jul 2026 20:41:35 +0000 Subject: [PATCH 2/6] add aztecnr domain sep uniqueness and derivation tests --- .../crates/types/src/constants.nr | 32 ---- .../crates/types/src/constants_tests.nr | 52 ++---- .../aztec-nr/aztec/src/authwit/account.nr | 7 +- .../labs/aztec-nr/aztec/src/authwit/auth.nr | 5 +- .../aztec/src/keys/ecdh_shared_secret.nr | 7 +- .../macros/functions/initialization_utils.nr | 5 + .../messages/delivery/constrained_delivery.nr | 7 +- .../aztec/src/messages/processing/mod.nr | 2 +- .../labs/aztec-nr/aztec/src/note/mod.nr | 1 + .../aztec-nr/aztec/src/note/partial_note.nr | 10 ++ .../labs/aztec-nr/aztec/src/state_vars/mod.nr | 2 +- .../aztec/src/state_vars/private_immutable.nr | 2 +- .../aztec/src/state_vars/private_mutable.nr | 2 +- .../aztec/src/state_vars/public_immutable.nr | 5 +- .../state_vars/single_private_immutable.nr | 5 +- .../src/state_vars/single_private_mutable.nr | 6 +- .../aztec/src/state_vars/single_use_claim.nr | 6 +- .../aztec/src/test/domain_separators.nr | 160 ++++++++++++++++++ .../labs/aztec-nr/aztec/src/test/mod.nr | 1 + .../labs/aztec-nr/uint-note/src/uint_note.nr | 11 +- .../app/nft_contract/src/types/nft_note.nr | 11 +- 21 files changed, 236 insertions(+), 103 deletions(-) create mode 100644 noir-projects/labs/aztec-nr/aztec/src/note/partial_note.nr create mode 100644 noir-projects/labs/aztec-nr/aztec/src/test/domain_separators.nr diff --git a/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants.nr index c61dab2ef3ef..597476347b20 100644 --- a/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants.nr @@ -642,15 +642,6 @@ pub global MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS: u32 = 21; /// This is not technically a protocol constant as note hashes are computed by each contract. pub global DOM_SEP__NOTE_HASH: u32 = 116501019; -/// Domain separator for partial note commitments. -/// -/// This is not technically a protocol constant as partial note commitments are computed by each contract. -/// -/// A partial note commitment is the first round of hashing of a partial note, combining the private fields before the -/// public completion fields (storage slot and public note data) are mixed in. Distinct from [`DOM_SEP__NOTE_HASH`], -/// which preserves the storage-slot-first invariant. -pub global DOM_SEP__PARTIAL_NOTE_COMMITMENT: u32 = 568912195; - /// Domain separator for siloed note hashes. /// /// Used by [`crate::hash::compute_siloed_note_hash`]. @@ -666,11 +657,6 @@ pub global DOM_SEP__UNIQUE_NOTE_HASH: u32 = 226850429; /// Used by [`crate::hash::compute_note_hash_nonce`]. pub global DOM_SEP__NOTE_HASH_NONCE: u32 = 1721808740; -/// Domain separator for `SingleUseClaim` nullifiers. -/// -/// This is not technically a protocol constant as these nullifiers are computed by each contract. -pub global DOM_SEP__SINGLE_USE_CLAIM_NULLIFIER: u32 = 1465998995; - /// Domain separator for note nullifiers. /// /// This is not technically a protocol constant as note nullifiers are computed by each contract. @@ -688,14 +674,10 @@ pub global DOM_SEP__MESSAGE_NULLIFIER: u32 = 3754509616; /// Domain separator for event log tags. Used by [`crate::hash::compute_log_tag`]. pub global DOM_SEP__EVENT_LOG_TAG: u32 = 926040838; -/// Domain separator for partial note completion log tags. Used by [`crate::hash::compute_log_tag`]. -pub global DOM_SEP__NOTE_COMPLETION_LOG_TAG: u32 = 3372669888; /// Domain separator for unconstrained message delivery log tags. Used by [`crate::hash::compute_log_tag`]. pub global DOM_SEP__UNCONSTRAINED_MSG_LOG_TAG: u32 = 1485357192; /// Domain separator for constrained message delivery log tags. Used by [`crate::hash::compute_log_tag`]. pub global DOM_SEP__CONSTRAINED_MSG_LOG_TAG: u32 = 3715244738; -/// Domain separator for nullifiers used during constrained delivery. -pub global DOM_SEP__CONSTRAINED_MSG_NULLIFIER: u32 = 3723577546; /// Domain separator for the sender-only secret folded into constrained-delivery nullifiers. pub global DOM_SEP__CONSTRAINED_MSG_SENDER_SECRET: u32 = 1182889476; /// Domain separator for non-interactive handshake log tags emitted by the handshake registry contract. Used by @@ -783,11 +765,8 @@ pub global DOM_SEP__EVENT_COMMITMENT: u32 = 2517418573; pub global DOM_SEP__AUTHWIT_INNER: u32 = 221354163; pub global DOM_SEP__AUTHWIT_OUTER: u32 = 3283595782; -pub global DOM_SEP__AUTHWIT_NULLIFIER: u32 = 1239150694; pub global DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET: u32 = 1707851664; -pub global DOM_SEP__ECDH_SUBKEY: u32 = 4277646631; -pub global DOM_SEP__ECDH_FIELD_MASK: u32 = 190532684; pub global DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT: u32 = 623934423; @@ -795,23 +774,12 @@ pub global DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT: u32 = 623934423; // TODO(F-397): move these to aztec-nr, along with note hash, note nullifier, message nullifier and single use claim // nullifier. -/// Domain separator for state variable initialization. -/// -/// Should not be reused for a given storage slot. -pub global DOM_SEP__INITIALIZATION_NULLIFIER: u32 = 1653084894; pub global DOM_SEP__PUBLIC_INITIALIZATION_NULLIFIER: u32 = 3342006647; pub global DOM_SEP__PRIVATE_INITIALIZATION_NULLIFIER: u32 = 3990889078; /// Domain separator for L1 to L2 message secret hashes. pub global DOM_SEP__SECRET_HASH: u32 = 4199652938; -/// Domain separator for transaction nullifiers. -/// -/// Used to produce cancellable (replaceable) transactions. -/// -/// This is not technically a protocol constant as cancellable transactions are an account contract feature. -pub global DOM_SEP__TX_NULLIFIER: u32 = 1025801951; - /// Domain separator for account contract payloads. /// /// Used to check for authorization to execute a payload. diff --git a/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants_tests.nr b/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants_tests.nr index ec50093d2527..cf30010625c6 100644 --- a/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants_tests.nr +++ b/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants_tests.nr @@ -4,21 +4,18 @@ use crate::{ BLOCK_END_PREFIX, CHECKPOINT_END_PREFIX, CONTRACT_CLASS_PUBLISHED_MAGIC_VALUE, CONTRACT_CLASS_REGISTRY_BYTECODE_CAPSULE_SLOT, CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE, CONTRACT_INSTANCE_UPDATED_MAGIC_VALUE, DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, - DOM_SEP__AUTHWIT_INNER, DOM_SEP__AUTHWIT_NULLIFIER, DOM_SEP__AUTHWIT_OUTER, - DOM_SEP__BLOB_CHALLENGE_Z, DOM_SEP__BLOB_GAMMA_ACC, DOM_SEP__BLOB_GAMMA_FINAL, - DOM_SEP__BLOB_HASHED_Y_LIMBS, DOM_SEP__BLOB_Z_ACC, DOM_SEP__BLOCK_HEADER_HASH, - DOM_SEP__BLOCK_HEADERS_HASH, DOM_SEP__CONSTRAINED_MSG_LOG_TAG, - DOM_SEP__CONSTRAINED_MSG_NULLIFIER, DOM_SEP__CONSTRAINED_MSG_SENDER_SECRET, - DOM_SEP__CONTRACT_ADDRESS_V2, DOM_SEP__CONTRACT_CLASS_ID, DOM_SEP__ECDH_FIELD_MASK, - DOM_SEP__ECDH_SUBKEY, DOM_SEP__EVENT_COMMITMENT, DOM_SEP__EVENT_LOG_TAG, DOM_SEP__FBSK_M, - DOM_SEP__FUNCTION_ARGS, DOM_SEP__HANDSHAKE_FORGERY_PROTECTION, - DOM_SEP__INITIALIZATION_NULLIFIER, DOM_SEP__INITIALIZER, + DOM_SEP__AUTHWIT_INNER, DOM_SEP__AUTHWIT_OUTER, DOM_SEP__BLOB_CHALLENGE_Z, + DOM_SEP__BLOB_GAMMA_ACC, DOM_SEP__BLOB_GAMMA_FINAL, DOM_SEP__BLOB_HASHED_Y_LIMBS, + DOM_SEP__BLOB_Z_ACC, DOM_SEP__BLOCK_HEADER_HASH, DOM_SEP__BLOCK_HEADERS_HASH, + DOM_SEP__CONSTRAINED_MSG_LOG_TAG, DOM_SEP__CONSTRAINED_MSG_SENDER_SECRET, + DOM_SEP__CONTRACT_ADDRESS_V2, DOM_SEP__CONTRACT_CLASS_ID, DOM_SEP__EVENT_COMMITMENT, + DOM_SEP__EVENT_LOG_TAG, DOM_SEP__FBSK_M, DOM_SEP__FUNCTION_ARGS, + DOM_SEP__HANDSHAKE_FORGERY_PROTECTION, DOM_SEP__INITIALIZER, DOM_SEP__INTERACTIVE_HANDSHAKE_SIGNATURE, DOM_SEP__IVSK_M, DOM_SEP__MERKLE_HASH, DOM_SEP__MESSAGE_NULLIFIER, DOM_SEP__MSSK_M, DOM_SEP__NHK_M, - DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, DOM_SEP__NOTE_COMPLETION_LOG_TAG, - DOM_SEP__NOTE_HASH, DOM_SEP__NOTE_HASH_NONCE, DOM_SEP__NOTE_NULLIFIER, - DOM_SEP__NULLIFIER_MERKLE, DOM_SEP__OVSK_M, DOM_SEP__PARTIAL_ADDRESS, - DOM_SEP__PARTIAL_NOTE_COMMITMENT, DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, + DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, DOM_SEP__NOTE_HASH, DOM_SEP__NOTE_HASH_NONCE, + DOM_SEP__NOTE_NULLIFIER, DOM_SEP__NULLIFIER_MERKLE, DOM_SEP__OVSK_M, + DOM_SEP__PARTIAL_ADDRESS, DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, DOM_SEP__PRIVATE_FUNCTION_LEAF, DOM_SEP__PRIVATE_INITIALIZATION_NULLIFIER, DOM_SEP__PRIVATE_LOG_FIRST_FIELD, DOM_SEP__PRIVATE_TX_HASH, DOM_SEP__PROTOCOL_CONTRACTS, DOM_SEP__PUBLIC_BYTECODE, DOM_SEP__PUBLIC_CALLDATA, DOM_SEP__PUBLIC_DATA_MERKLE, @@ -26,8 +23,7 @@ use crate::{ DOM_SEP__PUBLIC_LEAF_SLOT, DOM_SEP__PUBLIC_STORAGE_MAP_SLOT, DOM_SEP__PUBLIC_TX_HASH, DOM_SEP__RETRIEVED_BYTECODES_MERKLE, DOM_SEP__SALTED_INITIALIZATION_HASH, DOM_SEP__SECRET_HASH, DOM_SEP__SIGNATURE_PAYLOAD, DOM_SEP__SILOED_NOTE_HASH, - DOM_SEP__SILOED_NULLIFIER, DOM_SEP__SINGLE_PUBLIC_KEY_HASH, - DOM_SEP__SINGLE_USE_CLAIM_NULLIFIER, DOM_SEP__TSK_M, DOM_SEP__TX_NULLIFIER, + DOM_SEP__SILOED_NULLIFIER, DOM_SEP__SINGLE_PUBLIC_KEY_HASH, DOM_SEP__TSK_M, DOM_SEP__TX_REQUEST, DOM_SEP__UNCONSTRAINED_MSG_LOG_TAG, DOM_SEP__UNIQUE_NOTE_HASH, DOM_SEP__WRITTEN_SLOTS_MERKLE, NULL_MSG_SENDER_CONTRACT_ADDRESS, SIDE_EFFECT_MASKING_ADDRESS, TX_START_PREFIX, @@ -144,7 +140,7 @@ impl HashedValueTester::new(); + let mut tester = HashedValueTester::<67, 62>::new(); // ----------------- // Domain separators @@ -154,10 +150,6 @@ fn hashed_values_match_derived() { tester.assert_dom_sep_matches_derived(DOM_SEP__UNIQUE_NOTE_HASH, "unique_note_hash"); tester.assert_dom_sep_matches_derived(DOM_SEP__SILOED_NOTE_HASH, "siloed_note_hash"); tester.assert_dom_sep_matches_derived(DOM_SEP__NOTE_NULLIFIER, "note_nullifier"); - tester.assert_dom_sep_matches_derived( - DOM_SEP__SINGLE_USE_CLAIM_NULLIFIER, - "single_use_claim_nullifier", - ); tester.assert_dom_sep_matches_derived(DOM_SEP__SILOED_NULLIFIER, "siloed_nullifier"); tester.assert_dom_sep_matches_derived( DOM_SEP__PRIVATE_LOG_FIRST_FIELD, @@ -169,10 +161,6 @@ fn hashed_values_match_derived() { "public_storage_map_slot", ); tester.assert_dom_sep_matches_derived(DOM_SEP__EVENT_LOG_TAG, "event_log_tag"); - tester.assert_dom_sep_matches_derived( - DOM_SEP__NOTE_COMPLETION_LOG_TAG, - "note_completion_log_tag", - ); tester.assert_dom_sep_matches_derived( DOM_SEP__UNCONSTRAINED_MSG_LOG_TAG, "unconstrained_msg_log_tag", @@ -181,10 +169,6 @@ fn hashed_values_match_derived() { DOM_SEP__CONSTRAINED_MSG_LOG_TAG, "constrained_msg_log_tag", ); - tester.assert_dom_sep_matches_derived( - DOM_SEP__CONSTRAINED_MSG_NULLIFIER, - "constrained_msg_nullifier", - ); tester.assert_dom_sep_matches_derived( DOM_SEP__CONSTRAINED_MSG_SENDER_SECRET, "constrained_msg_sender_secret", @@ -230,25 +214,14 @@ fn hashed_values_match_derived() { tester.assert_dom_sep_matches_derived(DOM_SEP__EVENT_COMMITMENT, "event_commitment"); tester.assert_dom_sep_matches_derived(DOM_SEP__AUTHWIT_INNER, "authwit_inner"); tester.assert_dom_sep_matches_derived(DOM_SEP__AUTHWIT_OUTER, "authwit_outer"); - tester.assert_dom_sep_matches_derived(DOM_SEP__AUTHWIT_NULLIFIER, "authwit_nullifier"); tester.assert_dom_sep_matches_derived( DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, "app_siloed_ecdh_shared_secret", ); - tester.assert_dom_sep_matches_derived(DOM_SEP__ECDH_SUBKEY, "ecdh_subkey"); - tester.assert_dom_sep_matches_derived(DOM_SEP__ECDH_FIELD_MASK, "ecdh_field_mask"); tester.assert_dom_sep_matches_derived( DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, "partial_note_validity_commitment", ); - tester.assert_dom_sep_matches_derived( - DOM_SEP__PARTIAL_NOTE_COMMITMENT, - "partial_note_commitment", - ); - tester.assert_dom_sep_matches_derived( - DOM_SEP__INITIALIZATION_NULLIFIER, - "initialization_nullifier", - ); tester.assert_dom_sep_matches_derived( DOM_SEP__PUBLIC_INITIALIZATION_NULLIFIER, "public_initialization_nullifier", @@ -258,7 +231,6 @@ fn hashed_values_match_derived() { "private_initialization_nullifier", ); tester.assert_dom_sep_matches_derived(DOM_SEP__SECRET_HASH, "secret_hash"); - tester.assert_dom_sep_matches_derived(DOM_SEP__TX_NULLIFIER, "tx_nullifier"); tester.assert_dom_sep_matches_derived(DOM_SEP__SIGNATURE_PAYLOAD, "signature_payload"); tester.assert_dom_sep_matches_derived(DOM_SEP__BLOCK_HEADERS_HASH, "block_headers_hash"); tester.assert_dom_sep_matches_derived(DOM_SEP__BLOB_HASHED_Y_LIMBS, "blob_hashed_y_limbs"); diff --git a/noir-projects/labs/aztec-nr/aztec/src/authwit/account.nr b/noir-projects/labs/aztec-nr/aztec/src/authwit/account.nr index 72f5607f1392..c48416aa3446 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/authwit/account.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/authwit/account.nr @@ -1,10 +1,15 @@ use crate::context::PrivateContext; -use crate::protocol::{constants::DOM_SEP__TX_NULLIFIER, hash::poseidon2_hash_with_separator, traits::Hash}; +use crate::protocol::{hash::poseidon2_hash_with_separator, traits::Hash}; use crate::authwit::auth::{compute_authwit_message_hash, IS_VALID_SELECTOR}; use crate::authwit::entrypoint::app::AppPayload; +/// Domain separator for transaction nullifiers +/// +/// Used to produce cancellable (replaceable) transactions. +pub global DOM_SEP__TX_NULLIFIER: u32 = 1025801951; + pub struct AccountActions { context: Context, is_valid_impl: fn(&mut PrivateContext, Field) -> bool, diff --git a/noir-projects/labs/aztec-nr/aztec/src/authwit/auth.nr b/noir-projects/labs/aztec-nr/aztec/src/authwit/auth.nr index f4564b99e84e..3534c510de15 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/authwit/auth.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/authwit/auth.nr @@ -8,12 +8,15 @@ use crate::{ use crate::protocol::{ abis::function_selector::FunctionSelector, address::AztecAddress, - constants::{DOM_SEP__AUTHWIT_INNER, DOM_SEP__AUTHWIT_NULLIFIER, DOM_SEP__AUTHWIT_OUTER}, + constants::{DOM_SEP__AUTHWIT_INNER, DOM_SEP__AUTHWIT_OUTER}, hash::poseidon2_hash_with_separator, traits::{Serialize, ToField}, }; use crate::standard_addresses::STANDARD_AUTH_REGISTRY_ADDRESS; +/// Domain separator for authentication witness nullifiers. +pub global DOM_SEP__AUTHWIT_NULLIFIER: u32 = 1239150694; + /// Authentication witness helper library /// /// Authentication Witness is a scheme for authenticating actions on Aztec, so users can allow third-parties (e.g. diff --git a/noir-projects/labs/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr b/noir-projects/labs/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr index 091ccff3161a..3f1a62db267f 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr @@ -1,6 +1,6 @@ use crate::protocol::{ address::aztec_address::AztecAddress, - constants::{DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, DOM_SEP__ECDH_FIELD_MASK, DOM_SEP__ECDH_SUBKEY}, + constants::DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, hash::poseidon2_hash_with_separator, point::EmbeddedCurvePoint, scalar::Scalar, @@ -8,6 +8,11 @@ use crate::protocol::{ }; use std::{embedded_curve_ops::multi_scalar_mul, ops::Neg}; +/// Domain separator for deriving ECDH sub-secrets from an app-siloed shared secret. +pub global DOM_SEP__ECDH_SUBKEY: u32 = 4277646631; +/// Domain separator for deriving field masks from an app-siloed shared secret. +pub global DOM_SEP__ECDH_FIELD_MASK: u32 = 190532684; + /// Computes a standard ECDH shared secret: secret * public_key = shared_secret. /// /// The input secret is known only to one party. The output shared secret can be derived given knowledge of diff --git a/noir-projects/labs/aztec-nr/aztec/src/macros/functions/initialization_utils.nr b/noir-projects/labs/aztec-nr/aztec/src/macros/functions/initialization_utils.nr index 64d9ddd13daa..b644b0ae1c89 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/macros/functions/initialization_utils.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/macros/functions/initialization_utils.nr @@ -23,6 +23,11 @@ use crate::{ }, }; +/// Domain separator for state variable initialization. +/// +/// Should not be reused for a given storage slot. +pub global DOM_SEP__INITIALIZATION_NULLIFIER: u32 = 1653084894; + /// The name of the auto-generated function that emits the public initialization nullifier. /// /// This function is injected into the public dispatch table for contracts with initializers. diff --git a/noir-projects/labs/aztec-nr/aztec/src/messages/delivery/constrained_delivery.nr b/noir-projects/labs/aztec-nr/aztec/src/messages/delivery/constrained_delivery.nr index 791c7acf5659..9e3bcb14e780 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/messages/delivery/constrained_delivery.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/messages/delivery/constrained_delivery.nr @@ -15,10 +15,13 @@ use crate::messages::delivery::handshake::AppSiloedHandshakeSecrets; use crate::nullifier::utils::compute_nullifier_existence_request; use crate::protocol::{ - abis::function_selector::FunctionSelector, address::AztecAddress, constants::DOM_SEP__CONSTRAINED_MSG_NULLIFIER, - hash::poseidon2_hash_with_separator, traits::ToField, + abis::function_selector::FunctionSelector, address::AztecAddress, hash::poseidon2_hash_with_separator, + traits::ToField, }; +/// Domain separator for nullifiers used during constrained delivery. +pub global DOM_SEP__CONSTRAINED_MSG_NULLIFIER: u32 = 3723577546; + // The helper cannot import the handshake registry interface because the registry contract depends on aztec-nr. The // registry's test suite compares this against its macro-generated `HandshakeRegistry::at(...).method(...).selector` // value so signature drift fails in tests. diff --git a/noir-projects/labs/aztec-nr/aztec/src/messages/processing/mod.nr b/noir-projects/labs/aztec-nr/aztec/src/messages/processing/mod.nr index 1eeb720630d6..248c29c8632f 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/messages/processing/mod.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/messages/processing/mod.nr @@ -22,9 +22,9 @@ use crate::{ oracle::message_processing, partial_notes::DeliveredPendingPartialNote, }; +use crate::note::partial_note::DOM_SEP__NOTE_COMPLETION_LOG_TAG; use crate::protocol::{ address::AztecAddress, - constants::DOM_SEP__NOTE_COMPLETION_LOG_TAG, hash::{compute_log_tag, sha256_to_field}, traits::{Deserialize, Serialize}, }; diff --git a/noir-projects/labs/aztec-nr/aztec/src/note/mod.nr b/noir-projects/labs/aztec-nr/aztec/src/note/mod.nr index 3cb3a7793998..c7acec636c23 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/note/mod.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/note/mod.nr @@ -4,6 +4,7 @@ pub mod constants; pub mod lifecycle; +pub mod partial_note; pub mod note_metadata; pub mod note_getter; pub mod note_getter_options; diff --git a/noir-projects/labs/aztec-nr/aztec/src/note/partial_note.nr b/noir-projects/labs/aztec-nr/aztec/src/note/partial_note.nr new file mode 100644 index 000000000000..156367bdf18d --- /dev/null +++ b/noir-projects/labs/aztec-nr/aztec/src/note/partial_note.nr @@ -0,0 +1,10 @@ +//! Partial notes. + +/// Domain separator for partial note commitments. +/// +/// A partial note commitment is the first round of hashing of a partial note, combining the private fields before the +/// public completion fields (storage slot and public note data) are mixed in. +pub global DOM_SEP__PARTIAL_NOTE_COMMITMENT: u32 = 568912195; + +/// Domain separator for partial note completion log tags. +pub global DOM_SEP__NOTE_COMPLETION_LOG_TAG: u32 = 3372669888; diff --git a/noir-projects/labs/aztec-nr/aztec/src/state_vars/mod.nr b/noir-projects/labs/aztec-nr/aztec/src/state_vars/mod.nr index 362dc6125685..1b0e7955ca97 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/state_vars/mod.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/state_vars/mod.nr @@ -160,7 +160,7 @@ mod single_private_mutable; pub use single_private_mutable::SinglePrivateMutable; mod private_set; pub use private_set::PrivateSet; -mod single_use_claim; +pub(crate) mod single_use_claim; pub use single_use_claim::SingleUseClaim; mod public_immutable; diff --git a/noir-projects/labs/aztec-nr/aztec/src/state_vars/private_immutable.nr b/noir-projects/labs/aztec-nr/aztec/src/state_vars/private_immutable.nr index cf9d6a63482f..ab8d166b2048 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/state_vars/private_immutable.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/state_vars/private_immutable.nr @@ -11,9 +11,9 @@ use crate::{ state_vars::OwnedStateVariable, }; +use crate::macros::functions::initialization_utils::DOM_SEP__INITIALIZATION_NULLIFIER; use crate::protocol::{ address::AztecAddress, - constants::DOM_SEP__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator, traits::{Packable, ToField}, }; diff --git a/noir-projects/labs/aztec-nr/aztec/src/state_vars/private_mutable.nr b/noir-projects/labs/aztec-nr/aztec/src/state_vars/private_mutable.nr index 086f51ee3159..a9bcd9b514a5 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/state_vars/private_mutable.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/state_vars/private_mutable.nr @@ -11,9 +11,9 @@ use crate::{ state_vars::OwnedStateVariable, }; +use crate::macros::functions::initialization_utils::DOM_SEP__INITIALIZATION_NULLIFIER; use crate::protocol::{ address::AztecAddress, - constants::DOM_SEP__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator, traits::{Packable, ToField}, }; diff --git a/noir-projects/labs/aztec-nr/aztec/src/state_vars/public_immutable.nr b/noir-projects/labs/aztec-nr/aztec/src/state_vars/public_immutable.nr index d7f7e99b4754..28956cee6018 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/state_vars/public_immutable.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/state_vars/public_immutable.nr @@ -5,9 +5,8 @@ use crate::{ state_vars::StateVariable, utils::WithHash, }; -use crate::protocol::{ - constants::DOM_SEP__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator, traits::Packable, -}; +use crate::macros::functions::initialization_utils::DOM_SEP__INITIALIZATION_NULLIFIER; +use crate::protocol::{hash::poseidon2_hash_with_separator, traits::Packable}; mod test; diff --git a/noir-projects/labs/aztec-nr/aztec/src/state_vars/single_private_immutable.nr b/noir-projects/labs/aztec-nr/aztec/src/state_vars/single_private_immutable.nr index 9e822bb64cea..bda8f63f4e84 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/state_vars/single_private_immutable.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/state_vars/single_private_immutable.nr @@ -11,9 +11,8 @@ use crate::{ state_vars::StateVariable, }; -use crate::protocol::{ - constants::DOM_SEP__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator, traits::Packable, -}; +use crate::macros::functions::initialization_utils::DOM_SEP__INITIALIZATION_NULLIFIER; +use crate::protocol::{hash::poseidon2_hash_with_separator, traits::Packable}; mod test; diff --git a/noir-projects/labs/aztec-nr/aztec/src/state_vars/single_private_mutable.nr b/noir-projects/labs/aztec-nr/aztec/src/state_vars/single_private_mutable.nr index 04951b29263d..1ec3cbbdb6b4 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/state_vars/single_private_mutable.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/state_vars/single_private_mutable.nr @@ -11,10 +11,8 @@ use crate::{ state_vars::StateVariable, }; -use crate::protocol::{ - address::AztecAddress, constants::DOM_SEP__INITIALIZATION_NULLIFIER, hash::poseidon2_hash_with_separator, - traits::Packable, -}; +use crate::macros::functions::initialization_utils::DOM_SEP__INITIALIZATION_NULLIFIER; +use crate::protocol::{address::AztecAddress, hash::poseidon2_hash_with_separator, traits::Packable}; mod test; diff --git a/noir-projects/labs/aztec-nr/aztec/src/state_vars/single_use_claim.nr b/noir-projects/labs/aztec-nr/aztec/src/state_vars/single_use_claim.nr index 6dfaa23d053f..b16713a0a71f 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/state_vars/single_use_claim.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/state_vars/single_use_claim.nr @@ -1,6 +1,5 @@ use crate::protocol::{ - address::AztecAddress, constants::DOM_SEP__SINGLE_USE_CLAIM_NULLIFIER, hash::poseidon2_hash_with_separator, - traits::ToField, + address::AztecAddress, hash::poseidon2_hash_with_separator, traits::ToField, }; use crate::{ @@ -13,6 +12,9 @@ use crate::{ mod test; +/// Domain separator for `SingleUseClaim` nullifiers. +pub global DOM_SEP__SINGLE_USE_CLAIM_NULLIFIER: u32 = 1465998995; + /// Private right to perform an action. /// /// A private state variable type that represents a right each user can exercise at most once. diff --git a/noir-projects/labs/aztec-nr/aztec/src/test/domain_separators.nr b/noir-projects/labs/aztec-nr/aztec/src/test/domain_separators.nr new file mode 100644 index 000000000000..96aa56a8567c --- /dev/null +++ b/noir-projects/labs/aztec-nr/aztec/src/test/domain_separators.nr @@ -0,0 +1,160 @@ +//! Domain separator tests. +//! +//! Every domain separator is derived by truncating a poseidon hash to `u32` (see the `az_dom_sep` derivation in the +//! protocol crate), so all separators - whether owned by the protocol or by aztec-nr - share a single `u32` space. A +//! collision would let one hashing context be substituted for another. +//! +//! This test checks two things about aztec-nr's separators: that each matches the value derived from its name, and +//! that the whole set (every aztec-nr separator plus every protocol separator) is collision-free. The protocol enforces +//! the same for its own separators in its own tests. + +use crate::authwit::account::DOM_SEP__TX_NULLIFIER; +use crate::authwit::auth::DOM_SEP__AUTHWIT_NULLIFIER; +use crate::keys::ecdh_shared_secret::{DOM_SEP__ECDH_FIELD_MASK, DOM_SEP__ECDH_SUBKEY}; +use crate::macros::functions::initialization_utils::DOM_SEP__INITIALIZATION_NULLIFIER; +use crate::messages::delivery::constrained_delivery::DOM_SEP__CONSTRAINED_MSG_NULLIFIER; +use crate::note::partial_note::{DOM_SEP__NOTE_COMPLETION_LOG_TAG, DOM_SEP__PARTIAL_NOTE_COMMITMENT}; +use crate::state_vars::single_use_claim::DOM_SEP__SINGLE_USE_CLAIM_NULLIFIER; + +use crate::protocol::constants::{ + DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, DOM_SEP__AUTHWIT_INNER, DOM_SEP__AUTHWIT_OUTER, DOM_SEP__BLOB_CHALLENGE_Z, + DOM_SEP__BLOB_GAMMA_ACC, DOM_SEP__BLOB_GAMMA_FINAL, DOM_SEP__BLOB_HASHED_Y_LIMBS, DOM_SEP__BLOB_Z_ACC, + DOM_SEP__BLOCK_HEADER_HASH, DOM_SEP__BLOCK_HEADERS_HASH, DOM_SEP__CONSTRAINED_MSG_LOG_TAG, + DOM_SEP__CONSTRAINED_MSG_SENDER_SECRET, DOM_SEP__CONTRACT_ADDRESS_V2, DOM_SEP__CONTRACT_CLASS_ID, + DOM_SEP__EVENT_COMMITMENT, DOM_SEP__EVENT_LOG_TAG, DOM_SEP__FBSK_M, DOM_SEP__FUNCTION_ARGS, + DOM_SEP__HANDSHAKE_FORGERY_PROTECTION, DOM_SEP__INITIALIZER, DOM_SEP__INTERACTIVE_HANDSHAKE_SIGNATURE, + DOM_SEP__IVSK_M, DOM_SEP__MERKLE_HASH, DOM_SEP__MESSAGE_NULLIFIER, DOM_SEP__MSSK_M, DOM_SEP__NHK_M, + DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, DOM_SEP__NOTE_HASH, DOM_SEP__NOTE_HASH_NONCE, DOM_SEP__NOTE_NULLIFIER, + DOM_SEP__NULLIFIER_MERKLE, DOM_SEP__OVSK_M, DOM_SEP__PARTIAL_ADDRESS, DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, + DOM_SEP__PRIVATE_FUNCTION_LEAF, DOM_SEP__PRIVATE_INITIALIZATION_NULLIFIER, DOM_SEP__PRIVATE_LOG_FIRST_FIELD, + DOM_SEP__PRIVATE_TX_HASH, DOM_SEP__PROTOCOL_CONTRACTS, DOM_SEP__PUBLIC_BYTECODE, DOM_SEP__PUBLIC_CALLDATA, + DOM_SEP__PUBLIC_DATA_MERKLE, DOM_SEP__PUBLIC_INITIALIZATION_NULLIFIER, DOM_SEP__PUBLIC_KEYS_HASH, + DOM_SEP__PUBLIC_LEAF_SLOT, DOM_SEP__PUBLIC_STORAGE_MAP_SLOT, DOM_SEP__PUBLIC_TX_HASH, + DOM_SEP__RETRIEVED_BYTECODES_MERKLE, DOM_SEP__SALTED_INITIALIZATION_HASH, DOM_SEP__SECRET_HASH, + DOM_SEP__SIGNATURE_PAYLOAD, DOM_SEP__SILOED_NOTE_HASH, DOM_SEP__SILOED_NULLIFIER, DOM_SEP__SINGLE_PUBLIC_KEY_HASH, + DOM_SEP__TSK_M, DOM_SEP__TX_REQUEST, DOM_SEP__UNCONSTRAINED_MSG_LOG_TAG, DOM_SEP__UNIQUE_NOTE_HASH, + DOM_SEP__WRITTEN_SLOTS_MERKLE, +}; +use crate::protocol::hash::poseidon2_hash_bytes; + +/// The complete set of domain separators owned by the protocol. +/// +/// Kept in sync with the `protocol_types` crate. +global PROTOCOL_DOMAIN_SEPARATORS: [u32; 59] = [ + DOM_SEP__NOTE_HASH, + DOM_SEP__NOTE_HASH_NONCE, + DOM_SEP__UNIQUE_NOTE_HASH, + DOM_SEP__SILOED_NOTE_HASH, + DOM_SEP__NOTE_NULLIFIER, + DOM_SEP__SILOED_NULLIFIER, + DOM_SEP__PRIVATE_LOG_FIRST_FIELD, + DOM_SEP__PUBLIC_LEAF_SLOT, + DOM_SEP__PUBLIC_STORAGE_MAP_SLOT, + DOM_SEP__EVENT_LOG_TAG, + DOM_SEP__UNCONSTRAINED_MSG_LOG_TAG, + DOM_SEP__CONSTRAINED_MSG_LOG_TAG, + DOM_SEP__CONSTRAINED_MSG_SENDER_SECRET, + DOM_SEP__NON_INTERACTIVE_HANDSHAKE_LOG_TAG, + DOM_SEP__INTERACTIVE_HANDSHAKE_SIGNATURE, + DOM_SEP__HANDSHAKE_FORGERY_PROTECTION, + DOM_SEP__MESSAGE_NULLIFIER, + DOM_SEP__PRIVATE_FUNCTION_LEAF, + DOM_SEP__PUBLIC_BYTECODE, + DOM_SEP__CONTRACT_CLASS_ID, + DOM_SEP__INITIALIZER, + DOM_SEP__SALTED_INITIALIZATION_HASH, + DOM_SEP__NHK_M, + DOM_SEP__IVSK_M, + DOM_SEP__OVSK_M, + DOM_SEP__TSK_M, + DOM_SEP__MSSK_M, + DOM_SEP__FBSK_M, + DOM_SEP__PUBLIC_KEYS_HASH, + DOM_SEP__SINGLE_PUBLIC_KEY_HASH, + DOM_SEP__PARTIAL_ADDRESS, + DOM_SEP__CONTRACT_ADDRESS_V2, + DOM_SEP__BLOCK_HEADER_HASH, + DOM_SEP__TX_REQUEST, + DOM_SEP__PUBLIC_TX_HASH, + DOM_SEP__PRIVATE_TX_HASH, + DOM_SEP__PUBLIC_CALLDATA, + DOM_SEP__FUNCTION_ARGS, + DOM_SEP__PROTOCOL_CONTRACTS, + DOM_SEP__EVENT_COMMITMENT, + DOM_SEP__AUTHWIT_INNER, + DOM_SEP__AUTHWIT_OUTER, + DOM_SEP__APP_SILOED_ECDH_SHARED_SECRET, + DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, + DOM_SEP__PUBLIC_INITIALIZATION_NULLIFIER, + DOM_SEP__PRIVATE_INITIALIZATION_NULLIFIER, + DOM_SEP__SECRET_HASH, + DOM_SEP__SIGNATURE_PAYLOAD, + DOM_SEP__BLOCK_HEADERS_HASH, + DOM_SEP__BLOB_HASHED_Y_LIMBS, + DOM_SEP__BLOB_CHALLENGE_Z, + DOM_SEP__BLOB_Z_ACC, + DOM_SEP__BLOB_GAMMA_ACC, + DOM_SEP__BLOB_GAMMA_FINAL, + DOM_SEP__MERKLE_HASH, + DOM_SEP__NULLIFIER_MERKLE, + DOM_SEP__PUBLIC_DATA_MERKLE, + DOM_SEP__WRITTEN_SLOTS_MERKLE, + DOM_SEP__RETRIEVED_BYTECODES_MERKLE, +]; + +/// Prefix (and `__` joiner) hashed to derive every domain separator's `u32` value. +global DOMAIN_SEPARATOR_PREFIX: str<10> = "az_dom_sep"; + +#[test] +unconstrained fn domain_separators_are_valid() { + // Every separator lives in one u32 space, so the whole set must be collision-free. Start from the protocol + // separators (uniqueness only, as their derivation is checked by the protocol's own tests) and add aztec-nr's on + // top (checking their derivation as we go). + let mut all = PROTOCOL_DOMAIN_SEPARATORS.as_vector(); + + // aztec-nr-owned separators + all = all.push_back(derived(DOM_SEP__PARTIAL_NOTE_COMMITMENT, "partial_note_commitment")); + all = all.push_back(derived(DOM_SEP__NOTE_COMPLETION_LOG_TAG, "note_completion_log_tag")); + all = all + .push_back( + derived( + DOM_SEP__SINGLE_USE_CLAIM_NULLIFIER, + "single_use_claim_nullifier", + ), + ); + all = all.push_back(derived(DOM_SEP__TX_NULLIFIER, "tx_nullifier")); + all = all.push_back(derived(DOM_SEP__AUTHWIT_NULLIFIER, "authwit_nullifier")); + all = all.push_back(derived(DOM_SEP__ECDH_SUBKEY, "ecdh_subkey")); + all = all.push_back(derived(DOM_SEP__ECDH_FIELD_MASK, "ecdh_field_mask")); + all = all + .push_back( + derived( + DOM_SEP__INITIALIZATION_NULLIFIER, + "initialization_nullifier", + ), + ); + all = all + .push_back( + derived( + DOM_SEP__CONSTRAINED_MSG_NULLIFIER, + "constrained_msg_nullifier", + ), + ); + + assert_all_unique(all); +} + +/// Asserts `value` is the domain separator derived from `name`, and returns it. +fn derived(value: u32, name: str) -> u32 { + let bytes = DOMAIN_SEPARATOR_PREFIX.as_bytes().concat("__".as_bytes()).concat(name.as_bytes()); + assert(value == poseidon2_hash_bytes(bytes) as u32); + value +} + +fn assert_all_unique(separators: [u32]) { + for i in 0..separators.len() { + for j in i + 1..separators.len() { + assert(separators[i] != separators[j]); + } + } +} diff --git a/noir-projects/labs/aztec-nr/aztec/src/test/mod.nr b/noir-projects/labs/aztec-nr/aztec/src/test/mod.nr index a967b72c8a90..dd17bd4b54a4 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/test/mod.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/test/mod.nr @@ -2,3 +2,4 @@ pub mod helpers; pub mod mocks; +mod domain_separators; diff --git a/noir-projects/labs/aztec-nr/uint-note/src/uint_note.nr b/noir-projects/labs/aztec-nr/uint-note/src/uint_note.nr index ac66bffc6e47..d1f674f79d75 100644 --- a/noir-projects/labs/aztec-nr/uint-note/src/uint_note.nr +++ b/noir-projects/labs/aztec-nr/uint-note/src/uint_note.nr @@ -6,14 +6,15 @@ use aztec::{ delivery::{do_private_message_delivery, MessageDelivery}, logs::partial_note::encode_partial_note_private_message, }, - note::{note_interface::{NoteHash, NoteType}, utils::{compute_note_hash, compute_note_nullifier}}, + note::{ + note_interface::{NoteHash, NoteType}, + partial_note::{DOM_SEP__NOTE_COMPLETION_LOG_TAG, DOM_SEP__PARTIAL_NOTE_COMMITMENT}, + utils::{compute_note_hash, compute_note_nullifier}, + }, oracle::random::random, protocol::{ address::AztecAddress, - constants::{ - DOM_SEP__NOTE_COMPLETION_LOG_TAG, DOM_SEP__PARTIAL_NOTE_COMMITMENT, - DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, - }, + constants::DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, hash::{compute_log_tag, compute_siloed_nullifier, poseidon2_hash_with_separator}, traits::{Deserialize, FromField, Packable, Serialize, ToField}, }, diff --git a/noir-projects/labs/noir-contracts/contracts/app/nft_contract/src/types/nft_note.nr b/noir-projects/labs/noir-contracts/contracts/app/nft_contract/src/types/nft_note.nr index bc41fd35b4c9..a5c18e719d6d 100644 --- a/noir-projects/labs/noir-contracts/contracts/app/nft_contract/src/types/nft_note.nr +++ b/noir-projects/labs/noir-contracts/contracts/app/nft_contract/src/types/nft_note.nr @@ -6,14 +6,15 @@ use aztec::{ delivery::{do_private_message_delivery, MessageDelivery}, logs::partial_note::encode_partial_note_private_message, }, - note::{note_interface::{NoteHash, NoteType}, utils::{compute_note_hash, compute_note_nullifier}}, + note::{ + note_interface::{NoteHash, NoteType}, + partial_note::{DOM_SEP__NOTE_COMPLETION_LOG_TAG, DOM_SEP__PARTIAL_NOTE_COMMITMENT}, + utils::{compute_note_hash, compute_note_nullifier}, + }, oracle::random::random, protocol::{ address::AztecAddress, - constants::{ - DOM_SEP__NOTE_COMPLETION_LOG_TAG, DOM_SEP__PARTIAL_NOTE_COMMITMENT, - DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, - }, + constants::DOM_SEP__PARTIAL_NOTE_VALIDITY_COMMITMENT, hash::{compute_log_tag, poseidon2_hash_with_separator}, traits::{Deserialize, Packable, Serialize, ToField}, }, From 056dfacf303de586c508a46deb198c7c5ecc7797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Fri, 17 Jul 2026 21:33:18 +0000 Subject: [PATCH 3/6] refactor: scope crate-internal domain separators to pub(crate) Seven of the domain separators moved into aztec-nr are only used within the aztec crate (and its test), so they don't belong on the external API. Downgrade them from pub to pub(crate). PARTIAL_NOTE_COMMITMENT and NOTE_COMPLETION_LOG_TAG stay pub, since the uint-note crate and nft_contract import them. --- noir-projects/labs/aztec-nr/aztec/src/authwit/account.nr | 2 +- noir-projects/labs/aztec-nr/aztec/src/authwit/auth.nr | 2 +- .../labs/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr | 4 ++-- .../aztec/src/macros/functions/initialization_utils.nr | 2 +- .../aztec/src/messages/delivery/constrained_delivery.nr | 2 +- .../labs/aztec-nr/aztec/src/state_vars/single_use_claim.nr | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/noir-projects/labs/aztec-nr/aztec/src/authwit/account.nr b/noir-projects/labs/aztec-nr/aztec/src/authwit/account.nr index c48416aa3446..b161ae3a97b3 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/authwit/account.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/authwit/account.nr @@ -8,7 +8,7 @@ use crate::authwit::entrypoint::app::AppPayload; /// Domain separator for transaction nullifiers /// /// Used to produce cancellable (replaceable) transactions. -pub global DOM_SEP__TX_NULLIFIER: u32 = 1025801951; +pub(crate) global DOM_SEP__TX_NULLIFIER: u32 = 1025801951; pub struct AccountActions { context: Context, diff --git a/noir-projects/labs/aztec-nr/aztec/src/authwit/auth.nr b/noir-projects/labs/aztec-nr/aztec/src/authwit/auth.nr index 3534c510de15..53c744465485 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/authwit/auth.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/authwit/auth.nr @@ -15,7 +15,7 @@ use crate::protocol::{ use crate::standard_addresses::STANDARD_AUTH_REGISTRY_ADDRESS; /// Domain separator for authentication witness nullifiers. -pub global DOM_SEP__AUTHWIT_NULLIFIER: u32 = 1239150694; +pub(crate) global DOM_SEP__AUTHWIT_NULLIFIER: u32 = 1239150694; /// Authentication witness helper library /// diff --git a/noir-projects/labs/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr b/noir-projects/labs/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr index 3f1a62db267f..349d29e074bb 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/keys/ecdh_shared_secret.nr @@ -9,9 +9,9 @@ use crate::protocol::{ use std::{embedded_curve_ops::multi_scalar_mul, ops::Neg}; /// Domain separator for deriving ECDH sub-secrets from an app-siloed shared secret. -pub global DOM_SEP__ECDH_SUBKEY: u32 = 4277646631; +pub(crate) global DOM_SEP__ECDH_SUBKEY: u32 = 4277646631; /// Domain separator for deriving field masks from an app-siloed shared secret. -pub global DOM_SEP__ECDH_FIELD_MASK: u32 = 190532684; +pub(crate) global DOM_SEP__ECDH_FIELD_MASK: u32 = 190532684; /// Computes a standard ECDH shared secret: secret * public_key = shared_secret. /// diff --git a/noir-projects/labs/aztec-nr/aztec/src/macros/functions/initialization_utils.nr b/noir-projects/labs/aztec-nr/aztec/src/macros/functions/initialization_utils.nr index b644b0ae1c89..462ecbc15eed 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/macros/functions/initialization_utils.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/macros/functions/initialization_utils.nr @@ -26,7 +26,7 @@ use crate::{ /// Domain separator for state variable initialization. /// /// Should not be reused for a given storage slot. -pub global DOM_SEP__INITIALIZATION_NULLIFIER: u32 = 1653084894; +pub(crate) global DOM_SEP__INITIALIZATION_NULLIFIER: u32 = 1653084894; /// The name of the auto-generated function that emits the public initialization nullifier. /// diff --git a/noir-projects/labs/aztec-nr/aztec/src/messages/delivery/constrained_delivery.nr b/noir-projects/labs/aztec-nr/aztec/src/messages/delivery/constrained_delivery.nr index 9e3bcb14e780..22e459ccb010 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/messages/delivery/constrained_delivery.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/messages/delivery/constrained_delivery.nr @@ -20,7 +20,7 @@ use crate::protocol::{ }; /// Domain separator for nullifiers used during constrained delivery. -pub global DOM_SEP__CONSTRAINED_MSG_NULLIFIER: u32 = 3723577546; +pub(crate) global DOM_SEP__CONSTRAINED_MSG_NULLIFIER: u32 = 3723577546; // The helper cannot import the handshake registry interface because the registry contract depends on aztec-nr. The // registry's test suite compares this against its macro-generated `HandshakeRegistry::at(...).method(...).selector` diff --git a/noir-projects/labs/aztec-nr/aztec/src/state_vars/single_use_claim.nr b/noir-projects/labs/aztec-nr/aztec/src/state_vars/single_use_claim.nr index b16713a0a71f..a35b1369062b 100644 --- a/noir-projects/labs/aztec-nr/aztec/src/state_vars/single_use_claim.nr +++ b/noir-projects/labs/aztec-nr/aztec/src/state_vars/single_use_claim.nr @@ -13,7 +13,7 @@ use crate::{ mod test; /// Domain separator for `SingleUseClaim` nullifiers. -pub global DOM_SEP__SINGLE_USE_CLAIM_NULLIFIER: u32 = 1465998995; +pub(crate) global DOM_SEP__SINGLE_USE_CLAIM_NULLIFIER: u32 = 1465998995; /// Private right to perform an action. /// From ac3f0da003251772a342ce6f6609046593440905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Fri, 17 Jul 2026 21:48:45 +0000 Subject: [PATCH 4/6] refactor: move DEFAULT_MAX_DEBUG_LOG_MEMORY_READS out of constants.nr This is a node-level DoS-mitigation default (max AVM debug-log memory reads during public tx simulation), not a protocol constant, and it is consumed only by TypeScript. Define it in stdlib's avm.ts next to CollectionLimitsConfig and drop it from constants.nr and the generated C++/TS copies. --- barretenberg/cpp/scripts/constants-codegen/cpp.json | 1 - .../fnd/noir-protocol-circuits/crates/types/src/constants.nr | 4 ---- yarn-project/stdlib/src/avm/avm.ts | 5 ++++- yarn-project/stdlib/src/config/node-rpc-config.ts | 3 ++- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/barretenberg/cpp/scripts/constants-codegen/cpp.json b/barretenberg/cpp/scripts/constants-codegen/cpp.json index 26c2d3aa4f72..eafb52b3cc6a 100644 --- a/barretenberg/cpp/scripts/constants-codegen/cpp.json +++ b/barretenberg/cpp/scripts/constants-codegen/cpp.json @@ -44,7 +44,6 @@ "TIMESTAMP_OF_CHANGE_BIT_SIZE", "UPDATES_DELAYED_PUBLIC_MUTABLE_VALUES_LEN", "UPDATES_DELAYED_PUBLIC_MUTABLE_METADATA_BIT_SIZE", - "DEFAULT_MAX_DEBUG_LOG_MEMORY_READS", "DOM_SEP__SILOED_NOTE_HASH", "DOM_SEP__UNIQUE_NOTE_HASH", "DOM_SEP__NOTE_HASH_NONCE", diff --git a/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants.nr index 597476347b20..e531ddc0df94 100644 --- a/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/fnd/noir-protocol-circuits/crates/types/src/constants.nr @@ -1298,10 +1298,6 @@ pub global UPDATES_DELAYED_PUBLIC_MUTABLE_METADATA_BIT_SIZE: u32 = pub global GRUMPKIN_ONE_X: Field = 1; pub global GRUMPKIN_ONE_Y: Field = 17631683881184975370165255887551781615748388533673675138860; -// Excessive memory reads due to debug logging can open a DOS vector to nodes that perform public tx simulation for users. -// This default limit (4MB) can be configured further by node runners via the `RPC_SIMULATE_PUBLIC_MAX_DEBUG_LOG_MEMORY_READS` environment variable. -pub global DEFAULT_MAX_DEBUG_LOG_MEMORY_READS: u32 = 125000; - mod test { use crate::constants::{ AVM_RETRIEVED_BYTECODES_TREE_HEIGHT, AVM_WRITTEN_PUBLIC_DATA_SLOTS_TREE_HEIGHT, diff --git a/yarn-project/stdlib/src/avm/avm.ts b/yarn-project/stdlib/src/avm/avm.ts index 5ef89c02d0f5..c3b6c7ce482a 100644 --- a/yarn-project/stdlib/src/avm/avm.ts +++ b/yarn-project/stdlib/src/avm/avm.ts @@ -1,4 +1,3 @@ -import { DEFAULT_MAX_DEBUG_LOG_MEMORY_READS } from '@aztec/constants'; import { Fr } from '@aztec/foundation/curves/bn254'; import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc'; @@ -1384,6 +1383,10 @@ export class PublicTxResult { } } +// Excessive memory reads due to debug logging can open a DOS vector to nodes that perform public tx simulation for users. +// This default limit (4MB) can be configured further by node runners via the `RPC_SIMULATE_PUBLIC_MAX_DEBUG_LOG_MEMORY_READS` environment variable. +export const DEFAULT_MAX_DEBUG_LOG_MEMORY_READS = 125000; + export class CollectionLimitsConfig { constructor( public readonly maxDebugLogMemoryReads: number, diff --git a/yarn-project/stdlib/src/config/node-rpc-config.ts b/yarn-project/stdlib/src/config/node-rpc-config.ts index c1d4e70d0d23..d1e9313941c6 100644 --- a/yarn-project/stdlib/src/config/node-rpc-config.ts +++ b/yarn-project/stdlib/src/config/node-rpc-config.ts @@ -1,6 +1,7 @@ -import { DEFAULT_MAX_DEBUG_LOG_MEMORY_READS } from '@aztec/constants'; import { type ConfigMappingsType, numberConfigHelper } from '@aztec/foundation/config'; +import { DEFAULT_MAX_DEBUG_LOG_MEMORY_READS } from '../avm/avm.js'; + export const nodeRpcConfigMappings: ConfigMappingsType = { rpcSimulatePublicMaxGasLimit: { env: 'RPC_SIMULATE_PUBLIC_MAX_GAS_LIMIT', From c2a372e15ecba00462995ff786e83b59ade7e392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Fri, 17 Jul 2026 22:22:21 +0000 Subject: [PATCH 5/6] docs: migration note for domain separators moved out of protocol constants Document the relocation of nine DOM_SEP__* domain separators from the protocol constants module into the aztec crate: two stay public under aztec::note::partial_note, the other seven become pub(crate). --- .../docs/resources/migration_notes.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/docs-developers/docs/resources/migration_notes.md b/docs/docs-developers/docs/resources/migration_notes.md index 2bcf27750ecc..0a9345d5553c 100644 --- a/docs/docs-developers/docs/resources/migration_notes.md +++ b/docs/docs-developers/docs/resources/migration_notes.md @@ -52,6 +52,26 @@ Breaking changes: - `properties()` cannot be used with a custom `Packable` layout. Define property selectors manually for such notes. - Every note field type must implement `Packable`, even when the note's own `Packable` is hand-written. +### [Aztec.nr] Domain separators moved out of the protocol constants module + +Nine `DOM_SEP__*` domain separators that used to live in the protocol constants module (`aztec::protocol::constants`, generated from `noir-protocol-circuits`) have moved into the `aztec` crate, next to the code that uses them. None of them were ever protocol constants (each hash is computed per-contract), so they no longer belong on the protocol export. + +Two remain public, at a new path: + +| Constant | Old path | New path | +| --- | --- | --- | +| `DOM_SEP__PARTIAL_NOTE_COMMITMENT` | `aztec::protocol::constants` | `aztec::note::partial_note` | +| `DOM_SEP__NOTE_COMPLETION_LOG_TAG` | `aztec::protocol::constants` | `aztec::note::partial_note` | + +```diff +- use aztec::protocol::constants::{DOM_SEP__NOTE_COMPLETION_LOG_TAG, DOM_SEP__PARTIAL_NOTE_COMMITMENT}; ++ use aztec::note::partial_note::{DOM_SEP__NOTE_COMPLETION_LOG_TAG, DOM_SEP__PARTIAL_NOTE_COMMITMENT}; +``` + +The other seven are now crate-internal (`pub(crate)`) and can no longer be imported from outside the `aztec` crate: `DOM_SEP__AUTHWIT_NULLIFIER`, `DOM_SEP__TX_NULLIFIER`, `DOM_SEP__SINGLE_USE_CLAIM_NULLIFIER`, `DOM_SEP__CONSTRAINED_MSG_NULLIFIER`, `DOM_SEP__ECDH_SUBKEY`, `DOM_SEP__ECDH_FIELD_MASK`, and `DOM_SEP__INITIALIZATION_NULLIFIER`. + +**Impact**: Contracts that use aztec-nr's high-level APIs (notes, authwit, state variables, message delivery, ECDH) are unaffected, since these separators are applied internally. A contract that imported one of these constants directly must either switch to the new `aztec::note::partial_note` path (for the two public ones) or, for the now-internal ones, call the corresponding aztec-nr helper instead of recomputing the hash by hand. The generated TypeScript `DomainSeparator` enum in `@aztec/constants` / `@aztec/stdlib` likewise no longer contains the seven removed members (their values were unused in TypeScript). + ## 5.0.1 ### [Aztec.nr] History note nullification helpers renamed and restricted to own-contract notes From f51fbcbb900368d966799efe22053d21a43d3f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Venturo?= Date: Wed, 29 Jul 2026 20:55:29 +0000 Subject: [PATCH 6/6] chore: add subkey to docs spellcheck dictionary --- docs/docs-words.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs-words.txt b/docs/docs-words.txt index fbda74069aa2..43b164178123 100644 --- a/docs/docs-words.txt +++ b/docs/docs-words.txt @@ -365,6 +365,7 @@ stakeˮ Standardisation subcomponents suboperation +subkey subpath subpaths Substate